Make code a bit more readable
Changed so that int_conv<string_view>() called on a non-constexpr doesn't compiler anymore (because code would try to go through a consteval method). It wouldn't work anyways as the returned value would be always garbage. If you want a string_view then you must either give a constexpr input value or you must call int_conv_raw and call to_string_view() yourself. This is better than throwing a runtime exception (which was working ok btw). All the SafeRetVal stuff is not needed anymore. Also no need for all that confusing sfinae, I can just use a bool FromInt and specialise on that.
This commit is contained in:
parent
a675624cab
commit
938c8fa9a4
2 changed files with 44 additions and 23 deletions
|
@ -22,11 +22,10 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
namespace dhandy {
|
namespace dhandy {
|
||||||
namespace implem {
|
namespace implem {
|
||||||
template <typename T, typename F, bool SafeRetval, typename Tr>
|
template <typename T, typename F, typename Tr, bool FromInt=std::is_integral_v<F>>
|
||||||
struct IntConv;
|
struct IntConv;
|
||||||
|
|
||||||
template <typename Tr>
|
template <typename Tr>
|
||||||
|
@ -35,24 +34,21 @@ namespace dhandy {
|
||||||
template <typename Tr>
|
template <typename Tr>
|
||||||
using IntConvStringView = std::basic_string_view<typename Tr::char_type>;
|
using IntConvStringView = std::basic_string_view<typename Tr::char_type>;
|
||||||
|
|
||||||
template <typename F, bool SafeRetval, typename Tr>
|
template <typename F, typename Tr>
|
||||||
struct IntConv<std::enable_if_t<std::is_integral_v<F>, IntConvString<Tr>>, F, SafeRetval, Tr> {
|
struct IntConv<IntConvString<Tr>, F, Tr, true> {
|
||||||
static IntConvString<Tr> conv (const F& in) {
|
static IntConvString<Tr> conv (const F& in) {
|
||||||
auto retval = dhandy::int_to_ary<F, 10, Tr>(in);
|
auto retval = dhandy::int_to_ary<F, 10, Tr>(in);
|
||||||
return IntConvString<Tr>{retval.begin(), retval.end() - 1};
|
return IntConvString<Tr>{retval.begin(), retval.end() - 1};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <typename F, bool SafeRetval, typename Tr>
|
template <typename F, typename Tr>
|
||||||
struct IntConv<std::enable_if_t<std::is_integral_v<F>, IntConvStringView<Tr>>, F, SafeRetval, Tr> {
|
struct IntConv<IntConvStringView<Tr>, F, Tr, true> {
|
||||||
constexpr static IntConvStringView<Tr> conv (const F& in) {
|
consteval static IntConvStringView<Tr> conv (const F& in) {
|
||||||
if (std::is_constant_evaluated() or not SafeRetval)
|
|
||||||
return dhandy::int_to_ary<F, 10, Tr>(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, typename Tr>
|
template <typename T, typename Tr>
|
||||||
struct IntConv<T, std::enable_if_t<std::is_integral_v<T>, IntConvString<Tr>>, SafeRetval, Tr> {
|
struct IntConv<T, IntConvString<Tr>, Tr, false> {
|
||||||
constexpr static T conv (const IntConvString<Tr>& in) {
|
constexpr static T conv (const IntConvString<Tr>& in) {
|
||||||
return dhandy::ary_to_int<T, char, 10, Tr>(
|
return dhandy::ary_to_int<T, char, 10, Tr>(
|
||||||
in.data(),
|
in.data(),
|
||||||
|
@ -60,8 +56,8 @@ namespace dhandy {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <typename T, bool SafeRetval, typename Tr>
|
template <typename T, typename Tr>
|
||||||
struct IntConv<T, std::enable_if_t<std::is_integral_v<T>, IntConvStringView<Tr>>, SafeRetval, Tr> {
|
struct IntConv<T, IntConvStringView<Tr>, Tr, false> {
|
||||||
constexpr static T conv (const IntConvStringView<Tr>& in) {
|
constexpr static T conv (const IntConvStringView<Tr>& in) {
|
||||||
return dhandy::ary_to_int<T, char, 10, Tr>(
|
return dhandy::ary_to_int<T, char, 10, Tr>(
|
||||||
in.data(),
|
in.data(),
|
||||||
|
@ -69,8 +65,8 @@ namespace dhandy {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <typename T, typename F, F In, bool SafeRetval, typename Tr>
|
template <typename T, typename F, F In, typename Tr, bool FromInt>
|
||||||
struct IntConv<T, std::integral_constant<F, In>, SafeRetval, Tr> {
|
struct IntConv<T, std::integral_constant<F, In>, Tr, FromInt> {
|
||||||
constexpr static T conv (const std::integral_constant<F, In>&) {
|
constexpr static T conv (const std::integral_constant<F, In>&) {
|
||||||
return dhandy::buildtime_int_to_ary<F, In, 10, Tr>().to_string_view();
|
return dhandy::buildtime_int_to_ary<F, In, 10, Tr>().to_string_view();
|
||||||
}
|
}
|
||||||
|
@ -80,14 +76,14 @@ namespace dhandy {
|
||||||
template <typename To, typename From>
|
template <typename To, typename From>
|
||||||
constexpr inline To int_conv (const From& from, bool all_caps=false) {
|
constexpr inline To int_conv (const From& from, bool all_caps=false) {
|
||||||
if (all_caps)
|
if (all_caps)
|
||||||
return implem::IntConv<To, From, true, ASCIITranslatorUpcase<char>>::conv(from);
|
return implem::IntConv<To, From, ASCIITranslatorUpcase<char>>::conv(from);
|
||||||
else
|
else
|
||||||
return implem::IntConv<To, From, true, ASCIITranslator<char>>::conv(from);
|
return implem::IntConv<To, From, ASCIITranslator<char>>::conv(from);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename To, typename From>
|
template <typename From>
|
||||||
constexpr inline To int_conv_temporary (const From& from) {
|
inline auto int_conv_raw (const From& from) {
|
||||||
return implem::IntConv<To, From, false, ASCIITranslator<char>>::conv(from);
|
return int_to_ary<From, 10, ASCIITranslator<char>>(from);
|
||||||
}
|
}
|
||||||
} //namespace dhandy
|
} //namespace dhandy
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
template <typename T> using int_info_10 = dhandy::implem::int_info<T, 10>;
|
template <typename T> using int_info_10 = dhandy::implem::int_info<T, 10>;
|
||||||
template <typename T> using int_info_16 = dhandy::implem::int_info<T, 16>;
|
template <typename T> using int_info_16 = dhandy::implem::int_info<T, 16>;
|
||||||
|
@ -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
|
//Try a random test, which should not compile as constexpr
|
||||||
std::mt19937 gen;
|
std::mt19937 gen;
|
||||||
gen.seed(1234);
|
gen.seed(std::time(nullptr));
|
||||||
for (int z = 0; z < 10; ++z) {
|
for (int z = 0; z < 10; ++z) {
|
||||||
const int num = gen();
|
const int num = gen();
|
||||||
CHECK(int_to_ary(num) == std::to_string(num));
|
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<std::int32_t, 16>("aAbBc", 0xaabbc, true);
|
AryConversionTestHelperIns<std::int32_t, 16>("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<string_view>(integral_constant<short int, 71>{});
|
||||||
|
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<string>(123);
|
||||||
|
CHECK("123" == str123);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE ("Check upcase/downcase int to array conversions", "[i2s][int_conv]") {
|
TEST_CASE ("Check upcase/downcase int to array conversions", "[i2s][int_conv]") {
|
||||||
using dhandy::int_conv;
|
using dhandy::int_conv;
|
||||||
using std::string_view;
|
using std::string_view;
|
||||||
|
|
Loading…
Reference in a new issue