diff --git a/ulbn.hpp b/ulbn.hpp index a6e7901..2a1b797 100644 --- a/ulbn.hpp +++ b/ulbn.hpp @@ -272,6 +272,20 @@ inline ulbn_alloc_t* getCurrentAllocator() { return &alloc; } +template +concept FitSlimb = requires { + requires std::is_integral_v; + requires std::is_signed_v; + requires sizeof(T) <= sizeof(ulbn_slimb_t); + requires std::is_convertible_v; +}; +template +concept FitLimb = requires { + requires std::is_integral_v; + requires std::is_unsigned_v; + requires sizeof(T) <= sizeof(ulbn_limb_t); + requires std::is_convertible_v; +}; template concept FitSlong = requires { requires std::is_integral_v; @@ -287,19 +301,16 @@ concept FitUlong = requires { requires std::is_convertible_v; }; template -concept FitLimb = requires { - requires std::is_integral_v; - requires std::is_unsigned_v; - requires sizeof(T) <= sizeof(ulbn_limb_t); - requires std::is_convertible_v; +concept FitSlongCase = requires { + requires FitSlong; + requires !FitSlimb; }; template -concept FitSlimb = requires { - requires std::is_integral_v; - requires std::is_signed_v; - requires sizeof(T) <= sizeof(ulbn_slimb_t); - requires std::is_convertible_v; +concept FitUlongCase = requires { + requires FitUlong; + requires !FitLimb; }; + template concept FitUsize = requires { requires std::is_integral_v; @@ -333,6 +344,7 @@ concept FitOutBit = requires { requires std::is_integral_v; requires std::is_convertible_v; }; + #if ULBN_CONF_HAS_FLOAT template concept FitFloat = requires { @@ -345,6 +357,7 @@ concept FitFloat = requires { requires std::numeric_limits::max_exponent <= std::numeric_limits::max_exponent; }; #endif /* ULBN_CONF_HAS_FLOAT */ + #if ULBN_CONF_HAS_DOUBLE template concept FitDouble = requires { @@ -364,6 +377,7 @@ concept FitDoubleCase = requires { #endif }; #endif /* ULBN_CONF_HAS_DOUBLE */ + #if ULBN_CONF_HAS_LONG_DOUBLE template concept FitLongDouble = requires { @@ -465,24 +479,20 @@ class BigInt { return *this; } - template - requires(!FitSlimb) + template BigInt(T value) noexcept { ulbi_init_slong(_value, static_cast(value)); } - template - requires(!FitLimb) + template BigInt(T value) noexcept { ulbi_init_ulong(_value, static_cast(value)); } - template - requires(!FitSlimb) + template BigInt& operator=(T value) noexcept { ulbi_set_slong(_value, static_cast(value)); return *this; } - template - requires(!FitLimb) + template BigInt& operator=(T value) noexcept { ulbi_set_ulong(_value, static_cast(value)); return *this; @@ -1086,13 +1096,11 @@ class BigInt { friend std::strong_ordering operator<=>(const BigInt& lhs, T rhs) noexcept { return ulbi_comp_slimb(lhs._value, static_cast(rhs)) <=> 0; } - template - requires(!FitLimb) + template friend std::strong_ordering operator<=>(const BigInt& lhs, T rhs) noexcept { return ulbi_comp_ulong(lhs._value, static_cast(rhs)) <=> 0; } - template - requires(!FitSlimb) + template friend std::strong_ordering operator<=>(const BigInt& lhs, T rhs) noexcept { return ulbi_comp_slong(lhs._value, static_cast(rhs)) <=> 0; } @@ -1105,13 +1113,11 @@ class BigInt { friend std::strong_ordering operator<=>(T lhs, const BigInt& rhs) noexcept { return (-ulbi_comp_slimb(rhs._value, static_cast(lhs))) <=> 0; } - template - requires(!FitLimb) + template friend std::strong_ordering operator<=>(T lhs, const BigInt& rhs) noexcept { return (-ulbi_comp_ulong(rhs._value, static_cast(lhs))) <=> 0; } - template - requires(!FitSlimb) + template friend std::strong_ordering operator<=>(T lhs, const BigInt& rhs) noexcept { return (-ulbi_comp_slong(rhs._value, static_cast(lhs))) <=> 0; } @@ -1129,13 +1135,11 @@ class BigInt { friend bool operator==(const BigInt& lhs, T rhs) noexcept { return ulbi_eq_slimb(lhs._value, static_cast(rhs)) != 0; } - template - requires(!FitLimb) + template friend bool operator==(const BigInt& lhs, T rhs) noexcept { return ulbi_eq_ulong(lhs._value, static_cast(rhs)) != 0; } - template - requires(!FitSlimb) + template friend bool operator==(const BigInt& lhs, T rhs) noexcept { return ulbi_eq_slong(lhs._value, static_cast(rhs)) != 0; } @@ -1148,13 +1152,11 @@ class BigInt { friend bool operator==(T lhs, const BigInt& rhs) noexcept { return ulbi_eq_slimb(rhs._value, static_cast(lhs)) != 0; } - template - requires(!FitLimb) + template friend bool operator==(T lhs, const BigInt& rhs) noexcept { return ulbi_eq_ulong(rhs._value, static_cast(lhs)) != 0; } - template - requires(!FitSlimb) + template friend bool operator==(T lhs, const BigInt& rhs) noexcept { return ulbi_eq_slong(rhs._value, static_cast(lhs)) != 0; } @@ -1384,13 +1386,11 @@ class BigInt { explicit operator T() const noexcept { return static_cast(toLimb()); } - template - requires(!FitSlimb) + template explicit operator T() const noexcept { return static_cast(toSlong()); } - template - requires(!FitLimb) + template explicit operator T() const noexcept { return static_cast(toUlong()); } @@ -1892,8 +1892,12 @@ class BigInt { base = 10; return; } + if(helper.has_precision) + throw std::format_error("precision is not supported"); + if(helper.use_locale) + throw std::format_error("locale is not supported"); if(helper.target_type.size() != 1) - throw std::format_error("invalid target type"); + throw std::format_error("invalid type"); switch(helper.target_type[0]) { case 'b': base = -2; @@ -1914,7 +1918,7 @@ class BigInt { base = 16; break; default: - throw std::format_error("invalid target type"); + throw std::format_error("invalid type"); } } #endif