X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fhb-private.hh;h=f7731df036dcbcd40ee8c7349fbbf1e27b5fc0bd;hb=43ff203d8ea3e1b09e316e3aae1a4e5ec15bfdd2;hp=28c33b79b18acfaa7f1e8dee31904a016765b398;hpb=811482bd650fb5652a9835471ae8ecf0fb185611;p=framework%2Fuifw%2Fharfbuzz.git diff --git a/src/hb-private.hh b/src/hb-private.hh index 28c33b7..f7731df 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -85,6 +85,7 @@ HB_BEGIN_DECLS #define ASSERT_STATIC(_cond) _ASSERT_STATIC0 (__LINE__, (_cond)) #define ASSERT_STATIC_EXPR(_cond) ((void) sizeof (char[(_cond) ? 1 : -1])) +#define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * sizeof (char[(_cond) ? 1 : -1])) /* Lets assert int types. Saves trouble down the road. */ @@ -228,17 +229,15 @@ HB_END_DECLS template -struct hb_static_array_t { +struct hb_prealloced_array_t { unsigned int len; unsigned int allocated; Type *array; Type static_array[StaticSize]; - inline Type& operator [] (unsigned int i) - { - return array[i]; - } + inline Type& operator [] (unsigned int i) { return array[i]; } + inline const Type& operator [] (unsigned int i) const { return array[i]; } inline Type *push (void) { @@ -277,62 +276,140 @@ struct hb_static_array_t { len--; /* TODO: shrink array if needed */ } -}; -template -struct hb_array_t : hb_static_array_t {}; + inline void shrink (unsigned int l) + { + if (l < len) + len = l; + /* TODO: shrink array if needed */ + } + template + inline Type *find (T v) { + for (unsigned int i = 0; i < len; i++) + if (array[i] == v) + return &array[i]; + return NULL; + } + template + inline const Type *find (T v) const { + for (unsigned int i = 0; i < len; i++) + if (array[i] == v) + return &array[i]; + return NULL; + } -template -struct hb_set_t -{ - hb_array_t items; + inline void sort (void) + { + qsort (array, len, sizeof (Type), (hb_compare_func_t) Type::cmp); + } - private: + inline void sort (unsigned int start, unsigned int end) + { + qsort (array + start, end - start, sizeof (Type), (hb_compare_func_t) Type::cmp); + } template - inline item_t *find (T v) { - for (unsigned int i = 0; i < items.len; i++) - if (items[i] == v) - return &items[i]; - return NULL; + inline Type *bsearch (T *key) + { + return (Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp); + } + template + inline const Type *bsearch (T *key) const + { + return (const Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp); } - public: + inline void finish (void) + { + if (array != static_array) + free (array); + array = NULL; + allocated = len = 0; + } +}; + +template +struct hb_array_t : hb_prealloced_array_t {}; + + +template +struct hb_lockable_set_t +{ + hb_array_t items; template - inline bool insert (T v) + inline item_t *replace_or_insert (T v, lock_t &l) { - item_t *item = find (v); - if (item) - item->finish (); - else + l.lock (); + item_t *item = items.find (v); + if (item) { + item_t old = *item; + *item = v; + l.unlock (); + old.finish (); + } else { item = items.push (); - if (unlikely (!item)) return false; - *item = v; - return true; + if (likely (item)) + *item = v; + l.unlock (); + } + return item; } template - inline void remove (T v) + inline void remove (T v, lock_t &l) { - item_t *item = find (v); - if (!item) return; + l.lock (); + item_t *item = items.find (v); + if (item) { + item_t old = *item; + *item = items[items.len - 1]; + items.pop (); + l.unlock (); + old.finish (); + } else { + l.unlock (); + } + } - item->finish (); - *item = items[items.len - 1]; - items.pop (); + template + inline bool find (T v, item_t *i, lock_t &l) + { + l.lock (); + item_t *item = items.find (v); + if (item) + *i = *item; + l.unlock (); + return !!item; } template - inline item_t *get (T v) + inline item_t *find_or_insert (T v, lock_t &l) { - return find (v); + l.lock (); + item_t *item = items.find (v); + if (!item) { + item = items.push (); + if (likely (item)) + *item = v; + } + l.unlock (); + return item; } - void finish (void) { - for (unsigned i = 0; i < items.len; i++) - items[i].finish (); + inline void finish (lock_t &l) + { + l.lock (); + while (items.len) { + item_t old = items[items.len - 1]; + items.pop (); + l.unlock (); + old.finish (); + l.lock (); + } + items.finish (); + l.unlock (); } }; @@ -375,24 +452,57 @@ static inline unsigned char TOLOWER (unsigned char c) ((const char *) s)[3])) +/* C++ helpers */ + +/* Makes class uncopyable. Use in private: section. */ +#define NO_COPY(T) \ + T (const T &o); \ + T &operator = (const T &o) + + /* Debug */ #ifndef HB_DEBUG #define HB_DEBUG 0 #endif +#define DEBUG_LEVEL(WHAT, LEVEL) (HB_DEBUG_##WHAT && (int) (LEVEL) < (int) (HB_DEBUG_##WHAT)) +#define DEBUG(WHAT) (DEBUG_LEVEL (WHAT, 0)) + +#define DEBUG_MSG_LEVEL(WHAT, LEVEL, ...) (void) (DEBUG_LEVEL (WHAT, LEVEL) && fprintf (stderr, __VA_ARGS__)) +#define DEBUG_MSG(WHAT, ...) DEBUG_MSG_LEVEL (WHAT, 0, __VA_ARGS__) + static inline bool /* always returns TRUE */ _hb_trace (const char *what, - const char *function, + const char *message, const void *obj, unsigned int depth, unsigned int max_depth) { - (void) ((depth < max_depth) && fprintf (stderr, "%s(%p) %-*d-> %s\n", what, obj, depth, depth, function)); + (void) ((depth < max_depth) && fprintf (stderr, "%s(%p) %-*d-> %s\n", what, obj, depth, depth, message)); return TRUE; } +/* Pre-mature optimization: + * Checks for lo <= u <= hi but with an optimization if lo and hi + * are only different in a contiguous set of lower-most bits. + */ +static inline bool +hb_codepoint_in_range (hb_codepoint_t u, hb_codepoint_t lo, hb_codepoint_t hi) +{ + if ( ((lo^hi) & lo) == 0 && + ((lo^hi) & hi) == (lo^hi) && + ((lo^hi) & ((lo^hi) + 1)) == 0 ) + return (u & ~(lo^hi)) == lo; + else + return lo <= u && u <= hi; +} + + +/* Useful for set-operations on small enums */ +#define FLAG(x) (1<<(x)) + HB_END_DECLS #endif /* HB_PRIVATE_HH */