164aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod/* 22409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 2007,2008,2009 Red Hat, Inc. 30ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod * Copyright © 2011,2012 Google, Inc. 464aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * 5c755cb3e3ac55156d0d2ec05adea7a650b97cc41Behdad Esfahbod * This is part of HarfBuzz, a text shaping library. 664aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * 764aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * Permission is hereby granted, without written agreement and without 864aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 964aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * software and its documentation for any purpose, provided that the 1064aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * above copyright notice and the following two paragraphs appear in 1164aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * all copies of this software. 1264aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * 1364aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 1464aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 1564aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 1664aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 1764aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * DAMAGE. 1864aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * 1964aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 2064aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 2164aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 2264aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 2364aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 2464aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * 2564aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod * Red Hat Author(s): Behdad Esfahbod 262409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Google Author(s): Behdad Esfahbod 2764aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod */ 2864aef3a54999496fd1de4f5aa5b019e4c03b3836Behdad Esfahbod 29c57d454accff66e5f2c58006e8fb40bc020b6182Behdad Esfahbod#ifndef HB_PRIVATE_HH 30c57d454accff66e5f2c58006e8fb40bc020b6182Behdad Esfahbod#define HB_PRIVATE_HH 315b3f7702a64fe0513d08a67bdb72704e46fd7cd4Behdad Esfahbod 325ddd9cc499f2470eca239ae357a5c8a3626c0809Behdad Esfahbod#ifdef HAVE_CONFIG_H 33df66028781a7609a515980e64396e6f1044d764aBehdad Esfahbod#include "config.h" 34df66028781a7609a515980e64396e6f1044d764aBehdad Esfahbod#endif 35c7d457aa3ae7138630f52ca7263f663a3ea284c0Behdad Esfahbod 36d1c9eb458c843215da8df84b596bfae51fee135bBehdad Esfahbod#include "hb.h" 37d1c9eb458c843215da8df84b596bfae51fee135bBehdad Esfahbod#define HB_H_IN 383e32cd9570fd8b09901fb790b80365ae425f681aBehdad Esfahbod#ifdef HAVE_OT 393e32cd9570fd8b09901fb790b80365ae425f681aBehdad Esfahbod#include "hb-ot.h" 40d1c9eb458c843215da8df84b596bfae51fee135bBehdad Esfahbod#define HB_OT_H_IN 413e32cd9570fd8b09901fb790b80365ae425f681aBehdad Esfahbod#endif 42b28815c1f6e46d38471cacbc31248ca6fda8c4d1Behdad Esfahbod 43c7d457aa3ae7138630f52ca7263f663a3ea284c0Behdad Esfahbod#include <stdlib.h> 44b65c06025d2b54a44f716e030d4b10072c65bea8Behdad Esfahbod#include <stddef.h> 45f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod#include <string.h> 46f0954d1e08ae288eda9904e17108fc73f48c0b98Behdad Esfahbod#include <assert.h> 477acb389569cf99c6bae9db31a8ed7c7007fbb566Behdad Esfahbod#include <errno.h> 4840ec3bbb55b8af1668bb3d5f6232a85b15cff136Behdad Esfahbod#include <stdio.h> 49cc06c243d8be3ebb1190281653d2dba504c16c0fBehdad Esfahbod#include <stdarg.h> 50c7d457aa3ae7138630f52ca7263f663a3ea284c0Behdad Esfahbod 51acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 522a749680441bbe6b4aa8134bb6ce9f21a8b1bc3cBehdad Esfahbod#define HB_PASTE1(a,b) a##b 532a749680441bbe6b4aa8134bb6ce9f21a8b1bc3cBehdad Esfahbod#define HB_PASTE(a,b) HB_PASTE1(a,b) 542a749680441bbe6b4aa8134bb6ce9f21a8b1bc3cBehdad Esfahbod 5552b418555b62a3b25399f202c1fa72ab7288c224Behdad Esfahbod/* Compile-time custom allocator support. */ 5652b418555b62a3b25399f202c1fa72ab7288c224Behdad Esfahbod 5752b418555b62a3b25399f202c1fa72ab7288c224Behdad Esfahbod#if defined(hb_malloc_impl) \ 5852b418555b62a3b25399f202c1fa72ab7288c224Behdad Esfahbod && defined(hb_calloc_impl) \ 5952b418555b62a3b25399f202c1fa72ab7288c224Behdad Esfahbod && defined(hb_realloc_impl) \ 6052b418555b62a3b25399f202c1fa72ab7288c224Behdad Esfahbod && defined(hb_free_impl) 61cc6ea308d4c99b9dd6d625fa3a9b0ef62fa2614fBehdad Esfahbodextern "C" void* hb_malloc_impl(size_t size); 62cc6ea308d4c99b9dd6d625fa3a9b0ef62fa2614fBehdad Esfahbodextern "C" void* hb_calloc_impl(size_t nmemb, size_t size); 63cc6ea308d4c99b9dd6d625fa3a9b0ef62fa2614fBehdad Esfahbodextern "C" void* hb_realloc_impl(void *ptr, size_t size); 64cc6ea308d4c99b9dd6d625fa3a9b0ef62fa2614fBehdad Esfahbodextern "C" void hb_free_impl(void *ptr); 6552b418555b62a3b25399f202c1fa72ab7288c224Behdad Esfahbod#define malloc hb_malloc_impl 6652b418555b62a3b25399f202c1fa72ab7288c224Behdad Esfahbod#define calloc hb_calloc_impl 6752b418555b62a3b25399f202c1fa72ab7288c224Behdad Esfahbod#define realloc hb_realloc_impl 6852b418555b62a3b25399f202c1fa72ab7288c224Behdad Esfahbod#define free hb_free_impl 6952b418555b62a3b25399f202c1fa72ab7288c224Behdad Esfahbod#endif 7052b418555b62a3b25399f202c1fa72ab7288c224Behdad Esfahbod 7152b418555b62a3b25399f202c1fa72ab7288c224Behdad Esfahbod 72ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod/* Compiler attributes */ 73bc200457430c083914a64bf4b056153506749610Behdad Esfahbod 74bc200457430c083914a64bf4b056153506749610Behdad Esfahbod 7576dcbf8b23475b25f8f1918f982bfd8f0dd3456eBehdad Esfahbod#if __cplusplus < 201103L 7676dcbf8b23475b25f8f1918f982bfd8f0dd3456eBehdad Esfahbod 7762e312ead808cec055049592b0d40aa3a8882bc9Behdad Esfahbod#ifndef nullptr 7862e312ead808cec055049592b0d40aa3a8882bc9Behdad Esfahbod#define nullptr NULL 7962e312ead808cec055049592b0d40aa3a8882bc9Behdad Esfahbod#endif 8076dcbf8b23475b25f8f1918f982bfd8f0dd3456eBehdad Esfahbod 8176dcbf8b23475b25f8f1918f982bfd8f0dd3456eBehdad Esfahbod// Static assertions 8276dcbf8b23475b25f8f1918f982bfd8f0dd3456eBehdad Esfahbod#ifndef static_assert 8376dcbf8b23475b25f8f1918f982bfd8f0dd3456eBehdad Esfahbod#define static_assert(e, msg) \ 846f08b12bc38166dee2f9740d396d617b32e887a3Behdad Esfahbod HB_UNUSED typedef int HB_PASTE(static_assertion_failed_at_line_, __LINE__) [(e) ? 1 : -1] 8576dcbf8b23475b25f8f1918f982bfd8f0dd3456eBehdad Esfahbod#endif // static_assert 8676dcbf8b23475b25f8f1918f982bfd8f0dd3456eBehdad Esfahbod 8776dcbf8b23475b25f8f1918f982bfd8f0dd3456eBehdad Esfahbod#endif // __cplusplus < 201103L 8876dcbf8b23475b25f8f1918f982bfd8f0dd3456eBehdad Esfahbod 89c290ba5b7d4e9e4a5f02340a22e6c9c46564906bBehdad Esfahbod#define _GNU_SOURCE 1 9076dcbf8b23475b25f8f1918f982bfd8f0dd3456eBehdad Esfahbod 9176c4873e8cad2871d2d547318d371b9a89d8c806Ebrahim Byagowi#if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE__) 9276c4873e8cad2871d2d547318d371b9a89d8c806Ebrahim Byagowi#define likely(expr) (__builtin_expect (!!(expr), 1)) 9376c4873e8cad2871d2d547318d371b9a89d8c806Ebrahim Byagowi#define unlikely(expr) (__builtin_expect (!!(expr), 0)) 94ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#else 95ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#define likely(expr) (expr) 96ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#define unlikely(expr) (expr) 97bc200457430c083914a64bf4b056153506749610Behdad Esfahbod#endif 98bc200457430c083914a64bf4b056153506749610Behdad Esfahbod 990b8f3ab0220ca4731516313828515f26bb480645Steve Lhomme#if !defined(__GNUC__) && !defined(__clang__) 100ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#undef __attribute__ 101ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#define __attribute__(x) 102ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#endif 103ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod 104ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#if __GNUC__ >= 3 105ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#define HB_PURE_FUNC __attribute__((pure)) 106ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#define HB_CONST_FUNC __attribute__((const)) 107ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx))) 108ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#else 109ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#define HB_PURE_FUNC 110ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#define HB_CONST_FUNC 111ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#define HB_PRINTF_FUNC(format_idx, arg_idx) 112ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#endif 113ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#if __GNUC__ >= 4 114ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#define HB_UNUSED __attribute__((unused)) 115be59f3cbf4e3269ea05d5a707cdae04a32e097ceBehdad Esfahbod#elif defined(_MSC_VER) /* https://github.com/harfbuzz/harfbuzz/issues/635 */ 116be59f3cbf4e3269ea05d5a707cdae04a32e097ceBehdad Esfahbod#define HB_UNUSED __pragma(warning(suppress: 4100 4101)) 117ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#else 118ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#define HB_UNUSED 119ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#endif 120ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod 121ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#ifndef HB_INTERNAL 122f1a8d50a87edfb8147aa1bec732ed7ccbfef2877Behdad Esfahbod# if !defined(__MINGW32__) && !defined(__CYGWIN__) 123ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod# define HB_INTERNAL __attribute__((__visibility__("hidden"))) 124ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod# else 125ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod# define HB_INTERNAL 126ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod# endif 127ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#endif 128ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod 129ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#if __GNUC__ >= 3 130ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#define HB_FUNC __PRETTY_FUNCTION__ 131ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#elif defined(_MSC_VER) 132ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#define HB_FUNC __FUNCSIG__ 133ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#else 134ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#define HB_FUNC __func__ 135ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod#endif 136a794ebf4be9896393f4badf02905a4007981a588Behdad Esfahbod 137305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod/* 138305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod * Borrowed from https://bugzilla.mozilla.org/show_bug.cgi?id=1215411 139305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod * HB_FALLTHROUGH is an annotation to suppress compiler warnings about switch 140305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod * cases that fall through without a break or return statement. HB_FALLTHROUGH 141305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod * is only needed on cases that have code: 142305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod * 143305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod * switch (foo) { 144305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod * case 1: // These cases have no code. No fallthrough annotations are needed. 145305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod * case 2: 146305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod * case 3: 147305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod * foo = 4; // This case has code, so a fallthrough annotation is needed: 148305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod * HB_FALLTHROUGH; 149305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod * default: 150305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod * return foo; 151305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod * } 152305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod */ 153305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod#if defined(__clang__) && __cplusplus >= 201103L 154305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod /* clang's fallthrough annotations are only available starting in C++11. */ 155305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod# define HB_FALLTHROUGH [[clang::fallthrough]] 156305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod#elif defined(_MSC_VER) 157305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod /* 158305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod * MSVC's __fallthrough annotations are checked by /analyze (Code Analysis): 159305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod * https://msdn.microsoft.com/en-us/library/ms235402%28VS.80%29.aspx 160305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod */ 161305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod# include <sal.h> 162305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod# define HB_FALLTHROUGH __fallthrough 163305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod#else 164305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod# define HB_FALLTHROUGH /* FALLTHROUGH */ 165305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod#endif 166305d2fbf5a2db51447c8ed894a48a88896930673Behdad Esfahbod 1670fc0a1022854324261fea8893678a3e9fd9443ebBehdad Esfahbod#if defined(_WIN32) || defined(__CYGWIN__) 168db308280488c2ee11ba865a9922eb6a0c1abeef3Behdad Esfahbod /* We need Windows Vista for both Uniscribe backend and for 169db308280488c2ee11ba865a9922eb6a0c1abeef3Behdad Esfahbod * MemoryBarrier. We don't support compiling on Windows XP, 170db308280488c2ee11ba865a9922eb6a0c1abeef3Behdad Esfahbod * though we run on it fine. */ 171db308280488c2ee11ba865a9922eb6a0c1abeef3Behdad Esfahbod# if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600 172db308280488c2ee11ba865a9922eb6a0c1abeef3Behdad Esfahbod# undef _WIN32_WINNT 173db308280488c2ee11ba865a9922eb6a0c1abeef3Behdad Esfahbod# endif 174db308280488c2ee11ba865a9922eb6a0c1abeef3Behdad Esfahbod# ifndef _WIN32_WINNT 175db308280488c2ee11ba865a9922eb6a0c1abeef3Behdad Esfahbod# define _WIN32_WINNT 0x0600 176db308280488c2ee11ba865a9922eb6a0c1abeef3Behdad Esfahbod# endif 177270971a0fccdf4964fd3e8ab8e5cf53037a3518dBehdad Esfahbod# ifndef WIN32_LEAN_AND_MEAN 178270971a0fccdf4964fd3e8ab8e5cf53037a3518dBehdad Esfahbod# define WIN32_LEAN_AND_MEAN 1 179270971a0fccdf4964fd3e8ab8e5cf53037a3518dBehdad Esfahbod# endif 180270971a0fccdf4964fd3e8ab8e5cf53037a3518dBehdad Esfahbod# ifndef STRICT 181270971a0fccdf4964fd3e8ab8e5cf53037a3518dBehdad Esfahbod# define STRICT 1 182270971a0fccdf4964fd3e8ab8e5cf53037a3518dBehdad Esfahbod# endif 183dabe698fcbeb02911128b17aa8e3b2d864795960Behdad Esfahbod 184f3537b620b0a7392ea27f01f465c5ba79459c858Konstantin Ritt# if defined(_WIN32_WCE) 185f3537b620b0a7392ea27f01f465c5ba79459c858Konstantin Ritt /* Some things not defined on Windows CE. */ 1865069062d0a9342bb716eebf3ddc1efad91924caaKonstantin Ritt# define vsnprintf _vsnprintf 187dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod# define getenv(Name) nullptr 188855a5d7cb8f585bf66dd18cb480b8c3feef62480Konstantin Ritt# if _WIN32_WCE < 0x800 189855a5d7cb8f585bf66dd18cb480b8c3feef62480Konstantin Ritt# define setlocale(Category, Locale) "C" 19026a963b9cb4af3119177f277a2d48a5d537458fbBehdad Esfahbodstatic int errno = 0; /* Use something better? */ 191855a5d7cb8f585bf66dd18cb480b8c3feef62480Konstantin Ritt# endif 192f3537b620b0a7392ea27f01f465c5ba79459c858Konstantin Ritt# elif defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) 193dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod# define getenv(Name) nullptr 194f3537b620b0a7392ea27f01f465c5ba79459c858Konstantin Ritt# endif 195ce01ad7c2f5a259030f4dbec746f85522aa9c3f9Behdad Esfahbod# if defined(_MSC_VER) && _MSC_VER < 1900 196f3537b620b0a7392ea27f01f465c5ba79459c858Konstantin Ritt# define snprintf _snprintf 197f3537b620b0a7392ea27f01f465c5ba79459c858Konstantin Ritt# endif 19826a963b9cb4af3119177f277a2d48a5d537458fbBehdad Esfahbod#endif 19926a963b9cb4af3119177f277a2d48a5d537458fbBehdad Esfahbod 20038fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod#if HAVE_ATEXIT 20138fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod/* atexit() is only safe to be called from shared libraries on certain 20238fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod * platforms. Whitelist. 20338fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod * https://bugs.freedesktop.org/show_bug.cgi?id=82246 */ 20438fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod# if defined(__linux) && defined(__GLIBC_PREREQ) 20538fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod# if __GLIBC_PREREQ(2,3) 20638fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod/* From atexit() manpage, it's safe with glibc 2.2.3 on Linux. */ 20738fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod# define HB_USE_ATEXIT 1 20838fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod# endif 20938fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod# elif defined(_MSC_VER) || defined(__MINGW32__) 21038fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod/* For MSVC: 21138fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod * http://msdn.microsoft.com/en-ca/library/tze57ck3.aspx 21238fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod * http://msdn.microsoft.com/en-ca/library/zk17ww08.aspx 21338fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod * mingw32 headers say atexit is safe to use in shared libraries. 21438fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod */ 21538fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod# define HB_USE_ATEXIT 1 21638fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod# elif defined(__ANDROID__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) 21738fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod/* This was fixed in Android NKD r8 or r8b: 21838fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod * https://code.google.com/p/android/issues/detail?id=6455 21938fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod * which introduced GCC 4.6: 22038fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod * https://developer.android.com/tools/sdk/ndk/index.html 22138fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod */ 22238fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod# define HB_USE_ATEXIT 1 22338fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod# endif 22438fb30d7420a4b01f99cee31baa8c3990a1d1c5fBehdad Esfahbod#endif 225dabe698fcbeb02911128b17aa8e3b2d864795960Behdad Esfahbod 226c7d457aa3ae7138630f52ca7263f663a3ea284c0Behdad Esfahbod/* Basics */ 227c7d457aa3ae7138630f52ca7263f663a3ea284c0Behdad Esfahbod 228c7d457aa3ae7138630f52ca7263f663a3ea284c0Behdad Esfahbod#undef MIN 22925326c2359b0a3e25222b94acd142bc36eff78a4Behdad Esfahbodtemplate <typename Type> 23025326c2359b0a3e25222b94acd142bc36eff78a4Behdad Esfahbodstatic inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; } 2317586089c6fa8185cad8387869d3703c637e5cbb1Behdad Esfahbod 2328a3511ac6c795226699c2b36e03401ecdf88f5f8Behdad Esfahbod#undef MAX 23325326c2359b0a3e25222b94acd142bc36eff78a4Behdad Esfahbodtemplate <typename Type> 23425326c2359b0a3e25222b94acd142bc36eff78a4Behdad Esfahbodstatic inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; } 235153142dac8dd9abaf164bb88af07c600c17fc3a1Behdad Esfahbod 23616f175cb2e081e605fe7f9cd01bbe8c24380278aBehdad Esfahbodstatic inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b) 23716f175cb2e081e605fe7f9cd01bbe8c24380278aBehdad Esfahbod{ return (a + (b - 1)) / b; } 23816f175cb2e081e605fe7f9cd01bbe8c24380278aBehdad Esfahbod 2398a3511ac6c795226699c2b36e03401ecdf88f5f8Behdad Esfahbod 2404591753ad4b5ec0224e3f1befdfe4fc5f6075562Behdad Esfahbod#undef ARRAY_LENGTH 24125326c2359b0a3e25222b94acd142bc36eff78a4Behdad Esfahbodtemplate <typename Type, unsigned int n> 2420beb66e3a61ae8bb1fa66e54b1ff1abb2f8711e9Behdad Esfahbodstatic inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; } 243fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod/* A const version, but does not detect erratically being called on pointers. */ 244fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod#define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0]))) 24512360f7c159826ae72271b34486dee59d96aa8caBehdad Esfahbod 24635a7383c6138fd705560f0d4bb30659cbd1ab64cBehdad Esfahbod#define HB_STMT_START do 24735a7383c6138fd705560f0d4bb30659cbd1ab64cBehdad Esfahbod#define HB_STMT_END while (0) 2485b3f7702a64fe0513d08a67bdb72704e46fd7cd4Behdad Esfahbod 24976dcbf8b23475b25f8f1918f982bfd8f0dd3456eBehdad Esfahbodtemplate <unsigned int cond> class hb_assert_constant_t; 25076dcbf8b23475b25f8f1918f982bfd8f0dd3456eBehdad Esfahbodtemplate <> class hb_assert_constant_t<1> {}; 251672ca3b4e65a75fb3a418ec5d117ad242a98acbbBehdad Esfahbod 252672ca3b4e65a75fb3a418ec5d117ad242a98acbbBehdad Esfahbod#define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * (unsigned int) sizeof (hb_assert_constant_t<_cond>)) 253dcb7026f33cbcdf60e9b7fcdd44c64cc08702c74Behdad Esfahbod 2546fd5364bdc3a2b459175377e9e16c86cff054232Behdad Esfahbod/* Lets assert int types. Saves trouble down the road. */ 2556fd5364bdc3a2b459175377e9e16c86cff054232Behdad Esfahbod 256c3448e8d21963eb7fc357a37a7a426a4bf130ef3Behdad Esfahbodstatic_assert ((sizeof (int8_t) == 1), ""); 257c3448e8d21963eb7fc357a37a7a426a4bf130ef3Behdad Esfahbodstatic_assert ((sizeof (uint8_t) == 1), ""); 258c3448e8d21963eb7fc357a37a7a426a4bf130ef3Behdad Esfahbodstatic_assert ((sizeof (int16_t) == 2), ""); 259c3448e8d21963eb7fc357a37a7a426a4bf130ef3Behdad Esfahbodstatic_assert ((sizeof (uint16_t) == 2), ""); 260c3448e8d21963eb7fc357a37a7a426a4bf130ef3Behdad Esfahbodstatic_assert ((sizeof (int32_t) == 4), ""); 261c3448e8d21963eb7fc357a37a7a426a4bf130ef3Behdad Esfahbodstatic_assert ((sizeof (uint32_t) == 4), ""); 262c3448e8d21963eb7fc357a37a7a426a4bf130ef3Behdad Esfahbodstatic_assert ((sizeof (int64_t) == 8), ""); 263c3448e8d21963eb7fc357a37a7a426a4bf130ef3Behdad Esfahbodstatic_assert ((sizeof (uint64_t) == 8), ""); 2646fd5364bdc3a2b459175377e9e16c86cff054232Behdad Esfahbod 265c3448e8d21963eb7fc357a37a7a426a4bf130ef3Behdad Esfahbodstatic_assert ((sizeof (hb_codepoint_t) == 4), ""); 266c3448e8d21963eb7fc357a37a7a426a4bf130ef3Behdad Esfahbodstatic_assert ((sizeof (hb_position_t) == 4), ""); 267c3448e8d21963eb7fc357a37a7a426a4bf130ef3Behdad Esfahbodstatic_assert ((sizeof (hb_mask_t) == 4), ""); 268c3448e8d21963eb7fc357a37a7a426a4bf130ef3Behdad Esfahbodstatic_assert ((sizeof (hb_var_int_t) == 4), ""); 2696fd5364bdc3a2b459175377e9e16c86cff054232Behdad Esfahbod 270a00a63b5ef503fafa87e26b517732b2214e01719Behdad Esfahbod 271a00a63b5ef503fafa87e26b517732b2214e01719Behdad Esfahbod/* We like our types POD */ 272a00a63b5ef503fafa87e26b517732b2214e01719Behdad Esfahbod 27373cb02de2dd28b09d4aa76230132248215cfe83dBehdad Esfahbod#define _ASSERT_TYPE_POD1(_line, _type) union _type_##_type##_on_line_##_line##_is_not_POD { _type instance; } 27473cb02de2dd28b09d4aa76230132248215cfe83dBehdad Esfahbod#define _ASSERT_TYPE_POD0(_line, _type) _ASSERT_TYPE_POD1 (_line, _type) 27573cb02de2dd28b09d4aa76230132248215cfe83dBehdad Esfahbod#define ASSERT_TYPE_POD(_type) _ASSERT_TYPE_POD0 (__LINE__, _type) 276a00a63b5ef503fafa87e26b517732b2214e01719Behdad Esfahbod 277a00a63b5ef503fafa87e26b517732b2214e01719Behdad Esfahbod#ifdef __GNUC__ 27879e2b4791fe95ede9a1e6b1c71ccc6e36c4fc0e5Behdad Esfahbod# define _ASSERT_INSTANCE_POD1(_line, _instance) \ 27979e2b4791fe95ede9a1e6b1c71ccc6e36c4fc0e5Behdad Esfahbod HB_STMT_START { \ 28079e2b4791fe95ede9a1e6b1c71ccc6e36c4fc0e5Behdad Esfahbod typedef __typeof__(_instance) _type_##_line; \ 28179e2b4791fe95ede9a1e6b1c71ccc6e36c4fc0e5Behdad Esfahbod _ASSERT_TYPE_POD1 (_line, _type_##_line); \ 28279e2b4791fe95ede9a1e6b1c71ccc6e36c4fc0e5Behdad Esfahbod } HB_STMT_END 283a00a63b5ef503fafa87e26b517732b2214e01719Behdad Esfahbod#else 28473cb02de2dd28b09d4aa76230132248215cfe83dBehdad Esfahbod# define _ASSERT_INSTANCE_POD1(_line, _instance) typedef int _assertion_on_line_##_line##_not_tested 285a00a63b5ef503fafa87e26b517732b2214e01719Behdad Esfahbod#endif 28673cb02de2dd28b09d4aa76230132248215cfe83dBehdad Esfahbod# define _ASSERT_INSTANCE_POD0(_line, _instance) _ASSERT_INSTANCE_POD1 (_line, _instance) 28773cb02de2dd28b09d4aa76230132248215cfe83dBehdad Esfahbod# define ASSERT_INSTANCE_POD(_instance) _ASSERT_INSTANCE_POD0 (__LINE__, _instance) 288a00a63b5ef503fafa87e26b517732b2214e01719Behdad Esfahbod 289a00a63b5ef503fafa87e26b517732b2214e01719Behdad Esfahbod/* Check _assertion in a method environment */ 290a00a63b5ef503fafa87e26b517732b2214e01719Behdad Esfahbod#define _ASSERT_POD1(_line) \ 291dac86026a6bae5a8a03cfe885bf93f32e5f48614Behdad Esfahbod HB_UNUSED inline void _static_assertion_on_line_##_line (void) const \ 29273cb02de2dd28b09d4aa76230132248215cfe83dBehdad Esfahbod { _ASSERT_INSTANCE_POD1 (_line, *this); /* Make sure it's POD. */ } 29373cb02de2dd28b09d4aa76230132248215cfe83dBehdad Esfahbod# define _ASSERT_POD0(_line) _ASSERT_POD1 (_line) 29473cb02de2dd28b09d4aa76230132248215cfe83dBehdad Esfahbod# define ASSERT_POD() _ASSERT_POD0 (__LINE__) 295a00a63b5ef503fafa87e26b517732b2214e01719Behdad Esfahbod 296a00a63b5ef503fafa87e26b517732b2214e01719Behdad Esfahbod 297a00a63b5ef503fafa87e26b517732b2214e01719Behdad Esfahbod 298bc200457430c083914a64bf4b056153506749610Behdad Esfahbod/* Misc */ 299bc200457430c083914a64bf4b056153506749610Behdad Esfahbod 300ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbod/* Void! */ 301ae2b854eab7f1c48e56751c987a714c2c18d6eb6Behdad Esfahbodstruct _hb_void_t {}; 302a5e4f6d6088f6ed37fb1d68d3682b8eb4c9b46feBehdad Esfahbodtypedef const _hb_void_t *hb_void_t; 303dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod#define HB_VOID ((const _hb_void_t *) nullptr) 3047d3a126334f8e6f6441561c1bb592bd3fa7a2c5cBehdad Esfahbod 3059b6023338530a2dbb8214eb4391ef3e8372f3892Behdad Esfahbod/* Return the number of 1 bits in mask. */ 30697e7f8f305c47caf2968a9da3b8407825547286dBehdad Esfahbodstatic inline HB_CONST_FUNC unsigned int 307c7d457aa3ae7138630f52ca7263f663a3ea284c0Behdad Esfahbod_hb_popcount32 (uint32_t mask) 308c7d457aa3ae7138630f52ca7263f663a3ea284c0Behdad Esfahbod{ 309c7d457aa3ae7138630f52ca7263f663a3ea284c0Behdad Esfahbod#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) 3109b6023338530a2dbb8214eb4391ef3e8372f3892Behdad Esfahbod return __builtin_popcount (mask); 311c7d457aa3ae7138630f52ca7263f663a3ea284c0Behdad Esfahbod#else 3129b6023338530a2dbb8214eb4391ef3e8372f3892Behdad Esfahbod /* "HACKMEM 169" */ 313a949cd329e49d2c0ad6f1e023f324790d886dafeBehdad Esfahbod uint32_t y; 3149b6023338530a2dbb8214eb4391ef3e8372f3892Behdad Esfahbod y = (mask >> 1) &033333333333; 3159b6023338530a2dbb8214eb4391ef3e8372f3892Behdad Esfahbod y = mask - y - ((y >>1) & 033333333333); 3169b6023338530a2dbb8214eb4391ef3e8372f3892Behdad Esfahbod return (((y + (y >> 3)) & 030707070707) % 077); 317c7d457aa3ae7138630f52ca7263f663a3ea284c0Behdad Esfahbod#endif 318c7d457aa3ae7138630f52ca7263f663a3ea284c0Behdad Esfahbod} 3196fb4ac73f94636d19fcac143472b84f9d91985c9Behdad Esfahbodstatic inline HB_CONST_FUNC unsigned int 3206fb4ac73f94636d19fcac143472b84f9d91985c9Behdad Esfahbod_hb_popcount64 (uint64_t mask) 3216fb4ac73f94636d19fcac143472b84f9d91985c9Behdad Esfahbod{ 3226fb4ac73f94636d19fcac143472b84f9d91985c9Behdad Esfahbod#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) 323ced86da7ddbbd0d64f8ba1290b8e67600b1db2d4Behdad Esfahbod if (sizeof (long) >= sizeof (mask)) 324ced86da7ddbbd0d64f8ba1290b8e67600b1db2d4Behdad Esfahbod return __builtin_popcountl (mask); 3256fb4ac73f94636d19fcac143472b84f9d91985c9Behdad Esfahbod#endif 3262ee710e02fad1a8a4b94589bb6f0b90e2aeb7121Behdad Esfahbod return _hb_popcount32 (mask & 0xFFFFFFFF) + _hb_popcount32 (mask >> 32); 3276fb4ac73f94636d19fcac143472b84f9d91985c9Behdad Esfahbod} 3286fb4ac73f94636d19fcac143472b84f9d91985c9Behdad Esfahbodtemplate <typename T> static inline unsigned int _hb_popcount (T mask); 3296fb4ac73f94636d19fcac143472b84f9d91985c9Behdad Esfahbodtemplate <> inline unsigned int _hb_popcount<uint32_t> (uint32_t mask) { return _hb_popcount32 (mask); } 3306fb4ac73f94636d19fcac143472b84f9d91985c9Behdad Esfahbodtemplate <> inline unsigned int _hb_popcount<uint64_t> (uint64_t mask) { return _hb_popcount64 (mask); } 331c7d457aa3ae7138630f52ca7263f663a3ea284c0Behdad Esfahbod 3329b6023338530a2dbb8214eb4391ef3e8372f3892Behdad Esfahbod/* Returns the number of bits needed to store number */ 3339b6023338530a2dbb8214eb4391ef3e8372f3892Behdad Esfahbodstatic inline HB_CONST_FUNC unsigned int 3349b6023338530a2dbb8214eb4391ef3e8372f3892Behdad Esfahbod_hb_bit_storage (unsigned int number) 3359b6023338530a2dbb8214eb4391ef3e8372f3892Behdad Esfahbod{ 3369b6023338530a2dbb8214eb4391ef3e8372f3892Behdad Esfahbod#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__) 337f7acd8df5146155b51d6f50aeb04f54f3030c1c3Behdad Esfahbod return likely (number) ? (sizeof (unsigned int) * 8 - __builtin_clz (number)) : 0; 3389b6023338530a2dbb8214eb4391ef3e8372f3892Behdad Esfahbod#else 339a949cd329e49d2c0ad6f1e023f324790d886dafeBehdad Esfahbod unsigned int n_bits = 0; 3409b6023338530a2dbb8214eb4391ef3e8372f3892Behdad Esfahbod while (number) { 3419b6023338530a2dbb8214eb4391ef3e8372f3892Behdad Esfahbod n_bits++; 3429b6023338530a2dbb8214eb4391ef3e8372f3892Behdad Esfahbod number >>= 1; 3439b6023338530a2dbb8214eb4391ef3e8372f3892Behdad Esfahbod } 3449b6023338530a2dbb8214eb4391ef3e8372f3892Behdad Esfahbod return n_bits; 3459b6023338530a2dbb8214eb4391ef3e8372f3892Behdad Esfahbod#endif 3469b6023338530a2dbb8214eb4391ef3e8372f3892Behdad Esfahbod} 347df66028781a7609a515980e64396e6f1044d764aBehdad Esfahbod 348f7acd8df5146155b51d6f50aeb04f54f3030c1c3Behdad Esfahbod/* Returns the number of zero bits in the least significant side of number */ 349f7acd8df5146155b51d6f50aeb04f54f3030c1c3Behdad Esfahbodstatic inline HB_CONST_FUNC unsigned int 350f7acd8df5146155b51d6f50aeb04f54f3030c1c3Behdad Esfahbod_hb_ctz (unsigned int number) 351f7acd8df5146155b51d6f50aeb04f54f3030c1c3Behdad Esfahbod{ 352f7acd8df5146155b51d6f50aeb04f54f3030c1c3Behdad Esfahbod#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__) 353f7acd8df5146155b51d6f50aeb04f54f3030c1c3Behdad Esfahbod return likely (number) ? __builtin_ctz (number) : 0; 354f7acd8df5146155b51d6f50aeb04f54f3030c1c3Behdad Esfahbod#else 355a949cd329e49d2c0ad6f1e023f324790d886dafeBehdad Esfahbod unsigned int n_bits = 0; 356f7acd8df5146155b51d6f50aeb04f54f3030c1c3Behdad Esfahbod if (unlikely (!number)) return 0; 357f7acd8df5146155b51d6f50aeb04f54f3030c1c3Behdad Esfahbod while (!(number & 1)) { 358f7acd8df5146155b51d6f50aeb04f54f3030c1c3Behdad Esfahbod n_bits++; 359f7acd8df5146155b51d6f50aeb04f54f3030c1c3Behdad Esfahbod number >>= 1; 360f7acd8df5146155b51d6f50aeb04f54f3030c1c3Behdad Esfahbod } 361f7acd8df5146155b51d6f50aeb04f54f3030c1c3Behdad Esfahbod return n_bits; 362f7acd8df5146155b51d6f50aeb04f54f3030c1c3Behdad Esfahbod#endif 363f7acd8df5146155b51d6f50aeb04f54f3030c1c3Behdad Esfahbod} 364f7acd8df5146155b51d6f50aeb04f54f3030c1c3Behdad Esfahbod 365080a0eb7d82d7195be72c16ece6e0a3ffed636b6Behdad Esfahbodstatic inline bool 366080a0eb7d82d7195be72c16ece6e0a3ffed636b6Behdad Esfahbod_hb_unsigned_int_mul_overflows (unsigned int count, unsigned int size) 367080a0eb7d82d7195be72c16ece6e0a3ffed636b6Behdad Esfahbod{ 368080a0eb7d82d7195be72c16ece6e0a3ffed636b6Behdad Esfahbod return (size > 0) && (count >= ((unsigned int) -1) / size); 369080a0eb7d82d7195be72c16ece6e0a3ffed636b6Behdad Esfahbod} 370080a0eb7d82d7195be72c16ece6e0a3ffed636b6Behdad Esfahbod 371080a0eb7d82d7195be72c16ece6e0a3ffed636b6Behdad Esfahbod 372852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod 373852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod/* arrays and maps */ 374852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod 375852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod 376dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod#define HB_PREALLOCED_ARRAY_INIT {0, 0, nullptr} 377546b1adcdce2d3592843938b0b81ff32e67b0b83Behdad Esfahbodtemplate <typename Type, unsigned int StaticSize=16> 3780e253e97af71e2a7ead153589f61fd579a247502Behdad Esfahbodstruct hb_prealloced_array_t 3790e253e97af71e2a7ead153589f61fd579a247502Behdad Esfahbod{ 380852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod unsigned int len; 381852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod unsigned int allocated; 382852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod Type *array; 383852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod Type static_array[StaticSize]; 384852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod 38556ef4e0c52d5b474518bf0c1e4adba80f2ae6946Behdad Esfahbod void init (void) 38656ef4e0c52d5b474518bf0c1e4adba80f2ae6946Behdad Esfahbod { 38756ef4e0c52d5b474518bf0c1e4adba80f2ae6946Behdad Esfahbod len = 0; 38856ef4e0c52d5b474518bf0c1e4adba80f2ae6946Behdad Esfahbod allocated = ARRAY_LENGTH (static_array); 38956ef4e0c52d5b474518bf0c1e4adba80f2ae6946Behdad Esfahbod array = static_array; 39056ef4e0c52d5b474518bf0c1e4adba80f2ae6946Behdad Esfahbod } 391efde8113258b117ec0a7fbffe6d681442d045c41Behdad Esfahbod 392265ac614ea6d26041c7d64739098b76a82bbc4f4Behdad Esfahbod inline Type& operator [] (unsigned int i) { return array[i]; } 393265ac614ea6d26041c7d64739098b76a82bbc4f4Behdad Esfahbod inline const Type& operator [] (unsigned int i) const { return array[i]; } 394852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod 395852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod inline Type *push (void) 396852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod { 397deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod if (unlikely (!resize (len + 1))) 398deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod return nullptr; 399deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod 400deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod return &array[len - 1]; 401deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod } 402deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod 403deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod inline bool resize (unsigned int size) 404deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod { 40556ef4e0c52d5b474518bf0c1e4adba80f2ae6946Behdad Esfahbod if (unlikely (size > allocated)) 406deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod { 407deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod /* Need to reallocate */ 408deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod 409deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod unsigned int new_allocated = allocated; 410deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod while (size >= new_allocated) 411deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod new_allocated += (new_allocated >> 1) + 8; 412deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod 413deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod Type *new_array = nullptr; 414deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod 415deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod if (array == static_array) { 416deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod new_array = (Type *) calloc (new_allocated, sizeof (Type)); 417deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod if (new_array) 418deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod memcpy (new_array, array, len * sizeof (Type)); 419deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod } else { 420deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod bool overflows = (new_allocated < allocated) || _hb_unsigned_int_mul_overflows (new_allocated, sizeof (Type)); 421deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod if (likely (!overflows)) { 422deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod new_array = (Type *) realloc (array, new_allocated * sizeof (Type)); 423deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod } 424852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod } 4255a5030366e40baa8d96ca67b47a52ad5af143157Behdad Esfahbod 426deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod if (unlikely (!new_array)) 427deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod return false; 428deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod 429deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod array = new_array; 430deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod allocated = new_allocated; 431deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod } 4325a5030366e40baa8d96ca67b47a52ad5af143157Behdad Esfahbod 433deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod len = size; 434deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod return true; 435852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod } 436852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod 437852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod inline void pop (void) 438852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod { 439852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod len--; 440639afdc690c681a302080239a1967ce735ba5be5Behdad Esfahbod } 441639afdc690c681a302080239a1967ce735ba5be5Behdad Esfahbod 442639afdc690c681a302080239a1967ce735ba5be5Behdad Esfahbod inline void remove (unsigned int i) 443639afdc690c681a302080239a1967ce735ba5be5Behdad Esfahbod { 444639afdc690c681a302080239a1967ce735ba5be5Behdad Esfahbod if (unlikely (i >= len)) 445639afdc690c681a302080239a1967ce735ba5be5Behdad Esfahbod return; 446639afdc690c681a302080239a1967ce735ba5be5Behdad Esfahbod memmove (static_cast<void *> (&array[i]), 447639afdc690c681a302080239a1967ce735ba5be5Behdad Esfahbod static_cast<void *> (&array[i + 1]), 448639afdc690c681a302080239a1967ce735ba5be5Behdad Esfahbod (len - i - 1) * sizeof (Type)); 449639afdc690c681a302080239a1967ce735ba5be5Behdad Esfahbod len--; 450852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod } 45144b0a4d2fc62689fc56ef57f412b4bb1e439a614Behdad Esfahbod 45244b0a4d2fc62689fc56ef57f412b4bb1e439a614Behdad Esfahbod inline void shrink (unsigned int l) 45344b0a4d2fc62689fc56ef57f412b4bb1e439a614Behdad Esfahbod { 45444b0a4d2fc62689fc56ef57f412b4bb1e439a614Behdad Esfahbod if (l < len) 45544b0a4d2fc62689fc56ef57f412b4bb1e439a614Behdad Esfahbod len = l; 45644b0a4d2fc62689fc56ef57f412b4bb1e439a614Behdad Esfahbod } 45744b0a4d2fc62689fc56ef57f412b4bb1e439a614Behdad Esfahbod 4586843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod template <typename T> 4596843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod inline Type *find (T v) { 4606843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod for (unsigned int i = 0; i < len; i++) 4616843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod if (array[i] == v) 4626843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod return &array[i]; 463dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod return nullptr; 4646843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod } 4656843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod template <typename T> 4666843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod inline const Type *find (T v) const { 4676843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod for (unsigned int i = 0; i < len; i++) 4686843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod if (array[i] == v) 4696843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod return &array[i]; 470dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod return nullptr; 4716843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod } 4726843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod 473fb8cc86ff99c08064ac58a559bb66cc340693b92Behdad Esfahbod inline void qsort (void) 47444b0a4d2fc62689fc56ef57f412b4bb1e439a614Behdad Esfahbod { 4750712e915b4814e350aa1d833c1dee5010cdbd8f9Behdad Esfahbod ::qsort (array, len, sizeof (Type), Type::cmp); 47644b0a4d2fc62689fc56ef57f412b4bb1e439a614Behdad Esfahbod } 4776843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod 478fb8cc86ff99c08064ac58a559bb66cc340693b92Behdad Esfahbod inline void qsort (unsigned int start, unsigned int end) 479b70c96dbe41d6512b80fe3d966a1942e1ef64a4bBehdad Esfahbod { 4800712e915b4814e350aa1d833c1dee5010cdbd8f9Behdad Esfahbod ::qsort (array + start, end - start, sizeof (Type), Type::cmp); 481b70c96dbe41d6512b80fe3d966a1942e1ef64a4bBehdad Esfahbod } 482b70c96dbe41d6512b80fe3d966a1942e1ef64a4bBehdad Esfahbod 4836843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod template <typename T> 484db5f7ef18916abb0907bc8b569a65c9c6bbd4015Behdad Esfahbod inline Type *bsearch (T *x) 4856843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod { 4865e74044b6bd78c495561eb7d2981415d2c3336f4Behdad Esfahbod unsigned int i; 4875e74044b6bd78c495561eb7d2981415d2c3336f4Behdad Esfahbod return bfind (x, &i) ? &array[i] : nullptr; 4886843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod } 4896843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod template <typename T> 490db5f7ef18916abb0907bc8b569a65c9c6bbd4015Behdad Esfahbod inline const Type *bsearch (T *x) const 4916843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod { 4925e74044b6bd78c495561eb7d2981415d2c3336f4Behdad Esfahbod unsigned int i; 4935e74044b6bd78c495561eb7d2981415d2c3336f4Behdad Esfahbod return bfind (x, &i) ? &array[i] : nullptr; 4945e74044b6bd78c495561eb7d2981415d2c3336f4Behdad Esfahbod } 4955e74044b6bd78c495561eb7d2981415d2c3336f4Behdad Esfahbod template <typename T> 4965e74044b6bd78c495561eb7d2981415d2c3336f4Behdad Esfahbod inline bool bfind (T *x, unsigned int *i) const 4975e74044b6bd78c495561eb7d2981415d2c3336f4Behdad Esfahbod { 498db5f7ef18916abb0907bc8b569a65c9c6bbd4015Behdad Esfahbod int min = 0, max = (int) this->len - 1; 499db5f7ef18916abb0907bc8b569a65c9c6bbd4015Behdad Esfahbod while (min <= max) 500db5f7ef18916abb0907bc8b569a65c9c6bbd4015Behdad Esfahbod { 501db5f7ef18916abb0907bc8b569a65c9c6bbd4015Behdad Esfahbod int mid = (min + max) / 2; 502db5f7ef18916abb0907bc8b569a65c9c6bbd4015Behdad Esfahbod int c = this->array[mid].cmp (x); 503db5f7ef18916abb0907bc8b569a65c9c6bbd4015Behdad Esfahbod if (c < 0) 504db5f7ef18916abb0907bc8b569a65c9c6bbd4015Behdad Esfahbod max = mid - 1; 505db5f7ef18916abb0907bc8b569a65c9c6bbd4015Behdad Esfahbod else if (c > 0) 506db5f7ef18916abb0907bc8b569a65c9c6bbd4015Behdad Esfahbod min = mid + 1; 507db5f7ef18916abb0907bc8b569a65c9c6bbd4015Behdad Esfahbod else 5085e74044b6bd78c495561eb7d2981415d2c3336f4Behdad Esfahbod { 5095e74044b6bd78c495561eb7d2981415d2c3336f4Behdad Esfahbod *i = mid; 5105e74044b6bd78c495561eb7d2981415d2c3336f4Behdad Esfahbod return true; 5115e74044b6bd78c495561eb7d2981415d2c3336f4Behdad Esfahbod } 512db5f7ef18916abb0907bc8b569a65c9c6bbd4015Behdad Esfahbod } 513deed4a48d15d4a475f8695aa3269547adf63867aBehdad Esfahbod if (max < 0 || (max < (int) this->len && this->array[max].cmp (x) > 0)) 5145e74044b6bd78c495561eb7d2981415d2c3336f4Behdad Esfahbod max++; 5155e74044b6bd78c495561eb7d2981415d2c3336f4Behdad Esfahbod *i = max; 5165e74044b6bd78c495561eb7d2981415d2c3336f4Behdad Esfahbod return false; 5176843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod } 5186a7ac79e26e85f6781186cf708a12825c0857324Behdad Esfahbod 5196a7ac79e26e85f6781186cf708a12825c0857324Behdad Esfahbod inline void finish (void) 5206a7ac79e26e85f6781186cf708a12825c0857324Behdad Esfahbod { 5216a7ac79e26e85f6781186cf708a12825c0857324Behdad Esfahbod if (array != static_array) 5226a7ac79e26e85f6781186cf708a12825c0857324Behdad Esfahbod free (array); 523dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod array = nullptr; 5246a7ac79e26e85f6781186cf708a12825c0857324Behdad Esfahbod allocated = len = 0; 5256a7ac79e26e85f6781186cf708a12825c0857324Behdad Esfahbod } 526852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod}; 527852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod 528c5d91f39802078fc6f6de71940739ec4d04eca07Behdad Esfahbodtemplate <typename Type> 529546b1adcdce2d3592843938b0b81ff32e67b0b83Behdad Esfahbodstruct hb_auto_array_t : hb_prealloced_array_t <Type> 530c5d91f39802078fc6f6de71940739ec4d04eca07Behdad Esfahbod{ 531546b1adcdce2d3592843938b0b81ff32e67b0b83Behdad Esfahbod hb_auto_array_t (void) { hb_prealloced_array_t<Type>::init (); } 532546b1adcdce2d3592843938b0b81ff32e67b0b83Behdad Esfahbod ~hb_auto_array_t (void) { hb_prealloced_array_t<Type>::finish (); } 533c5d91f39802078fc6f6de71940739ec4d04eca07Behdad Esfahbod}; 534c5d91f39802078fc6f6de71940739ec4d04eca07Behdad Esfahbod 535a9f24c802956d57180d71b83e96a0fb81197df4aBehdad Esfahbod 5360e253e97af71e2a7ead153589f61fd579a247502Behdad Esfahbod#define HB_LOCKABLE_SET_INIT {HB_PREALLOCED_ARRAY_INIT} 53745bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbodtemplate <typename item_t, typename lock_t> 53845bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbodstruct hb_lockable_set_t 539852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod{ 54051f4d4d5cd5a0dd1a581bee5b55b3cc0a74cbea3Behdad Esfahbod hb_prealloced_array_t <item_t, 1> items; 541852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod 542bf93b636c4963cbc32d5fba7ace1053db6719192Behdad Esfahbod inline void init (void) { items.init (); } 543bf93b636c4963cbc32d5fba7ace1053db6719192Behdad Esfahbod 544478a42536ff7ab777a7774fbfdb9c5e51334a14eBehdad Esfahbod template <typename T> 54533ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod inline item_t *replace_or_insert (T v, lock_t &l, bool replace) 546852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod { 54745bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod l.lock (); 5486843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod item_t *item = items.find (v); 54945bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod if (item) { 55033ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod if (replace) { 55133ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod item_t old = *item; 55233ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod *item = v; 55333ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod l.unlock (); 55433ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod old.finish (); 55533ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod } 55633ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod else { 557dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod item = nullptr; 55833ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod l.unlock (); 55933ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod } 56045bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod } else { 561852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod item = items.push (); 56245bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod if (likely (item)) 56345bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod *item = v; 56445bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod l.unlock (); 56545bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod } 566b45f32ee4e599c515ce93e44315283d236b073bbBehdad Esfahbod return item; 567852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod } 568852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod 569811482bd650fb5652a9835471ae8ecf0fb185611Behdad Esfahbod template <typename T> 57045bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod inline void remove (T v, lock_t &l) 571852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod { 57245bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod l.lock (); 5736843569d2c70c1771ce964e3d1a4cf91e14e7687Behdad Esfahbod item_t *item = items.find (v); 57445bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod if (item) { 57545bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod item_t old = *item; 57645bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod *item = items[items.len - 1]; 57745bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod items.pop (); 57845bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod l.unlock (); 57945bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod old.finish (); 58045bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod } else { 58145bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod l.unlock (); 58245bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod } 583852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod } 584a9f24c802956d57180d71b83e96a0fb81197df4aBehdad Esfahbod 585478a42536ff7ab777a7774fbfdb9c5e51334a14eBehdad Esfahbod template <typename T> 58645bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod inline bool find (T v, item_t *i, lock_t &l) 587852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod { 58845bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod l.lock (); 58945bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod item_t *item = items.find (v); 59045bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod if (item) 59145bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod *i = *item; 59245bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod l.unlock (); 59345bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod return !!item; 594811482bd650fb5652a9835471ae8ecf0fb185611Behdad Esfahbod } 595811482bd650fb5652a9835471ae8ecf0fb185611Behdad Esfahbod 596b45f32ee4e599c515ce93e44315283d236b073bbBehdad Esfahbod template <typename T> 59745bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod inline item_t *find_or_insert (T v, lock_t &l) 59845bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod { 59945bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod l.lock (); 60045bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod item_t *item = items.find (v); 601b45f32ee4e599c515ce93e44315283d236b073bbBehdad Esfahbod if (!item) { 602b45f32ee4e599c515ce93e44315283d236b073bbBehdad Esfahbod item = items.push (); 603b45f32ee4e599c515ce93e44315283d236b073bbBehdad Esfahbod if (likely (item)) 604b45f32ee4e599c515ce93e44315283d236b073bbBehdad Esfahbod *item = v; 605b45f32ee4e599c515ce93e44315283d236b073bbBehdad Esfahbod } 60645bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod l.unlock (); 607b45f32ee4e599c515ce93e44315283d236b073bbBehdad Esfahbod return item; 608b45f32ee4e599c515ce93e44315283d236b073bbBehdad Esfahbod } 609b45f32ee4e599c515ce93e44315283d236b073bbBehdad Esfahbod 61045bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod inline void finish (lock_t &l) 61145bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod { 6123f4764bb56bb7e42ba8859f1905810bd2f998838Behdad Esfahbod if (!items.len) { 6133f4764bb56bb7e42ba8859f1905810bd2f998838Behdad Esfahbod /* No need for locking. */ 6143f4764bb56bb7e42ba8859f1905810bd2f998838Behdad Esfahbod items.finish (); 6153f4764bb56bb7e42ba8859f1905810bd2f998838Behdad Esfahbod return; 6163f4764bb56bb7e42ba8859f1905810bd2f998838Behdad Esfahbod } 61745bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod l.lock (); 61845bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod while (items.len) { 61945bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod item_t old = items[items.len - 1]; 62045bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod items.pop (); 62145bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod l.unlock (); 62245bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod old.finish (); 62345bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod l.lock (); 62445bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod } 6256a7ac79e26e85f6781186cf708a12825c0857324Behdad Esfahbod items.finish (); 62645bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod l.unlock (); 62745bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod } 62845bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod 62945bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod}; 63045bfa99034512e886d75b1d45a5a649647f4711fBehdad Esfahbod 631852e08ec8fbfbce1d50e571d0bb0b52ef4d4cc58Behdad Esfahbod 6324188096a7722f09ffa9319986c0286071da10a27Behdad Esfahbod/* ASCII tag/character handling */ 633db5227c40e5c35fe2ffb750f32b639cb44424a1dBehdad Esfahbod 63420b817ac21147e0a8edbf23ef071c2f4ce6c2b95Behdad Esfahbodstatic inline bool ISALPHA (unsigned char c) 635153142dac8dd9abaf164bb88af07c600c17fc3a1Behdad Esfahbod{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } 63620b817ac21147e0a8edbf23ef071c2f4ce6c2b95Behdad Esfahbodstatic inline bool ISALNUM (unsigned char c) 637153142dac8dd9abaf164bb88af07c600c17fc3a1Behdad Esfahbod{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); } 63820b817ac21147e0a8edbf23ef071c2f4ce6c2b95Behdad Esfahbodstatic inline bool ISSPACE (unsigned char c) 63920b817ac21147e0a8edbf23ef071c2f4ce6c2b95Behdad Esfahbod{ return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; } 640153142dac8dd9abaf164bb88af07c600c17fc3a1Behdad Esfahbodstatic inline unsigned char TOUPPER (unsigned char c) 641153142dac8dd9abaf164bb88af07c600c17fc3a1Behdad Esfahbod{ return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; } 642153142dac8dd9abaf164bb88af07c600c17fc3a1Behdad Esfahbodstatic inline unsigned char TOLOWER (unsigned char c) 643153142dac8dd9abaf164bb88af07c600c17fc3a1Behdad Esfahbod{ return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; } 644db5227c40e5c35fe2ffb750f32b639cb44424a1dBehdad Esfahbod 645db5227c40e5c35fe2ffb750f32b639cb44424a1dBehdad Esfahbod 64691dd11565221bdb108c138662ea013aac14bb968Behdad Esfahbod/* HB_NDEBUG disables some sanity checks that are very safe to disable and 64791dd11565221bdb108c138662ea013aac14bb968Behdad Esfahbod * should be disabled in production systems. If NDEBUG is defined, enable 64891dd11565221bdb108c138662ea013aac14bb968Behdad Esfahbod * HB_NDEBUG; but if it's desirable that normal assert()s (which are very 64991dd11565221bdb108c138662ea013aac14bb968Behdad Esfahbod * light-weight) to be enabled, then HB_DEBUG can be defined to disable 65091dd11565221bdb108c138662ea013aac14bb968Behdad Esfahbod * the costlier checks. */ 65191dd11565221bdb108c138662ea013aac14bb968Behdad Esfahbod#ifdef NDEBUG 65291dd11565221bdb108c138662ea013aac14bb968Behdad Esfahbod#define HB_NDEBUG 65391dd11565221bdb108c138662ea013aac14bb968Behdad Esfahbod#endif 65491dd11565221bdb108c138662ea013aac14bb968Behdad Esfahbod 655cc06c243d8be3ebb1190281653d2dba504c16c0fBehdad Esfahbod 656cc06c243d8be3ebb1190281653d2dba504c16c0fBehdad Esfahbod/* Misc */ 657cc06c243d8be3ebb1190281653d2dba504c16c0fBehdad Esfahbod 658a8b89a09f6d3a3466282aae07fd65e143f9f8f83Behdad Esfahbodtemplate <typename T> class hb_assert_unsigned_t; 659a8b89a09f6d3a3466282aae07fd65e143f9f8f83Behdad Esfahbodtemplate <> class hb_assert_unsigned_t<unsigned char> {}; 6609e7c720100e432b43564ed5ff12f3175ca2ed74aDominik Röttschestemplate <> class hb_assert_unsigned_t<unsigned short> {}; 661a8b89a09f6d3a3466282aae07fd65e143f9f8f83Behdad Esfahbodtemplate <> class hb_assert_unsigned_t<unsigned int> {}; 662a8b89a09f6d3a3466282aae07fd65e143f9f8f83Behdad Esfahbodtemplate <> class hb_assert_unsigned_t<unsigned long> {}; 663f60f2166c48d07f556ff83f04e95181946eb03dfBehdad Esfahbod 664b5aeb95afeb13a66177caada9f5d5ad4cddbd35fBehdad Esfahbodtemplate <typename T> static inline bool 6658f0b64fb6988f9502d2c5e39768a9af133d9a83fBehdad Esfahbodhb_in_range (T u, T lo, T hi) 6667b08b0a7f2057937dfc3ab2ec191656bf2386463Behdad Esfahbod{ 667385cf37cf084198e3aedb4354a7b025938a9f11bBehdad Esfahbod /* The sizeof() is here to force template instantiation. 668385cf37cf084198e3aedb4354a7b025938a9f11bBehdad Esfahbod * I'm sure there are better ways to do this but can't think of 669385cf37cf084198e3aedb4354a7b025938a9f11bBehdad Esfahbod * one right now. Declaring a variable won't work as HB_UNUSED 67068e04afbb1e1073c47474f7a4d6d2cacf7057f6fBehdad Esfahbod * is unusable on some platforms and unused types are less likely 671385cf37cf084198e3aedb4354a7b025938a9f11bBehdad Esfahbod * to generate a warning than unused variables. */ 672c3448e8d21963eb7fc357a37a7a426a4bf130ef3Behdad Esfahbod static_assert ((sizeof (hb_assert_unsigned_t<T>) >= 0), ""); 673385cf37cf084198e3aedb4354a7b025938a9f11bBehdad Esfahbod 674c2b151d95262a8dc2d2ce94e19ab0ef5b0c8f98dBehdad Esfahbod /* The casts below are important as if T is smaller than int, 675c2b151d95262a8dc2d2ce94e19ab0ef5b0c8f98dBehdad Esfahbod * the subtract results will become a signed int! */ 676c2b151d95262a8dc2d2ce94e19ab0ef5b0c8f98dBehdad Esfahbod return (T)(u - lo) <= (T)(hi - lo); 6777b08b0a7f2057937dfc3ab2ec191656bf2386463Behdad Esfahbod} 6787b08b0a7f2057937dfc3ab2ec191656bf2386463Behdad Esfahbod 6794a7f4f3e56f8f7640ae7337aa1b3324f31e0d4abBehdad Esfahbodtemplate <typename T> static inline bool 680c98b7183f7dc453d5bac1f2503017cded317a495Behdad Esfahbodhb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2) 681c98b7183f7dc453d5bac1f2503017cded317a495Behdad Esfahbod{ 682c98b7183f7dc453d5bac1f2503017cded317a495Behdad Esfahbod return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2); 683c98b7183f7dc453d5bac1f2503017cded317a495Behdad Esfahbod} 684c98b7183f7dc453d5bac1f2503017cded317a495Behdad Esfahbod 685c98b7183f7dc453d5bac1f2503017cded317a495Behdad Esfahbodtemplate <typename T> static inline bool 686093cd583263a5d427e3377b31585043fb55d2557Behdad Esfahbodhb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3) 6874a7f4f3e56f8f7640ae7337aa1b3324f31e0d4abBehdad Esfahbod{ 688093cd583263a5d427e3377b31585043fb55d2557Behdad Esfahbod return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3); 6894a7f4f3e56f8f7640ae7337aa1b3324f31e0d4abBehdad Esfahbod} 6904a7f4f3e56f8f7640ae7337aa1b3324f31e0d4abBehdad Esfahbod 6917b08b0a7f2057937dfc3ab2ec191656bf2386463Behdad Esfahbod 692aa7044de0ceacd71cab19212d266c3a66c03b41eBehdad Esfahbod/* Enable bitwise ops on enums marked as flags_t */ 6936986208ba3b395534f4c7bcfa51df6bf9038f717Behdad Esfahbod/* To my surprise, looks like the function resolver is happy to silently cast 6946986208ba3b395534f4c7bcfa51df6bf9038f717Behdad Esfahbod * one enum to another... So this doesn't provide the type-checking that I 695e0082ae60dbd87d433f3b2b9d2bfa64b9a4c3663Behdad Esfahbod * originally had in mind... :(. 696e0082ae60dbd87d433f3b2b9d2bfa64b9a4c3663Behdad Esfahbod * 6977c6937e7c7b62602fef10ac4b2e164d0c67c932bebraminio * For MSVC warnings, see: https://github.com/harfbuzz/harfbuzz/pull/163 698e0082ae60dbd87d433f3b2b9d2bfa64b9a4c3663Behdad Esfahbod */ 699e0082ae60dbd87d433f3b2b9d2bfa64b9a4c3663Behdad Esfahbod#ifdef _MSC_VER 700e0082ae60dbd87d433f3b2b9d2bfa64b9a4c3663Behdad Esfahbod# pragma warning(disable:4200) 701e0082ae60dbd87d433f3b2b9d2bfa64b9a4c3663Behdad Esfahbod# pragma warning(disable:4800) 702167c3271778cd1a8c4433b9d2230901ce17c099eChun-wei Fan#endif 7031dc32ea4d2f294f9d1ae1c8fd19fb75f9278223bBehdad Esfahbod#define HB_MARK_AS_FLAG_T(T) \ 7041dc32ea4d2f294f9d1ae1c8fd19fb75f9278223bBehdad Esfahbod extern "C++" { \ 7051dc32ea4d2f294f9d1ae1c8fd19fb75f9278223bBehdad Esfahbod static inline T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \ 7061dc32ea4d2f294f9d1ae1c8fd19fb75f9278223bBehdad Esfahbod static inline T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \ 7071dc32ea4d2f294f9d1ae1c8fd19fb75f9278223bBehdad Esfahbod static inline T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \ 7081dc32ea4d2f294f9d1ae1c8fd19fb75f9278223bBehdad Esfahbod static inline T operator ~ (T r) { return T (~(unsigned int) r); } \ 7091dc32ea4d2f294f9d1ae1c8fd19fb75f9278223bBehdad Esfahbod static inline T& operator |= (T &l, T r) { l = l | r; return l; } \ 7101dc32ea4d2f294f9d1ae1c8fd19fb75f9278223bBehdad Esfahbod static inline T& operator &= (T& l, T r) { l = l & r; return l; } \ 7111dc32ea4d2f294f9d1ae1c8fd19fb75f9278223bBehdad Esfahbod static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \ 7121dc32ea4d2f294f9d1ae1c8fd19fb75f9278223bBehdad Esfahbod } 713aa7044de0ceacd71cab19212d266c3a66c03b41eBehdad Esfahbod 714aa7044de0ceacd71cab19212d266c3a66c03b41eBehdad Esfahbod 71545d6f29f15f1d2323bcaa2498aed23ff0c8a1567Behdad Esfahbod/* Useful for set-operations on small enums. 71645d6f29f15f1d2323bcaa2498aed23ff0c8a1567Behdad Esfahbod * For example, for testing "x ∈ {x1, x2, x3}" use: 7176058f98825e8f134893a1bbfb402e45d85b56ff0Behdad Esfahbod * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) 71845d6f29f15f1d2323bcaa2498aed23ff0c8a1567Behdad Esfahbod */ 719d8adaa97fbf33071b8a4b5c05c3f2f15f2fd22eaBehdad Esfahbod#define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned int)(x) < 32) + (1U << (unsigned int)(x))) 720d8adaa97fbf33071b8a4b5c05c3f2f15f2fd22eaBehdad Esfahbod#define FLAG_UNSAFE(x) ((unsigned int)(x) < 32 ? (1U << (unsigned int)(x)) : 0) 7212c372b80f6befad69e216e3f218b38640b8cc044Behdad Esfahbod#define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x)) 7227b08b0a7f2057937dfc3ab2ec191656bf2386463Behdad Esfahbod 7238f0b64fb6988f9502d2c5e39768a9af133d9a83fBehdad Esfahbod 724c1e87442621beff98791ce56cfd1ccee506c4ee6Behdad Esfahbodtemplate <typename T, typename T2> static inline void 72585846b3de7491b6a07fed6a2c0c6c1b09943b249Behdad Esfahbodhb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *), T2 *array2) 72645d6f29f15f1d2323bcaa2498aed23ff0c8a1567Behdad Esfahbod{ 72785846b3de7491b6a07fed6a2c0c6c1b09943b249Behdad Esfahbod for (unsigned int i = 1; i < len; i++) 72885846b3de7491b6a07fed6a2c0c6c1b09943b249Behdad Esfahbod { 72985846b3de7491b6a07fed6a2c0c6c1b09943b249Behdad Esfahbod unsigned int j = i; 73085846b3de7491b6a07fed6a2c0c6c1b09943b249Behdad Esfahbod while (j && compar (&array[j - 1], &array[i]) > 0) 73185846b3de7491b6a07fed6a2c0c6c1b09943b249Behdad Esfahbod j--; 73285846b3de7491b6a07fed6a2c0c6c1b09943b249Behdad Esfahbod if (i == j) 73385846b3de7491b6a07fed6a2c0c6c1b09943b249Behdad Esfahbod continue; 73485846b3de7491b6a07fed6a2c0c6c1b09943b249Behdad Esfahbod /* Move item i to occupy place for item j, shift what's in between. */ 73585846b3de7491b6a07fed6a2c0c6c1b09943b249Behdad Esfahbod { 73693099748e39740a3f6f003c83d9dec1d21660ce8Behdad Esfahbod T t = array[i]; 73785846b3de7491b6a07fed6a2c0c6c1b09943b249Behdad Esfahbod memmove (&array[j + 1], &array[j], (i - j) * sizeof (T)); 73885846b3de7491b6a07fed6a2c0c6c1b09943b249Behdad Esfahbod array[j] = t; 73985846b3de7491b6a07fed6a2c0c6c1b09943b249Behdad Esfahbod } 74085846b3de7491b6a07fed6a2c0c6c1b09943b249Behdad Esfahbod if (array2) 74185846b3de7491b6a07fed6a2c0c6c1b09943b249Behdad Esfahbod { 74293099748e39740a3f6f003c83d9dec1d21660ce8Behdad Esfahbod T2 t = array2[i]; 74385846b3de7491b6a07fed6a2c0c6c1b09943b249Behdad Esfahbod memmove (&array2[j + 1], &array2[j], (i - j) * sizeof (T2)); 74485846b3de7491b6a07fed6a2c0c6c1b09943b249Behdad Esfahbod array2[j] = t; 74585846b3de7491b6a07fed6a2c0c6c1b09943b249Behdad Esfahbod } 74685846b3de7491b6a07fed6a2c0c6c1b09943b249Behdad Esfahbod } 74745d6f29f15f1d2323bcaa2498aed23ff0c8a1567Behdad Esfahbod} 74845d6f29f15f1d2323bcaa2498aed23ff0c8a1567Behdad Esfahbod 749250398b1e4f102e4e44eeb9e2aebf0cd2d397344Behdad Esfahbodtemplate <typename T> static inline void 75085846b3de7491b6a07fed6a2c0c6c1b09943b249Behdad Esfahbodhb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *)) 75139b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod{ 752dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod hb_stable_sort (array, len, compar, (int *) nullptr); 75339b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod} 75445d6f29f15f1d2323bcaa2498aed23ff0c8a1567Behdad Esfahbod 7556f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbodstatic inline hb_bool_t 7566f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbodhb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out) 7576f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod{ 7586f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod /* Pain because we don't know whether s is nul-terminated. */ 7596f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod char buf[64]; 760847794e929831750e97525137ab5e285ccd1064eBehdad Esfahbod len = MIN (ARRAY_LENGTH (buf) - 1, len); 761847794e929831750e97525137ab5e285ccd1064eBehdad Esfahbod strncpy (buf, s, len); 762847794e929831750e97525137ab5e285ccd1064eBehdad Esfahbod buf[len] = '\0'; 7636f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod 7646f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod char *end; 7656f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod errno = 0; 7666f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod unsigned long v = strtoul (buf, &end, base); 7676f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod if (errno) return false; 7686f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod if (*end) return false; 7696f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod *out = v; 7706f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod return true; 7716f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod} 77245d6f29f15f1d2323bcaa2498aed23ff0c8a1567Behdad Esfahbod 773acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 7747737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod/* Vectorization */ 7757737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod 7767737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbodstruct HbOpOr 7777737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod{ 7787737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod static const bool passthru_left = true; 7797737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod static const bool passthru_right = true; 7807737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod template <typename T> static void process (T &o, const T &a, const T &b) { o = a | b; } 7817737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod}; 7827737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbodstruct HbOpAnd 7837737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod{ 7847737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod static const bool passthru_left = false; 7857737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod static const bool passthru_right = false; 7867737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod template <typename T> static void process (T &o, const T &a, const T &b) { o = a & b; } 7877737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod}; 7887737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbodstruct HbOpMinus 7897737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod{ 7907737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod static const bool passthru_left = true; 7917737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod static const bool passthru_right = false; 7927737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod template <typename T> static void process (T &o, const T &a, const T &b) { o = a & ~b; } 7937737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod}; 7947737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbodstruct HbOpXor 7957737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod{ 7967737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod static const bool passthru_left = true; 7977737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod static const bool passthru_right = true; 7987737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod template <typename T> static void process (T &o, const T &a, const T &b) { o = a ^ b; } 7997737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod}; 8007737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod 8017737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod/* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))). */ 8027737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbodtemplate <typename elt_t, unsigned int byte_size> 8037737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbodstruct hb_vector_size_t 8047737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod{ 8057737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod elt_t& operator [] (unsigned int i) { return v[i]; } 8067737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod const elt_t& operator [] (unsigned int i) const { return v[i]; } 8077737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod 8087737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod template <class Op> 8097737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod inline hb_vector_size_t process (const hb_vector_size_t &o) const 8107737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod { 8117737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod hb_vector_size_t r; 8127737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) 8137737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod Op::process (r.v[i], v[i], o.v[i]); 8147737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod return r; 8157737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod } 8167737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod inline hb_vector_size_t operator | (const hb_vector_size_t &o) const 8177737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod { return process<HbOpOr> (o); } 8187737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod inline hb_vector_size_t operator & (const hb_vector_size_t &o) const 8197737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod { return process<HbOpAnd> (o); } 8207737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod inline hb_vector_size_t operator ^ (const hb_vector_size_t &o) const 8217737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod { return process<HbOpXor> (o); } 8227737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod inline hb_vector_size_t operator ~ () const 8237737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod { 8247737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod hb_vector_size_t r; 8257737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++) 8267737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod r.v[i] = ~v[i]; 8277737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod return r; 8287737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod } 8297737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod 8307737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod private: 831221ce6c18f2a1e878b68eb0a97f235efa4c044d3Behdad Esfahbod static_assert (byte_size / sizeof (elt_t) * sizeof (elt_t) == byte_size, ""); 8327737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod elt_t v[byte_size / sizeof (elt_t)]; 8337737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod}; 8347737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod 8357737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod/* The `vector_size' attribute was introduced in gcc 3.1. */ 8367737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod#if defined( __GNUC__ ) && ( __GNUC__ >= 4 ) 8377737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod#define HAVE_VECTOR_SIZE 1 8387737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod#endif 8397737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod 8407737e87ac4582d57945f3ffbbae1012f62c6b482Behdad Esfahbod 841bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbod/* Global runtime options. */ 842bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbod 843bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbodstruct hb_options_t 844bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbod{ 8455c87120b8178566ddae99d9825edc24f9b87ea3dBehdad Esfahbod unsigned int initialized : 1; 8465c87120b8178566ddae99d9825edc24f9b87ea3dBehdad Esfahbod unsigned int uniscribe_bug_compatible : 1; 847bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbod}; 848bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbod 849bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbodunion hb_options_union_t { 8505c87120b8178566ddae99d9825edc24f9b87ea3dBehdad Esfahbod unsigned int i; 851bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbod hb_options_t opts; 852bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbod}; 853c3448e8d21963eb7fc357a37a7a426a4bf130ef3Behdad Esfahbodstatic_assert ((sizeof (int) == sizeof (hb_options_union_t)), ""); 854bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbod 855bab02d339f39ed5168daaef9461227f78e596a2fBehdad EsfahbodHB_INTERNAL void 856bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbod_hb_options_init (void); 857bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbod 858bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbodextern HB_INTERNAL hb_options_union_t _hb_options; 859bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbod 860bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbodstatic inline hb_options_t 861bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbodhb_options (void) 862bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbod{ 863bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbod if (unlikely (!_hb_options.i)) 864bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbod _hb_options_init (); 865bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbod 866bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbod return _hb_options.opts; 867bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbod} 868bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbod 869a13b023dbfd0532e8cd74c356fbbd4453d0ffaa0Steven R. Loomis/* Size signifying variable-sized array */ 870a13b023dbfd0532e8cd74c356fbbd4453d0ffaa0Steven R. Loomis#define VAR 1 871bab02d339f39ed5168daaef9461227f78e596a2fBehdad Esfahbod 872e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod 873e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod/* String type. */ 874e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod 875e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbodstruct hb_string_t 876e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod{ 877e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod inline hb_string_t (void) : bytes (nullptr), len (0) {} 878e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod inline hb_string_t (const char *bytes_, unsigned int len_) : bytes (bytes_), len (len_) {} 879e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod 880e35a763c07b60da6e5fbdb6edd9d25f575cd3d8bBehdad Esfahbod inline int cmp (const hb_string_t &a) const 881e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod { 882e35a763c07b60da6e5fbdb6edd9d25f575cd3d8bBehdad Esfahbod if (len != a.len) 883e35a763c07b60da6e5fbdb6edd9d25f575cd3d8bBehdad Esfahbod return (int) a.len - (int) len; 884e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod 885e35a763c07b60da6e5fbdb6edd9d25f575cd3d8bBehdad Esfahbod return memcmp (a.bytes, bytes, len); 886e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod } 887e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod static inline int cmp (const void *pa, const void *pb) 888e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod { 889e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod hb_string_t *a = (hb_string_t *) pa; 890e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod hb_string_t *b = (hb_string_t *) pb; 891e35a763c07b60da6e5fbdb6edd9d25f575cd3d8bBehdad Esfahbod return b->cmp (*a); 892e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod } 893e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod 894e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod const char *bytes; 895e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod unsigned int len; 896e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod}; 897e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod 898e1a37f3db4f2364e98ff057209a94aa9b23e5c9dBehdad Esfahbod 899c57d454accff66e5f2c58006e8fb40bc020b6182Behdad Esfahbod#endif /* HB_PRIVATE_HH */ 900