32e335495cf206979fea82cbda42110d1adb8eeb
[platform/upstream/harfbuzz.git] / src / hb-private.hh
1 /*
2  * Copyright © 2007,2008,2009  Red Hat, Inc.
3  * Copyright © 2011,2012  Google, Inc.
4  *
5  *  This is part of HarfBuzz, a text shaping library.
6  *
7  * Permission is hereby granted, without written agreement and without
8  * license or royalty fees, to use, copy, modify, and distribute this
9  * software and its documentation for any purpose, provided that the
10  * above copyright notice and the following two paragraphs appear in
11  * all copies of this software.
12  *
13  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17  * DAMAGE.
18  *
19  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
22  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24  *
25  * Red Hat Author(s): Behdad Esfahbod
26  * Google Author(s): Behdad Esfahbod
27  */
28
29 #ifndef HB_PRIVATE_HH
30 #define HB_PRIVATE_HH
31
32 #define _GNU_SOURCE 1
33
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
37
38 #include "hb.h"
39 #define HB_H_IN
40 #ifdef HAVE_OT
41 #include "hb-ot.h"
42 #define HB_OT_H_IN
43 #endif
44
45 #include <math.h>
46 #include <stdlib.h>
47 #include <stddef.h>
48 #include <string.h>
49 #include <assert.h>
50 #include <errno.h>
51 #include <stdio.h>
52 #include <stdarg.h>
53
54 #if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__)
55 #include <intrin.h>
56 #endif
57
58 #define HB_PASTE1(a,b) a##b
59 #define HB_PASTE(a,b) HB_PASTE1(a,b)
60
61 /* Compile-time custom allocator support. */
62
63 #if defined(hb_malloc_impl) \
64  && defined(hb_calloc_impl) \
65  && defined(hb_realloc_impl) \
66  && defined(hb_free_impl)
67 extern "C" void* hb_malloc_impl(size_t size);
68 extern "C" void* hb_calloc_impl(size_t nmemb, size_t size);
69 extern "C" void* hb_realloc_impl(void *ptr, size_t size);
70 extern "C" void  hb_free_impl(void *ptr);
71 #define malloc hb_malloc_impl
72 #define calloc hb_calloc_impl
73 #define realloc hb_realloc_impl
74 #define free hb_free_impl
75 #endif
76
77
78 /* Compiler attributes */
79
80
81 #if __cplusplus < 201103L
82
83 #ifndef nullptr
84 #define nullptr NULL
85 #endif
86
87 // Static assertions
88 #ifndef static_assert
89 #define static_assert(e, msg) \
90         HB_UNUSED typedef int HB_PASTE(static_assertion_failed_at_line_, __LINE__) [(e) ? 1 : -1]
91 #endif // static_assert
92
93 #ifdef __GNUC__
94 #if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8))
95 #define thread_local __thread
96 #endif
97 #else
98 #define thread_local
99 #endif
100
101 #endif // __cplusplus < 201103L
102
103 #if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE__)
104 #define likely(expr) (__builtin_expect (!!(expr), 1))
105 #define unlikely(expr) (__builtin_expect (!!(expr), 0))
106 #else
107 #define likely(expr) (expr)
108 #define unlikely(expr) (expr)
109 #endif
110
111 #if !defined(__GNUC__) && !defined(__clang__)
112 #undef __attribute__
113 #define __attribute__(x)
114 #endif
115
116 #if __GNUC__ >= 3
117 #define HB_PURE_FUNC    __attribute__((pure))
118 #define HB_CONST_FUNC   __attribute__((const))
119 #define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx)))
120 #else
121 #define HB_PURE_FUNC
122 #define HB_CONST_FUNC
123 #define HB_PRINTF_FUNC(format_idx, arg_idx)
124 #endif
125 #if __GNUC__ >= 4
126 #define HB_UNUSED       __attribute__((unused))
127 #elif defined(_MSC_VER) /* https://github.com/harfbuzz/harfbuzz/issues/635 */
128 #define HB_UNUSED __pragma(warning(suppress: 4100 4101))
129 #else
130 #define HB_UNUSED
131 #endif
132
133 #ifndef HB_INTERNAL
134 # if !defined(HB_NO_VISIBILITY) && !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(_MSC_VER) && !defined(__SUNPRO_CC)
135 #  define HB_INTERNAL __attribute__((__visibility__("hidden")))
136 # else
137 #  define HB_INTERNAL
138 #  define HB_NO_VISIBILITY 1
139 # endif
140 #endif
141
142 #if __GNUC__ >= 3
143 #define HB_FUNC __PRETTY_FUNCTION__
144 #elif defined(_MSC_VER)
145 #define HB_FUNC __FUNCSIG__
146 #else
147 #define HB_FUNC __func__
148 #endif
149
150 #if defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5140)
151 /* https://github.com/harfbuzz/harfbuzz/issues/630 */
152 #define __restrict
153 #endif
154
155 /*
156  * Borrowed from https://bugzilla.mozilla.org/show_bug.cgi?id=1215411
157  * HB_FALLTHROUGH is an annotation to suppress compiler warnings about switch
158  * cases that fall through without a break or return statement. HB_FALLTHROUGH
159  * is only needed on cases that have code:
160  *
161  * switch (foo) {
162  *   case 1: // These cases have no code. No fallthrough annotations are needed.
163  *   case 2:
164  *   case 3:
165  *     foo = 4; // This case has code, so a fallthrough annotation is needed:
166  *     HB_FALLTHROUGH;
167  *   default:
168  *     return foo;
169  * }
170  */
171 #if defined(__clang__) && __cplusplus >= 201103L
172    /* clang's fallthrough annotations are only available starting in C++11. */
173 #  define HB_FALLTHROUGH [[clang::fallthrough]]
174 #elif __GNUC__ >= 7
175    /* GNU fallthrough attribute is available from GCC7 */
176 #  define HB_FALLTHROUGH __attribute__((fallthrough))
177 #elif defined(_MSC_VER)
178    /*
179     * MSVC's __fallthrough annotations are checked by /analyze (Code Analysis):
180     * https://msdn.microsoft.com/en-us/library/ms235402%28VS.80%29.aspx
181     */
182 #  include <sal.h>
183 #  define HB_FALLTHROUGH __fallthrough
184 #else
185 #  define HB_FALLTHROUGH /* FALLTHROUGH */
186 #endif
187
188 #if defined(_WIN32) || defined(__CYGWIN__)
189    /* We need Windows Vista for both Uniscribe backend and for
190     * MemoryBarrier.  We don't support compiling on Windows XP,
191     * though we run on it fine. */
192 #  if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600
193 #    undef _WIN32_WINNT
194 #  endif
195 #  ifndef _WIN32_WINNT
196 #    define _WIN32_WINNT 0x0600
197 #  endif
198 #  ifndef WIN32_LEAN_AND_MEAN
199 #    define WIN32_LEAN_AND_MEAN 1
200 #  endif
201 #  ifndef STRICT
202 #    define STRICT 1
203 #  endif
204
205 #  if defined(_WIN32_WCE)
206      /* Some things not defined on Windows CE. */
207 #    define vsnprintf _vsnprintf
208 #    define getenv(Name) nullptr
209 #    if _WIN32_WCE < 0x800
210 #      define setlocale(Category, Locale) "C"
211 static int errno = 0; /* Use something better? */
212 #    endif
213 #  elif defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
214 #    define getenv(Name) nullptr
215 #  endif
216 #  if defined(_MSC_VER) && _MSC_VER < 1900
217 #    define snprintf _snprintf
218 #  endif
219 #endif
220
221 #if HAVE_ATEXIT
222 /* atexit() is only safe to be called from shared libraries on certain
223  * platforms.  Whitelist.
224  * https://bugs.freedesktop.org/show_bug.cgi?id=82246 */
225 #  if defined(__linux) && defined(__GLIBC_PREREQ)
226 #    if __GLIBC_PREREQ(2,3)
227 /* From atexit() manpage, it's safe with glibc 2.2.3 on Linux. */
228 #      define HB_USE_ATEXIT 1
229 #    endif
230 #  elif defined(_MSC_VER) || defined(__MINGW32__)
231 /* For MSVC:
232  * https://msdn.microsoft.com/en-us/library/tze57ck3.aspx
233  * https://msdn.microsoft.com/en-us/library/zk17ww08.aspx
234  * mingw32 headers say atexit is safe to use in shared libraries.
235  */
236 #    define HB_USE_ATEXIT 1
237 #  elif defined(__ANDROID__)
238 /* This is available since Android NKD r8 or r8b:
239  * https://issuetracker.google.com/code/p/android/issues/detail?id=6455
240  */
241 #    define HB_USE_ATEXIT 1
242 #  elif defined(__APPLE__)
243 /* For macOS and related platforms, the atexit man page indicates
244  * that it will be invoked when the library is unloaded, not only
245  * at application exit.
246  */
247 #    define HB_USE_ATEXIT 1
248 #  endif
249 #endif
250 #ifdef HB_NO_ATEXIT
251 #  undef HB_USE_ATEXIT
252 #endif
253
254 /* Basics */
255
256 #undef MIN
257 template <typename Type>
258 static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; }
259
260 #undef MAX
261 template <typename Type>
262 static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; }
263
264 static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b)
265 { return (a + (b - 1)) / b; }
266
267
268 #undef  ARRAY_LENGTH
269 template <typename Type, unsigned int n>
270 static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; }
271 /* A const version, but does not detect erratically being called on pointers. */
272 #define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
273
274 #define HB_STMT_START do
275 #define HB_STMT_END   while (0)
276
277 template <unsigned int cond> class hb_assert_constant_t;
278 template <> class hb_assert_constant_t<1> {};
279
280 #define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * (unsigned int) sizeof (hb_assert_constant_t<_cond>))
281
282 /* Lets assert int types.  Saves trouble down the road. */
283
284 static_assert ((sizeof (int8_t) == 1), "");
285 static_assert ((sizeof (uint8_t) == 1), "");
286 static_assert ((sizeof (int16_t) == 2), "");
287 static_assert ((sizeof (uint16_t) == 2), "");
288 static_assert ((sizeof (int32_t) == 4), "");
289 static_assert ((sizeof (uint32_t) == 4), "");
290 static_assert ((sizeof (int64_t) == 8), "");
291 static_assert ((sizeof (uint64_t) == 8), "");
292
293 static_assert ((sizeof (hb_codepoint_t) == 4), "");
294 static_assert ((sizeof (hb_position_t) == 4), "");
295 static_assert ((sizeof (hb_mask_t) == 4), "");
296 static_assert ((sizeof (hb_var_int_t) == 4), "");
297
298
299 /* We like our types POD */
300
301 #define _ASSERT_TYPE_POD1(_line, _type) union _type_##_type##_on_line_##_line##_is_not_POD { _type instance; }
302 #define _ASSERT_TYPE_POD0(_line, _type) _ASSERT_TYPE_POD1 (_line, _type)
303 #define ASSERT_TYPE_POD(_type)          _ASSERT_TYPE_POD0 (__LINE__, _type)
304
305 #ifdef __GNUC__
306 # define _ASSERT_INSTANCE_POD1(_line, _instance) \
307         HB_STMT_START { \
308                 typedef __typeof__(_instance) _type_##_line; \
309                 _ASSERT_TYPE_POD1 (_line, _type_##_line); \
310         } HB_STMT_END
311 #else
312 # define _ASSERT_INSTANCE_POD1(_line, _instance)        typedef int _assertion_on_line_##_line##_not_tested
313 #endif
314 # define _ASSERT_INSTANCE_POD0(_line, _instance)        _ASSERT_INSTANCE_POD1 (_line, _instance)
315 # define ASSERT_INSTANCE_POD(_instance)                 _ASSERT_INSTANCE_POD0 (__LINE__, _instance)
316
317 /* Check _assertion in a method environment */
318 #define _ASSERT_POD1(_line) \
319         HB_UNUSED inline void _static_assertion_on_line_##_line (void) const \
320         { _ASSERT_INSTANCE_POD1 (_line, *this); /* Make sure it's POD. */ }
321 # define _ASSERT_POD0(_line)    _ASSERT_POD1 (_line)
322 # define ASSERT_POD()           _ASSERT_POD0 (__LINE__)
323
324
325
326 /* Tiny functions */
327
328 /*
329  * Void!
330  */
331 typedef const struct _hb_void_t *hb_void_t;
332 #define HB_VOID ((const _hb_void_t *) nullptr)
333
334 /* Return the number of 1 bits in v. */
335 template <typename T>
336 static inline HB_CONST_FUNC unsigned int
337 _hb_popcount (T v)
338 {
339 #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && defined(__OPTIMIZE__)
340   if (sizeof (T) <= sizeof (unsigned int))
341     return __builtin_popcount (v);
342
343   if (sizeof (T) <= sizeof (unsigned long))
344     return __builtin_popcountl (v);
345
346   if (sizeof (T) <= sizeof (unsigned long long))
347     return __builtin_popcountll (v);
348 #endif
349
350   if (sizeof (T) <= 4)
351   {
352     /* "HACKMEM 169" */
353     uint32_t y;
354     y = (v >> 1) &033333333333;
355     y = v - y - ((y >>1) & 033333333333);
356     return (((y + (y >> 3)) & 030707070707) % 077);
357   }
358
359   if (sizeof (T) == 8)
360   {
361     unsigned int shift = 32;
362     return _hb_popcount<uint32_t> ((uint32_t) v) + _hb_popcount ((uint32_t) (v >> shift));
363   }
364
365   if (sizeof (T) == 16)
366   {
367     unsigned int shift = 64;
368     return _hb_popcount<uint64_t> ((uint64_t) v) + _hb_popcount ((uint64_t) (v >> shift));
369   }
370
371   assert (0);
372   return 0; /* Shut up stupid compiler. */
373 }
374
375 /* Returns the number of bits needed to store number */
376 template <typename T>
377 static inline HB_CONST_FUNC unsigned int
378 _hb_bit_storage (T v)
379 {
380   if (unlikely (!v)) return 0;
381
382 #if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__)
383   if (sizeof (T) <= sizeof (unsigned int))
384     return sizeof (unsigned int) * 8 - __builtin_clz (v);
385
386   if (sizeof (T) <= sizeof (unsigned long))
387     return sizeof (unsigned long) * 8 - __builtin_clzl (v);
388
389   if (sizeof (T) <= sizeof (unsigned long long))
390     return sizeof (unsigned long long) * 8 - __builtin_clzll (v);
391 #endif
392
393 #if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__)
394   if (sizeof (T) <= sizeof (unsigned int))
395   {
396     unsigned long where;
397     _BitScanReverse (&where, v);
398     return 1 + where;
399   }
400 # if _WIN64
401   if (sizeof (T) <= 8)
402   {
403     unsigned long where;
404     _BitScanReverse64 (&where, v);
405     return 1 + where;
406   }
407 # endif
408 #endif
409
410   if (sizeof (T) <= 4)
411   {
412     /* "bithacks" */
413     const unsigned int b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
414     const unsigned int S[] = {1, 2, 4, 8, 16};
415     unsigned int r = 0;
416     for (int i = 4; i >= 0; i--)
417       if (v & b[i])
418       {
419         v >>= S[i];
420         r |= S[i];
421       }
422     return r + 1;
423   }
424   if (sizeof (T) <= 8)
425   {
426     /* "bithacks" */
427     const uint64_t b[] = {0x2ULL, 0xCULL, 0xF0ULL, 0xFF00ULL, 0xFFFF0000ULL, 0xFFFFFFFF00000000ULL};
428     const unsigned int S[] = {1, 2, 4, 8, 16, 32};
429     unsigned int r = 0;
430     for (int i = 5; i >= 0; i--)
431       if (v & b[i])
432       {
433         v >>= S[i];
434         r |= S[i];
435       }
436     return r + 1;
437   }
438   if (sizeof (T) == 16)
439   {
440     unsigned int shift = 64;
441     return (v >> shift) ? _hb_bit_storage<uint64_t> ((uint64_t) (v >> shift)) + shift :
442                           _hb_bit_storage<uint64_t> ((uint64_t) v);
443   }
444
445   assert (0);
446   return 0; /* Shut up stupid compiler. */
447 }
448
449 /* Returns the number of zero bits in the least significant side of v */
450 template <typename T>
451 static inline HB_CONST_FUNC unsigned int
452 _hb_ctz (T v)
453 {
454   if (unlikely (!v)) return 0;
455
456 #if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__)
457   if (sizeof (T) <= sizeof (unsigned int))
458     return __builtin_ctz (v);
459
460   if (sizeof (T) <= sizeof (unsigned long))
461     return __builtin_ctzl (v);
462
463   if (sizeof (T) <= sizeof (unsigned long long))
464     return __builtin_ctzll (v);
465 #endif
466
467 #if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__)
468   if (sizeof (T) <= sizeof (unsigned int))
469   {
470     unsigned long where;
471     _BitScanForward (&where, v);
472     return where;
473   }
474 # if _WIN64
475   if (sizeof (T) <= 8)
476   {
477     unsigned long where;
478     _BitScanForward64 (&where, v);
479     return where;
480   }
481 # endif
482 #endif
483
484   if (sizeof (T) <= 4)
485   {
486     /* "bithacks" */
487     unsigned int c = 32;
488     v &= - (int32_t) v;
489     if (v) c--;
490     if (v & 0x0000FFFF) c -= 16;
491     if (v & 0x00FF00FF) c -= 8;
492     if (v & 0x0F0F0F0F) c -= 4;
493     if (v & 0x33333333) c -= 2;
494     if (v & 0x55555555) c -= 1;
495     return c;
496   }
497   if (sizeof (T) <= 8)
498   {
499     /* "bithacks" */
500     unsigned int c = 64;
501     v &= - (int64_t) (v);
502     if (v) c--;
503     if (v & 0x00000000FFFFFFFFULL) c -= 32;
504     if (v & 0x0000FFFF0000FFFFULL) c -= 16;
505     if (v & 0x00FF00FF00FF00FFULL) c -= 8;
506     if (v & 0x0F0F0F0F0F0F0F0FULL) c -= 4;
507     if (v & 0x3333333333333333ULL) c -= 2;
508     if (v & 0x5555555555555555ULL) c -= 1;
509     return c;
510   }
511   if (sizeof (T) == 16)
512   {
513     unsigned int shift = 64;
514     return (uint64_t) v ? _hb_bit_storage<uint64_t> ((uint64_t) v) :
515                           _hb_bit_storage<uint64_t> ((uint64_t) v >> shift) + shift;
516   }
517
518   assert (0);
519   return 0; /* Shut up stupid compiler. */
520 }
521
522 static inline bool
523 _hb_unsigned_int_mul_overflows (unsigned int count, unsigned int size)
524 {
525   return (size > 0) && (count >= ((unsigned int) -1) / size);
526 }
527
528 static inline unsigned int
529 _hb_ceil_to_4 (unsigned int v)
530 {
531   return ((v - 1) | 3) + 1;
532 }
533
534
535
536 /*
537  *
538  * Utility types
539  *
540  */
541
542 #define HB_DISALLOW_COPY_AND_ASSIGN(TypeName) \
543   TypeName(const TypeName&); \
544   void operator=(const TypeName&)
545
546 /*
547  * Static pools
548  */
549
550 /* Global nul-content Null pool.  Enlarge as necessary. */
551
552 #define HB_NULL_POOL_SIZE 264
553 static_assert (HB_NULL_POOL_SIZE % sizeof (void *) == 0, "Align HB_NULL_POOL_SIZE.");
554
555 #ifdef HB_NO_VISIBILITY
556 static
557 #else
558 extern HB_INTERNAL
559 #endif
560 void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)]
561 #ifdef HB_NO_VISIBILITY
562 = {}
563 #endif
564 ;
565 /* Generic nul-content Null objects. */
566 template <typename Type>
567 static inline Type const & Null (void) {
568   static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE.");
569   return *reinterpret_cast<Type const *> (_hb_NullPool);
570 }
571 #define Null(Type) Null<Type>()
572
573 /* Specializaiton for arbitrary-content arbitrary-sized Null objects. */
574 #define DEFINE_NULL_DATA(Namespace, Type, data) \
575 } /* Close namespace. */ \
576 static const char _Null##Type[sizeof (Namespace::Type) + 1] = data; /* +1 is for nul-termination in data */ \
577 template <> \
578 /*static*/ inline const Namespace::Type& Null<Namespace::Type> (void) { \
579   return *reinterpret_cast<const Namespace::Type *> (_Null##Type); \
580 } \
581 namespace Namespace { \
582 /* The following line really exists such that we end in a place needing semicolon */ \
583 static_assert (Namespace::Type::min_size + 1 <= sizeof (_Null##Type), "Null pool too small.  Enlarge.")
584
585
586 /* Global writable pool.  Enlarge as necessary. */
587
588 /* To be fully correct, CrapPool must be thread_local. However, we do not rely on CrapPool
589  * for correct operation. It only exist to catch and divert program logic bugs instead of
590  * causing bad memory access. So, races there are not actually introducing incorrectness
591  * in the code. Has ~12kb binary size overhead to have it, also clang build fails with it. */
592 #ifdef HB_NO_VISIBILITY
593 static
594 #else
595 extern HB_INTERNAL
596 #endif
597 /*thread_local*/ void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)]
598 #ifdef HB_NO_VISIBILITY
599 = {}
600 #endif
601 ;
602 /* CRAP pool: Common Region for Access Protection. */
603 template <typename Type>
604 static inline Type& Crap (void) {
605   static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE.");
606   Type *obj = reinterpret_cast<Type *> (_hb_CrapPool);
607   *obj = Null(Type);
608   return *obj;
609 }
610 #define Crap(Type) Crap<Type>()
611
612 template <typename Type>
613 struct CrapOrNull {
614   static inline Type & get (void) { return Crap(Type); }
615 };
616 template <typename Type>
617 struct CrapOrNull<const Type> {
618   static inline Type const & get (void) { return Null(Type); }
619 };
620 #define CrapOrNull(Type) CrapOrNull<Type>::get ()
621
622
623
624 /* arrays and maps */
625
626
627 #define HB_PREALLOCED_ARRAY_INIT {0, 0, nullptr}
628 template <typename Type, unsigned int StaticSize=8>
629 struct hb_vector_t
630 {
631   unsigned int len;
632   unsigned int allocated;
633   bool successful;
634   Type *arrayZ;
635   Type static_array[StaticSize];
636
637   void init (void)
638   {
639     len = 0;
640     allocated = ARRAY_LENGTH (static_array);
641     successful = true;
642     arrayZ = static_array;
643   }
644
645   inline Type& operator [] (unsigned int i)
646   {
647     if (unlikely (i >= len))
648       return Crap (Type);
649     return arrayZ[i];
650   }
651   inline const Type& operator [] (unsigned int i) const
652   {
653     if (unlikely (i >= len))
654       return Null(Type);
655     return arrayZ[i];
656   }
657
658   inline Type *push (void)
659   {
660     if (unlikely (!resize (len + 1)))
661       return &Crap(Type);
662     return &arrayZ[len - 1];
663   }
664   inline Type *push (const Type& v)
665   {
666     Type *p = push ();
667     *p = v;
668     return p;
669   }
670
671   /* Allocate for size but don't adjust len. */
672   inline bool alloc (unsigned int size)
673   {
674     if (unlikely (!successful))
675       return false;
676
677     if (likely (size <= allocated))
678       return true;
679
680     /* Reallocate */
681
682     unsigned int new_allocated = allocated;
683     while (size >= new_allocated)
684       new_allocated += (new_allocated >> 1) + 8;
685
686     Type *new_array = nullptr;
687
688     if (arrayZ == static_array)
689     {
690       new_array = (Type *) calloc (new_allocated, sizeof (Type));
691       if (new_array)
692         memcpy (new_array, arrayZ, len * sizeof (Type));
693     }
694     else
695     {
696       bool overflows = (new_allocated < allocated) || _hb_unsigned_int_mul_overflows (new_allocated, sizeof (Type));
697       if (likely (!overflows))
698         new_array = (Type *) realloc (arrayZ, new_allocated * sizeof (Type));
699     }
700
701     if (unlikely (!new_array))
702     {
703       successful = false;
704       return false;
705     }
706
707     arrayZ = new_array;
708     allocated = new_allocated;
709
710     return true;
711   }
712
713   inline bool resize (int size_)
714   {
715     unsigned int size = size_ < 0 ? 0u : (unsigned int) size_;
716     if (!alloc (size))
717       return false;
718
719     if (size > len)
720       memset (arrayZ + len, 0, (size - len) * sizeof (*arrayZ));
721
722     len = size;
723     return true;
724   }
725
726   inline void pop (void)
727   {
728     if (!len) return;
729     len--;
730   }
731
732   inline void remove (unsigned int i)
733   {
734      if (unlikely (i >= len))
735        return;
736      memmove (static_cast<void *> (&arrayZ[i]),
737               static_cast<void *> (&arrayZ[i + 1]),
738               (len - i - 1) * sizeof (Type));
739      len--;
740   }
741
742   inline void shrink (int size_)
743   {
744     unsigned int size = size_ < 0 ? 0u : (unsigned int) size_;
745      if (size < len)
746        len = size;
747   }
748
749   template <typename T>
750   inline Type *find (T v) {
751     for (unsigned int i = 0; i < len; i++)
752       if (arrayZ[i] == v)
753         return &arrayZ[i];
754     return nullptr;
755   }
756   template <typename T>
757   inline const Type *find (T v) const {
758     for (unsigned int i = 0; i < len; i++)
759       if (arrayZ[i] == v)
760         return &arrayZ[i];
761     return nullptr;
762   }
763
764   inline void qsort (int (*cmp)(const void*, const void*))
765   {
766     ::qsort (arrayZ, len, sizeof (Type), cmp);
767   }
768
769   inline void qsort (void)
770   {
771     ::qsort (arrayZ, len, sizeof (Type), Type::cmp);
772   }
773
774   inline void qsort (unsigned int start, unsigned int end)
775   {
776     ::qsort (arrayZ + start, end - start, sizeof (Type), Type::cmp);
777   }
778
779   template <typename T>
780   inline Type *lsearch (const T &x)
781   {
782     for (unsigned int i = 0; i < len; i++)
783       if (0 == this->arrayZ[i].cmp (&x))
784         return &arrayZ[i];
785     return nullptr;
786   }
787
788   template <typename T>
789   inline Type *bsearch (const T &x)
790   {
791     unsigned int i;
792     return bfind (x, &i) ? &arrayZ[i] : nullptr;
793   }
794   template <typename T>
795   inline const Type *bsearch (const T &x) const
796   {
797     unsigned int i;
798     return bfind (x, &i) ? &arrayZ[i] : nullptr;
799   }
800   template <typename T>
801   inline bool bfind (const T &x, unsigned int *i) const
802   {
803     int min = 0, max = (int) this->len - 1;
804     while (min <= max)
805     {
806       int mid = (min + max) / 2;
807       int c = this->arrayZ[mid].cmp (&x);
808       if (c < 0)
809         max = mid - 1;
810       else if (c > 0)
811         min = mid + 1;
812       else
813       {
814         *i = mid;
815         return true;
816       }
817     }
818     if (max < 0 || (max < (int) this->len && this->arrayZ[max].cmp (&x) > 0))
819       max++;
820     *i = max;
821     return false;
822   }
823
824   inline void fini (void)
825   {
826     if (arrayZ != static_array)
827       free (arrayZ);
828     arrayZ = nullptr;
829     allocated = len = 0;
830   }
831 };
832
833 template <typename Type>
834 struct hb_auto_t : Type
835 {
836   hb_auto_t (void) { Type::init (); }
837   ~hb_auto_t (void) { Type::fini (); }
838   private: /* Hide */
839   void init (void) {}
840   void fini (void) {}
841 };
842 template <typename Type>
843 struct hb_auto_array_t : hb_auto_t <hb_vector_t <Type> > {};
844
845
846 #define HB_LOCKABLE_SET_INIT {HB_PREALLOCED_ARRAY_INIT}
847 template <typename item_t, typename lock_t>
848 struct hb_lockable_set_t
849 {
850   hb_vector_t <item_t, 1> items;
851
852   inline void init (void) { items.init (); }
853
854   template <typename T>
855   inline item_t *replace_or_insert (T v, lock_t &l, bool replace)
856   {
857     l.lock ();
858     item_t *item = items.find (v);
859     if (item) {
860       if (replace) {
861         item_t old = *item;
862         *item = v;
863         l.unlock ();
864         old.fini ();
865       }
866       else {
867         item = nullptr;
868         l.unlock ();
869       }
870     } else {
871       item = items.push (v);
872       l.unlock ();
873     }
874     return item;
875   }
876
877   template <typename T>
878   inline void remove (T v, lock_t &l)
879   {
880     l.lock ();
881     item_t *item = items.find (v);
882     if (item) {
883       item_t old = *item;
884       *item = items[items.len - 1];
885       items.pop ();
886       l.unlock ();
887       old.fini ();
888     } else {
889       l.unlock ();
890     }
891   }
892
893   template <typename T>
894   inline bool find (T v, item_t *i, lock_t &l)
895   {
896     l.lock ();
897     item_t *item = items.find (v);
898     if (item)
899       *i = *item;
900     l.unlock ();
901     return !!item;
902   }
903
904   template <typename T>
905   inline item_t *find_or_insert (T v, lock_t &l)
906   {
907     l.lock ();
908     item_t *item = items.find (v);
909     if (!item) {
910       item = items.push (v);
911     }
912     l.unlock ();
913     return item;
914   }
915
916   inline void fini (lock_t &l)
917   {
918     if (!items.len) {
919       /* No need for locking. */
920       items.fini ();
921       return;
922     }
923     l.lock ();
924     while (items.len) {
925       item_t old = items[items.len - 1];
926         items.pop ();
927         l.unlock ();
928         old.fini ();
929         l.lock ();
930     }
931     items.fini ();
932     l.unlock ();
933   }
934
935 };
936
937
938 /* ASCII tag/character handling */
939
940 static inline bool ISALPHA (unsigned char c)
941 { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); }
942 static inline bool ISALNUM (unsigned char c)
943 { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); }
944 static inline bool ISSPACE (unsigned char c)
945 { return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; }
946 static inline unsigned char TOUPPER (unsigned char c)
947 { return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; }
948 static inline unsigned char TOLOWER (unsigned char c)
949 { return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; }
950
951
952 /* HB_NDEBUG disables some sanity checks that are very safe to disable and
953  * should be disabled in production systems.  If NDEBUG is defined, enable
954  * HB_NDEBUG; but if it's desirable that normal assert()s (which are very
955  * light-weight) to be enabled, then HB_DEBUG can be defined to disable
956  * the costlier checks. */
957 #ifdef NDEBUG
958 #define HB_NDEBUG 1
959 #endif
960
961
962 /* Misc */
963
964 template <typename T> class hb_assert_unsigned_t;
965 template <> class hb_assert_unsigned_t<unsigned char> {};
966 template <> class hb_assert_unsigned_t<unsigned short> {};
967 template <> class hb_assert_unsigned_t<unsigned int> {};
968 template <> class hb_assert_unsigned_t<unsigned long> {};
969
970 template <typename T> static inline bool
971 hb_in_range (T u, T lo, T hi)
972 {
973   /* The sizeof() is here to force template instantiation.
974    * I'm sure there are better ways to do this but can't think of
975    * one right now.  Declaring a variable won't work as HB_UNUSED
976    * is unusable on some platforms and unused types are less likely
977    * to generate a warning than unused variables. */
978   static_assert ((sizeof (hb_assert_unsigned_t<T>) >= 0), "");
979
980   /* The casts below are important as if T is smaller than int,
981    * the subtract results will become a signed int! */
982   return (T)(u - lo) <= (T)(hi - lo);
983 }
984
985 template <typename T> static inline bool
986 hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2)
987 {
988   return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2);
989 }
990
991 template <typename T> static inline bool
992 hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
993 {
994   return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3);
995 }
996
997
998 /* Enable bitwise ops on enums marked as flags_t */
999 /* To my surprise, looks like the function resolver is happy to silently cast
1000  * one enum to another...  So this doesn't provide the type-checking that I
1001  * originally had in mind... :(.
1002  *
1003  * For MSVC warnings, see: https://github.com/harfbuzz/harfbuzz/pull/163
1004  */
1005 #ifdef _MSC_VER
1006 # pragma warning(disable:4200)
1007 # pragma warning(disable:4800)
1008 #endif
1009 #define HB_MARK_AS_FLAG_T(T) \
1010         extern "C++" { \
1011           static inline T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \
1012           static inline T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \
1013           static inline T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \
1014           static inline T operator ~ (T r) { return T (~(unsigned int) r); } \
1015           static inline T& operator |= (T &l, T r) { l = l | r; return l; } \
1016           static inline T& operator &= (T& l, T r) { l = l & r; return l; } \
1017           static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \
1018         }
1019
1020
1021 /* Useful for set-operations on small enums.
1022  * For example, for testing "x ∈ {x1, x2, x3}" use:
1023  * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3)))
1024  */
1025 #define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned int)(x) < 32) + (1U << (unsigned int)(x)))
1026 #define FLAG_UNSAFE(x) ((unsigned int)(x) < 32 ? (1U << (unsigned int)(x)) : 0)
1027 #define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x))
1028
1029
1030 template <typename T, typename T2> static inline void
1031 hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *), T2 *array2)
1032 {
1033   for (unsigned int i = 1; i < len; i++)
1034   {
1035     unsigned int j = i;
1036     while (j && compar (&array[j - 1], &array[i]) > 0)
1037       j--;
1038     if (i == j)
1039       continue;
1040     /* Move item i to occupy place for item j, shift what's in between. */
1041     {
1042       T t = array[i];
1043       memmove (&array[j + 1], &array[j], (i - j) * sizeof (T));
1044       array[j] = t;
1045     }
1046     if (array2)
1047     {
1048       T2 t = array2[i];
1049       memmove (&array2[j + 1], &array2[j], (i - j) * sizeof (T2));
1050       array2[j] = t;
1051     }
1052   }
1053 }
1054
1055 template <typename T> static inline void
1056 hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
1057 {
1058   hb_stable_sort (array, len, compar, (int *) nullptr);
1059 }
1060
1061 static inline hb_bool_t
1062 hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
1063 {
1064   /* Pain because we don't know whether s is nul-terminated. */
1065   char buf[64];
1066   len = MIN (ARRAY_LENGTH (buf) - 1, len);
1067   strncpy (buf, s, len);
1068   buf[len] = '\0';
1069
1070   char *end;
1071   errno = 0;
1072   unsigned long v = strtoul (buf, &end, base);
1073   if (errno) return false;
1074   if (*end) return false;
1075   *out = v;
1076   return true;
1077 }
1078
1079
1080 /* Vectorization */
1081
1082 struct HbOpOr
1083 {
1084   static const bool passthru_left = true;
1085   static const bool passthru_right = true;
1086   template <typename T> static void process (T &o, const T &a, const T &b) { o = a | b; }
1087 };
1088 struct HbOpAnd
1089 {
1090   static const bool passthru_left = false;
1091   static const bool passthru_right = false;
1092   template <typename T> static void process (T &o, const T &a, const T &b) { o = a & b; }
1093 };
1094 struct HbOpMinus
1095 {
1096   static const bool passthru_left = true;
1097   static const bool passthru_right = false;
1098   template <typename T> static void process (T &o, const T &a, const T &b) { o = a & ~b; }
1099 };
1100 struct HbOpXor
1101 {
1102   static const bool passthru_left = true;
1103   static const bool passthru_right = true;
1104   template <typename T> static void process (T &o, const T &a, const T &b) { o = a ^ b; }
1105 };
1106
1107
1108 /* Compiler-assisted vectorization. */
1109
1110 /* The `vector_size' attribute was introduced in gcc 3.1. */
1111 #if defined( __GNUC__ ) && ( __GNUC__ >= 4 )
1112 #define HB_VECTOR_SIZE 128
1113 #elif !defined(HB_VECTOR_SIZE)
1114 #define HB_VECTOR_SIZE 0
1115 #endif
1116
1117 /* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))). */
1118 template <typename elt_t, unsigned int byte_size>
1119 struct hb_vector_size_t
1120 {
1121   elt_t& operator [] (unsigned int i) { return u.v[i]; }
1122   const elt_t& operator [] (unsigned int i) const { return u.v[i]; }
1123
1124   template <class Op>
1125   inline hb_vector_size_t process (const hb_vector_size_t &o) const
1126   {
1127     hb_vector_size_t r;
1128 #if HB_VECTOR_SIZE
1129     if (HB_VECTOR_SIZE && 0 == (byte_size * 8) % HB_VECTOR_SIZE)
1130       for (unsigned int i = 0; i < ARRAY_LENGTH (u.vec); i++)
1131         Op::process (r.u.vec[i], u.vec[i], o.u.vec[i]);
1132     else
1133 #endif
1134       for (unsigned int i = 0; i < ARRAY_LENGTH (u.v); i++)
1135         Op::process (r.u.v[i], u.v[i], o.u.v[i]);
1136     return r;
1137   }
1138   inline hb_vector_size_t operator | (const hb_vector_size_t &o) const
1139   { return process<HbOpOr> (o); }
1140   inline hb_vector_size_t operator & (const hb_vector_size_t &o) const
1141   { return process<HbOpAnd> (o); }
1142   inline hb_vector_size_t operator ^ (const hb_vector_size_t &o) const
1143   { return process<HbOpXor> (o); }
1144   inline hb_vector_size_t operator ~ () const
1145   {
1146     hb_vector_size_t r;
1147 #if HB_VECTOR_SIZE && 0
1148     if (HB_VECTOR_SIZE && 0 == (byte_size * 8) % HB_VECTOR_SIZE)
1149       for (unsigned int i = 0; i < ARRAY_LENGTH (u.vec); i++)
1150         r.u.vec[i] = ~u.vec[i];
1151     else
1152 #endif
1153     for (unsigned int i = 0; i < ARRAY_LENGTH (u.v); i++)
1154       r.u.v[i] = ~u.v[i];
1155     return r;
1156   }
1157
1158   private:
1159   static_assert (byte_size / sizeof (elt_t) * sizeof (elt_t) == byte_size, "");
1160   union {
1161     elt_t v[byte_size / sizeof (elt_t)];
1162 #if HB_VECTOR_SIZE
1163     typedef unsigned long vec_t __attribute__((vector_size (HB_VECTOR_SIZE / 8)));
1164     vec_t vec[byte_size / sizeof (vec_t)];
1165 #endif
1166   } u;
1167 };
1168
1169
1170 /* Global runtime options. */
1171
1172 struct hb_options_t
1173 {
1174   unsigned int initialized : 1;
1175   unsigned int uniscribe_bug_compatible : 1;
1176 };
1177
1178 union hb_options_union_t {
1179   unsigned int i;
1180   hb_options_t opts;
1181 };
1182 static_assert ((sizeof (int) == sizeof (hb_options_union_t)), "");
1183
1184 HB_INTERNAL void
1185 _hb_options_init (void);
1186
1187 extern HB_INTERNAL hb_options_union_t _hb_options;
1188
1189 static inline hb_options_t
1190 hb_options (void)
1191 {
1192   if (unlikely (!_hb_options.i))
1193     _hb_options_init ();
1194
1195   return _hb_options.opts;
1196 }
1197
1198 /* Size signifying variable-sized array */
1199 #define VAR 1
1200
1201
1202 /* String type. */
1203
1204 struct hb_bytes_t
1205 {
1206   inline hb_bytes_t (void) : bytes (nullptr), len (0) {}
1207   inline hb_bytes_t (const char *bytes_, unsigned int len_) : bytes (bytes_), len (len_) {}
1208
1209   inline int cmp (const hb_bytes_t &a) const
1210   {
1211     if (len != a.len)
1212       return (int) a.len - (int) len;
1213
1214     return memcmp (a.bytes, bytes, len);
1215   }
1216   static inline int cmp (const void *pa, const void *pb)
1217   {
1218     hb_bytes_t *a = (hb_bytes_t *) pa;
1219     hb_bytes_t *b = (hb_bytes_t *) pb;
1220     return b->cmp (*a);
1221   }
1222
1223   const char *bytes;
1224   unsigned int len;
1225 };
1226
1227
1228 /* fallback for round() */
1229 #if !defined (HAVE_ROUND) && !defined (HAVE_DECL_ROUND)
1230 static inline double
1231 round (double x)
1232 {
1233   if (x >= 0)
1234     return floor (x + 0.5);
1235   else
1236     return ceil (x - 0.5);
1237 }
1238 #endif
1239
1240
1241 #endif /* HB_PRIVATE_HH */