diff --git a/modules/random/include/hephaestus/random/random_object_creator.h b/modules/random/include/hephaestus/random/random_object_creator.h index 74b48d51..aaf24a8f 100644 --- a/modules/random/include/hephaestus/random/random_object_creator.h +++ b/modules/random/include/hephaestus/random/random_object_creator.h @@ -14,6 +14,7 @@ #include #include +#include "hephaestus/utils/concepts.h" #include "hephaestus/utils/exception.h" namespace heph::random { @@ -21,10 +22,7 @@ namespace heph::random { //================================================================================================= // Random boolean creation //================================================================================================= -template -concept IsBoolean = std::is_same_v; - -template +template [[nodiscard]] auto random(std::mt19937_64& mt) -> T { std::bernoulli_distribution dist; return dist(mt); @@ -34,9 +32,9 @@ template // Random integer value creation //================================================================================================= template -concept IsNonBooleanIntegral = std::integral && !std::same_as; +concept NonBooleanIntegralType = std::integral && !BooleanType; -template +template [[nodiscard]] auto random(std::mt19937_64& mt) -> T { std::uniform_int_distribution dist; return dist(mt); @@ -54,10 +52,7 @@ template //================================================================================================= // Random enum creation //================================================================================================= -template -concept IsEnum = std::is_enum_v; - -template +template [[nodiscard]] auto random(std::mt19937_64& mt) -> T { static const auto enum_values = magic_enum::enum_values(); std::uniform_int_distribution dist(0, enum_values.size() - 1); @@ -67,17 +62,8 @@ template //================================================================================================= // Random timestamp creation //================================================================================================= -template -concept IsTimestamp = requires { - typename T::clock; - typename T::duration; - requires std::is_same_v || - std::is_same_v; - requires std::is_same_v>; -}; - namespace internal { -template +template [[nodiscard]] constexpr auto createFinalTimestampOfTheYear() -> T { // The final date of the year is YYYY-12-31. constexpr auto YEAR = std::chrono::year{ Year }; @@ -95,7 +81,7 @@ template } // namespace internal /// Create a random timestamp between year 1970 and the year 2100. -template +template [[nodiscard]] auto random(std::mt19937_64& mt) -> T { static constexpr auto MIN_DURATION = 0; // Start of UNIX epoch time == year 1970. static constexpr auto MAX_YEAR = 2100; @@ -113,11 +99,11 @@ template // Random struct/class creation //================================================================================================= template -concept HasrandomMethod = requires(std::mt19937_64& mt) { +concept HasRandomMethod = requires(std::mt19937_64& mt) { { T::random(mt) } -> std::convertible_to; }; -template +template [[nodiscard]] auto random(std::mt19937_64& mt) -> T { return T::random(mt); } @@ -126,7 +112,7 @@ template // Concept for random creatable types //================================================================================================= template -concept IsRandomCreatable = requires(std::mt19937_64& mt) { +concept RandomCreatable = requires(std::mt19937_64& mt) { { random(mt) } -> std::convertible_to; }; @@ -154,11 +140,8 @@ namespace internal { //================================================================================================= // Random string creation //================================================================================================= -template -concept IsString = std::same_as; - /// Generate a random string of characters, including special case characters and numbers. -template +template [[nodiscard]] auto random(std::mt19937_64& mt, std::optional fixed_size = std::nullopt, bool allow_empty = true) -> T { const auto size = internal::getSize(mt, fixed_size, allow_empty); @@ -179,17 +162,11 @@ template //================================================================================================= // Random vector creation //================================================================================================= -namespace internal { -template -concept IsVector = - requires { typename T::value_type; } && (std::is_same_v>); -} // namespace internal - template -concept IsRandomCreatableVector = internal::IsVector && IsRandomCreatable; +concept RandomCreatableVector = VectorType && RandomCreatable; /// Fill a vector with randomly generated values of type T. -template +template [[nodiscard]] auto random(std::mt19937_64& mt, std::optional fixed_size = std::nullopt, bool allow_empty = true) -> T { const auto size = internal::getSize(mt, fixed_size, allow_empty); diff --git a/modules/random/tests/random_object_creator_tests.cpp b/modules/random/tests/random_object_creator_tests.cpp index 863f3f26..780eadc2 100644 --- a/modules/random/tests/random_object_creator_tests.cpp +++ b/modules/random/tests/random_object_creator_tests.cpp @@ -84,7 +84,7 @@ TYPED_TEST(RandomTypeTests, RandomnessTest) { // case, as it is already included in testing for randomness. Repeadedly creating an empty container would // fail the RandomnessTest. TYPED_TEST(RandomTypeTests, ContainerSizeTest) { - if constexpr (IsRandomCreatableVector || IsString) { + if constexpr (RandomCreatableVector || StringType) { auto mt = createRNG(); static constexpr std::size_t SIZE_ZERO = 0; diff --git a/modules/utils/include/hephaestus/utils/concepts.h b/modules/utils/include/hephaestus/utils/concepts.h index e4e96f7d..37641114 100644 --- a/modules/utils/include/hephaestus/utils/concepts.h +++ b/modules/utils/include/hephaestus/utils/concepts.h @@ -18,6 +18,12 @@ concept ScalarType = std::is_scalar_v; template concept EnumType = std::is_enum_v; +template +concept BooleanType = std::is_same_v; + +template +concept StringType = std::is_same_v; + template concept ArrayType = requires { typename T::value_type; @@ -47,6 +53,28 @@ concept ChronoSystemClockType = std::is_same_v; template concept ChronoSteadyClockType = std::is_same_v; +template +concept ChronoClock = ChronoSystemClockType || ChronoSteadyClockType; + +template +concept ChronoSystemClockTimestampType = requires { + typename T::clock; + typename T::duration; + requires std::is_same_v; + requires std::is_same_v>; +}; + +template +concept ChronoSteadyClockTimestampType = requires { + typename T::clock; + typename T::duration; + requires std::is_same_v; + requires std::is_same_v>; +}; + +template +concept ChronoTimestampType = ChronoSystemClockTimestampType || ChronoSteadyClockTimestampType; + template concept NumericType = (std::integral || std::floating_point)&&!std::same_as;