tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

hb-cplusplus.hh (6262B)


      1 /*
      2 * Copyright © 2022 Behdad Esfahbod
      3 *
      4 *  This is part of HarfBuzz, a text shaping library.
      5 *
      6 * Permission is hereby granted, without written agreement and without
      7 * license or royalty fees, to use, copy, modify, and distribute this
      8 * software and its documentation for any purpose, provided that the
      9 * above copyright notice and the following two paragraphs appear in
     10 * all copies of this software.
     11 *
     12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
     13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
     14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
     15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
     16 * DAMAGE.
     17 *
     18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
     19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
     20 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
     21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
     22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
     23 */
     24 
     25 #ifndef HB_CPLUSPLUS_HH
     26 #define HB_CPLUSPLUS_HH
     27 
     28 #include "hb.h"
     29 
     30 #ifdef __cplusplus
     31 
     32 #include <functional>
     33 #include <utility>
     34 
     35 #if 0
     36 #if !(__cplusplus >= 201103L)
     37 #error "HarfBuzz C++ helpers require C++11"
     38 #endif
     39 #endif
     40 
     41 namespace hb {
     42 
     43 
     44 template <typename T>
     45 struct vtable;
     46 
     47 template <typename T>
     48 struct shared_ptr
     49 {
     50  using element_type = T;
     51 
     52  using v = vtable<T>;
     53 
     54  explicit shared_ptr (T *p = nullptr) : p (p) {}
     55  shared_ptr (const shared_ptr &o) : p (v::reference (o.p)) {}
     56  shared_ptr (shared_ptr &&o)  noexcept : p (o.p) { o.p = nullptr; }
     57  shared_ptr& operator = (const shared_ptr &o) { if (p != o.p) { destroy (); p = o.p; reference (); } return *this; }
     58  shared_ptr& operator = (shared_ptr &&o)  noexcept { v::destroy (p); p = o.p; o.p = nullptr; return *this; }
     59  ~shared_ptr () { v::destroy (p); p = nullptr; }
     60 
     61  T* get() const { return p; }
     62 
     63  void swap (shared_ptr &o)  noexcept { std::swap (p, o.p); }
     64  friend void swap (shared_ptr &a, shared_ptr &b)  noexcept { std::swap (a.p, b.p); }
     65 
     66  operator T * () const { return p; }
     67  T& operator * () const { return *get (); }
     68  T* operator -> () const { return get (); }
     69  operator bool () const { return p; }
     70  bool operator == (const shared_ptr &o) const { return p == o.p; }
     71  bool operator != (const shared_ptr &o) const { return p != o.p; }
     72 
     73  static T* get_empty() { return v::get_empty (); }
     74  T* reference() { return v::reference (p); }
     75  void destroy() { v::destroy (p); }
     76  void set_user_data (hb_user_data_key_t *key,
     77 	      void *value,
     78 	      hb_destroy_func_t destroy,
     79 	      hb_bool_t replace) { v::set_user_data (p, key, value, destroy, replace); } 
     80  void * get_user_data (hb_user_data_key_t *key) { return v::get_user_data (p, key); }
     81 
     82  private:
     83  T *p;
     84 };
     85 
     86 template<typename T> struct is_shared_ptr : std::false_type {};
     87 template<typename T> struct is_shared_ptr<shared_ptr<T>> : std::true_type {};
     88 
     89 template <typename T>
     90 struct unique_ptr
     91 {
     92  using element_type = T;
     93 
     94  using v = vtable<T>;
     95 
     96  explicit unique_ptr (T *p = nullptr) : p (p) {}
     97  unique_ptr (const unique_ptr &o) = delete;
     98  unique_ptr (unique_ptr &&o)  noexcept : p (o.p) { o.p = nullptr; }
     99  unique_ptr& operator = (const unique_ptr &o) = delete;
    100  unique_ptr& operator = (unique_ptr &&o)  noexcept { v::destroy (p); p = o.p; o.p = nullptr; return *this; }
    101  ~unique_ptr () { v::destroy (p); p = nullptr; }
    102 
    103  T* get() const { return p; }
    104  T* release () { T* v = p; p = nullptr; return v; }
    105 
    106  void swap (unique_ptr &o)  noexcept { std::swap (p, o.p); }
    107  friend void swap (unique_ptr &a, unique_ptr &b)  noexcept { std::swap (a.p, b.p); }
    108 
    109  operator T * () const { return p; }
    110  T& operator * () const { return *get (); }
    111  T* operator -> () const { return get (); }
    112  operator bool () { return p; }
    113 
    114  private:
    115  T *p;
    116 };
    117 
    118 template<typename T> struct is_unique_ptr : std::false_type {};
    119 template<typename T> struct is_unique_ptr<unique_ptr<T>> : std::true_type {};
    120 
    121 template <typename T,
    122   T * (*_get_empty) (void),
    123   T * (*_reference) (T *),
    124   void (*_destroy) (T *),
    125   hb_bool_t (*_set_user_data) (T *,
    126 			       hb_user_data_key_t *,
    127 			       void *,
    128 			       hb_destroy_func_t,
    129 			       hb_bool_t),
    130   void * (*_get_user_data) (const T *,
    131 			    hb_user_data_key_t *)>
    132 struct vtable_t
    133 {
    134  static constexpr auto get_empty = _get_empty;
    135  static constexpr auto reference = _reference;
    136  static constexpr auto destroy = _destroy;
    137  static constexpr auto set_user_data = _set_user_data;
    138  static constexpr auto get_user_data = _get_user_data;
    139 };
    140 
    141 #define HB_DEFINE_VTABLE(name) \
    142 template<> \
    143 struct vtable<hb_##name##_t> \
    144      : vtable_t<hb_##name##_t, \
    145 		&hb_##name##_get_empty, \
    146 		&hb_##name##_reference, \
    147 		&hb_##name##_destroy, \
    148 		&hb_##name##_set_user_data, \
    149 		&hb_##name##_get_user_data> {}
    150 
    151 HB_DEFINE_VTABLE (buffer);
    152 HB_DEFINE_VTABLE (blob);
    153 HB_DEFINE_VTABLE (face);
    154 HB_DEFINE_VTABLE (font);
    155 HB_DEFINE_VTABLE (font_funcs);
    156 HB_DEFINE_VTABLE (map);
    157 HB_DEFINE_VTABLE (set);
    158 HB_DEFINE_VTABLE (shape_plan);
    159 HB_DEFINE_VTABLE (unicode_funcs);
    160 HB_DEFINE_VTABLE (draw_funcs);
    161 HB_DEFINE_VTABLE (paint_funcs);
    162 
    163 #undef HB_DEFINE_VTABLE
    164 
    165 
    166 #ifdef HB_SUBSET_H
    167 
    168 #define HB_DEFINE_VTABLE(name) \
    169 template<> \
    170 struct vtable<hb_##name##_t> \
    171      : vtable_t<hb_##name##_t, \
    172 		nullptr, \
    173 		&hb_##name##_reference, \
    174 		&hb_##name##_destroy, \
    175 		&hb_##name##_set_user_data, \
    176 		&hb_##name##_get_user_data> {}
    177 
    178 
    179 HB_DEFINE_VTABLE (subset_input);
    180 HB_DEFINE_VTABLE (subset_plan);
    181 
    182 #undef HB_DEFINE_VTABLE
    183 
    184 #endif
    185 
    186 
    187 } // namespace hb
    188 
    189 /* Workaround for GCC < 7, see:
    190 * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480
    191 * https://stackoverflow.com/a/25594741 */
    192 namespace std {
    193 
    194 
    195 template<typename T>
    196 struct hash<hb::shared_ptr<T>>
    197 {
    198    std::size_t operator()(const hb::shared_ptr<T>& v) const noexcept
    199    {
    200        std::size_t h = std::hash<decltype (v.get ())>{}(v.get ());
    201        return h;
    202    }
    203 };
    204 
    205 template<typename T>
    206 struct hash<hb::unique_ptr<T>>
    207 {
    208    std::size_t operator()(const hb::unique_ptr<T>& v) const noexcept
    209    {
    210        std::size_t h = std::hash<decltype (v.get ())>{}(v.get ());
    211        return h;
    212    }
    213 };
    214 
    215 
    216 } // namespace std
    217 
    218 #endif /* __cplusplus */
    219 
    220 #endif /* HB_CPLUSPLUS_HH */