MCKL
Monte Carlo Kernel Library
increment_generic.hpp
Go to the documentation of this file.
1 //============================================================================
2 // MCKL/include/mckl/random/internal/increment_generic.hpp
3 //----------------------------------------------------------------------------
4 // MCKL: Monte Carlo Kernel Library
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2018, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
32 #ifndef MCKL_RANDOM_INTERNAL_INCREMENT_GENERIC_HPP
33 #define MCKL_RANDOM_INTERNAL_INCREMENT_GENERIC_HPP
34 
36 
37 namespace mckl {
38 
39 namespace internal {
40 
41 template <std::size_t, typename T, std::size_t K>
42 inline void increment1(std::array<T, K> &, std::false_type)
43 {
44 }
45 
46 template <std::size_t N, typename T, std::size_t K>
47 inline void increment1(std::array<T, K> &ctr, std::true_type)
48 {
49  if (++std::get<N>(ctr)) {
50  return;
51  }
52 
53  increment1<N + 1>(ctr, std::integral_constant<bool, N + 1 < K>());
54 }
55 
56 template <typename T, std::size_t K>
57 class Increment
58 {
59  public:
60  static void eval(std::array<T, K> &ctr)
61  {
62  internal::increment1<0>(ctr, std::true_type());
63  }
64 }; // class Increment
65 
66 template <typename T>
67 class Increment<T, 1>
68 {
69  public:
70  static void eval(std::array<T, 1> &ctr) { ++std::get<0>(ctr); }
71 }; // class Increment
72 
73 template <typename T>
74 class Increment<T, 2>
75 {
76  public:
77  static void eval(std::array<T, 2> &ctr)
78  {
79  if (++std::get<0>(ctr)) {
80  return;
81  }
82  ++std::get<1>(ctr);
83  }
84 }; // class Increment
85 
86 template <typename T>
87 class Increment<T, 4>
88 {
89  public:
90  static void eval(std::array<T, 4> &ctr)
91  {
92  if (++std::get<0>(ctr)) {
93  return;
94  }
95  if (++std::get<1>(ctr)) {
96  return;
97  }
98  if (++std::get<2>(ctr)) {
99  return;
100  }
101  ++std::get<3>(ctr);
102  }
103 }; // class Increment
104 
105 template <typename T>
106 class Increment<T, 8>
107 {
108  public:
109  static void eval(std::array<T, 8> &ctr)
110  {
111  if (++std::get<0>(ctr)) {
112  return;
113  }
114  if (++std::get<1>(ctr)) {
115  return;
116  }
117  if (++std::get<2>(ctr)) {
118  return;
119  }
120  if (++std::get<3>(ctr)) {
121  return;
122  }
123  if (++std::get<4>(ctr)) {
124  return;
125  }
126  if (++std::get<5>(ctr)) {
127  return;
128  }
129  if (++std::get<6>(ctr)) {
130  return;
131  }
132  ++std::get<7>(ctr);
133  }
134 }; // class Increment
135 
136 template <typename T>
137 class Increment<T, 16>
138 {
139  public:
140  static void eval(std::array<T, 16> &ctr)
141  {
142  if (++std::get<0x0>(ctr)) {
143  return;
144  }
145  if (++std::get<0x1>(ctr)) {
146  return;
147  }
148  if (++std::get<0x2>(ctr)) {
149  return;
150  }
151  if (++std::get<0x3>(ctr)) {
152  return;
153  }
154  if (++std::get<0x4>(ctr)) {
155  return;
156  }
157  if (++std::get<0x5>(ctr)) {
158  return;
159  }
160  if (++std::get<0x6>(ctr)) {
161  return;
162  }
163  if (++std::get<0x7>(ctr)) {
164  return;
165  }
166  if (++std::get<0x8>(ctr)) {
167  return;
168  }
169  if (++std::get<0x9>(ctr)) {
170  return;
171  }
172  if (++std::get<0xA>(ctr)) {
173  return;
174  }
175  if (++std::get<0xB>(ctr)) {
176  return;
177  }
178  if (++std::get<0xC>(ctr)) {
179  return;
180  }
181  if (++std::get<0xD>(ctr)) {
182  return;
183  }
184  if (++std::get<0xE>(ctr)) {
185  return;
186  }
187  ++std::get<0xF>(ctr);
188  }
189 }; // class Increment
190 
191 } // namespace internal
192 
195 template <typename T, std::size_t K, T NSkip>
196 inline void increment(std::array<T, K> &ctr, std::integral_constant<T, NSkip>)
197 {
198  if (std::get<0>(ctr) < std::numeric_limits<T>::max() - NSkip) {
199  std::get<0>(ctr) += NSkip;
200  } else {
201  std::get<0>(ctr) += NSkip;
202  internal::increment1<1>(ctr, std::integral_constant<bool, 1 < K>());
203  }
204 }
205 
208 template <typename T, std::size_t K>
209 inline void increment(std::array<T, K> &ctr, T nskip)
210 {
211  if (std::get<0>(ctr) < std::numeric_limits<T>::max() - nskip) {
212  std::get<0>(ctr) += nskip;
213  } else {
214  std::get<0>(ctr) += nskip;
215  internal::increment1<1>(ctr, std::integral_constant<bool, 1 < K>());
216  }
217 }
218 
219 namespace internal {
220 
221 template <typename T, std::size_t K, std::size_t Blocks>
223 {
224  public:
225  static void eval(
226  std::array<T, K> &ctr, std::array<std::array<T, K>, Blocks> &ctr_block)
227  {
228  eval<0>(ctr, ctr_block, std::integral_constant<bool, 0 < Blocks>());
229  }
230 
231  private:
232  template <std::size_t>
233  static void eval(std::array<T, K> &,
234  std::array<std::array<T, K>, Blocks> &, std::false_type)
235  {
236  }
237 
238  template <std::size_t N>
239  static void eval(std::array<T, K> &ctr,
240  std::array<std::array<T, K>, Blocks> &ctr_block, std::true_type)
241  {
243  std::get<N>(ctr_block) = ctr;
244  eval<N + 1>(
245  ctr, ctr_block, std::integral_constant<bool, N + 1 < Blocks>());
246  }
247 }; // class IncrementBlock
248 
249 template <typename T, std::size_t K>
250 class IncrementBlock<T, K, 1>
251 {
252  public:
253  static void eval(
254  std::array<T, K> &ctr, std::array<std::array<T, K>, 1> &ctr_block)
255  {
257  std::get<0>(ctr_block) = ctr;
258  }
259 }; // class IncrementBlock
260 
261 template <typename T, std::size_t K>
262 class IncrementBlock<T, K, 2>
263 {
264  public:
265  static void eval(
266  std::array<T, K> &ctr, std::array<std::array<T, K>, 2> &ctr_block)
267  {
268  std::get<0>(ctr_block) = ctr;
269  std::get<1>(ctr_block) = ctr;
270  increment(std::get<0>(ctr_block), std::integral_constant<T, 1>());
271  increment(std::get<1>(ctr_block), std::integral_constant<T, 2>());
272  ctr = std::get<1>(ctr_block);
273  }
274 }; // class IncrementBlock
275 
276 template <typename T, std::size_t K>
277 class IncrementBlock<T, K, 4>
278 {
279  public:
280  static void eval(
281  std::array<T, K> &ctr, std::array<std::array<T, K>, 4> &ctr_block)
282  {
283  std::get<0>(ctr_block) = ctr;
284  std::get<1>(ctr_block) = ctr;
285  std::get<2>(ctr_block) = ctr;
286  std::get<3>(ctr_block) = ctr;
287  increment(std::get<0>(ctr_block), std::integral_constant<T, 1>());
288  increment(std::get<1>(ctr_block), std::integral_constant<T, 2>());
289  increment(std::get<2>(ctr_block), std::integral_constant<T, 3>());
290  increment(std::get<3>(ctr_block), std::integral_constant<T, 4>());
291  ctr = std::get<3>(ctr_block);
292  }
293 }; // class IncrementBlock
294 
295 template <typename T, std::size_t K>
296 class IncrementBlock<T, K, 8>
297 {
298  public:
299  static void eval(
300  std::array<T, K> &ctr, std::array<std::array<T, K>, 8> &ctr_block)
301  {
302  std::get<0>(ctr_block) = ctr;
303  std::get<1>(ctr_block) = ctr;
304  std::get<2>(ctr_block) = ctr;
305  std::get<3>(ctr_block) = ctr;
306  std::get<4>(ctr_block) = ctr;
307  std::get<5>(ctr_block) = ctr;
308  std::get<6>(ctr_block) = ctr;
309  std::get<7>(ctr_block) = ctr;
310  increment(std::get<0>(ctr_block), std::integral_constant<T, 1>());
311  increment(std::get<1>(ctr_block), std::integral_constant<T, 2>());
312  increment(std::get<2>(ctr_block), std::integral_constant<T, 3>());
313  increment(std::get<3>(ctr_block), std::integral_constant<T, 4>());
314  increment(std::get<4>(ctr_block), std::integral_constant<T, 5>());
315  increment(std::get<5>(ctr_block), std::integral_constant<T, 6>());
316  increment(std::get<6>(ctr_block), std::integral_constant<T, 7>());
317  increment(std::get<7>(ctr_block), std::integral_constant<T, 8>());
318  ctr = std::get<7>(ctr_block);
319  }
320 }; // class IncrementBlock
321 
322 template <typename T, std::size_t K>
323 class IncrementBlock<T, K, 16>
324 {
325  public:
326  static void eval(
327  std::array<T, K> &ctr, std::array<std::array<T, K>, 16> &ctr_block)
328  {
329  std::get<0x0>(ctr_block) = ctr;
330  std::get<0x1>(ctr_block) = ctr;
331  std::get<0x2>(ctr_block) = ctr;
332  std::get<0x3>(ctr_block) = ctr;
333  std::get<0x4>(ctr_block) = ctr;
334  std::get<0x5>(ctr_block) = ctr;
335  std::get<0x6>(ctr_block) = ctr;
336  std::get<0x7>(ctr_block) = ctr;
337  std::get<0x8>(ctr_block) = ctr;
338  std::get<0x9>(ctr_block) = ctr;
339  std::get<0xA>(ctr_block) = ctr;
340  std::get<0xB>(ctr_block) = ctr;
341  std::get<0xC>(ctr_block) = ctr;
342  std::get<0xD>(ctr_block) = ctr;
343  std::get<0xE>(ctr_block) = ctr;
344  std::get<0xF>(ctr_block) = ctr;
345  increment(std::get<0x0>(ctr_block), std::integral_constant<T, 0x01>());
346  increment(std::get<0x1>(ctr_block), std::integral_constant<T, 0x02>());
347  increment(std::get<0x2>(ctr_block), std::integral_constant<T, 0x03>());
348  increment(std::get<0x3>(ctr_block), std::integral_constant<T, 0x04>());
349  increment(std::get<0x4>(ctr_block), std::integral_constant<T, 0x05>());
350  increment(std::get<0x5>(ctr_block), std::integral_constant<T, 0x06>());
351  increment(std::get<0x6>(ctr_block), std::integral_constant<T, 0x07>());
352  increment(std::get<0x7>(ctr_block), std::integral_constant<T, 0x08>());
353  increment(std::get<0x8>(ctr_block), std::integral_constant<T, 0x09>());
354  increment(std::get<0x9>(ctr_block), std::integral_constant<T, 0x0A>());
355  increment(std::get<0xA>(ctr_block), std::integral_constant<T, 0x0B>());
356  increment(std::get<0xB>(ctr_block), std::integral_constant<T, 0x0C>());
357  increment(std::get<0xC>(ctr_block), std::integral_constant<T, 0x0D>());
358  increment(std::get<0xD>(ctr_block), std::integral_constant<T, 0x0E>());
359  increment(std::get<0xE>(ctr_block), std::integral_constant<T, 0x0F>());
360  increment(std::get<0xF>(ctr_block), std::integral_constant<T, 0x10>());
361  ctr = std::get<0xF>(ctr_block);
362  }
363 }; // class IncrementBlock
364 
365 } // namespace internal
366 
369 template <typename T, std::size_t K>
370 MCKL_INLINE inline void increment(std::array<T, K> &ctr)
371 {
373 }
374 
378 template <typename T, std::size_t K, std::size_t Blocks>
379 inline void increment(
380  std::array<T, K> &ctr, std::array<std::array<T, K>, Blocks> &ctr_block)
381 {
383 }
384 
385 } // namespace mckl
386 
387 #endif // MCKL_RANDOM_INTERNAL_INCREMENT_GENERIC_HPP
static void eval(std::array< T, K > &ctr)
static void eval(std::array< T, 4 > &ctr)
static void eval(std::array< T, K > &ctr, std::array< std::array< T, K >, Blocks > &ctr_block)
void increment1(std::array< T, K > &, std::false_type)
static void eval(std::array< T, 8 > &ctr)
static void eval(std::array< T, 2 > &ctr)
static void eval(std::array< T, K > &ctr, std::array< std::array< T, K >, 4 > &ctr_block)
static void eval(std::array< T, K > &ctr, std::array< std::array< T, K >, 16 > &ctr_block)
void increment(std::array< T, K > &ctr, std::integral_constant< T, NSkip >)
Increment a counter by given steps.
static void eval(std::array< T, 1 > &ctr)
static void eval(std::array< T, K > &ctr, std::array< std::array< T, K >, 8 > &ctr_block)
static void eval(std::array< T, 16 > &ctr)
Definition: mcmc.hpp:40
static void eval(std::array< T, K > &ctr, std::array< std::array< T, K >, 1 > &ctr_block)
#define MCKL_INLINE
Definition: clang.h:147
static void eval(std::array< T, K > &ctr, std::array< std::array< T, K >, 2 > &ctr_block)