Allow string_view conv when it's safe

You can still force a string_view conv even when it's
not safe to do so if you only intend to use the
return value during its lifetime validity. Call
int_conv_temporary() in that case.
This commit is contained in:
King_DuckZ 2021-04-22 13:59:51 +02:00
parent b52343014b
commit 710cdf9f04

View file

@ -22,27 +22,37 @@
#include <type_traits>
#include <string>
#include <string_view>
#include <stdexcept>
namespace dhandy {
namespace implem {
template <typename T, typename F>
template <typename T, typename F, bool SafeRetval>
struct IntConv;
template <typename F>
struct IntConv<std::enable_if_t<std::is_integral_v<F>, std::string>, F> {
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 T>
struct IntConv<T, std::enable_if_t<std::is_integral_v<T>, std::string>> {
static T conv (const std::string& in) {
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) {
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 <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>
struct IntConv<T, std::enable_if_t<std::is_integral_v<T>, std::string_view>> {
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());
}
@ -51,7 +61,12 @@ namespace dhandy {
template <typename To, typename From>
constexpr inline To int_conv (const From& from) {
return implem::IntConv<To, From>::conv(from);
return implem::IntConv<To, From, true>::conv(from);
}
template <typename To, typename From>
constexpr inline To int_conv_temporary (const From& from) {
return implem::IntConv<To, From, false>::conv(from);
}
} //namespace dhandy