From 422b475ce3aa1da8d50ea29620ed221497cf7738 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Fri, 28 May 2021 02:06:28 +0200 Subject: [PATCH] Add support for constexpr string_view creation --- include/duckhandy/implem/int_conv.hpp | 8 ++++ include/duckhandy/int_conv.hpp | 63 ++++++++++++++++++--------- test/unit/int_conv_test.cpp | 24 ++++++++++ 3 files changed, 74 insertions(+), 21 deletions(-) diff --git a/include/duckhandy/implem/int_conv.hpp b/include/duckhandy/implem/int_conv.hpp index d7c8782..5dc8903 100644 --- a/include/duckhandy/implem/int_conv.hpp +++ b/include/duckhandy/implem/int_conv.hpp @@ -168,6 +168,9 @@ namespace dhandy { } }; + template + inline constexpr const auto g_int_to_str = IntConversion, Base, Tr>::to_ary(In); + template [[gnu::always_inline,gnu::pure]] constexpr inline T negated_ifn (T n, bool negate) { @@ -293,6 +296,11 @@ namespace dhandy { template using ASCIITranslatorUpcase = ASCIITranslator; + template > + constexpr inline const auto& buildtime_int_to_ary() { + return implem::g_int_to_str; + } + template > constexpr inline auto int_to_ary (I in) { return implem::IntConversion, Base, Tr>::to_ary(in); diff --git a/include/duckhandy/int_conv.hpp b/include/duckhandy/int_conv.hpp index a9fd3a7..6fb4b16 100644 --- a/include/duckhandy/int_conv.hpp +++ b/include/duckhandy/int_conv.hpp @@ -26,47 +26,68 @@ namespace dhandy { namespace implem { - template + template struct IntConv; - template - struct IntConv, std::string>, F, SafeRetval> { - static std::string conv (const F& in) { - auto retval = dhandy::int_to_ary(in); - return std::string(retval.begin(), retval.end() - 1); + template + using IntConvString = std::basic_string; + + template + using IntConvStringView = std::basic_string_view; + + template + struct IntConv, IntConvString>, F, SafeRetval, Tr> { + static IntConvString conv (const F& in) { + auto retval = dhandy::int_to_ary(in); + return IntConvString{retval.begin(), retval.end() - 1}; } }; - template - struct IntConv, std::string_view>, F, SafeRetval> { - constexpr static std::string_view conv (const F& in) { + 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(); + 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, std::string>, SafeRetval> { - constexpr static T conv (const std::string& in) { - return dhandy::ary_to_int(in.data(), in.data() + in.size()); + template + struct IntConv, IntConvString>, SafeRetval, Tr> { + constexpr static T conv (const IntConvString& in) { + return dhandy::ary_to_int( + in.data(), + in.data() + in.size() + ); } }; - template - struct IntConv, std::string_view>, SafeRetval> { - constexpr static T conv (const std::string_view& in) { - return dhandy::ary_to_int(in.data(), in.data() + in.size()); + template + struct IntConv, IntConvStringView>, SafeRetval, Tr> { + constexpr static T conv (const IntConvStringView& in) { + return dhandy::ary_to_int( + in.data(), + in.data() + in.size() + ); + } + }; + template + struct IntConv, SafeRetval, Tr> { + constexpr static T conv (const std::integral_constant&) { + return dhandy::buildtime_int_to_ary().to_string_view(); } }; } //namespace implem template - constexpr inline To int_conv (const From& from) { - return implem::IntConv::conv(from); + constexpr inline To int_conv (const From& from, bool all_caps=false) { + if (all_caps) + return implem::IntConv>::conv(from); + else + return implem::IntConv>::conv(from); } template constexpr inline To int_conv_temporary (const From& from) { - return implem::IntConv::conv(from); + return implem::IntConv>::conv(from); } } //namespace dhandy diff --git a/test/unit/int_conv_test.cpp b/test/unit/int_conv_test.cpp index ebbe445..cfe9276 100644 --- a/test/unit/int_conv_test.cpp +++ b/test/unit/int_conv_test.cpp @@ -171,3 +171,27 @@ TEST_CASE ("Check char array to int conversions", "[i2s][int_conv]") { AryConversionTestHelper("-1", -1, false); AryConversionTestHelper("-510123123123", -510123123123, false); } + +TEST_CASE ("Check upcase/downcase int to array conversions", "[i2s][int_conv]") { + using dhandy::int_conv; + using std::string_view; + using std::integral_constant; + + constexpr auto bool1 = int_conv(integral_constant{}); + CHECK("1" == bool1); + + constexpr auto bool2 = int_conv(integral_constant{}); + CHECK("0" == bool2); + + constexpr auto int1 = int_conv(integral_constant{}); + CHECK("42" == int1); + + constexpr auto int2 = int_conv(integral_constant{}); + CHECK("7777777" == int2); + + constexpr auto int3 = int_conv(integral_constant{}); + CHECK("-1234" == int3); + + constexpr auto int4 = int_conv(integral_constant{}); + CHECK("-256" == int4); +}