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