12#ifndef _TPF_CHRONO_RANDOM_HPP
13#define _TPF_CHRONO_RANDOM_HPP
20 #if _MSVC_LANG < 201703L
21 #error This libary requires C++17 Standard (Visual Studio 2017).
25 #if __cplusplus < 201703
26 #error This library requires C++17 Standard (GNU g++ version 8.0 or clang++ version 8.0 above)
50 namespace chrono_random
59 template<
typename TimeUnit>
60 using duration_t = std::chrono::duration<double, TimeUnit>;
70 using time_point_t = std::chrono::time_point<high_resolution_clock_t>;
79 using std::chrono::duration;
80 using std::chrono::duration_cast;
83 duration_cast<std::chrono::milliseconds>(
now().time_since_epoch());
85 return current.count();
89 template<
typename TimeUnit>
94 using std::chrono::duration;
95 using std::chrono::duration_cast;
97 if constexpr(std::is_same_v<TimeUnit, second_t>)
100 duration_cast<std::chrono::duration<double, second_t>>(end_time - start_time);
101 return period_of_time.count();
105 auto period_of_time =
106 duration_cast<std::chrono::duration<double, TimeUnit>>(end_time - start_time);
108 return period_of_time.count();
114 template<
typename IntegralType,
115 typename Type = std::enable_if_t<types::is_integral_v<IntegralType>>>
117 std::uniform_int_distribution<IntegralType>;
119 template<
typename RealType,
120 typename Type = std::enable_if_t<types::is_real_number_v<RealType>>>
122 std::uniform_real_distribution<RealType>;
136 template<
typename TimeUnit = milli_t>
139 auto rlt = time_difference_in_unit<TimeUnit>(this->m_start_time,
now());
144 template<
typename TimeUnit = milli_t>
145 std::string
elapsed_time(
bool bReset =
true, TimeUnit dummy_time = TimeUnit{})
const
147 std::ostringstream os;
149 os << time_difference_in_unit<TimeUnit>(this->m_start_time,
now());
151 if constexpr(std::is_same_v<TimeUnit, nano_t>)
152 os <<
" nano-seconds";
153 else if constexpr(std::is_same_v<TimeUnit, micro_t>)
154 os <<
" micro-seconds";
155 else if constexpr(std::is_same_v<TimeUnit, milli_t>)
156 os <<
" milli-seconds";
157 else if constexpr(std::is_same_v<TimeUnit, second_t>)
159 else if constexpr(std::is_same_v<TimeUnit, minute_t>)
161 else if constexpr(std::is_same_v<TimeUnit, hour_t>)
169 template<
typename Type,
170 typename = std::enable_if_t<tpf::types::is_integral_v<Type>>>
175 std::random_device m_rd;
176 std::mt19937 m_randomizer;
177 typename std::vector<Type>::iterator m_next;
178 std::vector<Type> m_array;
183 m_array((
end-start)*instance), m_rd{}, m_randomizer{ m_rd() }
185 auto diff =
end - start;
187 for(
size_t i = 0; i < m_array.size(); ++i )
188 m_array[i] = (i % diff) + start;
193 typename std::vector<Type>::iterator
begin() {
return this->m_array.begin(); };
194 typename std::vector<Type>::iterator
end() {
return this->m_array.end(); };
195 typename std::vector<Type>::iterator
next() {
return this->m_next; };
197 size_t size() {
return m_array.size(); }
201 std::shuffle(m_array.begin(), m_array.end(), m_randomizer);
202 this->m_next = m_array.begin();
207 if(this->m_next == m_array.end())
210 Type v = *this->m_next;
217 return this->m_array;
221 template<
typename Type,
222 typename DistributionType,
typename EngineType>
229 mutable Type m_range_start;
230 mutable Type m_range_end;
236 Type range_end = Type{100},
237 unsigned int seed = 0):
238 m_range_start{range_start},
239 m_range_end{range_end},
241 m_distribution{range_start, range_end} {}
248 return m_distribution(m_engine);
251 template<
typename SizeType>
252 auto clone(SizeType size)
const;
254 template<
typename SizeType>
258 template<
typename IntegralType,
259 typename Type = std::enable_if_t<types::is_integral_v<IntegralType>>>
263 template<
typename RealType,
264 typename Type = std::enable_if_t<types::is_real_number_v<RealType>>>
268 template<
typename ValueType,
typename RangeType1,
typename RangeType2>
271 if constexpr(tpf::types::is_integral_v<ValueType>)
278 else if constexpr(tpf::types::is_real_number_v<ValueType>)
287 template<
typename Type,
288 typename DistributionType,
typename EngineType>
289 template<
typename SizeType>
295 std::vector<random_type> randoms;
296 randoms.reserve((
size_t)size);
299 random_generator<unsigned>((
unsigned)1,
300 std::numeric_limits<unsigned>::max());
302 std::set<unsigned> seeds;
303 while(seeds.size() != (
size_t)size)
305 seeds.insert(generator());
308 for(
auto seed: seeds)
309 randoms.emplace_back(random_type{this->m_range_start,
310 this->m_range_end,
seed});
315 template<
typename Type,
316 typename DistributionType,
typename EngineType>
317 template<
typename SizeType>
322 using random_pair = std::pair<size_t, random_type>;
324 std::vector<random_pair> randoms;
325 randoms.reserve((
size_t)size);
328 random_generator<unsigned>((
unsigned)1,
329 std::numeric_limits<unsigned>::max());
331 std::set<unsigned> seeds;
332 while(seeds.size() != (
size_t)size)
334 seeds.insert(generator());
339 for(
auto seed: seeds)
340 randoms.emplace_back(index++, random_type{this->m_range_start,
341 this->m_range_end,
seed});
346 template<
template<
typename,
typename...>
class ContainerType,
347 typename Type,
typename RType,
typename... Types,
348 template<
typename,
typename...>
class RandomGeneratorType,
typename... RTypes>
352 if(container.empty())
355 for(
auto& e: container)
359 template<
typename Type, std::
size_t N,
typename RandomGeneratorType>
362 for(
auto& e: container)
366 template<
typename Type, std::
size_t M, std::
size_t N,
typename RandomGeneratorType>
369 using array_t = Type[M * N];
370 auto& array = (array_t&)container[0][0];
375 template<
typename Type, std::
size_t L, std::
size_t M, std::
size_t N,
typename RandomGeneratorType>
378 using array_t = Type[L * M * N];
379 auto& array = (array_t&)container[0][0];
384 template<
template<
typename, std::
size_t>
class ContainerType,
385 typename Type, std::size_t N,
typename RType,
386 template<
typename,
typename...>
class RandomGeneratorType,
typename... RTypes>
390 if(container.empty())
393 for(
auto& e: container)
397 template<
template<
typename,
typename...>
class ContainerType,
398 typename Type,
typename... Types,
typename RandomGeneratorType>
402 if(container.empty())
405 for(
auto& e: container)
409 template<
template<
typename,
typename...>
class ContainerType,
410 typename Type,
typename... Types,
typename RType,
411 template<
typename,
typename...>
class RandomGeneratorType,
typename... RTypes>
415 if(container.empty())
return;
417 size_t container_size = container.size();
418 size_t generator_size = std::thread::hardware_concurrency();
419 size_t span = container_size / generator_size;
427 if(container_size % generator_size ) ++generator_size;
429 auto generator_pairs =
432 std::for_each(std::execution::par,
433 generator_pairs.begin(), generator_pairs.end(),
436 auto index_start = pair.first * span;
437 auto index_end = index_start + span;
439 if(index_end > container_size) index_end = container_size;
441 for(size_t i = index_start; i < index_end; ++i)
442 container[i] = (Type)pair.second();
446 template<
typename Type, std::size_t N,
447 template<
typename,
typename...>
class RandomGeneratorType,
typename RType,
typename... RTypes>
451 size_t container_size = N;
452 size_t generator_size = std::thread::hardware_concurrency();
453 size_t span = container_size / generator_size;
461 if(container_size % generator_size ) ++generator_size;
463 auto generator_pairs =
466 std::for_each(std::execution::par,
467 generator_pairs.begin(), generator_pairs.end(),
470 auto index_start = pair.first * span;
471 auto index_end = index_start + span;
473 if(index_end > container_size) index_end = container_size;
475 for(size_t i = index_start; i < index_end; ++i)
476 container[i] = (Type)pair.second();
480 template<
typename Type, std::size_t M, std::size_t N,
481 template<
typename,
typename...>
class RandomGeneratorType,
typename RType,
typename... RTypes>
485 using array_t = Type[M * N];
486 auto& array = (array_t&)container[0][0];
491 template<
typename Type, std::size_t L, std::size_t M, std::size_t N,
492 template<
typename,
typename...>
class RandomGeneratorType,
typename RType,
typename... RTypes>
496 using array_t = Type[L * M * N];
497 auto& array = (array_t&)container[0][0][0];
503 template<
template<
typename, std::
size_t>
class ContainerType,
504 typename Type, std::size_t N,
typename RType,
505 template<
typename,
typename...>
class RandomGeneratorType,
typename... RTypes>
509 if(container.empty())
return;
511 size_t container_size = container.size();
512 size_t generator_size = std::thread::hardware_concurrency();
513 size_t span = container_size / generator_size;
521 if(container_size % generator_size ) ++generator_size;
523 auto generator_pairs =
526 std::for_each(std::execution::par,
527 generator_pairs.begin(), generator_pairs.end(),
530 auto index_start = pair.first * span;
531 auto index_end = index_start + span;
533 if(index_end > container_size) index_end = container_size;
535 for(size_t i = index_start; i < index_end; ++i)
536 container[i] = (Type)pair.second();
540 template<
template<
typename,
typename...>
class ContainerType,
541 typename Type,
typename... Types,
542 typename RandomGeneratorType>
546 if(container.empty())
return;
548 size_t container_size = container.size();
549 size_t generator_size = std::thread::hardware_concurrency();
550 size_t span = container_size / generator_size;
558 if(container_size % generator_size ) ++generator_size;
560 auto generator_pairs =
563 std::for_each(std::execution::par,
564 generator_pairs.begin(), generator_pairs.end(),
567 auto index_start = pair.first * span;
568 auto index_end = index_start + span;
570 if(index_end > container_size) index_end = container_size;
572 for(size_t i = index_start; i < index_end; ++i)
573 container[i] = pair.second();
593 template<
template<
typename,
typename...>
class ContainerType,
594 typename Type,
typename... Types,
typename SizeType,
595 template<
typename,
typename...>
class RandomGeneratorType,
typename... RTypes>
597 const RandomGeneratorType<Type, RTypes...>&
random_generator, SizeType size)
601 container.resize((
size_t)size);
603 for(
auto& e: container)
610 while(container.size() != size)
617 template<
typename CharType,
size_t Size>
628 template<
typename Type,
size_t ArraySize>
630 const Type(&alphabet)[ArraySize]):
631 m_alphabet{alphabet},
639 if constexpr(std::is_same_v<CharType, char>)
641 std::basic_ostringstream<CharType>
stream;
643 auto word_count = m_wordcount_selector();
645 for(
size_t j = 0; j < word_count; ++j)
647 auto length = this->m_length_selector();
649 std::basic_string<CharType> text(length,
' ');
651 for(
size_t i=0; i < length; ++i)
652 text[i] = m_alphabet[m_character_selector()];
656 if(j + 1 != (
size_t)word_count)
stream <<
' ';
663 std::basic_ostringstream<CharType>
stream;
665 auto word_count = m_wordcount_selector();
667 for(
size_t j = 0; j < word_count; ++j)
669 auto length = this->m_length_selector();
671 std::basic_string<CharType> text(length, L
' ');
673 for(
size_t i=0; i < length; ++i)
674 text[i] = m_alphabet[m_character_selector()];
678 if(j + 1 != (
size_t)word_count)
stream << L
' ';
690 template<
typename Type,
size_t ArraySize>
std::vector< Type >::iterator end()
std::vector< Type >::iterator begin()
fair_dice(Type start, Type end, Type instance=1)
const std::vector< Type > & array()
std::vector< Type >::iterator next()
random_t(Type range_start=Type{}, Type range_end=Type{100}, unsigned int seed=0)
auto clone_pair(SizeType size) const
DistributionType distribution_type
random_t & operator=(const random_t &)=default
auto clone(SizeType size) const
random_t(const random_t &)=default
random_words(size_t minimum, size_t maximum, size_t max_words, const Type(&alphabet)[ArraySize])
random_uniform_integer_t< size_t > m_wordcount_selector
const CharType * m_alphabet
random_uniform_integer_t< size_t > m_length_selector
random_uniform_integer_t< size_t > m_character_selector
std::basic_string< char > operator()()
std::string elapsed_time(bool bReset=true, TimeUnit dummy_time=TimeUnit{}) const
auto elapsed(bool bReset=true) const
std::uniform_int_distribution< IntegralType > random_uniform_integral_distribution
duration_t< nano_t > nanoseconds_t
std::ratio< 3600 > hour_t
auto random_generator(RangeType1 range_start, RangeType2 range_end)
std::chrono::duration< double, TimeUnit > duration_t
duration_t< second_t > seconds_t
std::chrono::time_point< high_resolution_clock_t > time_point_t
unsigned int get_current_tick()
duration_t< micro_t > microseconds_t
duration_t< milli_t > milliseconds_t
double time_difference_in_unit(const time_point_t &start_time, const time_point_t &end_time)
std::chrono::high_resolution_clock high_resolution_clock_t
void random_parallel_fill(ContainerType< Type, Types... > &container, const RandomGeneratorType< RType, RTypes... > &random_generator)
random_words(int, int, int, const Type(&)[ArraySize]) -> random_words< Type, ArraySize >
std::uniform_real_distribution< RealType > random_uniform_real_distribution
duration_t< hour_t > hours_t
std::default_random_engine random_engine_t
duration_t< minute_t > minutes_t
std::ratio< 60 > minute_t
void random_fill(ContainerType< Type, Types... > &container, const RandomGeneratorType< RType, RTypes... > &random_generator)
std::string wstring_to_string(const std::wstring &wstr, unsigned int codepage=CP_UTF8)
Converts from std::wstring to std::string with codepage.
constexpr bool is_resize_available_v
void push_back(ContainerType< Type, Types... > &container, EleType &&ele)
Includes subnamespace conversion.
auto minimum(Type_1 a, Type_2 b)
auto maximum(Type_1 a, Type_2 b)
String conversions are implemented.
Type functions are implemented.