hb-private.hh revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2007,2008,2009 Red Hat, Inc. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2011,2012 Google, Inc. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is part of HarfBuzz, a text shaping library. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission is hereby granted, without written agreement and without 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * license or royalty fees, to use, copy, modify, and distribute this 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * software and its documentation for any purpose, provided that the 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * above copyright notice and the following two paragraphs appear in 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * all copies of this software. 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DAMAGE. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Red Hat Author(s): Behdad Esfahbod 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Google Author(s): Behdad Esfahbod 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HB_PRIVATE_HH 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_PRIVATE_HH 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_CONFIG_H 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "config.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_H_IN 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_OT 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-ot.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_OT_H_IN 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stddef.h> 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h> 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* We only use these two for debug output. However, the debug code is 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * always seen by the compiler (and optimized out in non-debug builds. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If including these becomes a problem, we can start thinking about 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * someway around that. */ 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdarg.h> 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Essentials */ 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NULL 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define NULL ((void *) 0) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* Void! */ 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct _hb_void_t {}; 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef const _hb_void_t &hb_void_t; 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define HB_VOID (* (const _hb_void_t *) NULL) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Basics */ 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef MIN 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Type> 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef MAX 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Type> 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef ARRAY_LENGTH 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Type, unsigned int n> 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* A const version, but does not detect erratically being called on pointers. */ 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0]))) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_STMT_START do 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_STMT_END while (0) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1] 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _ASSERT_STATIC0(_line, _cond) _ASSERT_STATIC1 (_line, (_cond)) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_STATIC(_cond) _ASSERT_STATIC0 (__LINE__, (_cond)) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_STATIC_EXPR(_cond)((void) sizeof (char[(_cond) ? 1 : -1])) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * sizeof (char[(_cond) ? 1 : -1])) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _PASTE1(a,b) a##b 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PASTE(a,b) _PASTE1(a,b) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Lets assert int types. Saves trouble down the road. */ 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (int8_t) == 1); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (uint8_t) == 1); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (int16_t) == 2); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (uint16_t) == 2); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (int32_t) == 4); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (uint32_t) == 4); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (int64_t) == 8); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (uint64_t) == 8); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (hb_codepoint_t) == 4); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (hb_position_t) == 4); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (hb_mask_t) == 4); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ASSERT_STATIC (sizeof (hb_var_int_t) == 4); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* We like our types POD */ 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _ASSERT_TYPE_POD1(_line, _type) union _type_##_type##_on_line_##_line##_is_not_POD { _type instance; } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _ASSERT_TYPE_POD0(_line, _type) _ASSERT_TYPE_POD1 (_line, _type) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_TYPE_POD(_type) _ASSERT_TYPE_POD0 (__LINE__, _type) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __GNUC__ 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define _ASSERT_INSTANCE_POD1(_line, _instance) \ 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HB_STMT_START { \ 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef __typeof__(_instance) _type_##_line; \ 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _ASSERT_TYPE_POD1 (_line, _type_##_line); \ 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } HB_STMT_END 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define _ASSERT_INSTANCE_POD1(_line, _instance) typedef int _assertion_on_line_##_line##_not_tested 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define _ASSERT_INSTANCE_POD0(_line, _instance) _ASSERT_INSTANCE_POD1 (_line, _instance) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define ASSERT_INSTANCE_POD(_instance) _ASSERT_INSTANCE_POD0 (__LINE__, _instance) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Check _assertion in a method environment */ 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _ASSERT_POD1(_line) \ 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void _static_assertion_on_line_##_line (void) const \ 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { _ASSERT_INSTANCE_POD1 (_line, *this); /* Make sure it's POD. */ } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define _ASSERT_POD0(_line) _ASSERT_POD1 (_line) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define ASSERT_POD() _ASSERT_POD0 (__LINE__) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Misc */ 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _HB_BOOLEAN_EXPR(expr) ((expr) ? 1 : 0) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define likely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 1)) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define unlikely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 0)) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define likely(expr) (expr) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define unlikely(expr) (expr) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef __GNUC__ 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef __attribute__ 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define __attribute__(x) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if __GNUC__ >= 3 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_PURE_FUNC __attribute__((pure)) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_CONST_FUNC __attribute__((const)) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx))) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_PURE_FUNC 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_CONST_FUNC 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_PRINTF_FUNC(format_idx, arg_idx) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if __GNUC__ >= 4 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_UNUSED __attribute__((unused)) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_UNUSED 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HB_INTERNAL 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# ifndef __MINGW32__ 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define HB_INTERNAL __attribute__((__visibility__("hidden"))) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# else 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define HB_INTERNAL 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# endif 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if (defined(__WIN32__) && !defined(__WINE__)) || defined(_MSC_VER) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define snprintf _snprintf 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _MSC_VER 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef inline 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define inline __inline 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __STRICT_ANSI__ 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef inline 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define inline __inline__ 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if __GNUC__ >= 3 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_FUNC __PRETTY_FUNCTION__ 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(_MSC_VER) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_FUNC __FUNCSIG__ 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_FUNC __func__ 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Return the number of 1 bits in mask. */ 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline HB_CONST_FUNC unsigned int 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_popcount32 (uint32_t mask) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return __builtin_popcount (mask); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* "HACKMEM 169" */ 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register uint32_t y; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y = (mask >> 1) &033333333333; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) y = mask - y - ((y >>1) & 033333333333); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (((y + (y >> 3)) & 030707070707) % 077); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Returns the number of bits needed to store number */ 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline HB_CONST_FUNC unsigned int 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_bit_storage (unsigned int number) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return likely (number) ? (sizeof (unsigned int) * 8 - __builtin_clz (number)) : 0; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned int n_bits = 0; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (number) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n_bits++; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) number >>= 1; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return n_bits; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Returns the number of zero bits in the least significant side of number */ 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline HB_CONST_FUNC unsigned int 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_ctz (unsigned int number) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return likely (number) ? __builtin_ctz (number) : 0; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register unsigned int n_bits = 0; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!number)) return 0; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!(number & 1)) { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n_bits++; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) number >>= 1; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return n_bits; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_unsigned_int_mul_overflows (unsigned int count, unsigned int size) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (size > 0) && (count >= ((unsigned int) -1) / size); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Type of bsearch() / qsort() compare function */ 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int (*hb_compare_func_t) (const void *, const void *); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* arrays and maps */ 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_PREALLOCED_ARRAY_INIT {0} 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Type, unsigned int StaticSize> 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_prealloced_array_t 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int len; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int allocated; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type *array; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type static_array[StaticSize]; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void init (void) { memset (this, 0, sizeof (*this)); } 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline Type& operator [] (unsigned int i) { return array[i]; } 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Type& operator [] (unsigned int i) const { return array[i]; } 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline Type *push (void) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!array) { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array = static_array; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allocated = ARRAY_LENGTH (static_array); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (len < allocated)) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &array[len++]; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Need to reallocate */ 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int new_allocated = allocated + (allocated >> 1) + 8; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type *new_array = NULL; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (array == static_array) { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_array = (Type *) calloc (new_allocated, sizeof (Type)); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (new_array) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy (new_array, array, len * sizeof (Type)); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool overflows = (new_allocated < allocated) || _hb_unsigned_int_mul_overflows (new_allocated, sizeof (Type)); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (!overflows)) { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_array = (Type *) realloc (array, new_allocated * sizeof (Type)); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!new_array)) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array = new_array; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allocated = new_allocated; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &array[len++]; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void pop (void) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len--; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO: shrink array if needed */ 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void shrink (unsigned int l) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (l < len) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = l; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO: shrink array if needed */ 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename T> 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline Type *find (T v) { 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < len; i++) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (array[i] == v) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &array[i]; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename T> 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Type *find (T v) const { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < len; i++) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (array[i] == v) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &array[i]; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void sort (void) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) qsort (array, len, sizeof (Type), (hb_compare_func_t) Type::cmp); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void sort (unsigned int start, unsigned int end) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) qsort (array + start, end - start, sizeof (Type), (hb_compare_func_t) Type::cmp); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename T> 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline Type *bsearch (T *key) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename T> 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Type *bsearch (T *key) const 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (const Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void finish (void) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (array != static_array) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free (array); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array = NULL; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allocated = len = 0; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_LOCKABLE_SET_INIT {HB_PREALLOCED_ARRAY_INIT} 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename item_t, typename lock_t> 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_lockable_set_t 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_prealloced_array_t <item_t, 2> items; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void init (void) { items.init (); } 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename T> 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline item_t *replace_or_insert (T v, lock_t &l, bool replace) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.lock (); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_t *item = items.find (v); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (item) { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (replace) { 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_t old = *item; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *item = v; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.unlock (); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old.finish (); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item = NULL; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.unlock (); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item = items.push (); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (item)) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *item = v; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.unlock (); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return item; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename T> 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void remove (T v, lock_t &l) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.lock (); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_t *item = items.find (v); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (item) { 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_t old = *item; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *item = items[items.len - 1]; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) items.pop (); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.unlock (); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old.finish (); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.unlock (); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename T> 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool find (T v, item_t *i, lock_t &l) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.lock (); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_t *item = items.find (v); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (item) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *i = *item; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.unlock (); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !!item; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename T> 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline item_t *find_or_insert (T v, lock_t &l) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.lock (); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_t *item = items.find (v); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!item) { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item = items.push (); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (item)) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *item = v; 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.unlock (); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return item; 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void finish (lock_t &l) 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!items.len) { 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* No need for locking. */ 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) items.finish (); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.lock (); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (items.len) { 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_t old = items[items.len - 1]; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) items.pop (); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.unlock (); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old.finish (); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.lock (); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) items.finish (); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l.unlock (); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Big-endian handling */ 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline uint16_t hb_be_uint16 (const uint16_t v) 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8_t *V = (const uint8_t *) &v; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (V[0] << 8) | V[1]; 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline uint16_t hb_uint16_swap (const uint16_t v) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (v >> 8) | (v << 8); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline uint32_t hb_uint32_swap (const uint32_t v) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Note, of the following macros, uint16_get is the one called many many times. 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If there is any optimizations to be done, it's in that macro. However, I 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * already confirmed that on my T400 ThinkPad at least, using bswap_16(), which 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * results in a single ror instruction, does NOT speed this up. In fact, it 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * resulted in a minor slowdown. At any rate, note that v may not be correctly 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * aligned, so I think the current implementation is optimal. 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_be_uint16_put(v,V) HB_STMT_START { v[0] = (V>>8); v[1] = (V); } HB_STMT_END 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_be_uint16_get(v) (uint16_t) ((v[0] << 8) + v[1]) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_be_uint16_eq(a,b) (a[0] == b[0] && a[1] == b[1]) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_be_uint32_put(v,V) HB_STMT_START { v[0] = (V>>24); v[1] = (V>>16); v[2] = (V>>8); v[3] = (V); } HB_STMT_END 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_be_uint32_get(v) (uint32_t) ((v[0] << 24) + (v[1] << 16) + (v[2] << 8) + v[3]) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define hb_be_uint32_eq(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3]) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define hb_be_uint24_put(v,V) HB_STMT_START { v[0] = (V>>16); v[1] = (V>>8); v[2] (V); } HB_STMT_END 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define hb_be_uint24_get(v) (uint32_t) ((v[0] << 16) + (v[1] << 8) + v[2]) 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define hb_be_uint24_eq(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2]) 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ASCII tag/character handling */ 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline unsigned char ISALPHA (unsigned char c) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline unsigned char ISALNUM (unsigned char c) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); } 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline unsigned char TOUPPER (unsigned char c) 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; } 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline unsigned char TOLOWER (unsigned char c) 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; } 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_TAG_CHAR4(s) (HB_TAG(((const char *) s)[0], \ 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((const char *) s)[1], \ 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((const char *) s)[2], \ 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((const char *) s)[3])) 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* C++ helpers */ 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Makes class uncopyable. Use in private: section. */ 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NO_COPY(T) \ 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T (const T &o); \ 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T &operator = (const T &o) 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Debug */ 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HB_DEBUG 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_DEBUG 0 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_debug (unsigned int level, 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int max_level) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return level < max_level; 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEBUG_LEVEL(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT)) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEBUG(WHAT) (DEBUG_LEVEL (WHAT, 0)) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <int max_level> static inline void 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_debug_msg_va (const char *what, 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *obj, 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *func, 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool indented, 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int level, 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int level_dir, 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *message, 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_list ap) 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!_hb_debug (level, max_level)) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf (stderr, "%-10s", what ? what : ""); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (obj) 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf (stderr, "(%0*lx) ", (unsigned int) (2 * sizeof (void *)), (unsigned long) obj); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf (stderr, " %*s ", (unsigned int) (2 * sizeof (void *)), ""); 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (indented) { 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* One may want to add ASCII version of these. See: 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * https://bugs.freedesktop.org/show_bug.cgi?id=50970 */ 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VBAR "\342\224\202" /* U+2502 BOX DRAWINGS LIGHT VERTICAL */ 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VRBAR "\342\224\234" /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DLBAR "\342\225\256" /* U+256E BOX DRAWINGS LIGHT ARC DOWN AND LEFT */ 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ULBAR "\342\225\257" /* U+256F BOX DRAWINGS LIGHT ARC UP AND LEFT */ 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LBAR "\342\225\264" /* U+2574 BOX DRAWINGS LIGHT LEFT */ 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char bars[] = VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf (stderr, "%2d %s" VRBAR "%s", 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level, 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bars + sizeof (bars) - 1 - MIN ((unsigned int) sizeof (bars), (unsigned int) (sizeof (VBAR) - 1) * level), 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level_dir ? (level_dir > 0 ? DLBAR : ULBAR) : LBAR); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf (stderr, " " VRBAR LBAR); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (func) 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* Skip "typename" */ 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (0 == strncmp (func, "typename ", 9)) 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) func += 9; 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Skip return type */ 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *space = strchr (func, ' '); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (space) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) func = space + 1; 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Skip parameter list */ 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *paren = strchr (func, '('); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int func_len = paren ? paren - func : strlen (func); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf (stderr, "%.*s: ", func_len, func); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfprintf (stderr, message, ap); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf (stderr, "\n"); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> inline void 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_debug_msg_va<0> (const char *what HB_UNUSED, 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *obj HB_UNUSED, 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *func HB_UNUSED, 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool indented HB_UNUSED, 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int level HB_UNUSED, 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int level_dir HB_UNUSED, 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *message HB_UNUSED, 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_list ap HB_UNUSED) {} 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <int max_level> static inline void 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_debug_msg (const char *what, 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *obj, 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *func, 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool indented, 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int level, 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int level_dir, 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *message, 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ...) HB_PRINTF_FUNC(7, 8); 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <int max_level> static inline void 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_debug_msg (const char *what, 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *obj, 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *func, 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool indented, 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int level, 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int level_dir, 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *message, 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ...) 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_list ap; 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_start (ap, message); 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _hb_debug_msg_va<max_level> (what, obj, func, indented, level, level_dir, message, ap); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_end (ap); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> inline void 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_debug_msg<0> (const char *what HB_UNUSED, 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *obj HB_UNUSED, 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *func HB_UNUSED, 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool indented HB_UNUSED, 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int level HB_UNUSED, 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int level_dir HB_UNUSED, 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *message HB_UNUSED, 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ...) HB_PRINTF_FUNC(7, 8); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <> inline void 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_hb_debug_msg<0> (const char *what HB_UNUSED, 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *obj HB_UNUSED, 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *func HB_UNUSED, 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool indented HB_UNUSED, 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int level HB_UNUSED, 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int level_dir HB_UNUSED, 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *message HB_UNUSED, 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ...) {} 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEBUG_MSG_LEVEL(WHAT, OBJ, LEVEL, LEVEL_DIR, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), NULL, true, (LEVEL), (LEVEL_DIR), __VA_ARGS__) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEBUG_MSG(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), NULL, false, 0, 0, __VA_ARGS__) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEBUG_MSG_FUNC(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), HB_FUNC, false, 0, 0, __VA_ARGS__) 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Printer 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename T> 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct hb_printer_t {}; 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <> 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct hb_printer_t<bool> { 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char *print (bool v) { return v ? "true" : "false"; } 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <> 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct hb_printer_t<hb_void_t> { 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char *print (hb_void_t) { return ""; } 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Trace 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename T> 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static inline void _hb_warn_no_return (bool returned) 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (unlikely (!returned)) { 6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fprintf (stderr, "OUCH, returned with no call to TRACE_RETURN. This is a bug, please report.\n"); 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <> 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED) 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){} 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <int max_level, typename ret_t> 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_auto_trace_t { 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit inline hb_auto_trace_t (unsigned int *plevel_, 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *what_, 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *obj_, 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *func, 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *message, 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ...) : plevel (plevel_), what (what_), obj (obj_), returned (false) 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (plevel) ++*plevel; 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_list ap; 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_start (ap, message); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _hb_debug_msg_va<max_level> (what, obj, func, true, plevel ? *plevel : 0, +1, message, ap); 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) va_end (ap); 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline ~hb_auto_trace_t (void) 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _hb_warn_no_return<ret_t> (returned); 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!returned) { 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1, " "); 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (plevel) --*plevel; 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline ret_t ret (ret_t v, unsigned int line = 0) 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (returned)) { 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf (stderr, "OUCH, double calls to TRACE_RETURN. This is a bug, please report.\n"); 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return v; 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1, 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "return %s (line %d)", 7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_printer_t<ret_t>().print (v), line); 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (plevel) --*plevel; 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plevel = NULL; 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) returned = true; 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return v; 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int *plevel; 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *what; 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *obj; 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool returned; 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename ret_t> /* Optimize when tracing is disabled */ 7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct hb_auto_trace_t<0, ret_t> { 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit inline hb_auto_trace_t (unsigned int *plevel_ HB_UNUSED, 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *what HB_UNUSED, 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *obj HB_UNUSED, 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *func HB_UNUSED, 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *message HB_UNUSED, 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ...) {} 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; } 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TRACE_RETURN(RET) trace.ret (RET, __LINE__) 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Misc */ 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Pre-mature optimization: 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Checks for lo <= u <= hi but with an optimization if lo and hi 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * are only different in a contiguous set of lower-most bits. 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> static inline bool 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_in_range (T u, T lo, T hi) 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( ((lo^hi) & lo) == 0 && 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((lo^hi) & hi) == (lo^hi) && 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((lo^hi) & ((lo^hi) + 1)) == 0 ) 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (u & ~(lo^hi)) == lo; 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return lo <= u && u <= hi; 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> static inline bool 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3) 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3); 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Useful for set-operations on small enums. 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * For example, for testing "x ∈ {x1, x2, x3}" use: 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (FLAG(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FLAG(x) (1<<(x)) 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x)) 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T, typename T2> inline void 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_bubble_sort (T *array, unsigned int len, int(*compar)(const T *, const T *), T2 *array2) 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!len)) 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int k = len - 1; 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int new_k = 0; 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int j = 0; j < k; j++) 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (compar (&array[j], &array[j+1]) > 0) 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T t; 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = array[j]; 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array[j] = array[j + 1]; 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array[j + 1] = t; 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (array2) 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T2 t; 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = array2[j]; 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array2[j] = array2[j + 1]; 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array2[j + 1] = t; 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_k = j; 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) k = new_k; 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (k); 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> inline void 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_bubble_sort (T *array, unsigned int len, int(*compar)(const T *, const T *)) 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_bubble_sort (array, len, compar, (int *) NULL); 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline hb_bool_t 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out) 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Pain because we don't know whether s is nul-terminated. */ 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buf[64]; 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strncpy (buf, s, MIN (ARRAY_LENGTH (buf) - 1, len)); 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf[MIN (ARRAY_LENGTH (buf) - 1, len)] = '\0'; 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *end; 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errno = 0; 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long v = strtoul (buf, &end, base); 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (errno) return false; 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*end) return false; 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out = v; 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* HB_PRIVATE_HH */ 858