Edit

kc3-lang/harfbuzz/src/hb-cplusplus.hh

Branch :

  • Show log

    Commit

  • Author : Behdad Esfahbod
    Date : 2024-04-01 01:54:09
    Hash : 7de2d111
    Message : Fix autotools test

  • src/hb-cplusplus.hh
  • /*
     * Copyright © 2022 Behdad Esfahbod
     *
     *  This is part of HarfBuzz, a text shaping library.
     *
     * Permission is hereby granted, without written agreement and without
     * license or royalty fees, to use, copy, modify, and distribute this
     * software and its documentation for any purpose, provided that the
     * above copyright notice and the following two paragraphs appear in
     * all copies of this software.
     *
     * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
     * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
     * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
     * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
     * DAMAGE.
     *
     * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
     * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
     * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
     * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
     * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
     */
    
    #ifndef HB_CPLUSPLUS_HH
    #define HB_CPLUSPLUS_HH
    
    #include "hb.h"
    
    #ifdef __cplusplus
    
    #include <functional>
    #include <utility>
    
    #if 0
    #if !(__cplusplus >= 201103L)
    #error "HarfBuzz C++ helpers require C++11"
    #endif
    #endif
    
    namespace hb {
    
    
    template <typename T>
    struct vtable;
    
    template <typename T>
    struct shared_ptr
    {
      using element_type = T;
    
      using v = vtable<T>;
    
      explicit shared_ptr (T *p = nullptr) : p (p) {}
      shared_ptr (const shared_ptr &o) : p (v::reference (o.p)) {}
      shared_ptr (shared_ptr &&o)  noexcept : p (o.p) { o.p = nullptr; }
      shared_ptr& operator = (const shared_ptr &o) { if (p != o.p) { destroy (); p = o.p; reference (); } return *this; }
      shared_ptr& operator = (shared_ptr &&o)  noexcept { v::destroy (p); p = o.p; o.p = nullptr; return *this; }
      ~shared_ptr () { v::destroy (p); p = nullptr; }
    
      T* get() const { return p; }
    
      void swap (shared_ptr &o)  noexcept { std::swap (p, o.p); }
      friend void swap (shared_ptr &a, shared_ptr &b)  noexcept { std::swap (a.p, b.p); }
    
      operator T * () const { return p; }
      T& operator * () const { return *get (); }
      T* operator -> () const { return get (); }
      operator bool () const { return p; }
      bool operator == (const shared_ptr &o) const { return p == o.p; }
      bool operator != (const shared_ptr &o) const { return p != o.p; }
    
      static T* get_empty() { return v::get_empty (); }
      T* reference() { return v::reference (p); }
      void destroy() { v::destroy (p); }
      void set_user_data (hb_user_data_key_t *key,
    		      void *value,
    		      hb_destroy_func_t destroy,
    		      hb_bool_t replace) { v::set_user_data (p, key, value, destroy, replace); } 
      void * get_user_data (hb_user_data_key_t *key) { return v::get_user_data (p, key); }
    
      private:
      T *p;
    };
    
    template<typename T> struct is_shared_ptr : std::false_type {};
    template<typename T> struct is_shared_ptr<shared_ptr<T>> : std::true_type {};
    
    template <typename T>
    struct unique_ptr
    {
      using element_type = T;
    
      using v = vtable<T>;
    
      explicit unique_ptr (T *p = nullptr) : p (p) {}
      unique_ptr (const unique_ptr &o) = delete;
      unique_ptr (unique_ptr &&o)  noexcept : p (o.p) { o.p = nullptr; }
      unique_ptr& operator = (const unique_ptr &o) = delete;
      unique_ptr& operator = (unique_ptr &&o)  noexcept { v::destroy (p); p = o.p; o.p = nullptr; return *this; }
      ~unique_ptr () { v::destroy (p); p = nullptr; }
    
      T* get() const { return p; }
      T* release () { T* v = p; p = nullptr; return v; }
    
      void swap (unique_ptr &o)  noexcept { std::swap (p, o.p); }
      friend void swap (unique_ptr &a, unique_ptr &b)  noexcept { std::swap (a.p, b.p); }
    
      operator T * () const { return p; }
      T& operator * () const { return *get (); }
      T* operator -> () const { return get (); }
      operator bool () { return p; }
    
      private:
      T *p;
    };
    
    template<typename T> struct is_unique_ptr : std::false_type {};
    template<typename T> struct is_unique_ptr<unique_ptr<T>> : std::true_type {};
    
    template <typename T,
    	  T * (*_get_empty) (void),
    	  T * (*_reference) (T *),
    	  void (*_destroy) (T *),
    	  hb_bool_t (*_set_user_data) (T *,
    				       hb_user_data_key_t *,
    				       void *,
    				       hb_destroy_func_t,
    				       hb_bool_t),
    	  void * (*_get_user_data) (const T *,
    				    hb_user_data_key_t *)>
    struct vtable_t
    {
      static constexpr auto get_empty = _get_empty;
      static constexpr auto reference = _reference;
      static constexpr auto destroy = _destroy;
      static constexpr auto set_user_data = _set_user_data;
      static constexpr auto get_user_data = _get_user_data;
    };
    
    #define HB_DEFINE_VTABLE(name) \
    	template<> \
    	struct vtable<hb_##name##_t> \
    	     : vtable_t<hb_##name##_t, \
    			&hb_##name##_get_empty, \
    			&hb_##name##_reference, \
    			&hb_##name##_destroy, \
    			&hb_##name##_set_user_data, \
    			&hb_##name##_get_user_data> {}
    
    HB_DEFINE_VTABLE (buffer);
    HB_DEFINE_VTABLE (blob);
    HB_DEFINE_VTABLE (face);
    HB_DEFINE_VTABLE (font);
    HB_DEFINE_VTABLE (font_funcs);
    HB_DEFINE_VTABLE (map);
    HB_DEFINE_VTABLE (set);
    HB_DEFINE_VTABLE (shape_plan);
    HB_DEFINE_VTABLE (unicode_funcs);
    HB_DEFINE_VTABLE (draw_funcs);
    HB_DEFINE_VTABLE (paint_funcs);
    
    #undef HB_DEFINE_VTABLE
    
    
    #ifdef HB_SUBSET_H
    
    #define HB_DEFINE_VTABLE(name) \
    	template<> \
    	struct vtable<hb_##name##_t> \
    	     : vtable_t<hb_##name##_t, \
    			nullptr, \
    			&hb_##name##_reference, \
    			&hb_##name##_destroy, \
    			&hb_##name##_set_user_data, \
    			&hb_##name##_get_user_data> {}
    
    
    HB_DEFINE_VTABLE (subset_input);
    HB_DEFINE_VTABLE (subset_plan);
    
    #undef HB_DEFINE_VTABLE
    
    #endif
    
    
    } // namespace hb
    
    /* Workaround for GCC < 7, see:
     * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480
     * https://stackoverflow.com/a/25594741 */
    namespace std {
    
    
    template<typename T>
    struct hash<hb::shared_ptr<T>>
    {
        std::size_t operator()(const hb::shared_ptr<T>& v) const noexcept
        {
            std::size_t h = std::hash<decltype (v.get ())>{}(v.get ());
            return h;
        }
    };
    
    template<typename T>
    struct hash<hb::unique_ptr<T>>
    {
        std::size_t operator()(const hb::unique_ptr<T>& v) const noexcept
        {
            std::size_t h = std::hash<decltype (v.get ())>{}(v.get ());
            return h;
        }
    };
    
    
    } // namespace std
    
    #endif /* __cplusplus */
    
    #endif /* HB_CPLUSPLUS_HH */