Make ary_to_int() constexpr

This commit is contained in:
King_DuckZ 2021-04-22 13:02:51 +02:00
parent 3343b51a39
commit 93d2ad6bd0
2 changed files with 14 additions and 10 deletions

View file

@ -27,7 +27,7 @@ target_compile_features(${PROJECT_NAME}
INTERFACE cxx_decltype_incomplete_return_types INTERFACE cxx_decltype_incomplete_return_types
INTERFACE cxx_noexcept INTERFACE cxx_noexcept
INTERFACE cxx_rvalue_references INTERFACE cxx_rvalue_references
INTERFACE cxx_std_17 INTERFACE cxx_std_20
) )
target_include_directories(${PROJECT_NAME} target_include_directories(${PROJECT_NAME}

View file

@ -33,6 +33,7 @@
# include <string_view> # include <string_view>
# include <string> # include <string>
#endif #endif
#include <type_traits>
namespace dhandy { namespace dhandy {
namespace implem { namespace implem {
@ -168,15 +169,15 @@ namespace dhandy {
template <typename T> template <typename T>
[[gnu::always_inline,gnu::pure]] [[gnu::always_inline,gnu::pure]]
inline T negated_ifn (T n, bool negate) { constexpr inline T negated_ifn (T n, bool negate) {
//return static_cast<int32_t>(((static_cast<unsigned int>(n) - (mask bitand 1)) xor mask) bitor ((mask bitand 1) << 31)); //return static_cast<int32_t>(((static_cast<unsigned int>(n) - (mask bitand 1)) xor mask) bitor ((mask bitand 1) << 31));
return (negate ? -n : n); return (negate ? -n : n);
} }
template <typename I, unsigned int Base, typename Tr, typename=void> template <typename I, unsigned int Base, typename Tr, bool Constexpr, typename=void>
struct AryConversion { struct AryConversion {
template <typename C> template <typename C>
static I from_ary (const C* beg, const C* end) { constexpr static I from_ary (const C* beg, const C* end) {
I retval = 0; I retval = 0;
I factor = 1; I factor = 1;
std::size_t i = end - beg; std::size_t i = end - beg;
@ -195,13 +196,13 @@ namespace dhandy {
}; };
template <typename I, unsigned int Base, typename Tr> template <typename I, unsigned int Base, typename Tr>
struct AryConversion<I, Base, Tr, typename std::enable_if<Tr::BehavesLikeASCII and std::is_integral<I>::value and not std::is_same<I, bool>::value and sizeof(I) <= sizeof(uint32_t)>::type> { struct AryConversion<I, Base, Tr, false, typename std::enable_if<Tr::BehavesLikeASCII and std::is_integral<I>::value and not std::is_same<I, bool>::value and sizeof(I) <= sizeof(uint32_t)>::type> {
template <typename C> static I from_ary (C* beg, C* end) { return to_integer_sse<I, C, Base, Tr>(beg, end - beg); } template <typename C> static I from_ary (C* beg, C* end) { return to_integer_sse<I, C, Base, Tr>(beg, end - beg); }
}; };
template <unsigned int Base, typename Tr> template <unsigned int Base, typename Tr, bool Constexpr>
struct AryConversion<bool, Base, Tr, void> { struct AryConversion<bool, Base, Tr, Constexpr> {
template <typename C> static bool from_ary (C* beg, C* end) { template <typename C> constexpr static bool from_ary (C* beg, C* end) {
if (end == beg) if (end == beg)
return false; return false;
return (Tr::from_digit(*beg) ? true : false); return (Tr::from_digit(*beg) ? true : false);
@ -291,8 +292,11 @@ namespace dhandy {
} }
template <typename R, typename C, unsigned int Base=10, typename Tr=ASCIITranslator<C>> template <typename R, typename C, unsigned int Base=10, typename Tr=ASCIITranslator<C>>
inline R ary_to_int (const C* beg, const C* end) { constexpr inline R ary_to_int (const C* beg, const C* end) {
return implem::AryConversion<R, Base, Tr>::from_ary(beg, end); if (std::is_constant_evaluated())
return implem::AryConversion<R, Base, Tr, true>::from_ary(beg, end);
else
return implem::AryConversion<R, Base, Tr, false>::from_ary(beg, end);
} }
#if !defined(INT_CONV_WITHOUT_HELPERS) #if !defined(INT_CONV_WITHOUT_HELPERS)