3 #ifndef __CDS_NUMERIC_TRAITS_H
4 #define __CDS_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 //TODO - deprecated. Use is_power2 from int_algo.h
59 /// A tricky runtime algorithm to ensure that @p n is power of 2
60 static inline bool isExp2( size_t n )
62 return(n & (n - 1)) == 0 && n;
65 //TODO: deprecated. Use log2 from int_algo.h
66 /// Runtime algorithm to compute log2( @p nTest ). If @p nTest is not power of two then -1 returns
67 static inline int exponent2( size_t nTest )
71 for ( size_t n = 0; n < CDS_BUILD_BITS; n++ ) {
72 if ( nTest & nMask ) {
76 return -1 ; // nTest íå ÿâëÿåòñÿ ñòåïåíüþ äâîéêè
83 /// Returns @a N: 2**N is nearest to @p nNumber, 2**N < nNumber
84 static inline size_t exp2Ceil( size_t nNumber )
86 static_assert( sizeof(size_t) == (CDS_BUILD_BITS / 8), "Internal assumption error" );
89 size_t nBit = CDS_BUILD_BITS - 1;
90 #if CDS_BUILD_BITS == 32
91 size_t nMask = 0x80000000;
93 size_t nMask = 0x8000000000000000;
95 while ( nMask != 0 ) {
96 if ( nNumber & nMask ) {
103 if ( ( nNumber % ( ((size_t) 1) << nExp )) > ( ((size_t) 1) << (nExp - 1)) )
108 /* ExponentN< int BASE, int N >
110 If N = BASE**k then the algorithm returns k
111 Else compile-time error is encountered
115 template <int N, int BASE, int MOD> struct ExponentNHelper;
116 template <int N, int BASE> struct ExponentNHelper< N, BASE, 0 > {
117 enum { result = ExponentNHelper< N / BASE, BASE, N % BASE >::result + 1 };
119 template <int BASE> struct ExponentNHelper< 1, BASE, 0 > {
125 /// Compile-time computing log(@p N) based @p BASE. Result in @a Exponent<BASE, N>::result
126 template <int BASE, int N> struct ExponentN {
130 result = details::ExponentNHelper< N / BASE, BASE, N % BASE >::result + 1
134 template <int BASE> struct ExponentN< BASE, 1 > {
141 template <int BASE> struct ExponentN< BASE, 0 >;
145 template <int N> struct Power2 {
151 template <> struct Power2<0> {
160 template <int BASE, int N > struct PowerN {
164 result = PowerN< BASE, N - 1 >::result * BASE
167 template <int BASE> struct PowerN<BASE, 0> {
178 template <int N, int ALIGN, int MOD> struct NearestCeilHelper {
179 enum { result = N + ALIGN - MOD };
181 template <int N, int ALIGN> struct NearestCeilHelper< N, ALIGN, 0> {
185 template <int N, int ALIGN> struct NearestCeil {
189 result = details::NearestCeilHelper< N, ALIGN, N % ALIGN >::result
195 template <typename T, int ALIGN> struct AlignedSize {
196 typedef T NativeType;
198 nativeSize = sizeof(T),
199 result = NearestCeil< sizeof(T), ALIGN >::result,
200 alignBytes = result - nativeSize,
208 template < int N1, int N2, bool LESS > struct Max;
209 template < int N1, int N2 >
210 struct Max< N1, N2, true > {
211 enum { result = N2 };
214 template < int N1, int N2 >
215 struct Max< N1, N2, false > {
216 enum { result = N1 };
219 template < int N1, int N2, bool LESS > struct Min;
220 template < int N1, int N2 >
221 struct Min< N1, N2, true > {
222 enum { result = N1 };
225 template < int N1, int N2 >
226 struct Min< N1, N2, false > {
227 enum { result = N2 };
232 /// Returns max(N1, N2) as Max<N1,N2>::result
233 template <int N1, int N2>
235 enum { result = details::Max< N1, N2, N1 < N2 >::result };
238 /// Returns min(N1, N2) as Min<N1,N2>::result
239 template <int N1, int N2>
241 enum { result = details::Min< N1, N2, N1 < N2 >::result };
247 #endif // __CDS_NUMERIC_TRAITS_H