diff --git a/include/duckhandy/int_conv.hpp b/include/duckhandy/int_conv.hpp index 6fb4b16..b7edd46 100644 --- a/include/duckhandy/int_conv.hpp +++ b/include/duckhandy/int_conv.hpp @@ -22,11 +22,10 @@ #include #include #include -#include namespace dhandy { namespace implem { - template + template > struct IntConv; template @@ -35,24 +34,21 @@ namespace dhandy { template using IntConvStringView = std::basic_string_view; - template - struct IntConv, IntConvString>, F, SafeRetval, Tr> { + template + struct IntConv, F, Tr, true> { static IntConvString conv (const F& in) { auto retval = dhandy::int_to_ary(in); return IntConvString{retval.begin(), retval.end() - 1}; } }; - template - struct IntConv, IntConvStringView>, F, SafeRetval, Tr> { - constexpr static IntConvStringView conv (const F& in) { - if (std::is_constant_evaluated() or not SafeRetval) - return dhandy::int_to_ary(in).to_string_view(); - else - throw std::logic_error("Only callable in a constexpr context, call int_conv_temporary() instead if you know what you're doing"); + template + struct IntConv, F, Tr, true> { + consteval static IntConvStringView conv (const F& in) { + return dhandy::int_to_ary(in).to_string_view(); } }; - template - struct IntConv, IntConvString>, SafeRetval, Tr> { + template + struct IntConv, Tr, false> { constexpr static T conv (const IntConvString& in) { return dhandy::ary_to_int( in.data(), @@ -60,8 +56,8 @@ namespace dhandy { ); } }; - template - struct IntConv, IntConvStringView>, SafeRetval, Tr> { + template + struct IntConv, Tr, false> { constexpr static T conv (const IntConvStringView& in) { return dhandy::ary_to_int( in.data(), @@ -69,8 +65,8 @@ namespace dhandy { ); } }; - template - struct IntConv, SafeRetval, Tr> { + template + struct IntConv, Tr, FromInt> { constexpr static T conv (const std::integral_constant&) { return dhandy::buildtime_int_to_ary().to_string_view(); } @@ -80,14 +76,14 @@ namespace dhandy { template constexpr inline To int_conv (const From& from, bool all_caps=false) { if (all_caps) - return implem::IntConv>::conv(from); + return implem::IntConv>::conv(from); else - return implem::IntConv>::conv(from); + return implem::IntConv>::conv(from); } - template - constexpr inline To int_conv_temporary (const From& from) { - return implem::IntConv>::conv(from); + template + inline auto int_conv_raw (const From& from) { + return int_to_ary>(from); } } //namespace dhandy diff --git a/test/unit/int_conv_test.cpp b/test/unit/int_conv_test.cpp index f5eef34..d187ae7 100644 --- a/test/unit/int_conv_test.cpp +++ b/test/unit/int_conv_test.cpp @@ -23,6 +23,7 @@ #include #include #include +#include template using int_info_10 = dhandy::implem::int_info; template using int_info_16 = dhandy::implem::int_info; @@ -142,7 +143,7 @@ TEST_CASE ("Check int to char array conversions", "[s2i][int_conv]") { { //Try a random test, which should not compile as constexpr std::mt19937 gen; - gen.seed(1234); + gen.seed(std::time(nullptr)); for (int z = 0; z < 10; ++z) { const int num = gen(); CHECK(int_to_ary(num) == std::to_string(num)); @@ -199,6 +200,30 @@ TEST_CASE ("Check char array to int conversions", "[i2s][int_conv]") { AryConversionTestHelperIns("aAbBc", 0xaabbc, true); } +TEST_CASE ("Check string_view conversions work as expected", "[i2s][int_conv]") { + using dhandy::int_conv; + using dhandy::int_conv_raw; + using std::string_view; + using std::integral_constant; + using std::string; + + constexpr auto str71 = int_conv(integral_constant{}); + CHECK("71" == str71); + + { + //test random number to force non-constexpr + std::mt19937 gen; + gen.seed(std::time(nullptr)); + const int num = gen(); + + const string num_str {int_conv_raw(num).to_string_view()}; + CHECK(num_str == std::to_string(num)); + } + + const auto str123 = int_conv(123); + CHECK("123" == str123); +} + TEST_CASE ("Check upcase/downcase int to array conversions", "[i2s][int_conv]") { using dhandy::int_conv; using std::string_view;