32 #ifndef VSMC_UTILITY_COUNTER_HPP
33 #define VSMC_UTILITY_COUNTER_HPP
48 static_cast<T
>(~(
static_cast<T
>(0)));
51 static_cast<T
>(
static_cast<T
>(max_val << 8) >> 8);
54 static_cast<T
>(mask_hi^max_val);
88 template <
typename T, std::
size_t K>
96 static inline void set (ctr_type &ctr,
const ctr_type &c) {ctr = c;}
99 template <std::
size_t Blocks>
107 static inline void reset (ctr_type &ctr)
111 template <std::
size_t Blocks>
123 template <std::
size_t Blocks>
134 ctr.
front() += nskip;
143 if (ctr.
front() <= max_ - nskip) {
144 ctr.
front() += nskip;
148 nskip -= max_ - ctr.
front();
151 ctr.
front() = nskip - 1;
155 template <std::
size_t Blocks>
180 template <std::
size_t>
184 template <std::
size_t N>
187 if (++ctr[Position<N>()] != 0)
190 increment_single<N + 1>(ctr,
191 cxx11::integral_constant<bool, N + 2 < K>());
194 template <std::
size_t, std::
size_t Blocks>
195 static inline void set_block (Array<ctr_type, Blocks> &,
198 template <std::
size_t B, std::
size_t Blocks>
199 static inline void set_block (Array<ctr_type, Blocks> &ctr,
202 T m = ctr[Position<B - 1>()].back() & mask_lo_;
203 m >>=
sizeof(T) * 8 - 8;
205 m <<=
sizeof(T) * 8 - 8;
207 ctr[Position<B>()] = ctr[Position<B - 1>()];
208 ctr[Position<B>()].back() &= mask_hi_;
209 ctr[Position<B>()].back() ^= m;
210 set_block<B + 1>(ctr,
211 cxx11::integral_constant<bool, B + 1 < Blocks>());
214 template <std::
size_t, std::
size_t Blocks>
215 static inline void increment_block (Array<ctr_type, Blocks> &,
218 template <std::
size_t B, std::
size_t Blocks>
219 static inline void increment_block (Array<ctr_type, Blocks> &ctr,
222 increment_block_ctr(ctr[Position<B>()]);
223 increment_block<B + 1>(ctr,
224 cxx11::integral_constant<bool, B + 1 < Blocks>());
227 template <std::
size_t, std::
size_t Blocks>
228 static inline void increment_block (Array<ctr_type, Blocks> &, T,
231 template <std::
size_t B, std::
size_t Blocks>
232 static inline void increment_block (Array<ctr_type, Blocks> &ctr, T nskip,
235 increment_block_ctr(ctr[Position<B>()], nskip);
236 increment_block<B + 1>(ctr, nskip,
237 cxx11::integral_constant<bool, B + 1 < Blocks>());
240 static inline void increment_block_ctr (ctr_type &ctr)
241 {increment_block_single<0>(ctr, cxx11::integral_constant<bool, 1 < K>());}
243 static inline void increment_block_ctr (ctr_type &ctr, T nskip)
245 increment_block_nskip(ctr, nskip,
246 cxx11::integral_constant<
bool, 1 < K>());
249 template <std::
size_t>
250 static inline void increment_block_single (ctr_type &ctr,
253 T m = ctr.back() & mask_lo_;
257 ctr.back() &= mask_hi_;
261 template <std::
size_t N>
262 static inline void increment_block_single (ctr_type &ctr,
265 if (++ctr[Position<N>()] != 0)
268 increment_block_single<N + 1>(ctr,
269 cxx11::integral_constant<bool, N + 2 < K>());
272 static inline void increment_block_nskip (ctr_type &ctr, T nskip,
275 T m = ctr.back() & mask_lo_;
280 if (nskip <= mask_hi_ - b) {
288 nskip -= mask_hi_ - b - 1;
289 while (nskip > mask_hi_)
297 static inline void increment_block_nskip (ctr_type &ctr, T nskip,
304 increment_block_ctr(ctr);
308 if (ctr.front() <= max_ - nskip) {
309 ctr.front() += nskip;
313 nskip -= max_ - ctr.front();
315 increment_block_ctr(ctr);
316 ctr.front() = nskip - 1;
322 #endif // VSMC_UTILITY_COUNTER_HPP
static void set(Array< ctr_type, Blocks > &ctr, const ctr_type &c)
Set a block of counters given the value of the first counter.
static void reset(Array< ctr_type, Blocks > &ctr)
Reset a block of counters with the first set to zero.
#define VSMC_CONSTEXPR
constexpr
static void increment(Array< ctr_type, Blocks > &ctr)
Increment each counter in a block by one.
static void increment(ctr_type &ctr, T nskip)
Increment a counter by a given value.
integral_constant< bool, false > false_type
void * memset(void *dst, int ch, std::size_t n)
SIMD optimized memset with non-temporal store for large buffers.
static void set(ctr_type &ctr, const ctr_type &c)
Set the counter to a given value.
static void reset(ctr_type &ctr)
Reset a counter to zero.
integral_constant< bool, true > true_type
static void increment(Array< ctr_type, Blocks > &ctr, T nskip)
Increment each counter in a block by a given value.
static void increment(ctr_type &ctr)
Increment the counter by one.