tor-browser

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

hb-algs.hh (49120B)


      1 /*
      2 * Copyright © 2017  Google, Inc.
      3 * Copyright © 2019  Facebook, Inc.
      4 *
      5 *  This is part of HarfBuzz, a text shaping library.
      6 *
      7 * Permission is hereby granted, without written agreement and without
      8 * license or royalty fees, to use, copy, modify, and distribute this
      9 * software and its documentation for any purpose, provided that the
     10 * above copyright notice and the following two paragraphs appear in
     11 * all copies of this software.
     12 *
     13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
     14 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
     15 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
     16 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
     17 * DAMAGE.
     18 *
     19 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
     20 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
     21 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
     22 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
     23 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
     24 *
     25 * Google Author(s): Behdad Esfahbod
     26 * Facebook Author(s): Behdad Esfahbod
     27 */
     28 
     29 #ifndef HB_ALGS_HH
     30 #define HB_ALGS_HH
     31 
     32 #include "hb.hh"
     33 #include "hb-meta.hh"
     34 #include "hb-null.hh"
     35 #include "hb-number.hh"
     36 
     37 #include <algorithm>
     38 #include <initializer_list>
     39 #include <functional>
     40 #include <new>
     41 
     42 /*
     43 * Flags
     44 */
     45 
     46 /* Enable bitwise ops on enums marked as flags_t */
     47 /* To my surprise, looks like the function resolver is happy to silently cast
     48 * one enum to another...  So this doesn't provide the type-checking that I
     49 * originally had in mind... :(.
     50 *
     51 * For MSVC warnings, see: https://github.com/harfbuzz/harfbuzz/pull/163
     52 */
     53 #ifdef _MSC_VER
     54 # pragma warning(disable:4200)
     55 # pragma warning(disable:4800)
     56 #endif
     57 #define HB_MARK_AS_FLAG_T(T) \
     58 extern "C++" { \
     59   static inline constexpr T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \
     60   static inline constexpr T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \
     61   static inline constexpr T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \
     62   static inline constexpr unsigned operator ~ (T r) { return (~(unsigned) r); } \
     63   static inline T& operator |= (T &l, T r) { l = l | r; return l; } \
     64   static inline T& operator &= (T& l, T r) { l = l & r; return l; } \
     65   static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \
     66 } \
     67 static_assert (true, "")
     68 
     69 /* Useful for set-operations on small enums.
     70 * For example, for testing "x ∈ {x1, x2, x3}" use:
     71 * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3)))
     72 */
     73 #define FLAG(x) (static_assert_expr ((unsigned)(x) < 32) + (((uint32_t) 1U) << (unsigned)(x)))
     74 #define FLAG_UNSAFE(x) ((unsigned)(x) < 32 ? (((uint32_t) 1U) << (unsigned)(x)) : 0)
     75 #define FLAG_RANGE(x,y) (static_assert_expr ((x) < (y)) + FLAG(y+1) - FLAG(x))
     76 #define FLAG64(x) (static_assert_expr ((unsigned)(x) < 64) + (((uint64_t) 1ULL) << (unsigned)(x)))
     77 #define FLAG64_UNSAFE(x) ((unsigned)(x) < 64 ? (((uint64_t) 1ULL) << (unsigned)(x)) : 0)
     78 
     79 
     80 /*
     81 * Fixed-endian integers / floats.
     82 */
     83 
     84 
     85 /* Endian swap, used in Windows related backends */
     86 static inline constexpr uint16_t hb_uint16_swap (uint16_t v)
     87 { return (v >> 8) | (v << 8); }
     88 static inline constexpr uint32_t hb_uint32_swap (uint32_t v)
     89 { return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); }
     90 
     91 template <typename Type>
     92 struct __attribute__((packed)) hb_packed_t { Type v; };
     93 
     94 #ifndef HB_FAST_NUM_ACCESS
     95 
     96 #if defined(__OPTIMIZE__) && \
     97    defined(__BYTE_ORDER) && \
     98    (__BYTE_ORDER == __BIG_ENDIAN || \
     99     (__BYTE_ORDER == __LITTLE_ENDIAN && \
    100      hb_has_builtin(__builtin_bswap16) && \
    101      hb_has_builtin(__builtin_bswap32) && \
    102      hb_has_builtin(__builtin_bswap64)))
    103 #define HB_FAST_NUM_ACCESS 1
    104 #else
    105 #define HB_FAST_NUM_ACCESS 0
    106 #endif
    107 
    108 // https://github.com/harfbuzz/harfbuzz/issues/5456
    109 #if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ <= 12)
    110 #undef HB_FAST_NUM_ACCESS
    111 #define HB_FAST_NUM_ACCESS 0
    112 #endif
    113 
    114 #endif
    115 
    116 template <bool BE, typename Type, int Bytes = sizeof (Type)>
    117 struct HBInt;
    118 template <bool BE, typename Type>
    119 struct HBInt<BE, Type, 1>
    120 {
    121  public:
    122  HBInt () = default;
    123  constexpr HBInt (Type V) : v {uint8_t (V)} {}
    124  constexpr operator Type () const { return v; }
    125  private: uint8_t v;
    126 };
    127 template <bool BE, typename Type>
    128 struct HBInt<BE, Type, 2>
    129 {
    130  public:
    131  HBInt () = default;
    132 
    133  HBInt (Type V)
    134 #if HB_FAST_NUM_ACCESS
    135  {
    136    if (BE == (__BYTE_ORDER == __BIG_ENDIAN))
    137      ((hb_packed_t<uint16_t> *) v)->v = V;
    138    else
    139      ((hb_packed_t<uint16_t> *) v)->v = __builtin_bswap16 (V);
    140  }
    141 #else
    142    : v {BE ? uint8_t ((V >>  8) & 0xFF) : uint8_t ((V      ) & 0xFF),
    143  BE ? uint8_t ((V      ) & 0xFF) : uint8_t ((V >>  8) & 0xFF)} {}
    144 #endif
    145 
    146  constexpr operator Type () const
    147  {
    148 #if HB_FAST_NUM_ACCESS
    149    return (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ?
    150      ((const hb_packed_t<uint16_t> *) v)->v
    151    :
    152      __builtin_bswap16 (((const hb_packed_t<uint16_t> *) v)->v)
    153    ;
    154 #else
    155    return (BE ? (v[0] <<  8) : (v[0]      ))
    156  + (BE ? (v[1]      ) : (v[1] <<  8));
    157 #endif
    158  }
    159  private: uint8_t v[2];
    160 };
    161 template <bool BE, typename Type>
    162 struct HBInt<BE, Type, 3>
    163 {
    164  static_assert (!std::is_signed<Type>::value, "");
    165  public:
    166  HBInt () = default;
    167  constexpr HBInt (Type V) : v {BE ? uint8_t ((V >> 16) & 0xFF) : uint8_t ((V >> 16) & 0xFF),
    168 			BE ? uint8_t ((V >>  8) & 0xFF) : uint8_t ((V >>  8) & 0xFF),
    169 			BE ? uint8_t ((V      ) & 0xFF) : uint8_t ((V      ) & 0xFF)} {}
    170 
    171  constexpr operator Type () const { return (BE ? (v[0] << 16) : (v[0]      ))
    172 				  + (BE ? (v[1] <<  8) : (v[1] <<  8))
    173 				  + (BE ? (v[2]      ) : (v[2] << 16)); }
    174  private: uint8_t v[3];
    175 };
    176 template <bool BE, typename Type>
    177 struct HBInt<BE, Type, 4>
    178 {
    179  template <bool, typename, int>
    180  friend struct HBFloat;
    181 
    182  public:
    183  HBInt () = default;
    184 
    185  HBInt (Type V)
    186 #if HB_FAST_NUM_ACCESS
    187  {
    188    if (BE == (__BYTE_ORDER == __BIG_ENDIAN))
    189      ((hb_packed_t<uint32_t> *) v)->v = V;
    190    else
    191      ((hb_packed_t<uint32_t> *) v)->v = __builtin_bswap32 (V);
    192  }
    193 #else
    194    : v {BE ? uint8_t ((V >> 24) & 0xFF) : uint8_t ((V      ) & 0xFF),
    195  BE ? uint8_t ((V >> 16) & 0xFF) : uint8_t ((V >>  8) & 0xFF),
    196  BE ? uint8_t ((V >>  8) & 0xFF) : uint8_t ((V >> 16) & 0xFF),
    197  BE ? uint8_t ((V      ) & 0xFF) : uint8_t ((V >> 24) & 0xFF)} {}
    198 #endif
    199 
    200  constexpr operator Type () const {
    201 #if HB_FAST_NUM_ACCESS
    202    return (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ?
    203      ((const hb_packed_t<uint32_t> *) v)->v
    204    :
    205      __builtin_bswap32 (((const hb_packed_t<uint32_t> *) v)->v)
    206    ;
    207 #else
    208    return (BE ? (v[0] << 24) : (v[0]      ))
    209  + (BE ? (v[1] << 16) : (v[1] <<  8))
    210  + (BE ? (v[2] <<  8) : (v[2] << 16))
    211  + (BE ? (v[3]      ) : (v[3] << 24));
    212 #endif
    213  }
    214  private: uint8_t v[4];
    215 };
    216 template <bool BE, typename Type>
    217 struct HBInt<BE, Type, 8>
    218 {
    219  template <bool, typename, int>
    220  friend struct HBFloat;
    221 
    222  public:
    223  HBInt () = default;
    224 
    225  HBInt (Type V)
    226 #if HB_FAST_NUM_ACCESS
    227  {
    228    if (BE == (__BYTE_ORDER == __BIG_ENDIAN))
    229      ((hb_packed_t<uint64_t> *) v)->v = V;
    230    else
    231      ((hb_packed_t<uint64_t> *) v)->v = __builtin_bswap64 (V);
    232  }
    233 #else
    234    : v {BE ? uint8_t ((V >> 56) & 0xFF) : uint8_t ((V      ) & 0xFF),
    235  BE ? uint8_t ((V >> 48) & 0xFF) : uint8_t ((V >>  8) & 0xFF),
    236  BE ? uint8_t ((V >> 40) & 0xFF) : uint8_t ((V >> 16) & 0xFF),
    237  BE ? uint8_t ((V >> 32) & 0xFF) : uint8_t ((V >> 24) & 0xFF),
    238  BE ? uint8_t ((V >> 24) & 0xFF) : uint8_t ((V >> 32) & 0xFF),
    239  BE ? uint8_t ((V >> 16) & 0xFF) : uint8_t ((V >> 40) & 0xFF),
    240  BE ? uint8_t ((V >>  8) & 0xFF) : uint8_t ((V >> 48) & 0xFF),
    241  BE ? uint8_t ((V      ) & 0xFF) : uint8_t ((V >> 56) & 0xFF)} {}
    242 #endif
    243 
    244  constexpr operator Type () const {
    245 #if HB_FAST_NUM_ACCESS
    246    return (BE == (__BYTE_ORDER == __BIG_ENDIAN)) ?
    247      ((const hb_packed_t<uint64_t> *) v)->v
    248    :
    249      __builtin_bswap64 (((const hb_packed_t<uint64_t> *) v)->v)
    250    ;
    251 #else
    252    return (BE ? (uint64_t (v[0]) << 56) : (uint64_t (v[0])      ))
    253  + (BE ? (uint64_t (v[1]) << 48) : (uint64_t (v[1]) <<  8))
    254  + (BE ? (uint64_t (v[2]) << 40) : (uint64_t (v[2]) << 16))
    255  + (BE ? (uint64_t (v[3]) << 32) : (uint64_t (v[3]) << 24))
    256  + (BE ? (uint64_t (v[4]) << 24) : (uint64_t (v[4]) << 32))
    257  + (BE ? (uint64_t (v[5]) << 16) : (uint64_t (v[5]) << 40))
    258  + (BE ? (uint64_t (v[6]) <<  8) : (uint64_t (v[6]) << 48))
    259  + (BE ? (uint64_t (v[7])      ) : (uint64_t (v[7]) << 56));
    260 #endif
    261  }
    262  private: uint8_t v[8];
    263 };
    264 
    265 /* Floats. */
    266 
    267 template <bool BE, typename Type, int Bytes>
    268 struct HBFloat
    269 {
    270  using IntType = typename std::conditional<Bytes == 4, uint32_t, uint64_t>::type;
    271 
    272  public:
    273  HBFloat () = default;
    274 
    275  HBFloat (Type V)
    276  {
    277 #if HB_FAST_NUM_ACCESS
    278    {
    279      if (BE == (__BYTE_ORDER == __BIG_ENDIAN))
    280      {
    281        ((hb_packed_t<Type> *) v)->v = V;
    282        return;
    283      }
    284    }
    285 #endif
    286 
    287    union {
    288      hb_packed_t<Type> f;
    289      hb_packed_t<IntType> i;
    290    } u = {{V}};
    291 
    292    const HBInt<BE, IntType> I = u.i.v;
    293    for (unsigned i = 0; i < Bytes; i++)
    294      v[i] = I.v[i];
    295  }
    296 
    297  /* c++14 constexpr */ operator Type () const
    298  {
    299 #if HB_FAST_NUM_ACCESS
    300    {
    301      if (BE == (__BYTE_ORDER == __BIG_ENDIAN))
    302 return ((const hb_packed_t<Type> *) v)->v;
    303    }
    304 #endif
    305 
    306    HBInt<BE, IntType> I;
    307    for (unsigned i = 0; i < Bytes; i++)
    308      I.v[i] = v[i];
    309 
    310    union {
    311      hb_packed_t<IntType> i;
    312      hb_packed_t<Type> f;
    313    } u = {{I}};
    314 
    315    return u.f.v;
    316  }
    317  private: uint8_t v[Bytes];
    318 };
    319 
    320 
    321 /* We want our rounding towards +infinity. */
    322 static inline double
    323 _hb_roundf (double x) { return floor (x + .5); }
    324 
    325 static inline float
    326 _hb_roundf (float x) { return floorf (x + .5f); }
    327 
    328 #define roundf(x) _hb_roundf(x)
    329 
    330 static inline void
    331 hb_sincos (float rotation, float &s, float &c)
    332 {
    333 #ifdef HAVE_SINCOSF
    334  sincosf (rotation, &s, &c);
    335 #else
    336  c = cosf (rotation);
    337  s = sinf (rotation);
    338 #endif
    339 }
    340 static inline void
    341 hb_sincos (double rotation, double &s, double &c)
    342 {
    343 #ifdef HAVE_SINCOS
    344  sincos (rotation, &s, &c);
    345 #else
    346  c = cos (rotation);
    347  s = sin (rotation);
    348 #endif
    349 }
    350 
    351 
    352 /* Encodes three unsigned integers in one 64-bit number.  If the inputs have more than 21 bits,
    353 * values will be truncated / overlap, and might not decode exactly. */
    354 #define HB_CODEPOINT_ENCODE3(x,y,z) (((uint64_t) (x) << 42) | ((uint64_t) (y) << 21) | (uint64_t) (z))
    355 #define HB_CODEPOINT_DECODE3_1(v) ((hb_codepoint_t) ((v) >> 42))
    356 #define HB_CODEPOINT_DECODE3_2(v) ((hb_codepoint_t) ((v) >> 21) & 0x1FFFFFu)
    357 #define HB_CODEPOINT_DECODE3_3(v) ((hb_codepoint_t) (v) & 0x1FFFFFu)
    358 
    359 /* Custom encoding used by hb-ucd. */
    360 #define HB_CODEPOINT_ENCODE3_11_7_14(x,y,z) (((uint32_t) ((x) & 0x07FFu) << 21) | (((uint32_t) (y) & 0x007Fu) << 14) | (uint32_t) ((z) & 0x3FFFu))
    361 #define HB_CODEPOINT_DECODE3_11_7_14_1(v) ((hb_codepoint_t) ((v) >> 21))
    362 #define HB_CODEPOINT_DECODE3_11_7_14_2(v) ((hb_codepoint_t) (((v) >> 14) & 0x007Fu) | 0x0300)
    363 #define HB_CODEPOINT_DECODE3_11_7_14_3(v) ((hb_codepoint_t) (v) & 0x3FFFu)
    364 
    365 
    366 struct
    367 {
    368  /* Note.  This is dangerous in that if it's passed an rvalue, it returns rvalue-reference. */
    369  template <typename T> constexpr auto
    370  operator () (T&& v) const HB_AUTO_RETURN ( std::forward<T> (v) )
    371 }
    372 HB_FUNCOBJ (hb_identity);
    373 struct
    374 {
    375  /* Like identity(), but only retains lvalue-references.  Rvalues are returned as rvalues. */
    376  template <typename T> constexpr T&
    377  operator () (T& v) const { return v; }
    378 
    379  template <typename T> constexpr hb_remove_reference<T>
    380  operator () (T&& v) const { return v; }
    381 }
    382 HB_FUNCOBJ (hb_lidentity);
    383 struct
    384 {
    385  /* Like identity(), but always returns rvalue. */
    386  template <typename T> constexpr hb_remove_reference<T>
    387  operator () (T&& v) const { return v; }
    388 }
    389 HB_FUNCOBJ (hb_ridentity);
    390 
    391 struct
    392 {
    393  template <typename T> constexpr bool
    394  operator () (T&& v) const { return bool (std::forward<T> (v)); }
    395 }
    396 HB_FUNCOBJ (hb_bool);
    397 
    398 
    399 /* The MIT License
    400 
    401   Copyright (C) 2012 Zilong Tan (eric.zltan@gmail.com)
    402 
    403   Permission is hereby granted, free of charge, to any person
    404   obtaining a copy of this software and associated documentation
    405   files (the "Software"), to deal in the Software without
    406   restriction, including without limitation the rights to use, copy,
    407   modify, merge, publish, distribute, sublicense, and/or sell copies
    408   of the Software, and to permit persons to whom the Software is
    409   furnished to do so, subject to the following conditions:
    410 
    411   The above copyright notice and this permission notice shall be
    412   included in all copies or substantial portions of the Software.
    413 
    414   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    415   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    416   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    417   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
    418   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
    419   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    420   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    421   SOFTWARE.
    422 */
    423 
    424 
    425 // Compression function for Merkle-Damgard construction.
    426 // This function is generated using the framework provided.
    427 #define fasthash_mix(h) (					\
    428 		(void) ((h) ^= (h) >> 23),		\
    429 		(void) ((h) *= 0x2127599bf4325c37ULL),	\
    430 		(h) ^= (h) >> 47)
    431 
    432 static inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed)
    433 {
    434 struct __attribute__((packed)) packed_uint64_t { uint64_t v; };
    435 const uint64_t    m = 0x880355f21e6d1965ULL;
    436 const packed_uint64_t *pos = (const packed_uint64_t *)buf;
    437 const packed_uint64_t *end = pos + (len / 8);
    438 const unsigned char *pos2;
    439 uint64_t h = seed ^ (len * m);
    440 uint64_t v;
    441 
    442 #ifndef HB_OPTIMIZE_SIZE
    443 if (((uintptr_t) pos & 7) == 0)
    444 {
    445   while (pos != end)
    446   {
    447 #pragma GCC diagnostic push
    448 #pragma GCC diagnostic ignored "-Wcast-align"
    449     v  = * (const uint64_t *) (pos++);
    450 #pragma GCC diagnostic pop
    451     h ^= fasthash_mix(v);
    452     h *= m;
    453   }
    454 }
    455 else
    456 #endif
    457 {
    458   while (pos != end)
    459   {
    460     v  = pos++->v;
    461     h ^= fasthash_mix(v);
    462     h *= m;
    463   }
    464 }
    465 
    466 pos2 = (const unsigned char*)pos;
    467 v = 0;
    468 
    469 switch (len & 7) {
    470 case 7: v ^= (uint64_t)pos2[6] << 48; HB_FALLTHROUGH;
    471 case 6: v ^= (uint64_t)pos2[5] << 40; HB_FALLTHROUGH;
    472 case 5: v ^= (uint64_t)pos2[4] << 32; HB_FALLTHROUGH;
    473 case 4: v ^= (uint64_t)pos2[3] << 24; HB_FALLTHROUGH;
    474 case 3: v ^= (uint64_t)pos2[2] << 16; HB_FALLTHROUGH;
    475 case 2: v ^= (uint64_t)pos2[1] <<  8; HB_FALLTHROUGH;
    476 case 1: v ^= (uint64_t)pos2[0];
    477 	h ^= fasthash_mix(v);
    478 	h *= m;
    479 }
    480 
    481 return fasthash_mix(h);
    482 }
    483 
    484 static inline uint32_t fasthash32(const void *buf, size_t len, uint32_t seed)
    485 {
    486 // the following trick converts the 64-bit hashcode to Fermat
    487 // residue, which shall retain information from both the higher
    488 // and lower parts of hashcode.
    489        uint64_t h = fasthash64(buf, len, seed);
    490 return h - (h >> 32);
    491 }
    492 
    493 struct
    494 {
    495  private:
    496 
    497  template <typename T> constexpr auto
    498  impl (const T& v, hb_priority<2>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
    499 
    500  // Horrible: std:hash() of integers seems to be identity in gcc / clang?!
    501  // https://github.com/harfbuzz/harfbuzz/pull/4228
    502  //
    503  // For performance characteristics see:
    504  // https://github.com/harfbuzz/harfbuzz/pull/4228#issuecomment-1565079537
    505  template <typename T,
    506     hb_enable_if (std::is_integral<T>::value && sizeof (T) <= sizeof (uint32_t))> constexpr auto
    507  impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, (uint32_t) v * 2654435761u /* Knuh's multiplicative hash */)
    508  template <typename T,
    509     hb_enable_if (std::is_integral<T>::value && sizeof (T) > sizeof (uint32_t))> constexpr auto
    510  impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, (uint32_t) (v ^ (v >> 32)) * 2654435761u /* Knuth's multiplicative hash */)
    511 
    512  template <typename T,
    513     hb_enable_if (std::is_floating_point<T>::value)> constexpr auto
    514  impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, fasthash32 (std::addressof (v), sizeof (T), 0xf437ffe6))
    515 
    516  template <typename T> constexpr auto
    517  impl (const T& v, hb_priority<0>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v))>>{} (hb_deref (v)))
    518 
    519  public:
    520 
    521  template <typename T> constexpr auto
    522  operator () (const T& v) const HB_RETURN (uint32_t, impl (v, hb_prioritize))
    523 }
    524 HB_FUNCOBJ (hb_hash);
    525 
    526 
    527 struct
    528 {
    529  private:
    530 
    531  /* Pointer-to-member-function. */
    532  template <typename Appl, typename T, typename ...Ts> auto
    533  impl (Appl&& a, hb_priority<2>, T &&v, Ts&&... ds) const HB_AUTO_RETURN
    534  ((hb_deref (std::forward<T> (v)).*std::forward<Appl> (a)) (std::forward<Ts> (ds)...))
    535 
    536  /* Pointer-to-member. */
    537  template <typename Appl, typename T> auto
    538  impl (Appl&& a, hb_priority<1>, T &&v) const HB_AUTO_RETURN
    539  ((hb_deref (std::forward<T> (v))).*std::forward<Appl> (a))
    540 
    541  /* Operator(). */
    542  template <typename Appl, typename ...Ts> auto
    543  impl (Appl&& a, hb_priority<0>, Ts&&... ds) const HB_AUTO_RETURN
    544  (hb_deref (std::forward<Appl> (a)) (std::forward<Ts> (ds)...))
    545 
    546  public:
    547 
    548  template <typename Appl, typename ...Ts> auto
    549  operator () (Appl&& a, Ts&&... ds) const HB_AUTO_RETURN
    550  (
    551    impl (std::forward<Appl> (a),
    552   hb_prioritize,
    553   std::forward<Ts> (ds)...)
    554  )
    555 }
    556 HB_FUNCOBJ (hb_invoke);
    557 
    558 template <unsigned Pos, typename Appl, typename V>
    559 struct hb_partial_t
    560 {
    561  hb_partial_t (Appl a, V v) : a (a), v (v) {}
    562 
    563  static_assert (Pos > 0, "");
    564 
    565  template <typename ...Ts,
    566     unsigned P = Pos,
    567     hb_enable_if (P == 1)> auto
    568  operator () (Ts&& ...ds) -> decltype (hb_invoke (hb_declval (Appl),
    569 					   hb_declval (V),
    570 					   hb_declval (Ts)...))
    571  {
    572    return hb_invoke (std::forward<Appl> (a),
    573 	      std::forward<V> (v),
    574 	      std::forward<Ts> (ds)...);
    575  }
    576  template <typename T0, typename ...Ts,
    577     unsigned P = Pos,
    578     hb_enable_if (P == 2)> auto
    579  operator () (T0&& d0, Ts&& ...ds) -> decltype (hb_invoke (hb_declval (Appl),
    580 						    hb_declval (T0),
    581 						    hb_declval (V),
    582 						    hb_declval (Ts)...))
    583  {
    584    return hb_invoke (std::forward<Appl> (a),
    585 	      std::forward<T0> (d0),
    586 	      std::forward<V> (v),
    587 	      std::forward<Ts> (ds)...);
    588  }
    589 
    590  private:
    591  hb_reference_wrapper<Appl> a;
    592  V v;
    593 };
    594 template <unsigned Pos=1, typename Appl, typename V>
    595 auto hb_partial (Appl&& a, V&& v) HB_AUTO_RETURN
    596 (( hb_partial_t<Pos, Appl, V> (a, v) ))
    597 
    598 /* The following, HB_PARTIALIZE, macro uses a particular corner-case
    599 * of C++11 that is not particularly well-supported by all compilers.
    600 * What's happening is that it's using "this" in a trailing return-type
    601 * via decltype().  Broken compilers deduce the type of "this" pointer
    602 * in that context differently from what it resolves to in the body
    603 * of the function.
    604 *
    605 * One probable cause of this is that at the time of trailing return
    606 * type declaration, "this" points to an incomplete type, whereas in
    607 * the function body the type is complete.  That doesn't justify the
    608 * error in any way, but is probably what's happening.
    609 *
    610 * In the case of MSVC, we get around this by using C++14 "decltype(auto)"
    611 * which deduces the type from the actual return statement.  For gcc 4.8
    612 * we use "+this" instead of "this" which produces an rvalue that seems
    613 * to be deduced as the same type with this particular compiler, and seem
    614 * to be fine as default code path as well.
    615 */
    616 #ifdef _MSC_VER
    617 /* https://github.com/harfbuzz/harfbuzz/issues/1730 */ \
    618 #define HB_PARTIALIZE(Pos) \
    619  template <typename _T> \
    620  decltype(auto) operator () (_T&& _v) const \
    621  { return hb_partial<Pos> (this, std::forward<_T> (_v)); } \
    622  static_assert (true, "")
    623 #else
    624 /* https://github.com/harfbuzz/harfbuzz/issues/1724 */
    625 #define HB_PARTIALIZE(Pos) \
    626  template <typename _T> \
    627  auto operator () (_T&& _v) const HB_AUTO_RETURN \
    628  (hb_partial<Pos> (+this, std::forward<_T> (_v))) \
    629  static_assert (true, "")
    630 #endif
    631 
    632 
    633 struct
    634 {
    635  private:
    636 
    637  template <typename Pred, typename Val> auto
    638  impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
    639  (
    640    hb_deref (std::forward<Pred> (p)).has (std::forward<Val> (v))
    641  )
    642 
    643  template <typename Pred, typename Val> auto
    644  impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
    645  (
    646    hb_invoke (std::forward<Pred> (p),
    647        std::forward<Val> (v))
    648  )
    649 
    650  public:
    651 
    652  template <typename Pred, typename Val> auto
    653  operator () (Pred&& p, Val &&v) const HB_RETURN (bool,
    654    impl (std::forward<Pred> (p),
    655   std::forward<Val> (v),
    656   hb_prioritize)
    657  )
    658 }
    659 HB_FUNCOBJ (hb_has);
    660 
    661 struct
    662 {
    663  private:
    664 
    665  template <typename Pred, typename Val> auto
    666  impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
    667  (
    668    hb_has (std::forward<Pred> (p),
    669     std::forward<Val> (v))
    670  )
    671 
    672  template <typename Pred, typename Val> auto
    673  impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
    674  (
    675    std::forward<Pred> (p) == std::forward<Val> (v)
    676  )
    677 
    678  public:
    679 
    680  template <typename Pred, typename Val> auto
    681  operator () (Pred&& p, Val &&v) const HB_RETURN (bool,
    682    impl (std::forward<Pred> (p),
    683   std::forward<Val> (v),
    684   hb_prioritize)
    685  )
    686 }
    687 HB_FUNCOBJ (hb_match);
    688 
    689 struct
    690 {
    691  private:
    692 
    693  template <typename Proj, typename Val> auto
    694  impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN
    695  (
    696    hb_deref (std::forward<Proj> (f)).get (std::forward<Val> (v))
    697  )
    698 
    699  template <typename Proj, typename Val> auto
    700  impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
    701  (
    702    hb_invoke (std::forward<Proj> (f),
    703        std::forward<Val> (v))
    704  )
    705 
    706  template <typename Proj, typename Val> auto
    707  impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
    708  (
    709    std::forward<Proj> (f)[std::forward<Val> (v)]
    710  )
    711 
    712  public:
    713 
    714  template <typename Proj, typename Val> auto
    715  operator () (Proj&& f, Val &&v) const HB_AUTO_RETURN
    716  (
    717    impl (std::forward<Proj> (f),
    718   std::forward<Val> (v),
    719   hb_prioritize)
    720  )
    721 }
    722 HB_FUNCOBJ (hb_get);
    723 
    724 struct
    725 {
    726  private:
    727 
    728  template <typename T1, typename T2> auto
    729  impl (T1&& v1, T2 &&v2, hb_priority<3>) const HB_AUTO_RETURN
    730  (
    731    std::forward<T2> (v2).cmp (std::forward<T1> (v1)) == 0
    732  )
    733 
    734  template <typename T1, typename T2> auto
    735  impl (T1&& v1, T2 &&v2, hb_priority<2>) const HB_AUTO_RETURN
    736  (
    737    std::forward<T1> (v1).cmp (std::forward<T2> (v2)) == 0
    738  )
    739 
    740  template <typename T1, typename T2> auto
    741  impl (T1&& v1, T2 &&v2, hb_priority<1>) const HB_AUTO_RETURN
    742  (
    743    std::forward<T1> (v1) == std::forward<T2> (v2)
    744  )
    745 
    746  template <typename T1, typename T2> auto
    747  impl (T1&& v1, T2 &&v2, hb_priority<0>) const HB_AUTO_RETURN
    748  (
    749    std::forward<T2> (v2) == std::forward<T1> (v1)
    750  )
    751 
    752  public:
    753 
    754  template <typename T1, typename T2> auto
    755  operator () (T1&& v1, T2 &&v2) const HB_AUTO_RETURN
    756  (
    757    impl (std::forward<T1> (v1),
    758   std::forward<T2> (v2),
    759   hb_prioritize)
    760  )
    761 }
    762 HB_FUNCOBJ (hb_equal);
    763 
    764 struct
    765 {
    766  template <typename T> void
    767  operator () (T& a, T& b) const
    768  {
    769    using std::swap; // allow ADL
    770    swap (a, b);
    771  }
    772 }
    773 HB_FUNCOBJ (hb_swap);
    774 
    775 
    776 template <typename T1, typename T2>
    777 struct hb_pair_t
    778 {
    779  typedef T1 first_t;
    780  typedef T2 second_t;
    781  typedef hb_pair_t<T1, T2> pair_t;
    782 
    783  template <typename U1 = T1, typename U2 = T2,
    784     hb_enable_if (std::is_default_constructible<U1>::value &&
    785 		  std::is_default_constructible<U2>::value)>
    786  hb_pair_t () : first (), second () {}
    787  hb_pair_t (T1 a, T2 b) : first (std::forward<T1> (a)), second (std::forward<T2> (b)) {}
    788 
    789  template <typename Q1, typename Q2,
    790     hb_enable_if (hb_is_convertible (T1, Q1) &&
    791 		  hb_is_convertible (T2, Q2))>
    792  operator hb_pair_t<Q1, Q2> () { return hb_pair_t<Q1, Q2> (first, second); }
    793 
    794  hb_pair_t<T1, T2> reverse () const
    795  { return hb_pair_t<T1, T2> (second, first); }
    796 
    797  bool operator == (const pair_t& o) const { return first == o.first && second == o.second; }
    798  bool operator != (const pair_t& o) const { return !(*this == o); }
    799  bool operator < (const pair_t& o) const { return first < o.first || (first == o.first && second < o.second); }
    800  bool operator >= (const pair_t& o) const { return !(*this < o); }
    801  bool operator > (const pair_t& o) const { return first > o.first || (first == o.first && second > o.second); }
    802  bool operator <= (const pair_t& o) const { return !(*this > o); }
    803 
    804  static int cmp (const void *pa, const void *pb)
    805  {
    806    pair_t *a = (pair_t *) pa;
    807    pair_t *b = (pair_t *) pb;
    808 
    809    if (a->first < b->first) return -1;
    810    if (a->first > b->first) return +1;
    811    if (a->second < b->second) return -1;
    812    if (a->second > b->second) return +1;
    813    return 0;
    814  }
    815 
    816  friend void swap (hb_pair_t& a, hb_pair_t& b) noexcept
    817  {
    818    hb_swap (a.first, b.first);
    819    hb_swap (a.second, b.second);
    820  }
    821 
    822 
    823  T1 first;
    824  T2 second;
    825 };
    826 template <typename T1, typename T2> static inline hb_pair_t<T1, T2>
    827 hb_pair (T1&& a, T2&& b) { return hb_pair_t<T1, T2> (a, b); }
    828 
    829 typedef hb_pair_t<hb_codepoint_t, hb_codepoint_t> hb_codepoint_pair_t;
    830 
    831 struct
    832 {
    833  template <typename Pair> constexpr typename Pair::first_t
    834  operator () (const Pair& pair) const { return pair.first; }
    835 }
    836 HB_FUNCOBJ (hb_first);
    837 
    838 struct
    839 {
    840  template <typename Pair> constexpr typename Pair::second_t
    841  operator () (const Pair& pair) const { return pair.second; }
    842 }
    843 HB_FUNCOBJ (hb_second);
    844 
    845 /* Note.  In min/max impl, we can use hb_type_identity<T> for second argument.
    846 * However, that would silently convert between different-signedness integers.
    847 * Instead we accept two different types, such that compiler can err if
    848 * comparing integers of different signedness. */
    849 struct
    850 {
    851  template <typename T, typename T2> constexpr auto
    852  operator () (T&& a, T2&& b) const HB_AUTO_RETURN
    853  (a <= b ? a : b)
    854 }
    855 HB_FUNCOBJ (hb_min);
    856 struct
    857 {
    858  template <typename T, typename T2> constexpr auto
    859  operator () (T&& a, T2&& b) const HB_AUTO_RETURN
    860  (a >= b ? a : b)
    861 }
    862 HB_FUNCOBJ (hb_max);
    863 struct
    864 {
    865  template <typename T, typename T2, typename T3> constexpr auto
    866  operator () (T&& x, T2&& min, T3&& max) const HB_AUTO_RETURN
    867  (hb_min (hb_max (std::forward<T> (x), std::forward<T2> (min)), std::forward<T3> (max)))
    868 }
    869 HB_FUNCOBJ (hb_clamp);
    870 
    871 /*
    872 * Bithacks.
    873 */
    874 
    875 /* Return the number of 1 bits in a uint8_t; faster than hb_popcount() */
    876 static inline unsigned
    877 hb_popcount8 (uint8_t v)
    878 {
    879  static const uint8_t popcount4[16] = {
    880    0, 1, 1, 2, 1, 2, 2, 3,
    881    1, 2, 2, 3, 2, 3, 3, 4
    882  };
    883  return popcount4[v & 0xF] + popcount4[v >> 4];
    884 }
    885 
    886 /* Return the number of 1 bits in v. */
    887 template <typename T>
    888 static inline unsigned int
    889 hb_popcount (T v)
    890 {
    891 #if hb_has_builtin(__builtin_popcount)
    892  if (sizeof (T) <= sizeof (unsigned int))
    893    return __builtin_popcount (v);
    894 #endif
    895 
    896 #if hb_has_builtin(__builtin_popcountl)
    897  if (sizeof (T) <= sizeof (unsigned long))
    898    return __builtin_popcountl (v);
    899 #endif
    900 
    901 #if hb_has_builtin(__builtin_popcountll)
    902  if (sizeof (T) <= sizeof (unsigned long long))
    903    return __builtin_popcountll (v);
    904 #endif
    905 
    906  if (sizeof (T) <= 4)
    907  {
    908    /* "HACKMEM 169" */
    909    uint32_t y;
    910    y = (v >> 1) &033333333333;
    911    y = v - y - ((y >>1) & 033333333333);
    912    return (((y + (y >> 3)) & 030707070707) % 077);
    913  }
    914 
    915  if (sizeof (T) == 8)
    916  {
    917    uint64_t y = (uint64_t) v;
    918    y -= ((y >> 1) & 0x5555555555555555ull);
    919    y = (y & 0x3333333333333333ull) + (y >> 2 & 0x3333333333333333ull);
    920    return ((y + (y >> 4)) & 0xf0f0f0f0f0f0f0full) * 0x101010101010101ull >> 56;
    921  }
    922 
    923  if (sizeof (T) == 16)
    924  {
    925    unsigned int shift = 64;
    926    return hb_popcount<uint64_t> ((uint64_t) v) + hb_popcount ((uint64_t) (v >> shift));
    927  }
    928 
    929  assert (0);
    930  return 0; /* Shut up stupid compiler. */
    931 }
    932 
    933 /* Returns the number of bits needed to store number */
    934 template <typename T>
    935 static inline unsigned int
    936 hb_bit_storage (T v)
    937 {
    938  if (unlikely (!v)) return 0;
    939 
    940 #if hb_has_builtin(__builtin_clz)
    941  if (sizeof (T) <= sizeof (unsigned int))
    942    return sizeof (unsigned int) * 8 - __builtin_clz (v);
    943 #endif
    944 
    945 #if hb_has_builtin(__builtin_clzl)
    946  if (sizeof (T) <= sizeof (unsigned long))
    947    return sizeof (unsigned long) * 8 - __builtin_clzl (v);
    948 #endif
    949 
    950 #if hb_has_builtin(__builtin_clzll)
    951  if (sizeof (T) <= sizeof (unsigned long long))
    952    return sizeof (unsigned long long) * 8 - __builtin_clzll (v);
    953 #endif
    954 
    955 #if (defined(_MSC_VER) && _MSC_VER >= 1500) || (defined(__MINGW32__) && (__GNUC__ < 4))
    956  if (sizeof (T) <= sizeof (unsigned int))
    957  {
    958    unsigned long where;
    959    _BitScanReverse (&where, v);
    960    return 1 + where;
    961  }
    962 # if defined(_WIN64)
    963  if (sizeof (T) <= 8)
    964  {
    965    unsigned long where;
    966    _BitScanReverse64 (&where, v);
    967    return 1 + where;
    968  }
    969 # endif
    970 #endif
    971 
    972  if (sizeof (T) <= 4)
    973  {
    974    /* "bithacks" */
    975    const unsigned int b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
    976    const unsigned int S[] = {1, 2, 4, 8, 16};
    977    unsigned int r = 0;
    978    for (int i = 4; i >= 0; i--)
    979      if (v & b[i])
    980      {
    981 v >>= S[i];
    982 r |= S[i];
    983      }
    984    return r + 1;
    985  }
    986  if (sizeof (T) <= 8)
    987  {
    988    /* "bithacks" */
    989    const uint64_t b[] = {0x2ULL, 0xCULL, 0xF0ULL, 0xFF00ULL, 0xFFFF0000ULL, 0xFFFFFFFF00000000ULL};
    990    const unsigned int S[] = {1, 2, 4, 8, 16, 32};
    991    unsigned int r = 0;
    992    for (int i = 5; i >= 0; i--)
    993      if (v & b[i])
    994      {
    995 v >>= S[i];
    996 r |= S[i];
    997      }
    998    return r + 1;
    999  }
   1000  if (sizeof (T) == 16)
   1001  {
   1002    unsigned int shift = 64;
   1003    return (v >> shift) ? hb_bit_storage<uint64_t> ((uint64_t) (v >> shift)) + shift :
   1004 		  hb_bit_storage<uint64_t> ((uint64_t) v);
   1005  }
   1006 
   1007  assert (0);
   1008  return 0; /* Shut up stupid compiler. */
   1009 }
   1010 
   1011 /* Returns the number of zero bits in the least significant side of v */
   1012 template <typename T>
   1013 static inline unsigned int
   1014 hb_ctz (T v)
   1015 {
   1016  if (unlikely (!v)) return 8 * sizeof (T);
   1017 
   1018 #if hb_has_builtin(__builtin_ctz)
   1019  if (sizeof (T) <= sizeof (unsigned int))
   1020    return __builtin_ctz (v);
   1021 #endif
   1022 
   1023 #if hb_has_builtin(__builtin_ctzl)
   1024  if (sizeof (T) <= sizeof (unsigned long))
   1025    return __builtin_ctzl (v);
   1026 #endif
   1027 
   1028 #if hb_has_builtin(__builtin_ctzll)
   1029  if (sizeof (T) <= sizeof (unsigned long long))
   1030    return __builtin_ctzll (v);
   1031 #endif
   1032 
   1033 #if (defined(_MSC_VER) && _MSC_VER >= 1500) || (defined(__MINGW32__) && (__GNUC__ < 4))
   1034  if (sizeof (T) <= sizeof (unsigned int))
   1035  {
   1036    unsigned long where;
   1037    _BitScanForward (&where, v);
   1038    return where;
   1039  }
   1040 # if defined(_WIN64)
   1041  if (sizeof (T) <= 8)
   1042  {
   1043    unsigned long where;
   1044    _BitScanForward64 (&where, v);
   1045    return where;
   1046  }
   1047 # endif
   1048 #endif
   1049 
   1050  if (sizeof (T) <= 4)
   1051  {
   1052    /* "bithacks" */
   1053    unsigned int c = 32;
   1054    v &= - (int32_t) v;
   1055    if (v) c--;
   1056    if (v & 0x0000FFFF) c -= 16;
   1057    if (v & 0x00FF00FF) c -= 8;
   1058    if (v & 0x0F0F0F0F) c -= 4;
   1059    if (v & 0x33333333) c -= 2;
   1060    if (v & 0x55555555) c -= 1;
   1061    return c;
   1062  }
   1063  if (sizeof (T) <= 8)
   1064  {
   1065    /* "bithacks" */
   1066    unsigned int c = 64;
   1067    v &= - (int64_t) (v);
   1068    if (v) c--;
   1069    if (v & 0x00000000FFFFFFFFULL) c -= 32;
   1070    if (v & 0x0000FFFF0000FFFFULL) c -= 16;
   1071    if (v & 0x00FF00FF00FF00FFULL) c -= 8;
   1072    if (v & 0x0F0F0F0F0F0F0F0FULL) c -= 4;
   1073    if (v & 0x3333333333333333ULL) c -= 2;
   1074    if (v & 0x5555555555555555ULL) c -= 1;
   1075    return c;
   1076  }
   1077  if (sizeof (T) == 16)
   1078  {
   1079    unsigned int shift = 64;
   1080    return (uint64_t) v ? hb_bit_storage<uint64_t> ((uint64_t) v) :
   1081 		  hb_bit_storage<uint64_t> ((uint64_t) (v >> shift)) + shift;
   1082  }
   1083 
   1084  assert (0);
   1085  return 0; /* Shut up stupid compiler. */
   1086 }
   1087 
   1088 
   1089 /*
   1090 * Tiny stuff.
   1091 */
   1092 
   1093 /* ASCII tag/character handling */
   1094 static inline bool ISALPHA (unsigned char c)
   1095 { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); }
   1096 static inline bool ISALNUM (unsigned char c)
   1097 { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); }
   1098 static inline bool ISSPACE (unsigned char c)
   1099 { return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; }
   1100 static inline unsigned char TOUPPER (unsigned char c)
   1101 { return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; }
   1102 static inline unsigned char TOLOWER (unsigned char c)
   1103 { return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; }
   1104 static inline bool ISHEX (unsigned char c)
   1105 { return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); }
   1106 static inline unsigned char TOHEX (uint8_t c)
   1107 { return (c & 0xF) <= 9 ? (c & 0xF) + '0' : (c & 0xF) + 'a' - 10; }
   1108 static inline uint8_t FROMHEX (unsigned char c)
   1109 { return (c >= '0' && c <= '9') ? c - '0' : TOLOWER (c) - 'a' + 10; }
   1110 
   1111 static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b)
   1112 { return (a + (b - 1)) / b; }
   1113 
   1114 
   1115 #undef  ARRAY_LENGTH
   1116 template <typename Type, unsigned int n>
   1117 static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; }
   1118 /* A const version, but does not detect erratically being called on pointers. */
   1119 #define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
   1120 
   1121 
   1122 static inline void *
   1123 hb_memcpy (void *__restrict dst, const void *__restrict src, size_t len)
   1124 {
   1125  /* It's illegal to pass 0 as size to memcpy. */
   1126  if (unlikely (!len)) return dst;
   1127  return memcpy (dst, src, len);
   1128 }
   1129 
   1130 static inline int
   1131 hb_memcmp (const void *a, const void *b, unsigned int len)
   1132 {
   1133  /* It's illegal to pass NULL to memcmp(), even if len is zero.
   1134   * So, wrap it.
   1135   * https://sourceware.org/bugzilla/show_bug.cgi?id=23878 */
   1136  if (unlikely (!len)) return 0;
   1137  return memcmp (a, b, len);
   1138 }
   1139 
   1140 static inline void *
   1141 hb_memset (void *s, int c, unsigned int n)
   1142 {
   1143  /* It's illegal to pass NULL to memset(), even if n is zero. */
   1144  if (unlikely (!n)) return s;
   1145  return memset (s, c, n);
   1146 }
   1147 
   1148 static inline unsigned int
   1149 hb_ceil_to_4 (unsigned int v)
   1150 {
   1151  return ((v - 1) | 3) + 1;
   1152 }
   1153 
   1154 template <typename T> static inline bool
   1155 hb_in_range (T u, T lo, T hi)
   1156 {
   1157  static_assert (!std::is_signed<T>::value, "");
   1158 
   1159  /* The casts below are important as if T is smaller than int,
   1160   * the subtract results will become a signed int! */
   1161  return (T)(u - lo) <= (T)(hi - lo);
   1162 }
   1163 template <typename T> static inline bool
   1164 hb_in_ranges (T u, T lo1, T hi1)
   1165 {
   1166  return hb_in_range (u, lo1, hi1);
   1167 }
   1168 template <typename T, typename ...Ts> static inline bool
   1169 hb_in_ranges (T u, T lo1, T hi1, Ts... ds)
   1170 {
   1171  return hb_in_range<T> (u, lo1, hi1) || hb_in_ranges<T> (u, ds...);
   1172 }
   1173 
   1174 
   1175 /*
   1176 * Overflow checking.
   1177 */
   1178 
   1179 static inline bool
   1180 hb_unsigned_mul_overflows (unsigned int count, unsigned int size, unsigned *result = nullptr)
   1181 {
   1182 #if hb_has_builtin(__builtin_mul_overflow)
   1183  unsigned stack_result;
   1184  if (!result)
   1185    result = &stack_result;
   1186  return __builtin_mul_overflow (count, size, result);
   1187 #endif
   1188 
   1189  if (result)
   1190    *result = count * size;
   1191  return (size > 0) && (count >= ((unsigned int) -1) / size);
   1192 }
   1193 
   1194 
   1195 /*
   1196 * Sort and search.
   1197 */
   1198 
   1199 template <typename K, typename V, typename ...Ts>
   1200 static int
   1201 _hb_cmp_method (const void *pkey, const void *pval, Ts... ds)
   1202 {
   1203  const K& key = * (const K*) pkey;
   1204  const V& val = * (const V*) pval;
   1205 
   1206  return val.cmp (key, ds...);
   1207 }
   1208 
   1209 template <typename K, typename V>
   1210 static int
   1211 _hb_cmp_operator (const void *pkey, const void *pval)
   1212 {
   1213  const K& key = * (const K*) pkey;
   1214  const V& val = * (const V*) pval;
   1215 
   1216  if (key < val) return -1;
   1217  if (key > val) return  1;
   1218  return 0;
   1219 }
   1220 
   1221 template <typename V, typename K, typename ...Ts>
   1222 HB_HOT
   1223 static inline bool
   1224 hb_bsearch_impl (unsigned *pos, /* Out */
   1225 	 const K& key,
   1226 	 V* base, size_t nmemb, size_t stride,
   1227 	 int (*compar)(const void *_key, const void *_item, Ts... _ds),
   1228 	 Ts... ds)
   1229 {
   1230  /* This is our *only* bsearch implementation. */
   1231 
   1232  int min = 0, max = (int) nmemb - 1;
   1233  while (min <= max)
   1234  {
   1235    int mid = ((unsigned int) min + (unsigned int) max) / 2;
   1236 #pragma GCC diagnostic push
   1237 #pragma GCC diagnostic ignored "-Wcast-align"
   1238    V* p = (V*) (((const char *) base) + (mid * stride));
   1239 #pragma GCC diagnostic pop
   1240    int c = compar ((const void *) std::addressof (key), (const void *) p, ds...);
   1241    if (c < 0)
   1242      max = mid - 1;
   1243    else if (c > 0)
   1244      min = mid + 1;
   1245    else
   1246    {
   1247      *pos = mid;
   1248      return true;
   1249    }
   1250  }
   1251  *pos = min;
   1252  return false;
   1253 }
   1254 
   1255 template <typename V, typename K>
   1256 static inline V*
   1257 hb_bsearch (const K& key, V* base,
   1258     size_t nmemb, size_t stride = sizeof (V),
   1259     int (*compar)(const void *_key, const void *_item) = _hb_cmp_method<K, V>)
   1260 {
   1261  unsigned pos;
   1262 #pragma GCC diagnostic push
   1263 #pragma GCC diagnostic ignored "-Wcast-align"
   1264  return hb_bsearch_impl (&pos, key, base, nmemb, stride, compar) ?
   1265  (V*) (((const char *) base) + (pos * stride)) : nullptr;
   1266 #pragma GCC diagnostic pop
   1267 }
   1268 template <typename V, typename K, typename ...Ts>
   1269 static inline V*
   1270 hb_bsearch (const K& key, V* base,
   1271     size_t nmemb, size_t stride,
   1272     int (*compar)(const void *_key, const void *_item, Ts... _ds),
   1273     Ts... ds)
   1274 {
   1275  unsigned pos;
   1276 #pragma GCC diagnostic push
   1277 #pragma GCC diagnostic ignored "-Wcast-align"
   1278  return hb_bsearch_impl (&pos, key, base, nmemb, stride, compar, ds...) ?
   1279  (V*) (((const char *) base) + (pos * stride)) : nullptr;
   1280 #pragma GCC diagnostic pop
   1281 }
   1282 
   1283 
   1284 /* From https://github.com/noporpoise/sort_r
   1285   Feb 5, 2019 (c8c65c1e)
   1286   Modified to support optional argument using templates */
   1287 
   1288 /* Isaac Turner 29 April 2014 Public Domain */
   1289 
   1290 /*
   1291 hb_qsort function to be exported.
   1292 Parameters:
   1293  base is the array to be sorted
   1294  nel is the number of elements in the array
   1295  width is the size in bytes of each element of the array
   1296  compar is the comparison function
   1297  arg (optional) is a pointer to be passed to the comparison function
   1298 
   1299 void hb_qsort(void *base, size_t nel, size_t width,
   1300              int (*compar)(const void *_a, const void *_b, [void *_arg]),
   1301              [void *arg]);
   1302 */
   1303 
   1304 #define SORT_R_SWAP(a,b,tmp) ((void) ((tmp) = (a)), (void) ((a) = (b)), (b) = (tmp))
   1305 
   1306 /* swap a and b */
   1307 /* a and b must not be equal! */
   1308 static inline void sort_r_swap(char *__restrict a, char *__restrict b,
   1309                               size_t w)
   1310 {
   1311  char tmp, *end = a+w;
   1312  for(; a < end; a++, b++) { SORT_R_SWAP(*a, *b, tmp); }
   1313 }
   1314 
   1315 /* swap a, b iff a>b */
   1316 /* a and b must not be equal! */
   1317 /* __restrict is same as restrict but better support on old machines */
   1318 template <typename ...Ts>
   1319 static inline int sort_r_cmpswap(char *__restrict a,
   1320                                 char *__restrict b, size_t w,
   1321                                 int (*compar)(const void *_a,
   1322                                               const void *_b,
   1323                                               Ts... _ds),
   1324                                 Ts... ds)
   1325 {
   1326  if(compar(a, b, ds...) > 0) {
   1327    sort_r_swap(a, b, w);
   1328    return 1;
   1329  }
   1330  return 0;
   1331 }
   1332 
   1333 /*
   1334 Swap consecutive blocks of bytes of size na and nb starting at memory addr ptr,
   1335 with the smallest swap so that the blocks are in the opposite order. Blocks may
   1336 be internally re-ordered e.g.
   1337  12345ab  ->   ab34512
   1338  123abc   ->   abc123
   1339  12abcde  ->   deabc12
   1340 */
   1341 static inline void sort_r_swap_blocks(char *ptr, size_t na, size_t nb)
   1342 {
   1343  if(na > 0 && nb > 0) {
   1344    if(na > nb) { sort_r_swap(ptr, ptr+na, nb); }
   1345    else { sort_r_swap(ptr, ptr+nb, na); }
   1346  }
   1347 }
   1348 
   1349 /* Implement recursive quicksort ourselves */
   1350 /* Note: quicksort is not stable, equivalent values may be swapped */
   1351 template <typename ...Ts>
   1352 static inline void sort_r_simple(void *base, size_t nel, size_t w,
   1353                                 int (*compar)(const void *_a,
   1354                                               const void *_b,
   1355                                               Ts... _ds),
   1356                                 Ts... ds)
   1357 {
   1358  char *b = (char *)base, *end = b + nel*w;
   1359 
   1360  /* for(size_t i=0; i<nel; i++) {printf("%4i", *(int*)(b + i*sizeof(int)));}
   1361  printf("\n"); */
   1362 
   1363  if(nel < 10) {
   1364    /* Insertion sort for arbitrarily small inputs */
   1365    char *pi, *pj;
   1366    for(pi = b+w; pi < end; pi += w) {
   1367      for(pj = pi; pj > b && sort_r_cmpswap(pj-w,pj,w,compar,ds...); pj -= w) {}
   1368    }
   1369  }
   1370  else
   1371  {
   1372    /* nel > 9; Quicksort */
   1373 
   1374    int cmp;
   1375    char *pl, *ple, *pr, *pre, *pivot;
   1376    char *last = b+w*(nel-1), *tmp;
   1377 
   1378    /*
   1379    Use median of second, middle and second-last items as pivot.
   1380    First and last may have been swapped with pivot and therefore be extreme
   1381    */
   1382    char *l[3];
   1383    l[0] = b + w;
   1384    l[1] = b+w*(nel/2);
   1385    l[2] = last - w;
   1386 
   1387    /* printf("pivots: %i, %i, %i\n", *(int*)l[0], *(int*)l[1], *(int*)l[2]); */
   1388 
   1389    if(compar(l[0],l[1],ds...) > 0) { SORT_R_SWAP(l[0], l[1], tmp); }
   1390    if(compar(l[1],l[2],ds...) > 0) {
   1391      SORT_R_SWAP(l[1], l[2], tmp);
   1392      if(compar(l[0],l[1],ds...) > 0) { SORT_R_SWAP(l[0], l[1], tmp); }
   1393    }
   1394 
   1395    /* swap mid value (l[1]), and last element to put pivot as last element */
   1396    if(l[1] != last) { sort_r_swap(l[1], last, w); }
   1397 
   1398    /*
   1399    pl is the next item on the left to be compared to the pivot
   1400    pr is the last item on the right that was compared to the pivot
   1401    ple is the left position to put the next item that equals the pivot
   1402    ple is the last right position where we put an item that equals the pivot
   1403                                           v- end (beyond the array)
   1404      EEEEEELLLLLLLLuuuuuuuuGGGGGGGEEEEEEEE.
   1405      ^- b  ^- ple  ^- pl   ^- pr  ^- pre ^- last (where the pivot is)
   1406    Pivot comparison key:
   1407      E = equal, L = less than, u = unknown, G = greater than, E = equal
   1408    */
   1409    pivot = last;
   1410    ple = pl = b;
   1411    pre = pr = last;
   1412 
   1413    /*
   1414    Strategy:
   1415    Loop into the list from the left and right at the same time to find:
   1416    - an item on the left that is greater than the pivot
   1417    - an item on the right that is less than the pivot
   1418    Once found, they are swapped and the loop continues.
   1419    Meanwhile items that are equal to the pivot are moved to the edges of the
   1420    array.
   1421    */
   1422    while(pl < pr) {
   1423      /* Move left hand items which are equal to the pivot to the far left.
   1424         break when we find an item that is greater than the pivot */
   1425      for(; pl < pr; pl += w) {
   1426        cmp = compar(pl, pivot, ds...);
   1427        if(cmp > 0) { break; }
   1428        else if(cmp == 0) {
   1429          if(ple < pl) { sort_r_swap(ple, pl, w); }
   1430          ple += w;
   1431        }
   1432      }
   1433      /* break if last batch of left hand items were equal to pivot */
   1434      if(pl >= pr) { break; }
   1435      /* Move right hand items which are equal to the pivot to the far right.
   1436         break when we find an item that is less than the pivot */
   1437      for(; pl < pr; ) {
   1438        pr -= w; /* Move right pointer onto an unprocessed item */
   1439        cmp = compar(pr, pivot, ds...);
   1440        if(cmp == 0) {
   1441          pre -= w;
   1442          if(pr < pre) { sort_r_swap(pr, pre, w); }
   1443        }
   1444        else if(cmp < 0) {
   1445          if(pl < pr) { sort_r_swap(pl, pr, w); }
   1446          pl += w;
   1447          break;
   1448        }
   1449      }
   1450    }
   1451 
   1452    pl = pr; /* pr may have gone below pl */
   1453 
   1454    /*
   1455    Now we need to go from: EEELLLGGGGEEEE
   1456                        to: LLLEEEEEEEGGGG
   1457    Pivot comparison key:
   1458      E = equal, L = less than, u = unknown, G = greater than, E = equal
   1459    */
   1460    sort_r_swap_blocks(b, ple-b, pl-ple);
   1461    sort_r_swap_blocks(pr, pre-pr, end-pre);
   1462 
   1463    /*for(size_t i=0; i<nel; i++) {printf("%4i", *(int*)(b + i*sizeof(int)));}
   1464    printf("\n");*/
   1465 
   1466    sort_r_simple(b, (pl-ple)/w, w, compar, ds...);
   1467    sort_r_simple(end-(pre-pr), (pre-pr)/w, w, compar, ds...);
   1468  }
   1469 }
   1470 
   1471 static inline void
   1472 hb_qsort (void *base, size_t nel, size_t width,
   1473   int (*compar)(const void *_a, const void *_b))
   1474 {
   1475 #if defined(__OPTIMIZE_SIZE__) && !defined(HB_USE_INTERNAL_QSORT)
   1476  qsort (base, nel, width, compar);
   1477 #else
   1478  sort_r_simple (base, nel, width, compar);
   1479 #endif
   1480 }
   1481 
   1482 static inline void
   1483 hb_qsort (void *base, size_t nel, size_t width,
   1484   int (*compar)(const void *_a, const void *_b, void *_arg),
   1485   void *arg)
   1486 {
   1487 #ifdef HAVE_GNU_QSORT_R
   1488  qsort_r (base, nel, width, compar, arg);
   1489 #else
   1490  sort_r_simple (base, nel, width, compar, arg);
   1491 #endif
   1492 }
   1493 
   1494 
   1495 template <typename T, typename T2, typename T3 = int> static inline void
   1496 hb_stable_sort (T *array, unsigned int len, int(*compar)(const T2 *, const T2 *), T3 *array2 = nullptr)
   1497 {
   1498  static_assert (hb_is_trivially_copy_assignable (T), "");
   1499  static_assert (hb_is_trivially_copy_assignable (T3), "");
   1500 
   1501  for (unsigned int i = 1; i < len; i++)
   1502  {
   1503    unsigned int j = i;
   1504    while (j && compar (&array[j - 1], &array[i]) > 0)
   1505      j--;
   1506    if (i == j)
   1507      continue;
   1508    /* Move item i to occupy place for item j, shift what's in between. */
   1509    {
   1510      T t = array[i];
   1511      memmove (&array[j + 1], &array[j], (i - j) * sizeof (T));
   1512      array[j] = t;
   1513    }
   1514    if (array2)
   1515    {
   1516      T3 t = array2[i];
   1517      memmove (&array2[j + 1], &array2[j], (i - j) * sizeof (T3));
   1518      array2[j] = t;
   1519    }
   1520  }
   1521 }
   1522 
   1523 static inline hb_bool_t
   1524 hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
   1525 {
   1526  unsigned int v;
   1527  const char *p = s;
   1528  const char *end = p + len;
   1529  if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */, base)))
   1530    return false;
   1531 
   1532  *out = v;
   1533  return true;
   1534 }
   1535 
   1536 
   1537 /* Operators. */
   1538 
   1539 struct
   1540 { HB_PARTIALIZE(2);
   1541  template <typename T> constexpr auto
   1542  operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & b)
   1543 }
   1544 HB_FUNCOBJ (hb_bitwise_and);
   1545 struct
   1546 { HB_PARTIALIZE(2);
   1547  template <typename T> constexpr auto
   1548  operator () (const T &a, const T &b) const HB_AUTO_RETURN (a | b)
   1549 }
   1550 HB_FUNCOBJ (hb_bitwise_or);
   1551 struct
   1552 { HB_PARTIALIZE(2);
   1553  template <typename T> constexpr auto
   1554  operator () (const T &a, const T &b) const HB_AUTO_RETURN (a ^ b)
   1555 }
   1556 HB_FUNCOBJ (hb_bitwise_xor);
   1557 struct
   1558 { HB_PARTIALIZE(2);
   1559  template <typename T> constexpr auto
   1560  operator () (const T &a, const T &b) const HB_AUTO_RETURN (~a & b)
   1561 }
   1562 HB_FUNCOBJ (hb_bitwise_lt);
   1563 struct
   1564 { HB_PARTIALIZE(2);
   1565  template <typename T> constexpr auto
   1566  operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & ~b)
   1567 }
   1568 HB_FUNCOBJ (hb_bitwise_gt); // aka sub
   1569 struct
   1570 { HB_PARTIALIZE(2);
   1571  template <typename T> constexpr auto
   1572  operator () (const T &a, const T &b) const HB_AUTO_RETURN (~a | b)
   1573 }
   1574 HB_FUNCOBJ (hb_bitwise_le);
   1575 struct
   1576 { HB_PARTIALIZE(2);
   1577  template <typename T> constexpr auto
   1578  operator () (const T &a, const T &b) const HB_AUTO_RETURN (a | ~b)
   1579 }
   1580 HB_FUNCOBJ (hb_bitwise_ge);
   1581 struct
   1582 {
   1583  template <typename T> constexpr auto
   1584  operator () (const T &a) const HB_AUTO_RETURN (~a)
   1585 }
   1586 HB_FUNCOBJ (hb_bitwise_neg);
   1587 
   1588 struct
   1589 { HB_PARTIALIZE(2);
   1590  template <typename T, typename T2> constexpr auto
   1591  operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a + b)
   1592 }
   1593 HB_FUNCOBJ (hb_add);
   1594 struct
   1595 { HB_PARTIALIZE(2);
   1596  template <typename T, typename T2> constexpr auto
   1597  operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a - b)
   1598 }
   1599 HB_FUNCOBJ (hb_sub);
   1600 struct
   1601 { HB_PARTIALIZE(2);
   1602  template <typename T, typename T2> constexpr auto
   1603  operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (b - a)
   1604 }
   1605 HB_FUNCOBJ (hb_rsub);
   1606 struct
   1607 { HB_PARTIALIZE(2);
   1608  template <typename T, typename T2> constexpr auto
   1609  operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a * b)
   1610 }
   1611 HB_FUNCOBJ (hb_mul);
   1612 struct
   1613 { HB_PARTIALIZE(2);
   1614  template <typename T, typename T2> constexpr auto
   1615  operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a / b)
   1616 }
   1617 HB_FUNCOBJ (hb_div);
   1618 struct
   1619 { HB_PARTIALIZE(2);
   1620  template <typename T, typename T2> constexpr auto
   1621  operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a % b)
   1622 }
   1623 HB_FUNCOBJ (hb_mod);
   1624 struct
   1625 {
   1626  template <typename T> constexpr auto
   1627  operator () (const T &a) const HB_AUTO_RETURN (+a)
   1628 }
   1629 HB_FUNCOBJ (hb_pos);
   1630 struct
   1631 {
   1632  template <typename T> constexpr auto
   1633  operator () (const T &a) const HB_AUTO_RETURN (-a)
   1634 }
   1635 HB_FUNCOBJ (hb_neg);
   1636 struct
   1637 {
   1638  template <typename T> constexpr auto
   1639  operator () (T &a) const HB_AUTO_RETURN (++a)
   1640 }
   1641 HB_FUNCOBJ (hb_inc);
   1642 struct
   1643 {
   1644  template <typename T> constexpr auto
   1645  operator () (T &a) const HB_AUTO_RETURN (--a)
   1646 }
   1647 HB_FUNCOBJ (hb_dec);
   1648 
   1649 
   1650 /* Adapted from kurbo implementation with extra parameters added,
   1651 * and finding for a particular range instead of 0.
   1652 *
   1653 * For documentation and implementation see:
   1654 *
   1655 * [ITP method]: https://en.wikipedia.org/wiki/ITP_Method
   1656 * [An Enhancement of the Bisection Method Average Performance Preserving Minmax Optimality]: https://dl.acm.org/doi/10.1145/3423597
   1657 * https://docs.rs/kurbo/0.8.1/kurbo/common/fn.solve_itp.html
   1658 * https://github.com/linebender/kurbo/blob/fd839c25ea0c98576c7ce5789305822675a89938/src/common.rs#L162-L248
   1659 */
   1660 template <typename func_t>
   1661 double solve_itp (func_t f,
   1662 	  double a, double b,
   1663 	  double epsilon,
   1664 	  double min_y, double max_y,
   1665 	  double &ya, double &yb, double &y)
   1666 {
   1667  unsigned n1_2 = (unsigned) (hb_max (ceil (log2 ((b - a) / epsilon)) - 1.0, 0.0));
   1668  const unsigned n0 = 1; // Hardwired
   1669  const double k1 = 0.2 / (b - a); // Hardwired.
   1670  unsigned nmax = n0 + n1_2;
   1671  double scaled_epsilon = epsilon * double (1llu << nmax);
   1672  double _2_epsilon = 2.0 * epsilon;
   1673  while (b - a > _2_epsilon)
   1674  {
   1675    double x1_2 = 0.5 * (a + b);
   1676    double r = scaled_epsilon - 0.5 * (b - a);
   1677    double xf = (yb * a - ya * b) / (yb - ya);
   1678    double sigma = x1_2 - xf;
   1679    double b_a = b - a;
   1680    // This has k2 = 2 hardwired for efficiency.
   1681    double b_a_k2 = b_a * b_a;
   1682    double delta = k1 * b_a_k2;
   1683    int sigma_sign = sigma >= 0 ? +1 : -1;
   1684    double xt = delta <= fabs (x1_2 - xf) ? xf + delta * sigma_sign : x1_2;
   1685    double xitp = fabs (xt - x1_2) <= r ? xt : x1_2 - r * sigma_sign;
   1686    double yitp = f (xitp);
   1687    if (yitp > max_y)
   1688    {
   1689      b = xitp;
   1690      yb = yitp;
   1691    }
   1692    else if (yitp < min_y)
   1693    {
   1694      a = xitp;
   1695      ya = yitp;
   1696    }
   1697    else
   1698    {
   1699      y = yitp;
   1700      return xitp;
   1701    }
   1702    scaled_epsilon *= 0.5;
   1703  }
   1704  return 0.5 * (a + b);
   1705 }
   1706 
   1707 
   1708 #endif /* HB_ALGS_HH */