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_noexcept
INTERFACE cxx_rvalue_references
INTERFACE cxx_std_17
INTERFACE cxx_std_20
)
target_include_directories(${PROJECT_NAME}

View file

@ -33,6 +33,7 @@
# include <string_view>
# include <string>
#endif
#include <type_traits>
namespace dhandy {
namespace implem {
@ -168,15 +169,15 @@ namespace dhandy {
template <typename T>
[[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 (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 {
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 factor = 1;
std::size_t i = end - beg;
@ -195,13 +196,13 @@ namespace dhandy {
};
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 <unsigned int Base, typename Tr>
struct AryConversion<bool, Base, Tr, void> {
template <typename C> static bool from_ary (C* beg, C* end) {
template <unsigned int Base, typename Tr, bool Constexpr>
struct AryConversion<bool, Base, Tr, Constexpr> {
template <typename C> constexpr static bool from_ary (C* beg, C* end) {
if (end == beg)
return 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>>
inline R ary_to_int (const C* beg, const C* end) {
return implem::AryConversion<R, Base, Tr>::from_ary(beg, end);
constexpr inline R ary_to_int (const C* beg, const C* 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)