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:
parent
b52343014b
commit
710cdf9f04
1 changed files with 24 additions and 9 deletions
|
@ -22,27 +22,37 @@
|
||||||
#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>
|
template <typename T, typename F, bool SafeRetval>
|
||||||
struct IntConv;
|
struct IntConv;
|
||||||
|
|
||||||
template <typename F>
|
template <typename F, bool SafeRetval>
|
||||||
struct IntConv<std::enable_if_t<std::is_integral_v<F>, std::string>, F> {
|
struct IntConv<std::enable_if_t<std::is_integral_v<F>, std::string>, F, SafeRetval> {
|
||||||
static std::string conv (const F& in) {
|
static std::string conv (const F& in) {
|
||||||
auto retval = dhandy::int_to_ary(in);
|
auto retval = dhandy::int_to_ary(in);
|
||||||
return std::string(retval.begin(), retval.end() - 1);
|
return std::string(retval.begin(), retval.end() - 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <typename T>
|
template <typename F, bool SafeRetval>
|
||||||
struct IntConv<T, std::enable_if_t<std::is_integral_v<T>, std::string>> {
|
struct IntConv<std::enable_if_t<std::is_integral_v<F>, std::string_view>, F, SafeRetval> {
|
||||||
static T conv (const std::string& in) {
|
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());
|
return dhandy::ary_to_int<T>(in.data(), in.data() + in.size());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <typename T>
|
template <typename T, bool SafeRetval>
|
||||||
struct IntConv<T, std::enable_if_t<std::is_integral_v<T>, std::string_view>> {
|
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) {
|
constexpr static T conv (const std::string_view& in) {
|
||||||
return dhandy::ary_to_int<T>(in.data(), in.data() + in.size());
|
return dhandy::ary_to_int<T>(in.data(), in.data() + in.size());
|
||||||
}
|
}
|
||||||
|
@ -51,7 +61,12 @@ namespace dhandy {
|
||||||
|
|
||||||
template <typename To, typename From>
|
template <typename To, typename From>
|
||||||
constexpr inline To int_conv (const From& 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
|
} //namespace dhandy
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue