diff --git a/core/scale/encoder/primitives.hpp b/core/scale/encoder/primitives.hpp index 3ea7726966..db2b8bd179 100644 --- a/core/scale/encoder/primitives.hpp +++ b/core/scale/encoder/primitives.hpp @@ -25,85 +25,81 @@ namespace kagome::scale { template concept Invocable = std::is_invocable_v; + template + concept IsEnum = std::is_enum_v>; + + template + concept IsNotEnum = !std::is_enum_v>; + constexpr void putByte(const Invocable auto &func, const uint8_t *const val, size_t count); - template - constexpr void encode(const F &func, const std::tuple &v) requires std::is_invocable_v; + template + constexpr void encode(const Invocable auto &func, const std::tuple &v); - template - constexpr void encode(const F &func, const T &t, const Args &...args) requires std::is_invocable_v; + template + constexpr void encode(const Invocable auto &func, const T &t, const Args &...args); - template - constexpr void encode(const F &func, const std::vector &c) requires std::is_invocable_v; + template + constexpr void encode(const Invocable auto &func, const std::vector &c); template constexpr void encode(const Invocable auto &func, const std::pair &p); - template - constexpr void encode(const F &func, const std::span &c) requires std::is_invocable_v; + template + constexpr void encode(const Invocable auto &func, const std::span &c); - template - constexpr void encode(const F &func, const std::span &c) requires std::is_invocable_v; + template + constexpr void encode(const Invocable auto &func, const std::span &c); - template - constexpr void encode(const F &func, const std::array &c) requires std::is_invocable_v; + template + constexpr void encode(const Invocable auto &func, const std::array &c); - template - constexpr void encode(const F &func, const T (&c)[N]) requires std::is_invocable_v; + template + constexpr void encode(const Invocable auto &func, const T (&c)[N]); - template - constexpr void encode(const F &func, const std::map &c) requires std::is_invocable_v; + template + constexpr void encode(const Invocable auto &func, const std::map &c); - template - constexpr void encode(const F &func, const std::shared_ptr &v) requires std::is_invocable_v; + template + constexpr void encode(const Invocable auto &func, const std::shared_ptr &v); - template - constexpr void encode(const F &func, const std::string_view &v) requires std::is_invocable_v; + constexpr void encode(const Invocable auto &func, const std::string_view &v); - template - constexpr void encode(const F &func, const std::string &v) requires std::is_invocable_v; + constexpr void encode(const Invocable auto &func, const std::string &v); - template - constexpr void encode(const F &func, const std::unique_ptr &v) requires std::is_invocable_v; + template + constexpr void encode(const Invocable auto &func, const std::unique_ptr &v); - template - constexpr void encode(const F &func, const std::list &c) requires std::is_invocable_v; + template + constexpr void encode(const Invocable auto &func, const std::list &c); - template - constexpr void encode(const F &func, const std::deque &c) requires std::is_invocable_v; + template + constexpr void encode(const Invocable auto &func, const std::deque &c); - template - void encode(const F &func, const boost::variant &v) requires std::is_invocable_v; + template + void encode(const Invocable auto &func, const boost::variant &v); - template - void encode(const F &func, const boost::variant &v) requires std::is_invocable_v; + template + void encode(const Invocable auto &func, const boost::variant &v); - template - void encode(const F &func, const std::variant &v) requires std::is_invocable_v; + template + void encode(const Invocable auto &func, const std::variant &v); - template - void encode(const F &func, const ::scale::CompactInteger &value) requires std::is_invocable_v; + void encode(const Invocable auto &func, const ::scale::CompactInteger &value); - template - void encode(const F &func, const ::scale::BitVec &value) requires std::is_invocable_v; + void encode(const Invocable auto &func, const ::scale::BitVec &value); - template - void encode(const F &func, const std::optional &value) requires std::is_invocable_v; + void encode(const Invocable auto &func, const std::optional &value); - template - void encode(const F &func, const std::optional &value) requires std::is_invocable_v; + template + void encode(const Invocable auto &func, const std::optional &value); - template - void encode(const F &func, const crypto::EcdsaSignature &value) requires std::is_invocable_v; + void encode(const Invocable auto &func, const crypto::EcdsaSignature &value); - template - void encode(const F &func, const crypto::EcdsaPublicKey &value) requires std::is_invocable_v; + void encode(const Invocable auto &func, const crypto::EcdsaPublicKey &value); - template - constexpr void encode(const F &func, const T &v) requires (!std::is_enum_v>) && - std::is_invocable_v -{ - using I = std::decay_t; + constexpr void encode(const Invocable auto &func, const IsNotEnum auto &v) { + using I = std::decay_t; if constexpr (std::is_integral_v) { if constexpr (std::is_same_v) { const uint8_t byte = (v ? 1u : 0u); @@ -124,13 +120,12 @@ namespace kagome::scale { } } - template - constexpr void encode(const F &func, const T &value) requires std::is_enum_v> && std::is_invocable_v { - kagome::scale::encode(func, static_cast>>(value)); + constexpr void encode(const Invocable auto &func, const IsEnum auto &value) { + kagome::scale::encode(func, static_cast>>(value)); } - template - constexpr void encode(const F &func, const T &t, const Args &...args) requires std::is_invocable_v { + template + constexpr void encode(const Invocable auto &func, const T &t, const Args &...args) { kagome::scale::encode(func, t); kagome::scale::encode(func, args...); } @@ -198,8 +193,8 @@ namespace kagome::scale { func(val, count); } - template - void encode(const F &func, const boost::variant &v) requires std::is_invocable_v { + template + void encode(const Invocable auto &func, const boost::variant &v) { using T = std::tuple_element_t>; if (v.which() == I) { kagome::scale::encode(func, I); @@ -207,12 +202,12 @@ namespace kagome::scale { return; } if constexpr (sizeof...(Ts) > I + 1) { - kagome::scale::encode(func, v); + kagome::scale::encode(func, v); } } - template - constexpr void encode(const F &func, const T (&c)[N]) requires std::is_invocable_v { + template + constexpr void encode(const Invocable auto &func, const T (&c)[N]) { using E = std::decay_t; if constexpr (std::is_integral_v && sizeof(E) == 1u) { putByte(func, c, N); @@ -223,16 +218,15 @@ namespace kagome::scale { } } - template - void encode(const F &func, const boost::variant &v) requires std::is_invocable_v { - kagome::scale::encode(func, v); + template + void encode(const Invocable auto &func, const boost::variant &v) { + kagome::scale::encode<0>(func, v); } - template , std::enable_if_t, bool> = true> - constexpr void encodeCompactSmall(const F &func, T val) requires std::is_invocable_v { + constexpr void encodeCompactSmall(const Invocable auto &func, T val) { BOOST_ASSERT_MSG((val >> (8 * sizeof(I) - 2)) == 0, "Unexpected compact value in encoder"); val <<= 2; @@ -241,8 +235,7 @@ namespace kagome::scale { kagome::scale::encode(func, val); } - template - void encodeCompact(const F &func, uint64_t val) requires std::is_invocable_v { + void encodeCompact(const Invocable auto &func, uint64_t val) { if (val < ::scale::compact::EncodingCategoryLimits::kMinUint16) { kagome::scale::encodeCompactSmall(func, static_cast(val)); return; @@ -267,27 +260,24 @@ namespace kagome::scale { putByte(func, result, bigIntLength + 1ull); } - template - void encode(const F &func, const std::variant &v) requires std::is_invocable_v { + template + void encode(const Invocable auto &func, const std::variant &v) { kagome::scale::encode(func, (uint8_t)v.index()); std::visit([&](const auto &s) { kagome::scale::encode(func, s); }, v); } - template - constexpr void encode(const F &func, const std::string &v) requires std::is_invocable_v { + constexpr void encode(const Invocable auto &func, const std::string &v) { kagome::scale::encode(func, std::string_view{v}); } - template - constexpr void encode(const F &func, const std::string_view &v) requires std::is_invocable_v { + constexpr void encode(const Invocable auto &func, const std::string_view &v) { kagome::scale::encodeCompact(func, v.size()); putByte(func, (const uint8_t *)v.data(), v.size()); } - template - void encode(const F &func, const ::scale::BitVec &v) requires std::is_invocable_v { + void encode(const Invocable auto &func, const ::scale::BitVec &v) { const size_t bitsCount = v.bits.size(); const size_t bytesCount = ((bitsCount + 7ull) >> 3ull); const size_t blocksCount = ((bytesCount + 7ull) >> 3ull); @@ -312,8 +302,7 @@ namespace kagome::scale { } } - template - void encode(const F &func, const ::scale::CompactInteger &value) requires std::is_invocable_v { + void encode(const Invocable auto &func, const ::scale::CompactInteger &value) { if (value < 0) { raise(::scale::EncodeError::NEGATIVE_COMPACT_INTEGER); } @@ -359,25 +348,24 @@ namespace kagome::scale { } template < - typename F, typename It, typename = std::enable_if_t< !std::is_same_v::value_type, void>>> - constexpr void encode(const F &func, It begin, It end) requires std::is_invocable_v { + constexpr void encode(const Invocable auto &func, It begin, It end) { while (begin != end) { kagome::scale::encode(func, *begin); ++begin; } } - template - constexpr void encode(const F &func, const std::span &c) requires std::is_invocable_v { + template + constexpr void encode(const Invocable auto &func, const std::span &c) { kagome::scale::encodeCompact(func, c.size()); kagome::scale::encode(func, c.begin(), c.end()); } - template - constexpr void encode(const F &func, const std::span &c) requires std::is_invocable_v { + template + constexpr void encode(const Invocable auto &func, const std::span &c) { if constexpr (S == -1) { kagome::scale::encodeCompact(func, c.size()); kagome::scale::encode(func, c.begin(), c.end()); @@ -393,15 +381,15 @@ namespace kagome::scale { } } - template - constexpr void encode(const F &func, const std::array &c) requires std::is_invocable_v { + template + constexpr void encode(const Invocable auto &func, const std::array &c) { for (const auto &e : c) { kagome::scale::encode(func, e); } } - template - constexpr void encode(const F &func, const std::map &c) requires std::is_invocable_v { + template + constexpr void encode(const Invocable auto &func, const std::map &c) { kagome::scale::encodeCompact(func, c.size()); kagome::scale::encode(func, c.begin(), c.end()); } @@ -412,49 +400,48 @@ namespace kagome::scale { kagome::scale::encode(func, p.second); } - template - constexpr void encode(const F &func, const std::vector &c) requires std::is_invocable_v { + template + constexpr void encode(const Invocable auto &func, const std::vector &c) { kagome::scale::encodeCompact(func, c.size()); kagome::scale::encode(func, c.begin(), c.end()); } - template - constexpr void encode(const F &func, const std::shared_ptr &v) requires std::is_invocable_v { + template + constexpr void encode(const Invocable auto &func, const std::shared_ptr &v){ if (v == nullptr) { raise(::scale::EncodeError::DEREF_NULLPOINTER); } kagome::scale::encode(func, *v); } - template - constexpr void encode(const F &func, const std::unique_ptr &v) requires std::is_invocable_v { + template + constexpr void encode(const Invocable auto &func, const std::unique_ptr &v){ if (v == nullptr) { raise(::scale::EncodeError::DEREF_NULLPOINTER); } kagome::scale::encode(func, *v); } - template - constexpr void encode(const F &func, const std::list &c) requires std::is_invocable_v{ + template + constexpr void encode(const Invocable auto &func, const std::list &c) { kagome::scale::encodeCompact(func, c.size()); kagome::scale::encode(func, c.begin(), c.end()); } - template - constexpr void encode(const F &func, const std::deque &c) requires std::is_invocable_v{ + template + constexpr void encode(const Invocable auto &func, const std::deque &c) { kagome::scale::encodeCompact(func, c.size()); kagome::scale::encode(func, c.begin(), c.end()); } - template - constexpr void encode(const F &func, const std::tuple &v) requires std::is_invocable_v{ + template + constexpr void encode(const Invocable auto &func, const std::tuple &v) { if constexpr (sizeof...(Ts) > 0) { std::apply([&](const auto &...s) { (..., kagome::scale::encode(func, s)); }, v); } } - template - void encode(const F &func, const std::optional &v) requires std::is_invocable_v{ + void encode(const Invocable auto &func, const std::optional &v) { enum class OptionalBool : uint8_t { NONE = 0u, OPT_TRUE = 1u, @@ -470,8 +457,8 @@ namespace kagome::scale { kagome::scale::encode(func, result); } - template - void encode(const F &func, const std::optional &v) requires std::is_invocable_v{ + template + void encode(const Invocable auto &func, const std::optional &v) { if (!v.has_value()) { kagome::scale::encode(func, uint8_t(0u)); } else { @@ -480,13 +467,11 @@ namespace kagome::scale { } } - template - void encode(const F &func, const crypto::EcdsaSignature &data) requires std::is_invocable_v { + void encode(const Invocable auto &func, const crypto::EcdsaSignature &data) { kagome::scale::encode(func, static_cast &>(data)); } - template - void encode(const F &func, const crypto::EcdsaPublicKey &data) requires std::is_invocable_v { + void encode(const Invocable auto &func, const crypto::EcdsaPublicKey &data) { kagome::scale::encode(func, static_cast &>(data)); }