QtBase  v6.3.1
hb-open-type.hh
Go to the documentation of this file.
1 /*
2  * Copyright © 2007,2008,2009,2010 Red Hat, Inc.
3  * Copyright © 2012 Google, Inc.
4  *
5  * This is part of HarfBuzz, a text shaping library.
6  *
7  * Permission is hereby granted, without written agreement and without
8  * license or royalty fees, to use, copy, modify, and distribute this
9  * software and its documentation for any purpose, provided that the
10  * above copyright notice and the following two paragraphs appear in
11  * all copies of this software.
12  *
13  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17  * DAMAGE.
18  *
19  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
22  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24  *
25  * Red Hat Author(s): Behdad Esfahbod
26  * Google Author(s): Behdad Esfahbod
27  */
28 
29 #ifndef HB_OPEN_TYPE_HH
30 #define HB_OPEN_TYPE_HH
31 
32 #include "hb.hh"
33 #include "hb-blob.hh"
34 #include "hb-face.hh"
35 #include "hb-machinery.hh"
36 #include "hb-subset.hh"
37 
38 
39 namespace OT {
40 
41 
42 /*
43  *
44  * The OpenType Font File: Data Types
45  */
46 
47 
48 /* "The following data types are used in the OpenType font file.
49  * All OpenType fonts use Motorola-style byte ordering (Big Endian):" */
50 
51 /*
52  * Int types
53  */
54 
55 /* Integer types in big-endian order and no alignment requirement */
56 template <typename Type,
57  unsigned int Size = sizeof (Type)>
58 struct IntType
59 {
60  typedef Type type;
61 
62  IntType () = default;
63  explicit constexpr IntType (Type V) : v {V} {}
64  IntType& operator = (Type i) { v = i; return *this; }
65  /* For reason we define cast out operator for signed/unsigned, instead of Type, see:
66  * https://github.com/harfbuzz/harfbuzz/pull/2875/commits/09836013995cab2b9f07577a179ad7b024130467 */
67  operator typename std::conditional<std::is_signed<Type>::value, signed, unsigned>::type () const { return v; }
68 
69  bool operator == (const IntType &o) const { return (Type) v == (Type) o.v; }
70  bool operator != (const IntType &o) const { return !(*this == o); }
71 
72  IntType& operator += (unsigned count) { *this = *this + count; return *this; }
73  IntType& operator -= (unsigned count) { *this = *this - count; return *this; }
74  IntType& operator ++ () { *this += 1; return *this; }
75  IntType& operator -- () { *this -= 1; return *this; }
76  IntType operator ++ (int) { IntType c (*this); ++*this; return c; }
77  IntType operator -- (int) { IntType c (*this); --*this; return c; }
78 
79  HB_INTERNAL static int cmp (const IntType *a, const IntType *b)
80  { return b->cmp (*a); }
81  HB_INTERNAL static int cmp (const void *a, const void *b)
82  {
83  IntType *pa = (IntType *) a;
84  IntType *pb = (IntType *) b;
85 
86  return pb->cmp (*pa);
87  }
88  template <typename Type2,
90  sizeof (Type2) < sizeof (int) &&
91  sizeof (Type) < sizeof (int))>
92  int cmp (Type2 a) const
93  {
94  Type b = v;
95  return (int) a - (int) b;
96  }
97  template <typename Type2,
99  int cmp (Type2 a) const
100  {
101  Type b = v;
102  return a < b ? -1 : a == b ? 0 : +1;
103  }
105  {
106  TRACE_SANITIZE (this);
107  return_trace (likely (c->check_struct (this)));
108  }
109  protected:
111  public:
113 };
114 
115 typedef IntType<uint8_t> HBUINT8; /* 8-bit unsigned integer. */
116 typedef IntType<int8_t> HBINT8; /* 8-bit signed integer. */
117 typedef IntType<uint16_t> HBUINT16; /* 16-bit unsigned integer. */
118 typedef IntType<int16_t> HBINT16; /* 16-bit signed integer. */
119 typedef IntType<uint32_t> HBUINT32; /* 32-bit unsigned integer. */
120 typedef IntType<int32_t> HBINT32; /* 32-bit signed integer. */
121 /* Note: we cannot defined a signed HBINT24 because there's no corresponding C type.
122  * Works for unsigned, but not signed, since we rely on compiler for sign-extension. */
123 typedef IntType<uint32_t, 3> HBUINT24; /* 24-bit unsigned integer. */
124 
125 /* 15-bit unsigned number; top bit used for extension. */
127 {
128  /* TODO Flesh out; actually mask top bit. */
129  HBUINT15& operator = (uint16_t i ) { HBUINT16::operator= (i); return *this; }
130  public:
132 };
133 
134 /* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */
135 typedef HBINT16 FWORD;
136 
137 /* 32-bit signed integer (HBINT32) that describes a quantity in FUnits. */
138 typedef HBINT32 FWORD32;
139 
140 /* 16-bit unsigned integer (HBUINT16) that describes a quantity in FUnits. */
141 typedef HBUINT16 UFWORD;
142 
143 /* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
144 struct F2DOT14 : HBINT16
145 {
146  F2DOT14& operator = (uint16_t i ) { HBINT16::operator= (i); return *this; }
147  // 16384 means 1<<14
148  float to_float () const { return ((int32_t) v) / 16384.f; }
149  void set_float (float f) { v = roundf (f * 16384.f); }
150  public:
152 };
153 
154 /* 32-bit signed fixed-point number (16.16). */
155 struct HBFixed : HBINT32
156 {
157  HBFixed& operator = (uint32_t i) { HBINT32::operator= (i); return *this; }
158  // 65536 means 1<<16
159  float to_float () const { return ((int32_t) v) / 65536.f; }
160  void set_float (float f) { v = roundf (f * 65536.f); }
161  public:
163 };
164 
165 /* Date represented in number of seconds since 12:00 midnight, January 1,
166  * 1904. The value is represented as a signed 64-bit integer. */
168 {
170  {
171  TRACE_SANITIZE (this);
172  return_trace (likely (c->check_struct (this)));
173  }
174  protected:
177  public:
179 };
180 
181 /* Array of four uint8s (length = 32 bits) used to identify a script, language
182  * system, feature, or baseline */
183 struct Tag : HBUINT32
184 {
186  /* What the char* converters return is NOT nul-terminated. Print using "%.4s" */
187  operator const char* () const { return reinterpret_cast<const char *> (this); }
188  operator char* () { return reinterpret_cast<char *> (this); }
189  public:
191 };
192 
193 /* Glyph index number, same as uint16 (length = 16 bits) */
195 {
196  HBGlyphID16& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; }
197 };
198 
199 /* Script/language-system/feature index */
200 struct Index : HBUINT16 {
201  static constexpr unsigned NOT_FOUND_INDEX = 0xFFFFu;
202  Index& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; }
203 };
205 
206 typedef Index NameID;
207 
208 struct VarIdx : HBUINT32 {
209  static constexpr unsigned NO_VARIATION = 0xFFFFFFFFu;
210  VarIdx& operator = (uint32_t i) { HBUINT32::operator= (i); return *this; }
211 };
213 
214 /* Offset, Null offset = 0 */
215 template <typename Type, bool has_null=true>
216 struct Offset : Type
217 {
218  Offset& operator = (typename Type::type i) { Type::operator= (i); return *this; }
219 
220  typedef Type type;
221 
222  bool is_null () const { return has_null && 0 == *this; }
223 
224  public:
226 };
227 
231 
232 
233 /* CheckSum */
235 {
236  CheckSum& operator = (uint32_t i) { HBUINT32::operator= (i); return *this; }
237 
238  /* This is reference implementation from the spec. */
239  static uint32_t CalcTableChecksum (const HBUINT32 *Table, uint32_t Length)
240  {
241  uint32_t Sum = 0L;
242  assert (0 == (Length & 3));
243  const HBUINT32 *EndPtr = Table + Length / HBUINT32::static_size;
244 
245  while (Table < EndPtr)
246  Sum += *Table++;
247  return Sum;
248  }
249 
250  /* Note: data should be 4byte aligned and have 4byte padding at the end. */
251  void set_for_data (const void *data, unsigned int length)
252  { *this = CalcTableChecksum ((const HBUINT32 *) data, length); }
253 
254  public:
256 };
257 
258 
259 /*
260  * Version Numbers
261  */
262 
263 template <typename FixedType=HBUINT16>
265 {
266  uint32_t to_int () const { return (major << (sizeof (FixedType) * 8)) + minor; }
267 
269  {
270  TRACE_SANITIZE (this);
271  return_trace (c->check_struct (this));
272  }
273 
274  FixedType major;
275  FixedType minor;
276  public:
277  DEFINE_SIZE_STATIC (2 * sizeof (FixedType));
278 };
279 
280 
281 /*
282  * Template subclasses of Offset that do the dereferencing.
283  * Use: (base+offset)
284  */
285 
286 template <typename Type, bool has_null>
288 {
289  static const Type *get_null () { return nullptr; }
290  static Type *get_crap () { return nullptr; }
291 };
292 template <typename Type>
294 {
295  static const Type *get_null () { return &Null (Type); }
296  static Type *get_crap () { return &Crap (Type); }
297 };
298 
299 template <typename Type, typename OffsetType, bool has_null=true>
300 struct OffsetTo : Offset<OffsetType, has_null>
301 {
303  OffsetTo () = default;
304 
305  OffsetTo& operator = (typename OffsetType::type i) { OffsetType::operator= (i); return *this; }
306 
307  const Type& operator () (const void *base) const
308  {
309  if (unlikely (this->is_null ())) return *_hb_has_null<Type, has_null>::get_null ();
310  return StructAtOffset<const Type> (base, *this);
311  }
312  Type& operator () (void *base) const
313  {
314  if (unlikely (this->is_null ())) return *_hb_has_null<Type, has_null>::get_crap ();
315  return StructAtOffset<Type> (base, *this);
316  }
317 
318  template <typename Base,
319  hb_enable_if (hb_is_convertible (const Base, const void *))>
320  friend const Type& operator + (const Base &base, const OffsetTo &offset) { return offset ((const void *) base); }
321  template <typename Base,
322  hb_enable_if (hb_is_convertible (const Base, const void *))>
323  friend const Type& operator + (const OffsetTo &offset, const Base &base) { return offset ((const void *) base); }
324  template <typename Base,
325  hb_enable_if (hb_is_convertible (Base, void *))>
326  friend Type& operator + (Base &&base, OffsetTo &offset) { return offset ((void *) base); }
327  template <typename Base,
328  hb_enable_if (hb_is_convertible (Base, void *))>
329  friend Type& operator + (OffsetTo &offset, Base &&base) { return offset ((void *) base); }
330 
331 
332  template <typename ...Ts>
334  const void *src_base, Ts&&... ds)
335  {
336  *this = 0;
337  if (src.is_null ())
338  return false;
339 
340  auto *s = c->serializer;
341 
342  s->push ();
343 
344  bool ret = c->dispatch (src_base+src, std::forward<Ts> (ds)...);
345 
346  if (ret || !has_null)
347  s->add_link (*this, s->pop_pack ());
348  else
349  s->pop_discard ();
350 
351  return ret;
352  }
353 
354 
355  template <typename ...Ts>
357  {
358  *this = 0;
359 
360  Type* obj = c->push<Type> ();
361  bool ret = obj->serialize (c, std::forward<Ts> (ds)...);
362 
363  if (ret)
364  c->add_link (*this, c->pop_pack ());
365  else
366  c->pop_discard ();
367 
368  return ret;
369  }
370 
371  /* TODO: Somehow merge this with previous function into a serialize_dispatch(). */
372  /* Workaround clang bug: https://bugs.llvm.org/show_bug.cgi?id=23029
373  * Can't compile: whence = hb_serialize_context_t::Head followed by Ts&&...
374  */
375  template <typename ...Ts>
377  const void *src_base, unsigned dst_bias,
379  Ts&&... ds)
380  {
381  *this = 0;
382  if (src.is_null ())
383  return false;
384 
385  c->push ();
386 
387  bool ret = c->copy (src_base+src, std::forward<Ts> (ds)...);
388 
389  c->add_link (*this, c->pop_pack (), whence, dst_bias);
390 
391  return ret;
392  }
393 
395  const void *src_base, unsigned dst_bias = 0)
396  { return serialize_copy (c, src, src_base, dst_bias, hb_serialize_context_t::Head); }
397 
398  bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const
399  {
400  TRACE_SANITIZE (this);
401  if (unlikely (!c->check_struct (this))) return_trace (false);
402  if (unlikely (this->is_null ())) return_trace (true);
403  if (unlikely ((const char *) base + (unsigned) *this < (const char *) base)) return_trace (false);
404  return_trace (true);
405  }
406 
407  template <typename ...Ts>
408  bool sanitize (hb_sanitize_context_t *c, const void *base, Ts&&... ds) const
409  {
410  TRACE_SANITIZE (this);
412  (this->is_null () ||
413  c->dispatch (StructAtOffset<Type> (base, *this), std::forward<Ts> (ds)...) ||
414  neuter (c)));
415  }
416 
417  /* Set the offset to Null */
419  {
420  if (!has_null) return false;
421  return c->try_set (this, 0);
422  }
423  DEFINE_SIZE_STATIC (sizeof (OffsetType));
424 };
425 /* Partial specializations. */
426 template <typename Type, bool has_null=true> using Offset16To = OffsetTo<Type, HBUINT16, has_null>;
427 template <typename Type, bool has_null=true> using Offset24To = OffsetTo<Type, HBUINT24, has_null>;
428 template <typename Type, bool has_null=true> using Offset32To = OffsetTo<Type, HBUINT32, has_null>;
429 
430 template <typename Type, typename OffsetType> using NNOffsetTo = OffsetTo<Type, OffsetType, false>;
431 template <typename Type> using NNOffset16To = Offset16To<Type, false>;
432 template <typename Type> using NNOffset24To = Offset24To<Type, false>;
433 template <typename Type> using NNOffset32To = Offset32To<Type, false>;
434 
435 
436 /*
437  * Array Types
438  */
439 
440 template <typename Type>
442 {
443  typedef Type item_t;
444  static constexpr unsigned item_size = hb_static_size (Type);
445 
447 
448  const Type& operator [] (int i_) const
449  {
450  unsigned int i = (unsigned int) i_;
451  const Type *p = &arrayZ[i];
452  if (unlikely (p < arrayZ)) return Null (Type); /* Overflowed. */
453  return *p;
454  }
456  {
457  unsigned int i = (unsigned int) i_;
458  Type *p = &arrayZ[i];
459  if (unlikely (p < arrayZ)) return Crap (Type); /* Overflowed. */
460  return *p;
461  }
462 
463  unsigned int get_size (unsigned int len) const
464  { return len * Type::static_size; }
465 
466  template <typename T> operator T * () { return arrayZ; }
467  template <typename T> operator const T * () const { return arrayZ; }
469  { return hb_array (arrayZ, len); }
470  hb_array_t<const Type> as_array (unsigned int len) const
471  { return hb_array (arrayZ, len); }
472 
473  template <typename T>
474  Type &lsearch (unsigned int len, const T &x, Type &not_found = Crap (Type))
475  { return *as_array (len).lsearch (x, &not_found); }
476  template <typename T>
477  const Type &lsearch (unsigned int len, const T &x, const Type &not_found = Null (Type)) const
478  { return *as_array (len).lsearch (x, &not_found); }
479  template <typename T>
480  bool lfind (unsigned int len, const T &x, unsigned int *i = nullptr,
482  unsigned int to_store = (unsigned int) -1) const
483  { return as_array (len).lfind (x, i, not_found, to_store); }
484 
485  void qsort (unsigned int len, unsigned int start = 0, unsigned int end = (unsigned int) -1)
486  { as_array (len).qsort (start, end); }
487 
488  bool serialize (hb_serialize_context_t *c, unsigned int items_len)
489  {
490  TRACE_SERIALIZE (this);
491  if (unlikely (!c->extend (this, items_len))) return_trace (false);
492  return_trace (true);
493  }
494  template <typename Iterator,
495  hb_requires (hb_is_source_of (Iterator, Type))>
497  {
498  TRACE_SERIALIZE (this);
499  unsigned count = items.len ();
500  if (unlikely (!serialize (c, count))) return_trace (false);
501  /* TODO Umm. Just exhaust the iterator instead? Being extra
502  * cautious right now.. */
503  for (unsigned i = 0; i < count; i++, ++items)
504  arrayZ[i] = *items;
505  return_trace (true);
506  }
507 
509  {
510  TRACE_SERIALIZE (this);
511  auto *out = c->start_embed (this);
512  if (unlikely (!as_array (count).copy (c))) return_trace (nullptr);
513  return_trace (out);
514  }
515 
516  template <typename ...Ts>
517  bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts&&... ds) const
518  {
519  TRACE_SANITIZE (this);
520  if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
521  if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
522  for (unsigned int i = 0; i < count; i++)
523  if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
524  return_trace (false);
525  return_trace (true);
526  }
527 
528  bool sanitize_shallow (hb_sanitize_context_t *c, unsigned int count) const
529  {
530  TRACE_SANITIZE (this);
531  return_trace (c->check_array (arrayZ, count));
532  }
533 
534  public:
536  public:
538 };
539 
540 /* Unsized array of offset's */
541 template <typename Type, typename OffsetType, bool has_null=true>
543 
544 /* Unsized array of offsets relative to the beginning of the array itself. */
545 template <typename Type, typename OffsetType, bool has_null=true>
546 struct UnsizedListOfOffset16To : UnsizedArray16OfOffsetTo<Type, OffsetType, has_null>
547 {
548  const Type& operator [] (int i_) const
549  {
550  unsigned int i = (unsigned int) i_;
552  if (unlikely (p < this->arrayZ)) return Null (Type); /* Overflowed. */
553  return this+*p;
554  }
556  {
557  unsigned int i = (unsigned int) i_;
559  if (unlikely (p < this->arrayZ)) return Crap (Type); /* Overflowed. */
560  return this+*p;
561  }
562 
563  template <typename ...Ts>
564  bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts&&... ds) const
565  {
566  TRACE_SANITIZE (this);
568  ::sanitize (c, count, this, std::forward<Ts> (ds)...)));
569  }
570 };
571 
572 /* An array with sorted elements. Supports binary searching. */
573 template <typename Type>
575 {
577  { return hb_sorted_array (this->arrayZ, len); }
579  { return hb_sorted_array (this->arrayZ, len); }
580  operator hb_sorted_array_t<Type> () { return as_array (); }
581  operator hb_sorted_array_t<const Type> () const { return as_array (); }
582 
583  template <typename T>
584  Type &bsearch (unsigned int len, const T &x, Type &not_found = Crap (Type))
585  { return *as_array (len).bsearch (x, &not_found); }
586  template <typename T>
587  const Type &bsearch (unsigned int len, const T &x, const Type &not_found = Null (Type)) const
588  { return *as_array (len).bsearch (x, &not_found); }
589  template <typename T>
590  bool bfind (unsigned int len, const T &x, unsigned int *i = nullptr,
592  unsigned int to_store = (unsigned int) -1) const
593  { return as_array (len).bfind (x, i, not_found, to_store); }
594 };
595 
596 
597 /* An array with a number of elements. */
598 template <typename Type, typename LenType>
599 struct ArrayOf
600 {
601  typedef Type item_t;
602  static constexpr unsigned item_size = hb_static_size (Type);
603 
605 
606  const Type& operator [] (int i_) const
607  {
608  unsigned int i = (unsigned int) i_;
609  if (unlikely (i >= len)) return Null (Type);
610  return arrayZ[i];
611  }
613  {
614  unsigned int i = (unsigned int) i_;
615  if (unlikely (i >= len)) return Crap (Type);
616  return arrayZ[i];
617  }
618 
619  unsigned int get_size () const
620  { return len.static_size + len * Type::static_size; }
621 
622  explicit operator bool () const { return len; }
623 
624  void pop () { len--; }
625 
628 
629  /* Iterator. */
632  iter_t iter () const { return as_array (); }
633  writer_t writer () { return as_array (); }
634  operator iter_t () const { return iter (); }
635  operator writer_t () { return writer (); }
636 
637  hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const
638  { return as_array ().sub_array (start_offset, count); }
639  hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
640  { return as_array ().sub_array (start_offset, count); }
641  hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int count)
642  { return as_array ().sub_array (start_offset, count); }
643  hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
644  { return as_array ().sub_array (start_offset, count); }
645 
646  template <typename T>
647  Type &lsearch (const T &x, Type &not_found = Crap (Type))
648  { return *as_array ().lsearch (x, &not_found); }
649  template <typename T>
650  const Type &lsearch (const T &x, const Type &not_found = Null (Type)) const
651  { return *as_array ().lsearch (x, &not_found); }
652  template <typename T>
653  bool lfind (const T &x, unsigned int *i = nullptr,
655  unsigned int to_store = (unsigned int) -1) const
656  { return as_array ().lfind (x, i, not_found, to_store); }
657 
658  void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1)
659  { as_array ().qsort (start, end); }
660 
661  HB_NODISCARD bool serialize (hb_serialize_context_t *c, unsigned items_len)
662  {
663  TRACE_SERIALIZE (this);
664  if (unlikely (!c->extend_min (this))) return_trace (false);
665  c->check_assign (len, items_len, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW);
666  if (unlikely (!c->extend (this))) return_trace (false);
667  return_trace (true);
668  }
669  template <typename Iterator,
670  hb_requires (hb_is_source_of (Iterator, Type))>
672  {
673  TRACE_SERIALIZE (this);
674  unsigned count = items.len ();
675  if (unlikely (!serialize (c, count))) return_trace (false);
676  /* TODO Umm. Just exhaust the iterator instead? Being extra
677  * cautious right now.. */
678  for (unsigned i = 0; i < count; i++, ++items)
679  arrayZ[i] = *items;
680  return_trace (true);
681  }
682 
684  {
685  TRACE_SERIALIZE (this);
686  len++;
687  if (unlikely (!len || !c->extend (this)))
688  {
689  len--;
690  return_trace (nullptr);
691  }
692  return_trace (&arrayZ[len - 1]);
693  }
694 
696  {
697  TRACE_SERIALIZE (this);
698  auto *out = c->start_embed (this);
699  if (unlikely (!c->extend_min (out))) return_trace (nullptr);
700  c->check_assign (out->len, len, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW);
701  if (unlikely (!as_array ().copy (c))) return_trace (nullptr);
702  return_trace (out);
703  }
704 
705  template <typename ...Ts>
706  bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
707  {
708  TRACE_SANITIZE (this);
709  if (unlikely (!sanitize_shallow (c))) return_trace (false);
710  if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
711  unsigned int count = len;
712  for (unsigned int i = 0; i < count; i++)
713  if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
714  return_trace (false);
715  return_trace (true);
716  }
717 
719  {
720  TRACE_SANITIZE (this);
721  return_trace (len.sanitize (c) && c->check_array (arrayZ, len));
722  }
723 
724  public:
725  LenType len;
727  public:
728  DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
729 };
730 template <typename Type> using Array16Of = ArrayOf<Type, HBUINT16>;
731 template <typename Type> using Array32Of = ArrayOf<Type, HBUINT32>;
733 
734 /* Array of Offset's */
738 
739 /* Array of offsets relative to the beginning of the array itself. */
740 template <typename Type>
742 {
743  const Type& operator [] (int i_) const
744  {
745  unsigned int i = (unsigned int) i_;
746  if (unlikely (i >= this->len)) return Null (Type);
747  return this+this->arrayZ[i];
748  }
749  const Type& operator [] (int i_)
750  {
751  unsigned int i = (unsigned int) i_;
752  if (unlikely (i >= this->len)) return Crap (Type);
753  return this+this->arrayZ[i];
754  }
755 
757  {
758  TRACE_SUBSET (this);
759  struct List16OfOffset16To<Type> *out = c->serializer->embed (*this);
760  if (unlikely (!out)) return_trace (false);
761  unsigned int count = this->len;
762  for (unsigned int i = 0; i < count; i++)
763  out->arrayZ[i].serialize_subset (c, this->arrayZ[i], this, out);
764  return_trace (true);
765  }
766 
767  template <typename ...Ts>
768  bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
769  {
770  TRACE_SANITIZE (this);
771  return_trace (Array16OfOffset16To<Type>::sanitize (c, this, std::forward<Ts> (ds)...));
772  }
773 };
774 
775 /* An array starting at second element. */
776 template <typename Type, typename LenType=HBUINT16>
778 {
779  static constexpr unsigned item_size = Type::static_size;
780 
782 
783  const Type& operator [] (int i_) const
784  {
785  unsigned int i = (unsigned int) i_;
786  if (unlikely (i >= lenP1 || !i)) return Null (Type);
787  return arrayZ[i-1];
788  }
790  {
791  unsigned int i = (unsigned int) i_;
792  if (unlikely (i >= lenP1 || !i)) return Crap (Type);
793  return arrayZ[i-1];
794  }
795  unsigned int get_size () const
796  { return lenP1.static_size + get_length () * Type::static_size; }
797 
798  unsigned get_length () const { return lenP1 ? lenP1 - 1 : 0; }
799 
802 
803  /* Iterator. */
806  iter_t iter () const { return as_array (); }
807  writer_t writer () { return as_array (); }
808  operator iter_t () const { return iter (); }
809  operator writer_t () { return writer (); }
810 
811  bool serialize (hb_serialize_context_t *c, unsigned int items_len)
812  {
813  TRACE_SERIALIZE (this);
814  if (unlikely (!c->extend_min (this))) return_trace (false);
815  c->check_assign (lenP1, items_len + 1, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW);
816  if (unlikely (!c->extend (this))) return_trace (false);
817  return_trace (true);
818  }
819  template <typename Iterator,
820  hb_requires (hb_is_source_of (Iterator, Type))>
822  {
823  TRACE_SERIALIZE (this);
824  unsigned count = items.len ();
825  if (unlikely (!serialize (c, count))) return_trace (false);
826  /* TODO Umm. Just exhaust the iterator instead? Being extra
827  * cautious right now.. */
828  for (unsigned i = 0; i < count; i++, ++items)
829  arrayZ[i] = *items;
830  return_trace (true);
831  }
832 
833  template <typename ...Ts>
834  bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
835  {
836  TRACE_SANITIZE (this);
837  if (unlikely (!sanitize_shallow (c))) return_trace (false);
838  if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
839  unsigned int count = get_length ();
840  for (unsigned int i = 0; i < count; i++)
841  if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
842  return_trace (false);
843  return_trace (true);
844  }
845 
846  private:
847  bool sanitize_shallow (hb_sanitize_context_t *c) const
848  {
849  TRACE_SANITIZE (this);
850  return_trace (lenP1.sanitize (c) &&
851  (!lenP1 || c->check_array (arrayZ, lenP1 - 1)));
852  }
853 
854  public:
855  LenType lenP1;
857  public:
858  DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
859 };
860 
861 /* An array storing length-1. */
862 template <typename Type, typename LenType=HBUINT16>
863 struct ArrayOfM1
864 {
866 
867  const Type& operator [] (int i_) const
868  {
869  unsigned int i = (unsigned int) i_;
870  if (unlikely (i > lenM1)) return Null (Type);
871  return arrayZ[i];
872  }
874  {
875  unsigned int i = (unsigned int) i_;
876  if (unlikely (i > lenM1)) return Crap (Type);
877  return arrayZ[i];
878  }
879  unsigned int get_size () const
880  { return lenM1.static_size + (lenM1 + 1) * Type::static_size; }
881 
882  template <typename ...Ts>
883  bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
884  {
885  TRACE_SANITIZE (this);
886  if (unlikely (!sanitize_shallow (c))) return_trace (false);
887  if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
888  unsigned int count = lenM1 + 1;
889  for (unsigned int i = 0; i < count; i++)
890  if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
891  return_trace (false);
892  return_trace (true);
893  }
894 
895  private:
896  bool sanitize_shallow (hb_sanitize_context_t *c) const
897  {
898  TRACE_SANITIZE (this);
899  return_trace (lenM1.sanitize (c) &&
900  (c->check_array (arrayZ, lenM1 + 1)));
901  }
902 
903  public:
904  LenType lenM1;
906  public:
907  DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
908 };
909 
910 /* An array with sorted elements. Supports binary searching. */
911 template <typename Type, typename LenType>
912 struct SortedArrayOf : ArrayOf<Type, LenType>
913 {
914  hb_sorted_array_t< Type> as_array () { return hb_sorted_array (this->arrayZ, this->len); }
915  hb_sorted_array_t<const Type> as_array () const { return hb_sorted_array (this->arrayZ, this->len); }
916 
917  /* Iterator. */
920  iter_t iter () const { return as_array (); }
921  writer_t writer () { return as_array (); }
922  operator iter_t () const { return iter (); }
923  operator writer_t () { return writer (); }
924 
925  hb_sorted_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const
926  { return as_array ().sub_array (start_offset, count); }
927  hb_sorted_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
928  { return as_array ().sub_array (start_offset, count); }
930  { return as_array ().sub_array (start_offset, count); }
931  hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
932  { return as_array ().sub_array (start_offset, count); }
933 
934  bool serialize (hb_serialize_context_t *c, unsigned int items_len)
935  {
936  TRACE_SERIALIZE (this);
937  bool ret = ArrayOf<Type, LenType>::serialize (c, items_len);
938  return_trace (ret);
939  }
940  template <typename Iterator,
943  {
944  TRACE_SERIALIZE (this);
946  return_trace (ret);
947  }
948 
949  template <typename T>
950  Type &bsearch (const T &x, Type &not_found = Crap (Type))
951  { return *as_array ().bsearch (x, &not_found); }
952  template <typename T>
953  const Type &bsearch (const T &x, const Type &not_found = Null (Type)) const
954  { return *as_array ().bsearch (x, &not_found); }
955  template <typename T>
956  bool bfind (const T &x, unsigned int *i = nullptr,
958  unsigned int to_store = (unsigned int) -1) const
959  { return as_array ().bfind (x, i, not_found, to_store); }
960 };
961 
962 template <typename Type> using SortedArray16Of = SortedArrayOf<Type, HBUINT16>;
963 template <typename Type> using SortedArray32Of = SortedArrayOf<Type, HBUINT32>;
964 
965 /*
966  * Binary-search arrays
967  */
968 
969 template <typename LenType=HBUINT16>
971 {
972  operator uint32_t () const { return len; }
973 
975  {
976  TRACE_SANITIZE (this);
977  return_trace (c->check_struct (this));
978  }
979 
981  {
982  len = v;
983  assert (len == v);
984  entrySelector = hb_max (1u, hb_bit_storage (v)) - 1;
985  searchRange = 16 * (1u << entrySelector);
986  rangeShift = v * 16 > searchRange
987  ? 16 * v - searchRange
988  : 0;
989  return *this;
990  }
991 
992  protected:
993  LenType len;
994  LenType searchRange;
995  LenType entrySelector;
996  LenType rangeShift;
997 
998  public:
1000 };
1001 
1002 template <typename Type, typename LenType=HBUINT16>
1004 
1005 
1007 {
1008 
1010  {
1011  TRACE_SANITIZE (this);
1012  return_trace (c->check_struct (this));
1013  }
1014 
1015  HBUINT16 unitSize; /* Size of a lookup unit for this search in bytes. */
1016  HBUINT16 nUnits; /* Number of units of the preceding size to be searched. */
1017  HBUINT16 searchRange; /* The value of unitSize times the largest power of 2
1018  * that is less than or equal to the value of nUnits. */
1019  HBUINT16 entrySelector; /* The log base 2 of the largest power of 2 less than
1020  * or equal to the value of nUnits. */
1021  HBUINT16 rangeShift; /* The value of unitSize times the difference of the
1022  * value of nUnits minus the largest power of 2 less
1023  * than or equal to the value of nUnits. */
1024  public:
1026 };
1027 
1028 template <typename Type>
1030 {
1031  static constexpr unsigned item_size = Type::static_size;
1032 
1034 
1035  bool last_is_terminator () const
1036  {
1037  if (unlikely (!header.nUnits)) return false;
1038 
1039  /* Gah.
1040  *
1041  * "The number of termination values that need to be included is table-specific.
1042  * The value that indicates binary search termination is 0xFFFF." */
1043  const HBUINT16 *words = &StructAtOffset<HBUINT16> (&bytesZ, (header.nUnits - 1) * header.unitSize);
1044  unsigned int count = Type::TerminationWordCount;
1045  for (unsigned int i = 0; i < count; i++)
1046  if (words[i] != 0xFFFFu)
1047  return false;
1048  return true;
1049  }
1050 
1051  const Type& operator [] (int i_) const
1052  {
1053  unsigned int i = (unsigned int) i_;
1054  if (unlikely (i >= get_length ())) return Null (Type);
1055  return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
1056  }
1058  {
1059  unsigned int i = (unsigned int) i_;
1060  if (unlikely (i >= get_length ())) return Crap (Type);
1061  return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
1062  }
1063  unsigned int get_length () const
1064  { return header.nUnits - last_is_terminator (); }
1065  unsigned int get_size () const
1066  { return header.static_size + header.nUnits * header.unitSize; }
1067 
1068  template <typename ...Ts>
1069  bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
1070  {
1071  TRACE_SANITIZE (this);
1072  if (unlikely (!sanitize_shallow (c))) return_trace (false);
1073  if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
1074  unsigned int count = get_length ();
1075  for (unsigned int i = 0; i < count; i++)
1076  if (unlikely (!(*this)[i].sanitize (c, std::forward<Ts> (ds)...)))
1077  return_trace (false);
1078  return_trace (true);
1079  }
1080 
1081  template <typename T>
1082  const Type *bsearch (const T &key) const
1083  {
1084  unsigned pos;
1085  return hb_bsearch_impl (&pos,
1086  key,
1087  (const void *) bytesZ,
1088  get_length (),
1089  header.unitSize,
1090  _hb_cmp_method<T, Type>)
1091  ? (const Type *) (((const char *) &bytesZ) + (pos * header.unitSize))
1092  : nullptr;
1093  }
1094 
1095  private:
1096  bool sanitize_shallow (hb_sanitize_context_t *c) const
1097  {
1098  TRACE_SANITIZE (this);
1100  Type::static_size <= header.unitSize &&
1101  c->check_range (bytesZ.arrayZ,
1102  header.nUnits,
1103  header.unitSize));
1104  }
1105 
1106  protected:
1109  public:
1111 };
1112 
1113 
1114 } /* namespace OT */
1115 
1116 
1117 #endif /* HB_OPEN_TYPE_HH */
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
#define value
[5]
Definition: base.h:37
#define this
Definition: dialogs.cpp:56
#define true
Definition: ftrandom.c:51
#define roundf(x)
Definition: hb-algs.hh:165
auto V(a, v))) struct
Definition: hb-algs.hh:317
hb_not_found_t
Definition: hb-array.hh:40
@ HB_NOT_FOUND_DONT_STORE
Definition: hb-array.hh:41
hb_array_t< T > hb_array(T *array, unsigned int length)
Definition: hb-array.hh:295
hb_sorted_array_t< T > hb_sorted_array(T *array, unsigned int length)
Definition: hb-array.hh:399
#define TRACE_SERIALIZE(this)
Definition: hb-debug.hh:426
#define TRACE_SANITIZE(this)
Definition: hb-debug.hh:414
#define return_trace(RET)
Definition: hb-debug.hh:349
#define TRACE_SUBSET(this)
Definition: hb-debug.hh:438
#define hb_is_sorted_source_of(Iter, Item)
Definition: hb-iter.hh:320
static auto hb_requires(hb_is_iterable(Iterable))> static inline auto end(Iterable &&iterable) HB_AUTO_RETURN(hb_iter(iterable).end()) namespace OT
Definition: hb-iter.hh:331
#define HB_VAR_ARRAY
Definition: hb-machinery.hh:85
#define hb_enable_if(Cond)
Definition: hb-meta.hh:65
#define hb_is_convertible(From, To)
Definition: hb-meta.hh:118
#define Crap(Type)
Definition: hb-null.hh:159
_hb_static_size< T, void > hb_static_size
Definition: hb-null.hh:72
HB_EXTERN unsigned int start_offset
@ HB_SERIALIZE_ERROR_ARRAY_OVERFLOW
Definition: hb-serialize.hh:53
#define HB_NODISCARD
Definition: hb.hh:348
#define likely(expr)
Definition: hb.hh:250
#define unlikely(expr)
Definition: hb.hh:251
#define HB_INTERNAL
Definition: hb.hh:274
HBUINT16 UFWORD
Index NameID
IntType< uint8_t > HBUINT8
IntType< int32_t > HBINT32
HBINT16 FWORD
DECLARE_NULL_NAMESPACE_BYTES(OT, Index)
Offset< HBUINT24 > Offset24
Offset< HBUINT16 > Offset16
IntType< uint32_t > HBUINT32
IntType< int8_t > HBINT8
IntType< uint16_t > HBUINT16
IntType< int16_t > HBINT16
HBINT32 FWORD32
Offset< HBUINT32 > Offset32
IntType< uint32_t, 3 > HBUINT24
QString & operator+=(QString &that, const ProString &other)
Definition: proitems.h:262
#define assert
Definition: qcborcommon_p.h:63
constexpr bool operator!=(const timespec &t1, const timespec &t2)
Definition: qcore_unix_p.h:124
bool operator==(const QMakeBaseKey &one, const QMakeBaseKey &two)
GLenum GLuint GLenum GLsizei length
Definition: qopengl.h:270
GLenum type
Definition: qopengl.h:270
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLuint64 key
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint GLuint end
GLenum GLenum GLsizei count
GLfloat GLfloat f
GLenum src
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint start
GLenum GLuint GLintptr offset
GLhandleARB obj
[2]
Definition: qopenglext.h:4164
const GLubyte * c
Definition: qopenglext.h:12701
GLenum GLsizei len
Definition: qopenglext.h:3292
GLdouble s
[6]
Definition: qopenglext.h:235
GLfloat GLfloat p
[1]
Definition: qopenglext.h:12698
uint32_t hb_tag_t
Definition: hb-common.h:157
QTextStream out(stdout)
[7]
QList< QTreeWidgetItem * > items
QDBusVariant Type
Definition: hb-algs.hh:91
Definition: hb-null.hh:93
static const Type * get_null()
static const Type * get_null()
static Type * get_crap()
hb_array_t< const Type > sub_array(unsigned int start_offset, unsigned int *count=nullptr) const
bool sanitize_shallow(hb_sanitize_context_t *c) const
ArrayOf * copy(hb_serialize_context_t *c) const
const Type & lsearch(const T &x, const Type &not_found=Null(Type)) const
bool sanitize(hb_sanitize_context_t *c, Ts &&... ds) const
hb_array_t< Type > writer_t
HB_NODISCARD bool serialize(hb_serialize_context_t *c, unsigned items_len)
Type & lsearch(const T &x, Type &not_found=Crap(Type))
hb_array_t< Type > as_array()
Type arrayZ[HB_VAR_ARRAY]
hb_array_t< Type > sub_array(unsigned int start_offset, unsigned int count)
const Type & operator[](int i_) const
hb_array_t< Type > sub_array(unsigned int start_offset, unsigned int *count=nullptr)
HB_NODISCARD bool serialize(hb_serialize_context_t *c, Iterator items)
DEFINE_SIZE_ARRAY(sizeof(LenType), arrayZ)
void qsort(unsigned int start=0, unsigned int end=(unsigned int) -1)
Type * serialize_append(hb_serialize_context_t *c)
unsigned int get_size() const
iter_t iter() const
HB_DELETE_CREATE_COPY_ASSIGN(ArrayOf)
static constexpr unsigned item_size
bool lfind(const T &x, unsigned int *i=nullptr, hb_not_found_t not_found=HB_NOT_FOUND_DONT_STORE, unsigned int to_store=(unsigned int) -1) const
writer_t writer()
hb_array_t< const Type > sub_array(unsigned int start_offset, unsigned int count) const
hb_array_t< const Type > iter_t
hb_array_t< const Type > as_array() const
HB_DELETE_CREATE_COPY_ASSIGN(ArrayOfM1)
const Type & operator[](int i_) const
Type arrayZ[HB_VAR_ARRAY]
unsigned int get_size() const
DEFINE_SIZE_ARRAY(sizeof(LenType), arrayZ)
bool sanitize(hb_sanitize_context_t *c, Ts &&... ds) const
BinSearchHeader & operator=(unsigned int v)
bool sanitize(hb_sanitize_context_t *c) const
static uint32_t CalcTableChecksum(const HBUINT32 *Table, uint32_t Length)
CheckSum & operator=(uint32_t i)
void set_for_data(const void *data, unsigned int length)
DEFINE_SIZE_STATIC(2)
F2DOT14 & operator=(uint16_t i)
float to_float() const
void set_float(float f)
bool sanitize(hb_sanitize_context_t *c) const
DEFINE_SIZE_STATIC(2 *sizeof(FixedType))
uint32_t to_int() const
DEFINE_SIZE_STATIC(4)
void set_float(float f)
float to_float() const
HBFixed & operator=(uint32_t i)
HBGlyphID16 & operator=(uint16_t i)
HBUINT15 & operator=(uint16_t i)
HB_DELETE_CREATE_COPY_ASSIGN(HeadlessArrayOf)
DEFINE_SIZE_ARRAY(sizeof(LenType), arrayZ)
bool sanitize(hb_sanitize_context_t *c, Ts &&... ds) const
hb_array_t< Type > writer_t
hb_array_t< const Type > iter_t
hb_array_t< const Type > as_array() const
Type arrayZ[HB_VAR_ARRAY]
hb_array_t< Type > as_array()
unsigned get_length() const
bool serialize(hb_serialize_context_t *c, Iterator items)
unsigned int get_size() const
static constexpr unsigned item_size
const Type & operator[](int i_) const
bool serialize(hb_serialize_context_t *c, unsigned int items_len)
iter_t iter() const
static constexpr unsigned NOT_FOUND_INDEX
Index & operator=(uint16_t i)
constexpr IntType(Type V)
Definition: hb-open-type.hh:63
BEInt< Type, Size > v
static HB_INTERNAL int cmp(const IntType *a, const IntType *b)
Definition: hb-open-type.hh:79
static HB_INTERNAL int cmp(const void *a, const void *b)
Definition: hb-open-type.hh:81
DEFINE_SIZE_STATIC(Size)
IntType & operator=(uint16_t i)
Definition: hb-open-type.hh:64
int cmp(Type2 a) const
Definition: hb-open-type.hh:92
IntType()=default
bool sanitize(hb_sanitize_context_t *c) const
bool sanitize(hb_sanitize_context_t *c) const
const Type & operator[](int i_) const
bool subset(hb_subset_context_t *c) const
bool sanitize(hb_sanitize_context_t *c, Ts &&... ds) const
bool is_null() const
Offset & operator=(typename Type::type i)
DEFINE_SIZE_STATIC(sizeof(Type))
OffsetTo & operator=(typename OffsetType::type i)
bool neuter(hb_sanitize_context_t *c) const
const Type & operator()(const void *base) const
DEFINE_SIZE_STATIC(sizeof(OffsetType))
HB_DELETE_COPY_ASSIGN(OffsetTo)
friend const Type & operator+(const Base &base, const OffsetTo &offset)
OffsetTo()=default
bool sanitize(hb_sanitize_context_t *c, const void *base, Ts &&... ds) const
bool serialize_copy(hb_serialize_context_t *c, const OffsetTo &src, const void *src_base, unsigned dst_bias=0)
bool serialize_serialize(hb_serialize_context_t *c, Ts &&... ds)
bool sanitize_shallow(hb_sanitize_context_t *c, const void *base) const
bool serialize_subset(hb_subset_context_t *c, const OffsetTo &src, const void *src_base, Ts &&... ds)
bool serialize_copy(hb_serialize_context_t *c, const OffsetTo &src, const void *src_base, unsigned dst_bias, hb_serialize_context_t::whence_t whence, Ts &&... ds)
bool serialize(hb_serialize_context_t *c, Iterator items)
bool serialize(hb_serialize_context_t *c, unsigned int items_len)
hb_sorted_array_t< const Type > sub_array(unsigned int start_offset, unsigned int *count=nullptr) const
bool bfind(const T &x, unsigned int *i=nullptr, hb_not_found_t not_found=HB_NOT_FOUND_DONT_STORE, unsigned int to_store=(unsigned int) -1) const
hb_sorted_array_t< const Type > as_array() const
hb_sorted_array_t< Type > as_array()
hb_sorted_array_t< const Type > sub_array(unsigned int start_offset, unsigned int count) const
Type & bsearch(const T &x, Type &not_found=Crap(Type))
hb_sorted_array_t< const Type > iter_t
hb_sorted_array_t< Type > sub_array(unsigned int start_offset, unsigned int count)
hb_sorted_array_t< Type > writer_t
hb_sorted_array_t< Type > sub_array(unsigned int start_offset, unsigned int *count=nullptr)
iter_t iter() const
const Type & bsearch(const T &x, const Type &not_found=Null(Type)) const
bool bfind(unsigned int len, const T &x, unsigned int *i=nullptr, hb_not_found_t not_found=HB_NOT_FOUND_DONT_STORE, unsigned int to_store=(unsigned int) -1) const
const Type & bsearch(unsigned int len, const T &x, const Type &not_found=Null(Type)) const
Type & bsearch(unsigned int len, const T &x, Type &not_found=Crap(Type))
hb_sorted_array_t< const Type > as_array(unsigned int len) const
hb_sorted_array_t< Type > as_array(unsigned int len)
DEFINE_SIZE_STATIC(4)
Tag & operator=(hb_tag_t i)
bool serialize(hb_serialize_context_t *c, Iterator items)
Type arrayZ[HB_VAR_ARRAY]
hb_array_t< Type > as_array(unsigned int len)
UnsizedArrayOf * copy(hb_serialize_context_t *c, unsigned count) const
bool serialize(hb_serialize_context_t *c, unsigned int items_len)
const Type & operator[](int i_) const
void qsort(unsigned int len, unsigned int start=0, unsigned int end=(unsigned int) -1)
const Type & lsearch(unsigned int len, const T &x, const Type &not_found=Null(Type)) const
bool lfind(unsigned int len, const T &x, unsigned int *i=nullptr, hb_not_found_t not_found=HB_NOT_FOUND_DONT_STORE, unsigned int to_store=(unsigned int) -1) const
HB_DELETE_CREATE_COPY_ASSIGN(UnsizedArrayOf)
Type & lsearch(unsigned int len, const T &x, Type &not_found=Crap(Type))
static constexpr unsigned item_size
hb_array_t< const Type > as_array(unsigned int len) const
unsigned int get_size(unsigned int len) const
bool sanitize_shallow(hb_sanitize_context_t *c, unsigned int count) const
bool sanitize(hb_sanitize_context_t *c, unsigned int count, Ts &&... ds) const
bool sanitize(hb_sanitize_context_t *c, unsigned int count, Ts &&... ds) const
const Type & operator[](int i_) const
static constexpr unsigned NO_VARIATION
VarIdx & operator=(uint32_t i)
bool sanitize(hb_sanitize_context_t *c, Ts &&... ds) const
unsigned int get_length() const
HB_DELETE_CREATE_COPY_ASSIGN(VarSizedBinSearchArrayOf)
UnsizedArrayOf< HBUINT8 > bytesZ
const Type & operator[](int i_) const
const Type * bsearch(const T &key) const
unsigned int get_size() const
static constexpr unsigned item_size
VarSizedBinSearchHeader header
bool sanitize(hb_sanitize_context_t *c) const
Definition: main.cpp:38
Definition: moc.h:48
return_t dispatch(const T &obj, Ts &&... ds)
Definition: hb-dispatch.hh:52
QCommandLinkButton * pb