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