Home | History | Annotate | Download | only in src
      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_HH
     30 #define HB_HH
     31 
     32 #ifdef HAVE_CONFIG_H
     33 #include "config.h"
     34 #endif
     35 
     36 /*
     37  * Following added based on what AC_USE_SYSTEM_EXTENSIONS adds to
     38  * config.h.in.  Copied here for the convenience of those embedding
     39  * HarfBuzz and not using our build system.
     40  */
     41 /* Enable extensions on AIX 3, Interix.  */
     42 #ifndef _ALL_SOURCE
     43 # define _ALL_SOURCE 1
     44 #endif
     45 /* Enable GNU extensions on systems that have them.  */
     46 #ifndef _GNU_SOURCE
     47 # define _GNU_SOURCE 1
     48 #endif
     49 /* Enable threading extensions on Solaris.  */
     50 #ifndef _POSIX_PTHREAD_SEMANTICS
     51 # define _POSIX_PTHREAD_SEMANTICS 1
     52 #endif
     53 /* Enable extensions on HP NonStop.  */
     54 #ifndef _TANDEM_SOURCE
     55 # define _TANDEM_SOURCE 1
     56 #endif
     57 /* Enable general extensions on Solaris.  */
     58 #ifndef __EXTENSIONS__
     59 # define __EXTENSIONS__ 1
     60 #endif
     61 
     62 #ifndef _POSIX_C_SOURCE
     63 #define _POSIX_C_SOURCE 200809L
     64 #endif
     65 
     66 #if defined (_MSC_VER) && defined (HB_DLL_EXPORT)
     67 #define HB_EXTERN __declspec (dllexport) extern
     68 #endif
     69 
     70 #include "hb.h"
     71 #define HB_H_IN
     72 #include "hb-ot.h"
     73 #define HB_OT_H_IN
     74 #include "hb-aat.h"
     75 #define HB_AAT_H_IN
     76 
     77 #include "hb-aat.h"
     78 
     79 #include <math.h>
     80 #include <stdlib.h>
     81 #include <stddef.h>
     82 #include <string.h>
     83 #include <assert.h>
     84 #include <errno.h>
     85 #include <stdio.h>
     86 #include <stdarg.h>
     87 
     88 #if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__)
     89 #include <intrin.h>
     90 #endif
     91 
     92 #define HB_PASTE1(a,b) a##b
     93 #define HB_PASTE(a,b) HB_PASTE1(a,b)
     94 
     95 
     96 /* Compile-time custom allocator support. */
     97 
     98 #if defined(hb_malloc_impl) \
     99  && defined(hb_calloc_impl) \
    100  && defined(hb_realloc_impl) \
    101  && defined(hb_free_impl)
    102 extern "C" void* hb_malloc_impl(size_t size);
    103 extern "C" void* hb_calloc_impl(size_t nmemb, size_t size);
    104 extern "C" void* hb_realloc_impl(void *ptr, size_t size);
    105 extern "C" void  hb_free_impl(void *ptr);
    106 #define malloc hb_malloc_impl
    107 #define calloc hb_calloc_impl
    108 #define realloc hb_realloc_impl
    109 #define free hb_free_impl
    110 
    111 #if defined(hb_memalign_impl)
    112 extern "C" int hb_memalign_impl(void **memptr, size_t alignment, size_t size);
    113 #define posix_memalign hb_memalign_impl
    114 #else
    115 #undef HAVE_POSIX_MEMALIGN
    116 #endif
    117 
    118 #endif
    119 
    120 
    121 /*
    122  * Compiler attributes
    123  */
    124 
    125 #if __cplusplus < 201103L
    126 
    127 #ifndef nullptr
    128 #define nullptr NULL
    129 #endif
    130 
    131 #ifndef constexpr
    132 #define constexpr const
    133 #endif
    134 
    135 #ifndef static_assert
    136 #define static_assert(e, msg) \
    137 	HB_UNUSED typedef int HB_PASTE(static_assertion_failed_at_line_, __LINE__) [(e) ? 1 : -1]
    138 #endif // static_assert
    139 
    140 #ifdef __GNUC__
    141 #if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8))
    142 #define thread_local __thread
    143 #endif
    144 #else
    145 #define thread_local
    146 #endif
    147 
    148 template <typename T>
    149 struct _hb_alignof
    150 {
    151   struct s
    152   {
    153     char c;
    154     T t;
    155   };
    156   static constexpr size_t value = offsetof (s, t);
    157 };
    158 #ifndef alignof
    159 #define alignof(x) (_hb_alignof<x>::value)
    160 #endif
    161 
    162 /* https://github.com/harfbuzz/harfbuzz/issues/1127 */
    163 #ifndef explicit_operator
    164 #define explicit_operator operator
    165 #endif
    166 
    167 #else /* __cplusplus >= 201103L */
    168 
    169 /* https://github.com/harfbuzz/harfbuzz/issues/1127 */
    170 #ifndef explicit_operator
    171 #define explicit_operator explicit operator
    172 #endif
    173 
    174 #endif /* __cplusplus < 201103L */
    175 
    176 
    177 #if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE__)
    178 #define likely(expr) (__builtin_expect (!!(expr), 1))
    179 #define unlikely(expr) (__builtin_expect (!!(expr), 0))
    180 #else
    181 #define likely(expr) (expr)
    182 #define unlikely(expr) (expr)
    183 #endif
    184 
    185 #if !defined(__GNUC__) && !defined(__clang__)
    186 #undef __attribute__
    187 #define __attribute__(x)
    188 #endif
    189 
    190 #if __GNUC__ >= 3
    191 #define HB_PURE_FUNC	__attribute__((pure))
    192 #define HB_CONST_FUNC	__attribute__((const))
    193 #define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx)))
    194 #else
    195 #define HB_PURE_FUNC
    196 #define HB_CONST_FUNC
    197 #define HB_PRINTF_FUNC(format_idx, arg_idx)
    198 #endif
    199 #if __GNUC__ >= 4
    200 #define HB_UNUSED	__attribute__((unused))
    201 #elif defined(_MSC_VER) /* https://github.com/harfbuzz/harfbuzz/issues/635 */
    202 #define HB_UNUSED __pragma(warning(suppress: 4100 4101))
    203 #else
    204 #define HB_UNUSED
    205 #endif
    206 
    207 #ifndef HB_INTERNAL
    208 # if !defined(HB_NO_VISIBILITY) && !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(_MSC_VER) && !defined(__SUNPRO_CC)
    209 #  define HB_INTERNAL __attribute__((__visibility__("hidden")))
    210 # elif defined(__MINGW32__)
    211    /* We use -export-symbols on mingw32, since it does not support visibility attributes. */
    212 #  define HB_INTERNAL
    213 # elif defined (_MSC_VER) && defined (HB_DLL_EXPORT)
    214    /* We do not try to export internal symbols on Visual Studio */
    215 #  define HB_INTERNAL
    216 #else
    217 #  define HB_INTERNAL
    218 #  define HB_NO_VISIBILITY 1
    219 # endif
    220 #endif
    221 
    222 #if __GNUC__ >= 3
    223 #define HB_FUNC __PRETTY_FUNCTION__
    224 #elif defined(_MSC_VER)
    225 #define HB_FUNC __FUNCSIG__
    226 #else
    227 #define HB_FUNC __func__
    228 #endif
    229 
    230 #if defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5140)
    231 /* https://github.com/harfbuzz/harfbuzz/issues/630 */
    232 #define __restrict
    233 #endif
    234 
    235 /*
    236  * Borrowed from https://bugzilla.mozilla.org/show_bug.cgi?id=1215411
    237  * HB_FALLTHROUGH is an annotation to suppress compiler warnings about switch
    238  * cases that fall through without a break or return statement. HB_FALLTHROUGH
    239  * is only needed on cases that have code:
    240  *
    241  * switch (foo) {
    242  *   case 1: // These cases have no code. No fallthrough annotations are needed.
    243  *   case 2:
    244  *   case 3:
    245  *     foo = 4; // This case has code, so a fallthrough annotation is needed:
    246  *     HB_FALLTHROUGH;
    247  *   default:
    248  *     return foo;
    249  * }
    250  */
    251 #if defined(__clang__) && __cplusplus >= 201103L
    252    /* clang's fallthrough annotations are only available starting in C++11. */
    253 #  define HB_FALLTHROUGH [[clang::fallthrough]]
    254 #elif __GNUC__ >= 7
    255    /* GNU fallthrough attribute is available from GCC7 */
    256 #  define HB_FALLTHROUGH __attribute__((fallthrough))
    257 #elif defined(_MSC_VER)
    258    /*
    259     * MSVC's __fallthrough annotations are checked by /analyze (Code Analysis):
    260     * https://msdn.microsoft.com/en-us/library/ms235402%28VS.80%29.aspx
    261     */
    262 #  include <sal.h>
    263 #  define HB_FALLTHROUGH __fallthrough
    264 #else
    265 #  define HB_FALLTHROUGH /* FALLTHROUGH */
    266 #endif
    267 
    268 #if defined(__clang__)
    269 /* Disable certain sanitizer errors. */
    270 /* https://github.com/harfbuzz/harfbuzz/issues/1247 */
    271 #define HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW __attribute__((no_sanitize("signed-integer-overflow")))
    272 #else
    273 #define HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW
    274 #endif
    275 
    276 
    277 #ifdef _WIN32
    278    /* We need Windows Vista for both Uniscribe backend and for
    279     * MemoryBarrier.  We don't support compiling on Windows XP,
    280     * though we run on it fine. */
    281 #  if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600
    282 #    undef _WIN32_WINNT
    283 #  endif
    284 #  ifndef _WIN32_WINNT
    285 #    if !defined(WINAPI_FAMILY) || !(WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
    286 #      define _WIN32_WINNT 0x0600
    287 #    endif
    288 #  endif
    289 #  ifndef WIN32_LEAN_AND_MEAN
    290 #    define WIN32_LEAN_AND_MEAN 1
    291 #  endif
    292 #  ifndef STRICT
    293 #    define STRICT 1
    294 #  endif
    295 
    296 #  if defined(_WIN32_WCE)
    297      /* Some things not defined on Windows CE. */
    298 #    define vsnprintf _vsnprintf
    299 #    define getenv(Name) nullptr
    300 #    if _WIN32_WCE < 0x800
    301 #      define setlocale(Category, Locale) "C"
    302 static int errno = 0; /* Use something better? */
    303 #    endif
    304 #  elif defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
    305 #    define getenv(Name) nullptr
    306 #  endif
    307 #  if defined(_MSC_VER) && _MSC_VER < 1900
    308 #    define snprintf _snprintf
    309 #  endif
    310 #endif
    311 
    312 #if defined(HAVE_ATEXIT) && !defined(HB_USE_ATEXIT)
    313 /* atexit() is only safe to be called from shared libraries on certain
    314  * platforms.  Whitelist.
    315  * https://bugs.freedesktop.org/show_bug.cgi?id=82246 */
    316 #  if defined(__linux) && defined(__GLIBC_PREREQ)
    317 #    if __GLIBC_PREREQ(2,3)
    318 /* From atexit() manpage, it's safe with glibc 2.2.3 on Linux. */
    319 #      define HB_USE_ATEXIT 1
    320 #    endif
    321 #  elif defined(_MSC_VER) || defined(__MINGW32__)
    322 /* For MSVC:
    323  * https://msdn.microsoft.com/en-us/library/tze57ck3.aspx
    324  * https://msdn.microsoft.com/en-us/library/zk17ww08.aspx
    325  * mingw32 headers say atexit is safe to use in shared libraries.
    326  */
    327 #    define HB_USE_ATEXIT 1
    328 #  elif defined(__ANDROID__)
    329 /* This is available since Android NKD r8 or r8b:
    330  * https://issuetracker.google.com/code/p/android/issues/detail?id=6455
    331  */
    332 #    define HB_USE_ATEXIT 1
    333 #  elif defined(__APPLE__)
    334 /* For macOS and related platforms, the atexit man page indicates
    335  * that it will be invoked when the library is unloaded, not only
    336  * at application exit.
    337  */
    338 #    define HB_USE_ATEXIT 1
    339 #  endif
    340 #endif
    341 #ifdef HB_NO_ATEXIT
    342 #  undef HB_USE_ATEXIT
    343 #endif
    344 #ifndef HB_USE_ATEXIT
    345 #  define HB_USE_ATEXIT 0
    346 #endif
    347 
    348 #define HB_STMT_START do
    349 #define HB_STMT_END   while (0)
    350 
    351 /* Static-assert as expression. */
    352 template <unsigned int cond> class hb_assert_constant_t;
    353 template <> class hb_assert_constant_t<1> {};
    354 #define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * (unsigned int) sizeof (hb_assert_constant_t<_cond>))
    355 
    356 /* Lets assert int types.  Saves trouble down the road. */
    357 static_assert ((sizeof (int8_t) == 1), "");
    358 static_assert ((sizeof (uint8_t) == 1), "");
    359 static_assert ((sizeof (int16_t) == 2), "");
    360 static_assert ((sizeof (uint16_t) == 2), "");
    361 static_assert ((sizeof (int32_t) == 4), "");
    362 static_assert ((sizeof (uint32_t) == 4), "");
    363 static_assert ((sizeof (int64_t) == 8), "");
    364 static_assert ((sizeof (uint64_t) == 8), "");
    365 static_assert ((sizeof (hb_codepoint_t) == 4), "");
    366 static_assert ((sizeof (hb_position_t) == 4), "");
    367 static_assert ((sizeof (hb_mask_t) == 4), "");
    368 static_assert ((sizeof (hb_var_int_t) == 4), "");
    369 
    370 
    371 #if __cplusplus >= 201103L
    372 
    373 /* We only enable these with C++11 or later, since earlier language
    374  * does not allow structs with constructors in unions, and we need
    375  * those. */
    376 
    377 #define HB_NO_COPY_ASSIGN(TypeName) \
    378   TypeName(const TypeName&); \
    379   void operator=(const TypeName&)
    380 #define HB_NO_COPY_ASSIGN_TEMPLATE2(TypeName, T1, T2) \
    381   TypeName(const TypeName<T1, T2>&); \
    382   void operator=(const TypeName<T1, T2>&)
    383 #define HB_NO_CREATE_COPY_ASSIGN(TypeName) \
    384   TypeName(); \
    385   TypeName(const TypeName&); \
    386   void operator=(const TypeName&)
    387 #define HB_NO_CREATE_COPY_ASSIGN_TEMPLATE(TypeName, T) \
    388   TypeName(); \
    389   TypeName(const TypeName<T>&); \
    390   void operator=(const TypeName<T>&)
    391 #define HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2(TypeName, T1, T2) \
    392   TypeName(); \
    393   TypeName(const TypeName<T1, T2>&); \
    394   void operator=(const TypeName<T1, T2>&)
    395 
    396 #else /* __cpluspplus >= 201103L */
    397 
    398 #define HB_NO_COPY_ASSIGN(TypeName) static_assert (true, "")
    399 #define HB_NO_COPY_ASSIGN_TEMPLATE2(TypeName, T1, T2) static_assert (true, "")
    400 #define HB_NO_CREATE_COPY_ASSIGN(TypeName) static_assert (true, "")
    401 #define HB_NO_CREATE_COPY_ASSIGN_TEMPLATE(TypeName, T) static_assert (true, "")
    402 #define HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2(TypeName, T1, T2) static_assert (true, "")
    403 
    404 #endif /* __cpluspplus >= 201103L */
    405 
    406 
    407 /*
    408  * Compiler-assisted vectorization parameters.
    409  */
    410 
    411 /*
    412  * Disable vectorization for now.  To correctly use them, we should
    413  * use posix_memalign() to allocate in hb_vector_t.  Otherwise, can
    414  * cause misaligned access.
    415  *
    416  * https://bugs.chromium.org/p/chromium/issues/detail?id=860184
    417  */
    418 #if !defined(HB_VECTOR_SIZE)
    419 #  define HB_VECTOR_SIZE 0
    420 #endif
    421 
    422 /* The `vector_size' attribute was introduced in gcc 3.1. */
    423 #if !defined(HB_VECTOR_SIZE)
    424 #  if defined( __GNUC__ ) && ( __GNUC__ >= 4 )
    425 #    define HB_VECTOR_SIZE 128
    426 #  else
    427 #    define HB_VECTOR_SIZE 0
    428 #  endif
    429 #endif
    430 static_assert (0 == (HB_VECTOR_SIZE & (HB_VECTOR_SIZE - 1)), "HB_VECTOR_SIZE is not power of 2.");
    431 static_assert (0 == (HB_VECTOR_SIZE % 64), "HB_VECTOR_SIZE is not multiple of 64.");
    432 #if HB_VECTOR_SIZE
    433 typedef uint64_t hb_vector_size_impl_t __attribute__((vector_size (HB_VECTOR_SIZE / 8)));
    434 #else
    435 typedef uint64_t hb_vector_size_impl_t;
    436 #endif
    437 
    438 
    439 /* HB_NDEBUG disables some sanity checks that are very safe to disable and
    440  * should be disabled in production systems.  If NDEBUG is defined, enable
    441  * HB_NDEBUG; but if it's desirable that normal assert()s (which are very
    442  * light-weight) to be enabled, then HB_DEBUG can be defined to disable
    443  * the costlier checks. */
    444 #ifdef NDEBUG
    445 #define HB_NDEBUG 1
    446 #endif
    447 
    448 
    449 /* Flags */
    450 
    451 /* Enable bitwise ops on enums marked as flags_t */
    452 /* To my surprise, looks like the function resolver is happy to silently cast
    453  * one enum to another...  So this doesn't provide the type-checking that I
    454  * originally had in mind... :(.
    455  *
    456  * For MSVC warnings, see: https://github.com/harfbuzz/harfbuzz/pull/163
    457  */
    458 #ifdef _MSC_VER
    459 # pragma warning(disable:4200)
    460 # pragma warning(disable:4800)
    461 #endif
    462 #define HB_MARK_AS_FLAG_T(T) \
    463 	extern "C++" { \
    464 	  static inline T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \
    465 	  static inline T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \
    466 	  static inline T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \
    467 	  static inline T operator ~ (T r) { return T (~(unsigned int) r); } \
    468 	  static inline T& operator |= (T &l, T r) { l = l | r; return l; } \
    469 	  static inline T& operator &= (T& l, T r) { l = l & r; return l; } \
    470 	  static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \
    471 	}
    472 
    473 /* Useful for set-operations on small enums.
    474  * For example, for testing "x  {x1, x2, x3}" use:
    475  * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3)))
    476  */
    477 #define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned)(x) < 32) + (((uint32_t) 1U) << (unsigned)(x)))
    478 #define FLAG_UNSAFE(x) ((unsigned)(x) < 32 ? (((uint32_t) 1U) << (unsigned)(x)) : 0)
    479 #define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x))
    480 #define FLAG64(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned)(x) < 64) + (((uint64_t) 1ULL) << (unsigned)(x)))
    481 #define FLAG64_UNSAFE(x) ((unsigned)(x) < 64 ? (((uint64_t) 1ULL) << (unsigned)(x)) : 0)
    482 
    483 
    484 /* Size signifying variable-sized array */
    485 #define VAR 1
    486 
    487 
    488 /* fallback for round() */
    489 static inline double
    490 _hb_round (double x)
    491 {
    492   if (x >= 0)
    493     return floor (x + 0.5);
    494   else
    495     return ceil (x - 0.5);
    496 }
    497 #if !defined (HAVE_ROUND) && !defined (HAVE_DECL_ROUND)
    498 #define round(x) _hb_round(x)
    499 #endif
    500 
    501 
    502 /* fallback for posix_memalign() */
    503 static inline int
    504 _hb_memalign(void **memptr, size_t alignment, size_t size)
    505 {
    506   if (unlikely (0 != (alignment & (alignment - 1)) ||
    507 		!alignment ||
    508 		0 != (alignment & (sizeof (void *) - 1))))
    509     return EINVAL;
    510 
    511   char *p = (char *) malloc (size + alignment - 1);
    512   if (unlikely (!p))
    513     return ENOMEM;
    514 
    515   size_t off = (size_t) p & (alignment - 1);
    516   if (off)
    517     p += alignment - off;
    518 
    519   *memptr = (void *) p;
    520 
    521   return 0;
    522 }
    523 #if !defined(posix_memalign) && !defined(HAVE_POSIX_MEMALIGN)
    524 #define posix_memalign _hb_memalign
    525 #endif
    526 
    527 
    528 /*
    529  * For lack of a better place, put Zawgyi script hack here.
    530  * https://github.com/harfbuzz/harfbuzz/issues/1162
    531  */
    532 
    533 #define HB_SCRIPT_MYANMAR_ZAWGYI	((hb_script_t) HB_TAG ('Q','a','a','g'))
    534 
    535 
    536 /* Some really basic things everyone wants. */
    537 template <typename T> struct hb_remove_const { typedef T value; };
    538 template <typename T> struct hb_remove_const<const T> { typedef T value; };
    539 #define hb_remove_const(T) hb_remove_const<T>::value
    540 template <typename T> struct hb_remove_reference { typedef T value; };
    541 template <typename T> struct hb_remove_reference<T &> { typedef T value; };
    542 #define hb_remove_reference(T) hb_remove_reference<T>::value
    543 template <typename T> struct hb_remove_pointer { typedef T value; };
    544 template <typename T> struct hb_remove_pointer<T *> { typedef T value; };
    545 #define hb_remove_pointer(T) hb_remove_pointer<T>::value
    546 
    547 
    548 /* Headers we include for everyone.  Keep sorted.  They express dependency amongst
    549  * themselves, but no other file should include them.*/
    550 #include "hb-atomic.hh"
    551 #include "hb-debug.hh"
    552 #include "hb-dsalgs.hh"
    553 #include "hb-mutex.hh"
    554 #include "hb-null.hh"
    555 #include "hb-object.hh"
    556 
    557 #endif /* HB_HH */
    558