FastUIDraw
util.hpp
Go to the documentation of this file.
1 /*!
2  * \file util.hpp
3  * \brief file util.hpp
4  *
5  * Adapted from: WRATHUtil.hpp and type_tag.hpp of WRATH:
6  *
7  * Copyright 2013 by Nomovok Ltd.
8  * Contact: info@nomovok.com
9  * This Source Code Form is subject to the
10  * terms of the Mozilla Public License, v. 2.0.
11  * If a copy of the MPL was not distributed with
12  * this file, You can obtain one at
13  * http://mozilla.org/MPL/2.0/.
14  *
15  * \author Kevin Rogovin <kevin.rogovin@nomovok.com>
16  * \author Kevin Rogovin <kevin.rogovin@gmail.com>
17  *
18  */
19 
20 
21 #ifndef FASTUIDRAW_UTIL_HPP
22 #define FASTUIDRAW_UTIL_HPP
23 
24 #include <stdint.h>
25 #include <stddef.h>
26 
27 
28 /*!\addtogroup Utility
29  * @{
30  */
31 
32 /*!
33  * Macro to round up an uint32_t to a multiple or 4
34  */
35 #define FASTUIDRAW_ROUND_UP_MULTIPLE_OF4(X) (((X) + 3u) & ~3u)
36 
37 /*!
38  * Macro to return how many blocks of size 4 to contain
39  * a given size, i.e. the smallest integer N so that
40  * 4 * N >= X where X is an uint32_t.
41  */
42 #define FASTUIDRAW_NUMBER_BLOCK4_NEEDED(X) (FASTUIDRAW_ROUND_UP_MULTIPLE_OF4(X) >> 2u)
43 
44 /*!\def FASTUIDRAW_MAX_VALUE_FROM_NUM_BITS
45  * Macro that gives the maximum value that can be
46  * held with a given number of bits. Caveat:
47  * if X is 32 (or higher), bad things may happen
48  * from overflow.
49  * \param X number bits
50  */
51 #define FASTUIDRAW_MAX_VALUE_FROM_NUM_BITS(X) ( (uint32_t(1) << uint32_t(X)) - uint32_t(1) )
52 
53 /*!\def FASTUIDRAW_MASK
54  * Macro that generates a 32-bit mask from number
55  * bits and location of bit0 to use
56  * \param BIT0 first bit of mask
57  * \param NUMBITS nuber bits of mask
58  */
59 #define FASTUIDRAW_MASK(BIT0, NUMBITS) (FASTUIDRAW_MAX_VALUE_FROM_NUM_BITS(NUMBITS) << uint32_t(BIT0))
60 
61 /*!\def FASTUIDRAW_MAX_VALUE_FROM_NUM_BITS_U64
62  * Macro that gives the maximum value that can be
63  * held with a given number of bits, returning an
64  * unsigned 64-bit integer.
65  * \param X number bits
66  */
67 #define FASTUIDRAW_MAX_VALUE_FROM_NUM_BITS_U64(X) ( (uint64_t(1) << uint64_t(X)) - uint64_t(1) )
68 
69 /*!\def FASTUIDRAW_MASK_U64
70  * Macro that generates a 64-bit mask from number
71  * bits and location of bit0 to use
72  * \param BIT0 first bit of mask
73  * \param NUMBITS nuber bits of mask
74  */
75 #define FASTUIDRAW_MASK_U64(BIT0, NUMBITS) (FASTUIDRAW_MAX_VALUE_FROM_NUM_BITS_U64(NUMBITS) << uint64_t(BIT0))
76 
77 /*!\def FASTUIDRAWunused
78  * Macro to stop the compiler from reporting
79  * an argument as unused. Typically used on
80  * those arguments used in FASTUIDRAWassert invocation
81  * but otherwise unused.
82  * \param X expression of which to ignore the value
83  */
84 #define FASTUIDRAWunused(X) do { (void)(X); } while(0)
85 
86 /*!\def FASTUIDRAWassert
87  * If FASTUIDRAW_DEBUG is defined, checks if the statement
88  * is true and if it is not true prints to std::cerr and
89  * then aborts. If FastUIDRAW_DEBUG is not defined, then
90  * macro is empty (and thus the condition is not evaluated).
91  * \param X condition to check
92  */
93 #ifdef FASTUIDRAW_DEBUG
94 #define FASTUIDRAWassert(X) do { \
95  if (!(X)) { \
96  fastuidraw::assert_fail("Assertion '" #X "' failed", __FILE__, __LINE__); \
97  } } while(0)
98 #else
99 #define FASTUIDRAWassert(X)
100 #endif
101 
102 /*!\def FASTUIDRAWmessaged_assert
103  * Regardless FASTUIDRAW_DEBUG is defined or not, checks if
104  * the statement is true and if it is not true prints to
105  * std::cerr. If FASTUIDRAW_DEBUG is defined also aborts.
106  * \param X condition to check
107  * \param Y string to print if condition is false
108  */
109 #define FASTUIDRAWmessaged_assert(X, Y) do { \
110  if (!(X)) { \
111  fastuidraw::assert_fail(Y, __FILE__, __LINE__); \
112  } } while(0)
113 
114 /*!\def FASTUIDRAWstatic_assert
115  * Conveniance for using static_assert where message
116  * is the condition stringified.
117  */
118 #define FASTUIDRAWstatic_assert(X) static_assert(X, #X)
119 
120 namespace fastuidraw
121 {
122  /*!
123  * Private function used by macro FASTUIDRAWassert, do NOT call.
124  */
125  void
126  assert_fail(const char *str, const char *file, int line);
127 }
128 
129 namespace fastuidraw
130 {
131  /*!
132  * \brief
133  * Conveniant typedef for C-style strings.
134  */
135  typedef const char *c_string;
136 
137  /*!
138  * \brief
139  * Enumeration for simple return codes for functions
140  * for success or failure.
141  */
143  {
144  /*!
145  * Routine failed
146  */
148 
149  /*!
150  * Routine suceeded
151  */
153  };
154 
155  /*!
156  * Returns the floor of the log2 of an unsinged integer,
157  * i.e. the value K so that 2^K <= x < 2^{K+1}
158  */
159  uint32_t
160  uint32_log2(uint32_t v);
161 
162  /*!
163  * Returns the floor of the log2 of an unsinged integer,
164  * i.e. the value K so that 2^K <= x < 2^{K+1}
165  */
166  uint64_t
167  uint64_log2(uint64_t v);
168 
169  /*!
170  * Returns the number of bits required to hold a 32-bit
171  * unsigned integer value.
172  */
173  uint32_t
174  number_bits_required(uint32_t v);
175 
176  /*!
177  * Returns the number of bits required to hold a 32-bit
178  * unsigned integer value.
179  */
180  uint64_t
181  uint64_number_bits_required(uint64_t v);
182 
183  /*!
184  * Returns true if a uint32_t is
185  * an exact non-zero power of 2.
186  * \param v uint32_t to query
187  */
188  inline
189  bool
190  is_power_of_2(uint32_t v)
191  {
192  return v && !(v & (v - uint32_t(1u)));
193  }
194 
195  /*!
196  * Returns true if a uint64_t is
197  * an exact non-zero power of 2.
198  * \param v uint64_t to query
199  */
200  inline
201  bool
203  {
204  return v && !(v & (v - uint64_t(1u)));
205  }
206 
207  /*!
208  * Given v > 0, compute N so that N is a power
209  * of 2 and so that N / 2 < v <= N. When v is 0,
210  * returns 0.
211  */
212  inline
213  uint32_t
214  next_power_of_2(uint32_t v)
215  {
216  /* taken from Bithacks */
217  --v;
218  v |= v >> 1u;
219  v |= v >> 2u;
220  v |= v >> 4u;
221  v |= v >> 8u;
222  v |= v >> 16u;
223  ++v;
224 
225  return v;
226  }
227 
228  /*!
229  * Given v > 0, compute N so that N is a power
230  * of 2 and so that N / 2 < v <= N. When v is 0,
231  * returns 0.
232  */
233  inline
234  uint64_t
236  {
237  /* taken from Bithacks */
238  --v;
239  v |= v >> 1u;
240  v |= v >> 2u;
241  v |= v >> 4u;
242  v |= v >> 8u;
243  v |= v >> 16u;
244  v |= v >> 32u;
245  ++v;
246 
247  return v;
248  }
249 
250  /*!
251  * Given if a bit should be up or down returns
252  * an input value with that bit made to be up
253  * or down.
254  * \param input_value value to return with the named bit(s) changed
255  * \param to_apply if true, return value has bits made up, otherwise has bits down
256  * \param bitfield_value bits to make up or down as according to to_apply
257  */
258  inline
259  uint32_t
260  apply_bit_flag(uint32_t input_value, bool to_apply,
261  uint32_t bitfield_value)
262  {
263  return to_apply ?
264  input_value | bitfield_value:
265  input_value & (~bitfield_value);
266  }
267 
268  /*!
269  * Given if a bit should be up or down returns
270  * an input value with that bit made to be up
271  * or down.
272  * \param input_value value to return with the named bit(s) changed
273  * \param to_apply if true, return value has bits made up, otherwise has bits down
274  * \param bitfield_value bits to make up or down as according to to_apply
275  */
276  inline
277  uint64_t
278  uint64_apply_bit_flag(uint64_t input_value, bool to_apply,
279  uint64_t bitfield_value)
280  {
281  return to_apply ?
282  input_value | bitfield_value:
283  input_value & (~bitfield_value);
284  }
285 
286  /*!
287  * Pack the lowest N bits of a value at a bit.
288  * \param bit0 bit location of return value at which to pack
289  * \param num_bits number of bits from value to pack
290  * \param value value to pack
291  */
292  inline
293  uint32_t
294  pack_bits(uint32_t bit0, uint32_t num_bits, uint32_t value)
295  {
296  uint32_t mask;
297  mask = (1u << num_bits) - 1u;
298  FASTUIDRAWassert(bit0 + num_bits <= 32u);
299  FASTUIDRAWassert(value <= mask);
300  return (value & mask) << bit0;
301  }
302 
303  /*!
304  * Pack the lowest N bits of a value at a bit.
305  * \param bit0 bit location of return value at which to pack
306  * \param num_bits number of bits from value to pack
307  * \param value value to pack
308  */
309  inline
310  uint64_t
311  uint64_pack_bits(uint64_t bit0, uint64_t num_bits, uint64_t value)
312  {
313  uint64_t mask;
314  mask = (uint64_t(1u) << num_bits) - uint64_t(1u);
315  FASTUIDRAWassert(bit0 + num_bits <= 64u);
316  FASTUIDRAWassert(value <= mask);
317  return (value & mask) << bit0;
318  }
319 
320  /*!
321  * Unpack N bits from a bit location.
322  * \param bit0 starting bit from which to unpack
323  * \param num_bits number bits to unpack
324  * \param value value from which to unpack
325  */
326  inline
327  uint32_t
328  unpack_bits(uint32_t bit0, uint32_t num_bits, uint32_t value)
329  {
330  FASTUIDRAWassert(bit0 + num_bits <= 32u);
331 
332  uint32_t mask;
333  mask = (uint32_t(1u) << num_bits) - uint32_t(1u);
334  return (value >> bit0) & mask;
335  }
336 
337  /*!
338  * Unpack N bits from a bit location.
339  * \param bit0 starting bit from which to unpack
340  * \param num_bits number bits to unpack
341  * \param value value from which to unpack
342  */
343  inline
344  uint64_t
345  uint64_unpack_bits(uint64_t bit0, uint64_t num_bits, uint64_t value)
346  {
347  FASTUIDRAWassert(bit0 + num_bits <= 64u);
348 
349  uint64_t mask;
350  mask = (uint64_t(1u) << num_bits) - uint64_t(1u);
351  return (value >> bit0) & mask;
352  }
353 
354  /*!
355  * Returns a float pack into a 32-bit unsigned integer.
356  * \param f value to pack
357  */
358  inline
359  uint32_t
360  pack_float(float f)
361  {
362  // casting to const char* first
363  // prevents from breaking stricting
364  // aliasing rules
365  const char *q;
366  q = reinterpret_cast<const char*>(&f);
367  return *reinterpret_cast<const uint32_t*>(q);
368  }
369 
370  /*!
371  * Unpack a float from a 32-bit unsigned integer.
372  * \param v value from which to unpack
373  */
374  inline
375  float
376  unpack_float(uint32_t v)
377  {
378  // casting to const char* first
379  // prevents from breaking stricting
380  // aliasing rules
381  const char * q;
382  q = reinterpret_cast<const char*>(&v);
383  return *reinterpret_cast<const float*>(q);
384  }
385 
386  /*!
387  * \brief
388  * A class reprenting the STL range
389  * [m_begin, m_end).
390  */
391  template<typename T>
393  {
394  public:
395  /*!
396  * Typedef to identify template argument type
397  */
398  typedef T type;
399 
400  /*!
401  * Iterator to first element
402  */
403  type m_begin;
404 
405  /*!
406  * iterator to one past the last element
407  */
408  type m_end;
409 
410  /*!
411  * Ctor.
412  * \param b value with which to initialize m_begin
413  * \param e value with which to initialize m_end
414  */
415  range_type(T b, T e):
416  m_begin(b),
417  m_end(e)
418  {}
419 
420  /*!
421  * Empty ctor, m_begin and m_end are uninitialized.
422  */
424  {}
425 
426  /*!
427  * Provided as a conveniance, equivalent to
428  * \code
429  * m_end - m_begin
430  * \endcode
431  */
432  template<typename W = T>
433  W
434  difference(void) const
435  {
436  return m_end - m_begin;
437  }
438 
439  /*!
440  * Increment both \ref m_begin and \ref m_end.
441  * \param v value by which to increment
442  */
443  template<typename W>
444  void
445  operator+=(const W &v)
446  {
447  m_begin += v;
448  m_end += v;
449  }
450 
451  /*!
452  * Decrement both \ref m_begin and \ref m_end.
453  * \param v value by which to decrement
454  */
455  template<typename W>
456  void
457  operator-=(const W &v)
458  {
459  m_begin -= v;
460  m_end -= v;
461  }
462 
463  /*!
464  * Make sure that \ref m_begin is no more than \ref m_end,
465  * requires that the type T supports comparison < operator
466  * and assignment = operator.
467  */
468  void
469  sanitize(void)
470  {
471  if (m_end < m_begin)
472  {
473  T t;
474  t = m_end;
475  m_end = m_begin;
476  m_begin = m_end;
477  }
478  }
479  };
480 
481  /*!
482  * For type T's which support comparison swap, makes
483  * sure that the returned \ref range_type has that
484  * range_type::m_begin < range_type::m_end
485  */
486  template<typename T>
488  create_range(T a, T b)
489  {
490  if (a < b)
491  {
492  return range_type<T>(a, b);
493  }
494  else
495  {
496  return range_type<T>(b, a);
497  }
498  }
499 
500  /*!
501  * \brief
502  * Class for which copy ctor and assignment operator
503  * are private functions.
504  */
506  {
507  public:
508  noncopyable(void)
509  {}
510 
511  private:
512  noncopyable(const noncopyable &obj) = delete;
513 
514  noncopyable&
515  operator=(const noncopyable &rhs) = delete;
516  };
517 
518  /*!
519  * \brief
520  * Class for type traits to indicate true.
521  * Functionally, a simplified version of
522  * std::true_type.
523  */
524  class true_type
525  {
526  public:
527  /*!
528  * Typedef for value_type.
529  */
530  typedef bool value_type;
531 
532  /*!
533  * constexpr for the value.
534  */
535  static constexpr value_type value = true;
536 
537  /*!
538  * implicit cast operator to bool to return false.
539  */
540  constexpr value_type operator()() const noexcept
541  {
542  return false;
543  }
544  };
545 
546  /*!
547  * \brief
548  * Class for type traits to indicate true.
549  * Functionally, a simplified version of
550  * std::false_type.
551  */
553  {
554  public:
555  /*!
556  * Typedef for value_type.
557  */
558  typedef bool value_type;
559 
560  /*!
561  * constexpr for the value.
562  */
563  static constexpr value_type value = false;
564 
565  /*!
566  * implicit cast operator to bool to return false.
567  */
568  constexpr value_type operator()() const noexcept
569  {
570  return false;
571  }
572  };
573 
574  /*!
575  * Provideds functionality of std::remove_const so
576  * that we do not depend on std.
577  */
578  template<typename T>
580  {
581  public:
582  /*!
583  * The type of \ref type will be the same
584  * as T but with the const-ness removed.
585  */
586  typedef T type;
587  };
588 
589  /*!
590  * Provideds functionality of std::remove_const so
591  * that we do not depend on std.
592  */
593  template<typename T>
594  class remove_const<T const>
595  {
596  public:
597  /*!
598  * The type of \ref type will be the same
599  * as T but with the const-ness removed.
600  */
601  typedef T type;
602  };
603 
604  /*!
605  * Provideds functionality of std::is_const so
606  * that we do not depend on std.
607  */
608  template<typename T>
609  class is_const : public false_type
610  {
611  };
612 
613  ///@cond
614  template<typename T>
615  class is_const<T const> : public true_type
616  {
617  };
618  ///@endcond
619 
620  /*!
621  * Typedef to give same const-ness of type T
622  * to a type S.
623  */
624  template<typename T, typename S>
626  {
627  public:
628  /*!
629  * The type of \ref type will be the same
630  * as S but with the const-ness of T.
631  */
632  typedef typename remove_const<S>::type type;
633  };
634 
635  ///@cond
636  template<typename T, typename S>
637  class same_const<T const, S>
638  {
639  public:
640  typedef typename remove_const<S>::type const type;
641  };
642  ///@endcond
643 
644 }
645 /*! @} */
646 
647 #endif
uint32_t unpack_bits(uint32_t bit0, uint32_t num_bits, uint32_t value)
Definition: util.hpp:328
Class for type traits to indicate true. Functionally, a simplified version of std::true_type.
Definition: util.hpp:524
void sanitize(void)
Definition: util.hpp:469
uint32_t uint32_log2(uint32_t v)
bool uint64_is_power_of_2(uint64_t v)
Definition: util.hpp:202
all classes and functions of FastUIDraw are in the namespace fastuidraw.
Definition: colorstop.hpp:28
void operator+=(const W &v)
Definition: util.hpp:445
uint32_t number_bits_required(uint32_t v)
return_code
Enumeration for simple return codes for functions for success or failure.
Definition: util.hpp:142
constexpr value_type operator()() const noexcept
Definition: util.hpp:568
uint64_t uint64_log2(uint64_t v)
uint64_t uint64_unpack_bits(uint64_t bit0, uint64_t num_bits, uint64_t value)
Definition: util.hpp:345
range_type< T > create_range(T a, T b)
Definition: util.hpp:488
uint32_t next_power_of_2(uint32_t v)
Definition: util.hpp:214
W difference(void) const
Definition: util.hpp:434
bool is_power_of_2(uint32_t v)
Definition: util.hpp:190
uint64_t uint64_number_bits_required(uint64_t v)
uint64_t uint64_apply_bit_flag(uint64_t input_value, bool to_apply, uint64_t bitfield_value)
Definition: util.hpp:278
uint32_t pack_float(float f)
Definition: util.hpp:360
float unpack_float(uint32_t v)
Definition: util.hpp:376
uint32_t pack_bits(uint32_t bit0, uint32_t num_bits, uint32_t value)
Definition: util.hpp:294
Class for type traits to indicate true. Functionally, a simplified version of std::false_type.
Definition: util.hpp:552
remove_const< S >::type type
Definition: util.hpp:632
A class reprenting the STL range [m_begin, m_end).
Definition: util.hpp:392
const char * c_string
Conveniant typedef for C-style strings.
Definition: util.hpp:135
uint64_t uint64_pack_bits(uint64_t bit0, uint64_t num_bits, uint64_t value)
Definition: util.hpp:311
void assert_fail(const char *str, const char *file, int line)
uint32_t apply_bit_flag(uint32_t input_value, bool to_apply, uint32_t bitfield_value)
Definition: util.hpp:260
Class for which copy ctor and assignment operator are private functions.
Definition: util.hpp:505
void operator-=(const W &v)
Definition: util.hpp:457
#define FASTUIDRAWassert(X)
Definition: util.hpp:99
uint64_t uint64_next_power_of_2(uint64_t v)
Definition: util.hpp:235
range_type(T b, T e)
Definition: util.hpp:415
constexpr value_type operator()() const noexcept
Definition: util.hpp:540