#ifndef CXXFOOZZ_INCLUDE_RANDOM_HPP_ #define CXXFOOZZ_INCLUDE_RANDOM_HPP_ #include #include #include namespace uuid { std::string generate_uuid_v4(); } namespace cxxfoozz { class Random { public: Random(); static const std::shared_ptr &GetInstance(); int NextInt(); int NextInt(int bound); int NextInt(int start, int exclusiveMax); long long NextLong(); bool NextBoolean(); double NextDouble(); double NextDouble(double min, double max); double NextGaussian(); std::string NextString(int minLen = 0, int exclusiveMaxLen = 11); template std::string NextIntGen(); template std::string NextRealGen(); private: static int counter_; static std::shared_ptr instance_; std::default_random_engine engine_; static constexpr double kSpecialValueThreshold = 0.02; template T GetSpecialValue(); }; template std::string Random::NextIntGen() { ++counter_; double gauss = NextGaussian(); if (gauss < kSpecialValueThreshold) return std::to_string((T) GetSpecialValue()); bool is_unsigned = bpstd::is_unsigned_v; if (is_unsigned) { std::uniform_int_distribution dist(0, std::numeric_limits::max()); return std::to_string((T) dist(engine_)); } else { std::uniform_int_distribution dist(std::numeric_limits::min(), std::numeric_limits::max()); return std::to_string((T) dist(engine_)); } } template std::string Random::NextRealGen() { ++counter_; double gauss = NextGaussian(); if (gauss < kSpecialValueThreshold) return std::to_string((T) GetSpecialValue()); std::uniform_real_distribution dist; return std::to_string((T) dist(engine_)); } template T Random::GetSpecialValue() { static std::array special_values{ std::numeric_limits::min(), std::numeric_limits::max(), (T) -5, (T) -4, (T) -3, (T) -2, (T) -1, (T) 0, (T) 1, (T) 2, (T) 3, (T) 4, (T) 5, }; int choice = NextInt(13); return special_values[choice]; } } // namespace cxxfoozz #endif //CXXFOOZZ_INCLUDE_RANDOM_HPP_