Thrill  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
clz.hpp
Go to the documentation of this file.
1 /*******************************************************************************
2  * tlx/math/clz.hpp
3  *
4  * clz() count leading zeros - mainly for portability.
5  *
6  * Part of tlx - http://panthema.net/tlx
7  *
8  * Copyright (C) 2017 Timo Bingmann <[email protected]>
9  *
10  * All rights reserved. Published under the Boost Software License, Version 1.0
11  ******************************************************************************/
12 
13 #ifndef TLX_MATH_CLZ_HEADER
14 #define TLX_MATH_CLZ_HEADER
15 
16 #ifdef _MSC_VER
17 #include <intrin.h>
18 #endif
19 
20 namespace tlx {
21 
22 //! \addtogroup tlx_math
23 //! \{
24 
25 /******************************************************************************/
26 // clz() - count leading zeros
27 
28 //! clz (count leading zeros) - generic implementation
29 template <typename Integral>
30 static inline unsigned clz_template(Integral x) {
31  if (x == 0) return 8 * sizeof(x);
32  unsigned r = 0;
33  while ((x & (static_cast<Integral>(1) << (8 * sizeof(x) - 1))) == 0)
34  x <<= 1, ++r;
35  return r;
36 }
37 
38 /******************************************************************************/
39 
40 template <typename Integral>
41 inline unsigned clz(Integral x);
42 
43 #if defined(__GNUC__) || defined(__clang__)
44 
45 //! clz (count leading zeros)
46 template <>
47 inline unsigned clz<unsigned>(unsigned i) {
48  return static_cast<unsigned>(__builtin_clz(i));
49 }
50 
51 //! clz (count leading zeros)
52 template <>
53 inline unsigned clz<int>(int i) {
54  return clz(static_cast<unsigned>(i));
55 }
56 
57 //! clz (count leading zeros)
58 template <>
59 inline unsigned clz<unsigned long>(unsigned long i) {
60  return static_cast<unsigned>(__builtin_clzl(i));
61 }
62 
63 //! clz (count leading zeros)
64 template <>
65 inline unsigned clz<long>(long i) {
66  return clz(static_cast<unsigned long>(i));
67 }
68 
69 //! clz (count leading zeros)
70 template <>
71 inline unsigned clz<unsigned long long>(unsigned long long i) {
72  return static_cast<unsigned>(__builtin_clzll(i));
73 }
74 
75 //! clz (count leading zeros)
76 template <>
77 inline unsigned clz<long long>(long long i) {
78  return clz(static_cast<unsigned long long>(i));
79 }
80 
81 #elif defined(_MSC_VER)
82 
83 //! clz (count leading zeros)
84 template <typename Integral>
85 inline unsigned clz<unsigned>(Integral i) {
86  unsigned long leading_zeros = 0;
87  if (sizeof(i) > 4) {
88  if (_BitScanReverse64(&leading_zeros, i))
89  return 63 - leading_zeros;
90  else
91  return 8 * sizeof(i);
92  }
93  else {
94  if (_BitScanReverse(&leading_zeros, static_cast<unsigned>(i)))
95  return 31 - leading_zeros;
96  else
97  return 8 * sizeof(i);
98  }
99 }
100 
101 #else
102 
103 //! clz (count leading zeros)
104 template <>
105 inline unsigned clz<int>(int i) {
106  return clz_template(i);
107 }
108 
109 //! clz (count leading zeros)
110 template <>
111 inline unsigned clz<unsigned>(unsigned i) {
112  return clz_template(i);
113 }
114 
115 //! clz (count leading zeros)
116 template <>
117 inline unsigned clz<long>(long i) {
118  return clz_template(i);
119 }
120 
121 //! clz (count leading zeros)
122 template <>
123 inline unsigned clz<unsigned long>(unsigned long i) {
124  return clz_template(i);
125 }
126 
127 //! clz (count leading zeros)
128 template <>
129 inline unsigned clz<long long>(long long i) {
130  return clz_template(i);
131 }
132 
133 //! clz (count leading zeros)
134 template <>
135 inline unsigned clz<unsigned long long>(unsigned long long i) {
136  return clz_template(i);
137 }
138 
139 #endif
140 
141 //! \}
142 
143 } // namespace tlx
144 
145 #endif // !TLX_MATH_CLZ_HEADER
146 
147 /******************************************************************************/
unsigned clz(Integral x)
unsigned clz< unsigned long >(unsigned long i)
clz (count leading zeros)
Definition: clz.hpp:123
unsigned clz< unsigned >(unsigned i)
clz (count leading zeros)
Definition: clz.hpp:111
list x
Definition: gen_data.py:39
unsigned clz< long long >(long long i)
clz (count leading zeros)
Definition: clz.hpp:129
static unsigned clz_template(Integral x)
clz (count leading zeros) - generic implementation
Definition: clz.hpp:30
unsigned clz< int >(int i)
clz (count leading zeros)
Definition: clz.hpp:105
unsigned clz< unsigned long long >(unsigned long long i)
clz (count leading zeros)
Definition: clz.hpp:135
unsigned clz< long >(long i)
clz (count leading zeros)
Definition: clz.hpp:117