Remove CDS_RVALUE_SUPPORT, CDS_MOVE_SEMANTICS_SUPPORT macros and emulating code
[libcds.git] / cds / details / numtraits.h
1 //$$CDS-header$$
2
3 #ifndef __CDS_DETAILS_NUMERIC_TRAITS_H
4 #define __CDS_DETAILS_NUMERIC_TRAITS_H
5
6 /*
7     Filename: numtraits.h
8     Created 2007.04.22 by Maxim.Khiszinsky
9
10     Description:
11         Various numeric constants and algorithms
12         Many algorithms are static (compile-time)
13         Result of static algorithm is the constant (enum) called "result".
14
15     Editions:
16         2007.04.22  Maxim.Khiszinsky    Created
17         2007.07.20  Maxim.Khiszinsky    Added functions: exponent2, exp2Ceil
18 */
19
20 namespace cds {
21     /// Some helper compile-time tricks
22     namespace beans {
23
24         // @cond details
25         namespace details {
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 };
29             };
30             template <> struct Exponent2Helper< 1, 0 > {
31                 enum { result = 0 };
32             };
33         }
34         // @endcond
35
36         /*! Compile-time computing of log2(N)
37
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
40         */
41         template <int N> struct Exponent2 {
42             enum {
43                 native    = N,
44                 base    = 2,
45                 result    = details::Exponent2Helper< N / 2, N % 2 >::result + 1
46             };
47         };
48         //@cond details
49         template <> struct Exponent2<1> {
50             enum {
51                 native    = 1,
52                 base    = 2,
53                 result    = 0
54             };
55         };
56         //@endcond
57
58         /// Returns @a N: 2**N is nearest to @p nNumber, 2**N < nNumber
59         static inline size_t exp2Ceil( size_t nNumber )
60         {
61             static_assert( sizeof(size_t) == (CDS_BUILD_BITS / 8), "Internal assumption error" );
62
63             size_t nExp = 0;
64             size_t nBit = CDS_BUILD_BITS - 1;
65 #if CDS_BUILD_BITS == 32
66             size_t nMask = 0x80000000;
67 #else
68             size_t nMask = 0x8000000000000000;
69 #endif
70             while ( nMask != 0 ) {
71                 if ( nNumber & nMask ) {
72                     nExp = nBit;
73                     break;
74                 }
75                 nMask = nMask >> 1;
76                 --nBit;
77             }
78             if ( ( nNumber % ( ((size_t) 1) << nExp )) > ( ((size_t) 1) << (nExp - 1)) )
79                 ++nExp;
80             return nExp;
81         }
82
83         /* ExponentN< int BASE, int N >
84             Exponent
85             If N = BASE**k then the algorithm returns k
86             Else compile-time error is encountered
87         */
88         //@cond details
89         namespace details {
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 };
93             };
94             template <int BASE> struct ExponentNHelper< 1, BASE, 0 > {
95                 enum { result = 0 };
96             };
97         }
98         //@endcond
99
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 {
102             enum {
103                 native    = N,
104                 base    = BASE,
105                 result    = details::ExponentNHelper< N / BASE, BASE, N % BASE >::result + 1
106             };
107         };
108         //@cond
109         template <int BASE> struct ExponentN< BASE, 1 > {
110             enum {
111                 native    = 1,
112                 base    = BASE,
113                 result    = 0
114             };
115         };
116         template <int BASE> struct ExponentN< BASE, 0 >;
117         //@endcond
118
119         //@cond none
120         template <int N> struct Power2 {
121             enum {
122                 exponent = N,
123                 result = 1 << N
124             };
125         };
126         template <> struct Power2<0> {
127             enum {
128                 exponent = 0,
129                 result = 1
130             };
131         };
132         //@endcond
133
134         //@cond none
135         template <int BASE, int N > struct PowerN {
136             enum {
137                 exponent = N,
138                 base     = BASE,
139                 result = PowerN< BASE, N - 1 >::result * BASE
140             };
141         };
142         template <int BASE> struct PowerN<BASE, 0> {
143             enum {
144                 exponent = 0,
145                 base     = BASE,
146                 result     = 1
147             };
148         };
149         //@endcond
150
151         //@cond none
152         namespace details {
153             template <int N, int ALIGN, int MOD> struct NearestCeilHelper {
154                 enum { result = N + ALIGN - MOD };
155             };
156             template <int N, int ALIGN> struct NearestCeilHelper< N, ALIGN, 0> {
157                 enum { result = N };
158             };
159         }
160         template <int N, int ALIGN> struct NearestCeil {
161             enum {
162                 native    = N,
163                 align    = ALIGN,
164                 result    = details::NearestCeilHelper< N, ALIGN, N % ALIGN >::result
165             };
166         };
167         //@endcond
168
169         //@cond none
170         template <typename T, int ALIGN> struct AlignedSize {
171             typedef T    NativeType;
172             enum {
173                 nativeSize    = sizeof(T),
174                 result        = NearestCeil< sizeof(T), ALIGN >::result,
175                 alignBytes    = result - nativeSize,
176                 alignedSize = result
177             };
178         };
179         //@endcond
180
181         //@cond none
182         namespace details {
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  };
187             };
188
189             template < int N1, int N2 >
190             struct Max< N1, N2, false > {
191                 enum { result = N1  };
192             };
193
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  };
198             };
199
200             template < int N1, int N2 >
201             struct Min< N1, N2, false > {
202                 enum { result = N2  };
203             };
204         }
205         //@endcond
206
207         /// Returns max(N1, N2) as Max<N1,N2>::result
208         template <int N1, int N2>
209         struct Max {
210             enum { result = details::Max< N1, N2, N1 < N2 >::result  };
211         };
212
213         /// Returns min(N1, N2) as Min<N1,N2>::result
214         template <int N1, int N2>
215         struct Min {
216             enum { result = details::Min< N1, N2, N1 < N2 >::result  };
217         };
218
219     }    // namespace beans
220 }    // namespace cds
221
222 #endif    // __CDS_DETAILS_NUMERIC_TRAITS_H