3 #ifndef __CDS_DETAILS_NUMERIC_TRAITS_H
4 #define __CDS_DETAILS_NUMERIC_TRAITS_H
8 Created 2007.04.22 by Maxim.Khiszinsky
11 Various numeric constants and algorithms
12 Many algorithms are static (compile-time)
13 Result of static algorithm is the constant (enum) called "result".
16 2007.04.22 Maxim.Khiszinsky Created
17 2007.07.20 Maxim.Khiszinsky Added functions: exponent2, exp2Ceil
21 /// Some helper compile-time tricks
26 template <int N, int MOD> struct Exponent2Helper;
27 template <int N> struct Exponent2Helper< N, 0 > {
28 enum { result = Exponent2Helper< N / 2, N % 2 >::result + 1 };
30 template <> struct Exponent2Helper< 1, 0 > {
36 /*! Compile-time computing of log2(N)
38 If N = 2**k for some natural k then Exponent2<N>::result = k
39 If N != 2**k for any natural k then compile-time error has been encountered
41 template <int N> struct Exponent2 {
45 result = details::Exponent2Helper< N / 2, N % 2 >::result + 1
49 template <> struct Exponent2<1> {
58 /// Returns @a N: 2**N is nearest to @p nNumber, 2**N < nNumber
59 static inline size_t exp2Ceil( size_t nNumber )
61 static_assert( sizeof(size_t) == (CDS_BUILD_BITS / 8), "Internal assumption error" );
64 size_t nBit = CDS_BUILD_BITS - 1;
65 #if CDS_BUILD_BITS == 32
66 size_t nMask = 0x80000000;
68 size_t nMask = 0x8000000000000000;
70 while ( nMask != 0 ) {
71 if ( nNumber & nMask ) {
78 if ( ( nNumber % ( ((size_t) 1) << nExp )) > ( ((size_t) 1) << (nExp - 1)) )
83 /* ExponentN< int BASE, int N >
85 If N = BASE**k then the algorithm returns k
86 Else compile-time error is encountered
90 template <int N, int BASE, int MOD> struct ExponentNHelper;
91 template <int N, int BASE> struct ExponentNHelper< N, BASE, 0 > {
92 enum { result = ExponentNHelper< N / BASE, BASE, N % BASE >::result + 1 };
94 template <int BASE> struct ExponentNHelper< 1, BASE, 0 > {
100 /// Compile-time computing log(@p N) based @p BASE. Result in @a Exponent<BASE, N>::result
101 template <int BASE, int N> struct ExponentN {
105 result = details::ExponentNHelper< N / BASE, BASE, N % BASE >::result + 1
109 template <int BASE> struct ExponentN< BASE, 1 > {
116 template <int BASE> struct ExponentN< BASE, 0 >;
120 template <int N> struct Power2 {
126 template <> struct Power2<0> {
135 template <int BASE, int N > struct PowerN {
139 result = PowerN< BASE, N - 1 >::result * BASE
142 template <int BASE> struct PowerN<BASE, 0> {
153 template <int N, int ALIGN, int MOD> struct NearestCeilHelper {
154 enum { result = N + ALIGN - MOD };
156 template <int N, int ALIGN> struct NearestCeilHelper< N, ALIGN, 0> {
160 template <int N, int ALIGN> struct NearestCeil {
164 result = details::NearestCeilHelper< N, ALIGN, N % ALIGN >::result
170 template <typename T, int ALIGN> struct AlignedSize {
171 typedef T NativeType;
173 nativeSize = sizeof(T),
174 result = NearestCeil< sizeof(T), ALIGN >::result,
175 alignBytes = result - nativeSize,
183 template < int N1, int N2, bool LESS > struct Max;
184 template < int N1, int N2 >
185 struct Max< N1, N2, true > {
186 enum { result = N2 };
189 template < int N1, int N2 >
190 struct Max< N1, N2, false > {
191 enum { result = N1 };
194 template < int N1, int N2, bool LESS > struct Min;
195 template < int N1, int N2 >
196 struct Min< N1, N2, true > {
197 enum { result = N1 };
200 template < int N1, int N2 >
201 struct Min< N1, N2, false > {
202 enum { result = N2 };
207 /// Returns max(N1, N2) as Max<N1,N2>::result
208 template <int N1, int N2>
210 enum { result = details::Max< N1, N2, N1 < N2 >::result };
213 /// Returns min(N1, N2) as Min<N1,N2>::result
214 template <int N1, int N2>
216 enum { result = details::Min< N1, N2, N1 < N2 >::result };
222 #endif // __CDS_DETAILS_NUMERIC_TRAITS_H