diff --git a/cpp/Platform.Random.Tests/RandomExtensionsTests.cpp b/cpp/Platform.Random.Tests/RandomExtensionsTests.cpp index a0d4a94..78b7199 100644 --- a/cpp/Platform.Random.Tests/RandomExtensionsTests.cpp +++ b/cpp/Platform.Random.Tests/RandomExtensionsTests.cpp @@ -24,6 +24,31 @@ ASSERT_LT(theSameCount, 8); } + TEST(RandomExtensionsTests, NextUIntTemplateTest) + { + // Test NextUInt with different unsigned integer types + auto value8 = NextUInt(RandomHelpers::Default); + auto value16 = NextUInt(RandomHelpers::Default); + auto value32 = NextUInt(RandomHelpers::Default); + auto value64 = NextUInt(RandomHelpers::Default); + + // Test with ranges + auto rangedValue8 = NextUInt(RandomHelpers::Default, {0, 10}); + auto rangedValue16 = NextUInt(RandomHelpers::Default, {0, 100}); + auto rangedValue32 = NextUInt(RandomHelpers::Default, {0, 1000}); + auto rangedValue64 = NextUInt(RandomHelpers::Default, {0UL, 10000UL}); + + // Verify ranges + ASSERT_LE(rangedValue8, 10); + ASSERT_GE(rangedValue8, 0); + ASSERT_LE(rangedValue16, 100); + ASSERT_GE(rangedValue16, 0); + ASSERT_LE(rangedValue32, 1000); + ASSERT_GE(rangedValue32, 0); + ASSERT_LE(rangedValue64, 10000UL); + ASSERT_GE(rangedValue64, 0UL); + } + TEST(RandomExtensionsTests, NextBooleanTest) { auto trueCount = 0; diff --git a/cpp/Platform.Random/Platform.Random.h b/cpp/Platform.Random/Platform.Random.h index f66173d..da5c349 100644 --- a/cpp/Platform.Random/Platform.Random.h +++ b/cpp/Platform.Random/Platform.Random.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include diff --git a/cpp/Platform.Random/RandomExtensions.h b/cpp/Platform.Random/RandomExtensions.h index b25a3b3..0d03c66 100644 --- a/cpp/Platform.Random/RandomExtensions.h +++ b/cpp/Platform.Random/RandomExtensions.h @@ -1,8 +1,26 @@ namespace Platform::Random { - std::uint64_t NextUInt64(std::mt19937_64& random, const Ranges::Range& range) { return std::uniform_int_distribution{range.Minimum, range.Maximum}(random); } + template + T NextUInt(std::mt19937_64& random, const Ranges::Range& range) + { + static_assert(std::is_unsigned_v, "T must be an unsigned integer type"); + return std::uniform_int_distribution{range.Minimum, range.Maximum}(random); + } - std::uint64_t NextUInt64(std::mt19937_64& random) { return NextUInt64(random, Ranges::UInt64); } + template + T NextUInt(std::mt19937_64& random) + { + static_assert(std::is_unsigned_v, "T must be an unsigned integer type"); + if constexpr (std::is_same_v) return NextUInt(random, Ranges::UInt8); + else if constexpr (std::is_same_v) return NextUInt(random, Ranges::UInt16); + else if constexpr (std::is_same_v) return NextUInt(random, Ranges::UInt32); + else if constexpr (std::is_same_v) return NextUInt(random, Ranges::UInt64); + else static_assert(std::false_type::value, "Unsupported unsigned integer type"); + } + + std::uint64_t NextUInt64(std::mt19937_64& random, const Ranges::Range& range) { return NextUInt(random, range); } + + std::uint64_t NextUInt64(std::mt19937_64& random) { return NextUInt(random); } bool NextBoolean(std::mt19937_64& random) { return std::uniform_int_distribution{}(random) % 2 == 0; } } diff --git a/examples/syntax_test.cpp b/examples/syntax_test.cpp new file mode 100644 index 0000000..ec9e216 --- /dev/null +++ b/examples/syntax_test.cpp @@ -0,0 +1,64 @@ +#include +#include + +// Mock the Range structure for syntax check +namespace Ranges { + template + struct Range { + T Minimum; + T Maximum; + }; + + inline Range UInt8{0, 255}; + inline Range UInt16{0, 65535}; + inline Range UInt32{0, 4294967295U}; + inline Range UInt64{0UL, 18446744073709551615UL}; +} + +// Copy of our implementation +namespace Platform::Random +{ + template + T NextUInt(std::mt19937_64& random, const Ranges::Range& range) + { + static_assert(std::is_unsigned_v, "T must be an unsigned integer type"); + return std::uniform_int_distribution{range.Minimum, range.Maximum}(random); + } + + template + T NextUInt(std::mt19937_64& random) + { + static_assert(std::is_unsigned_v, "T must be an unsigned integer type"); + if constexpr (std::is_same_v) return NextUInt(random, Ranges::UInt8); + else if constexpr (std::is_same_v) return NextUInt(random, Ranges::UInt16); + else if constexpr (std::is_same_v) return NextUInt(random, Ranges::UInt32); + else if constexpr (std::is_same_v) return NextUInt(random, Ranges::UInt64); + else static_assert(std::false_type::value, "Unsupported unsigned integer type"); + } + + std::uint64_t NextUInt64(std::mt19937_64& random, const Ranges::Range& range) { return NextUInt(random, range); } + + std::uint64_t NextUInt64(std::mt19937_64& random) { return NextUInt(random); } + + bool NextBoolean(std::mt19937_64& random) { return std::uniform_int_distribution{}(random) % 2 == 0; } +} + +int main() { + std::mt19937_64 rng; + + // Test the template functions + auto val8 = Platform::Random::NextUInt(rng); + auto val16 = Platform::Random::NextUInt(rng); + auto val32 = Platform::Random::NextUInt(rng); + auto val64 = Platform::Random::NextUInt(rng); + + // Test with ranges + auto ranged8 = Platform::Random::NextUInt(rng, {0, 10}); + auto ranged64 = Platform::Random::NextUInt(rng, {0UL, 100UL}); + + // Test existing functions still work + auto oldVal = Platform::Random::NextUInt64(rng); + auto oldRanged = Platform::Random::NextUInt64(rng, {0UL, 50UL}); + + return 0; +} \ No newline at end of file diff --git a/examples/syntax_test.o b/examples/syntax_test.o new file mode 100644 index 0000000..6bc3c89 Binary files /dev/null and b/examples/syntax_test.o differ