File indexing completed on 2025-02-21 10:04:01
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
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 }
0188
0189
0190
0191
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 }
0217
0218 #endif
0219
0220 #endif