Add support for constexpr string_view creation
This commit is contained in:
parent
e62da38cf9
commit
422b475ce3
3 changed files with 74 additions and 21 deletions
|
@ -168,6 +168,9 @@ namespace dhandy {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename I, I In, unsigned int Base, typename Tr>
|
||||
inline constexpr const auto g_int_to_str = IntConversion<std::remove_cvref_t<I>, Base, Tr>::to_ary(In);
|
||||
|
||||
template <typename T>
|
||||
[[gnu::always_inline,gnu::pure]]
|
||||
constexpr inline T negated_ifn (T n, bool negate) {
|
||||
|
@ -293,6 +296,11 @@ namespace dhandy {
|
|||
template <typename C>
|
||||
using ASCIITranslatorUpcase = ASCIITranslator<C, '0', 'A'>;
|
||||
|
||||
template <typename I, I In, unsigned int Base=10, typename Tr=ASCIITranslator<char>>
|
||||
constexpr inline const auto& buildtime_int_to_ary() {
|
||||
return implem::g_int_to_str<I, In, Base, Tr>;
|
||||
}
|
||||
|
||||
template <typename I, unsigned int Base=10, typename Tr=ASCIITranslator<char>>
|
||||
constexpr inline auto int_to_ary (I in) {
|
||||
return implem::IntConversion<std::remove_cvref_t<I>, Base, Tr>::to_ary(in);
|
||||
|
|
|
@ -26,47 +26,68 @@
|
|||
|
||||
namespace dhandy {
|
||||
namespace implem {
|
||||
template <typename T, typename F, bool SafeRetval>
|
||||
template <typename T, typename F, bool SafeRetval, typename Tr>
|
||||
struct IntConv;
|
||||
|
||||
template <typename F, bool SafeRetval>
|
||||
struct IntConv<std::enable_if_t<std::is_integral_v<F>, 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 <typename Tr>
|
||||
using IntConvString = std::basic_string<typename Tr::char_type>;
|
||||
|
||||
template <typename Tr>
|
||||
using IntConvStringView = std::basic_string_view<typename Tr::char_type>;
|
||||
|
||||
template <typename F, bool SafeRetval, typename Tr>
|
||||
struct IntConv<std::enable_if_t<std::is_integral_v<F>, IntConvString<Tr>>, F, SafeRetval, Tr> {
|
||||
static IntConvString<Tr> conv (const F& in) {
|
||||
auto retval = dhandy::int_to_ary<F, 10, Tr>(in);
|
||||
return IntConvString<Tr>{retval.begin(), retval.end() - 1};
|
||||
}
|
||||
};
|
||||
template <typename F, bool SafeRetval>
|
||||
struct IntConv<std::enable_if_t<std::is_integral_v<F>, std::string_view>, F, SafeRetval> {
|
||||
constexpr static std::string_view conv (const F& in) {
|
||||
template <typename F, bool SafeRetval, typename Tr>
|
||||
struct IntConv<std::enable_if_t<std::is_integral_v<F>, IntConvStringView<Tr>>, F, SafeRetval, Tr> {
|
||||
constexpr static IntConvStringView<Tr> 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<F, 10, Tr>(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 <typename T, bool SafeRetval>
|
||||
struct IntConv<T, std::enable_if_t<std::is_integral_v<T>, std::string>, SafeRetval> {
|
||||
constexpr static T conv (const std::string& in) {
|
||||
return dhandy::ary_to_int<T>(in.data(), in.data() + in.size());
|
||||
template <typename T, bool SafeRetval, typename Tr>
|
||||
struct IntConv<T, std::enable_if_t<std::is_integral_v<T>, IntConvString<Tr>>, SafeRetval, Tr> {
|
||||
constexpr static T conv (const IntConvString<Tr>& in) {
|
||||
return dhandy::ary_to_int<T, char, 10, Tr>(
|
||||
in.data(),
|
||||
in.data() + in.size()
|
||||
);
|
||||
}
|
||||
};
|
||||
template <typename T, bool SafeRetval>
|
||||
struct IntConv<T, std::enable_if_t<std::is_integral_v<T>, std::string_view>, SafeRetval> {
|
||||
constexpr static T conv (const std::string_view& in) {
|
||||
return dhandy::ary_to_int<T>(in.data(), in.data() + in.size());
|
||||
template <typename T, bool SafeRetval, typename Tr>
|
||||
struct IntConv<T, std::enable_if_t<std::is_integral_v<T>, IntConvStringView<Tr>>, SafeRetval, Tr> {
|
||||
constexpr static T conv (const IntConvStringView<Tr>& in) {
|
||||
return dhandy::ary_to_int<T, char, 10, Tr>(
|
||||
in.data(),
|
||||
in.data() + in.size()
|
||||
);
|
||||
}
|
||||
};
|
||||
template <typename T, typename F, F In, bool SafeRetval, typename Tr>
|
||||
struct IntConv<T, std::integral_constant<F, In>, SafeRetval, Tr> {
|
||||
constexpr static T conv (const std::integral_constant<F, In>&) {
|
||||
return dhandy::buildtime_int_to_ary<F, In, 10, Tr>().to_string_view();
|
||||
}
|
||||
};
|
||||
} //namespace implem
|
||||
|
||||
template <typename To, typename From>
|
||||
constexpr inline To int_conv (const From& from) {
|
||||
return implem::IntConv<To, From, true>::conv(from);
|
||||
constexpr inline To int_conv (const From& from, bool all_caps=false) {
|
||||
if (all_caps)
|
||||
return implem::IntConv<To, From, true, ASCIITranslatorUpcase<char>>::conv(from);
|
||||
else
|
||||
return implem::IntConv<To, From, true, ASCIITranslator<char>>::conv(from);
|
||||
}
|
||||
|
||||
template <typename To, typename From>
|
||||
constexpr inline To int_conv_temporary (const From& from) {
|
||||
return implem::IntConv<To, From, false>::conv(from);
|
||||
return implem::IntConv<To, From, false, ASCIITranslator<char>>::conv(from);
|
||||
}
|
||||
} //namespace dhandy
|
||||
|
||||
|
|
|
@ -171,3 +171,27 @@ TEST_CASE ("Check char array to int conversions", "[i2s][int_conv]") {
|
|||
AryConversionTestHelper<std::int64_t, 10>("-1", -1, false);
|
||||
AryConversionTestHelper<std::int64_t, 10>("-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<string_view>(integral_constant<bool, true>{});
|
||||
CHECK("1" == bool1);
|
||||
|
||||
constexpr auto bool2 = int_conv<string_view>(integral_constant<bool, false>{});
|
||||
CHECK("0" == bool2);
|
||||
|
||||
constexpr auto int1 = int_conv<string_view>(integral_constant<int, 42>{});
|
||||
CHECK("42" == int1);
|
||||
|
||||
constexpr auto int2 = int_conv<string_view>(integral_constant<unsigned int, 7777777>{});
|
||||
CHECK("7777777" == int2);
|
||||
|
||||
constexpr auto int3 = int_conv<string_view>(integral_constant<int, -1234>{});
|
||||
CHECK("-1234" == int3);
|
||||
|
||||
constexpr auto int4 = int_conv<string_view>(integral_constant<short int, -256>{});
|
||||
CHECK("-256" == int4);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue