Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 10:04:01

0001 /*
0002  * Copyright © 2022 Behdad Esfahbod
0003  *
0004  *  This is part of HarfBuzz, a text shaping library.
0005  *
0006  * Permission is hereby granted, without written agreement and without
0007  * license or royalty fees, to use, copy, modify, and distribute this
0008  * software and its documentation for any purpose, provided that the
0009  * above copyright notice and the following two paragraphs appear in
0010  * all copies of this software.
0011  *
0012  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
0013  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
0014  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
0015  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
0016  * DAMAGE.
0017  *
0018  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
0019  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
0020  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
0021  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
0022  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
0023  */
0024 
0025 #ifndef HB_CPLUSPLUS_HH
0026 #define HB_CPLUSPLUS_HH
0027 
0028 #include "hb.h"
0029 
0030 #ifdef __cplusplus
0031 
0032 #include <functional>
0033 #include <utility>
0034 
0035 #if 0
0036 #if !(__cplusplus >= 201103L)
0037 #error "HarfBuzz C++ helpers require C++11"
0038 #endif
0039 #endif
0040 
0041 namespace hb {
0042 
0043 
0044 template <typename T>
0045 struct vtable;
0046 
0047 template <typename T>
0048 struct shared_ptr
0049 {
0050   using element_type = T;
0051 
0052   using v = vtable<T>;
0053 
0054   explicit shared_ptr (T *p = nullptr) : p (p) {}
0055   shared_ptr (const shared_ptr &o) : p (v::reference (o.p)) {}
0056   shared_ptr (shared_ptr &&o)  noexcept : p (o.p) { o.p = nullptr; }
0057   shared_ptr& operator = (const shared_ptr &o) { if (p != o.p) { destroy (); p = o.p; reference (); } return *this; }
0058   shared_ptr& operator = (shared_ptr &&o)  noexcept { v::destroy (p); p = o.p; o.p = nullptr; return *this; }
0059   ~shared_ptr () { v::destroy (p); p = nullptr; }
0060 
0061   T* get() const { return p; }
0062 
0063   void swap (shared_ptr &o)  noexcept { std::swap (p, o.p); }
0064   friend void swap (shared_ptr &a, shared_ptr &b)  noexcept { std::swap (a.p, b.p); }
0065 
0066   operator T * () const { return p; }
0067   T& operator * () const { return *get (); }
0068   T* operator -> () const { return get (); }
0069   operator bool () const { return p; }
0070   bool operator == (const shared_ptr &o) const { return p == o.p; }
0071   bool operator != (const shared_ptr &o) const { return p != o.p; }
0072 
0073   static T* get_empty() { return v::get_empty (); }
0074   T* reference() { return v::reference (p); }
0075   void destroy() { v::destroy (p); }
0076   void set_user_data (hb_user_data_key_t *key,
0077               void *value,
0078               hb_destroy_func_t destroy,
0079               hb_bool_t replace) { v::set_user_data (p, key, value, destroy, replace); } 
0080   void * get_user_data (hb_user_data_key_t *key) { return v::get_user_data (p, key); }
0081 
0082   private:
0083   T *p;
0084 };
0085 
0086 template<typename T> struct is_shared_ptr : std::false_type {};
0087 template<typename T> struct is_shared_ptr<shared_ptr<T>> : std::true_type {};
0088 
0089 template <typename T>
0090 struct unique_ptr
0091 {
0092   using element_type = T;
0093 
0094   using v = vtable<T>;
0095 
0096   explicit unique_ptr (T *p = nullptr) : p (p) {}
0097   unique_ptr (const unique_ptr &o) = delete;
0098   unique_ptr (unique_ptr &&o)  noexcept : p (o.p) { o.p = nullptr; }
0099   unique_ptr& operator = (const unique_ptr &o) = delete;
0100   unique_ptr& operator = (unique_ptr &&o)  noexcept { v::destroy (p); p = o.p; o.p = nullptr; return *this; }
0101   ~unique_ptr () { v::destroy (p); p = nullptr; }
0102 
0103   T* get() const { return p; }
0104   T* release () { T* v = p; p = nullptr; return v; }
0105 
0106   void swap (unique_ptr &o)  noexcept { std::swap (p, o.p); }
0107   friend void swap (unique_ptr &a, unique_ptr &b)  noexcept { std::swap (a.p, b.p); }
0108 
0109   operator T * () const { return p; }
0110   T& operator * () const { return *get (); }
0111   T* operator -> () const { return get (); }
0112   operator bool () { return p; }
0113 
0114   private:
0115   T *p;
0116 };
0117 
0118 template<typename T> struct is_unique_ptr : std::false_type {};
0119 template<typename T> struct is_unique_ptr<unique_ptr<T>> : std::true_type {};
0120 
0121 template <typename T,
0122       T * (*_get_empty) (void),
0123       T * (*_reference) (T *),
0124       void (*_destroy) (T *),
0125       hb_bool_t (*_set_user_data) (T *,
0126                        hb_user_data_key_t *,
0127                        void *,
0128                        hb_destroy_func_t,
0129                        hb_bool_t),
0130       void * (*_get_user_data) (const T *,
0131                     hb_user_data_key_t *)>
0132 struct vtable_t
0133 {
0134   static constexpr auto get_empty = _get_empty;
0135   static constexpr auto reference = _reference;
0136   static constexpr auto destroy = _destroy;
0137   static constexpr auto set_user_data = _set_user_data;
0138   static constexpr auto get_user_data = _get_user_data;
0139 };
0140 
0141 #define HB_DEFINE_VTABLE(name) \
0142     template<> \
0143     struct vtable<hb_##name##_t> \
0144          : vtable_t<hb_##name##_t, \
0145             &hb_##name##_get_empty, \
0146             &hb_##name##_reference, \
0147             &hb_##name##_destroy, \
0148             &hb_##name##_set_user_data, \
0149             &hb_##name##_get_user_data> {}
0150 
0151 HB_DEFINE_VTABLE (buffer);
0152 HB_DEFINE_VTABLE (blob);
0153 HB_DEFINE_VTABLE (face);
0154 HB_DEFINE_VTABLE (font);
0155 HB_DEFINE_VTABLE (font_funcs);
0156 HB_DEFINE_VTABLE (map);
0157 HB_DEFINE_VTABLE (set);
0158 HB_DEFINE_VTABLE (shape_plan);
0159 HB_DEFINE_VTABLE (unicode_funcs);
0160 HB_DEFINE_VTABLE (draw_funcs);
0161 HB_DEFINE_VTABLE (paint_funcs);
0162 
0163 #undef HB_DEFINE_VTABLE
0164 
0165 
0166 #ifdef HB_SUBSET_H
0167 
0168 #define HB_DEFINE_VTABLE(name) \
0169     template<> \
0170     struct vtable<hb_##name##_t> \
0171          : vtable_t<hb_##name##_t, \
0172             nullptr, \
0173             &hb_##name##_reference, \
0174             &hb_##name##_destroy, \
0175             &hb_##name##_set_user_data, \
0176             &hb_##name##_get_user_data> {}
0177 
0178 
0179 HB_DEFINE_VTABLE (subset_input);
0180 HB_DEFINE_VTABLE (subset_plan);
0181 
0182 #undef HB_DEFINE_VTABLE
0183 
0184 #endif
0185 
0186 
0187 } // namespace hb
0188 
0189 /* Workaround for GCC < 7, see:
0190  * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480
0191  * https://stackoverflow.com/a/25594741 */
0192 namespace std {
0193 
0194 
0195 template<typename T>
0196 struct hash<hb::shared_ptr<T>>
0197 {
0198     std::size_t operator()(const hb::shared_ptr<T>& v) const noexcept
0199     {
0200         std::size_t h = std::hash<decltype (v.get ())>{}(v.get ());
0201         return h;
0202     }
0203 };
0204 
0205 template<typename T>
0206 struct hash<hb::unique_ptr<T>>
0207 {
0208     std::size_t operator()(const hb::unique_ptr<T>& v) const noexcept
0209     {
0210         std::size_t h = std::hash<decltype (v.get ())>{}(v.get ());
0211         return h;
0212     }
0213 };
0214 
0215 
0216 } // namespace std
0217 
0218 #endif /* __cplusplus */
0219 
0220 #endif /* HB_CPLUSPLUS_HH */