Skip to content

Commit c30e4a7

Browse files
committed
feature: CompactReflection for coding int value as compact
feature: func for convert int between each other fix: using global definition Signed-off-by: Dmitriy Khaustov aka xDimon <[email protected]>
1 parent e31f904 commit c30e4a7

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

include/scale/types.hpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,13 @@
1414
#include <boost/multiprecision/cpp_int.hpp>
1515
#include <qtils/tagged.hpp>
1616

17+
#include <scale/definitions.hpp>
18+
1719
namespace scale {
1820

21+
class ScaleEncoderStream;
22+
class ScaleDecoderStream;
23+
1924
using uint128_t = boost::multiprecision::uint128_t;
2025
using uint256_t = boost::multiprecision::uint256_t;
2126
using uint512_t = boost::multiprecision::uint512_t;
@@ -65,6 +70,63 @@ namespace scale {
6570

6671
using Length = Compact<size_t>;
6772

73+
template <typename T>
74+
inline T convert_to(const CompactCompatible auto &&value) {
75+
constexpr auto is_integral =
76+
std::unsigned_integral<std::remove_cvref_t<decltype(value)>>;
77+
if constexpr (is_integral) {
78+
return static_cast<T>(value);
79+
} else {
80+
return value.template convert_to<T>();
81+
}
82+
}
83+
84+
template <typename T>
85+
requires CompactCompatible<std::remove_cvref_t<T>>
86+
struct CompactReflection {
87+
private:
88+
template <typename U>
89+
explicit CompactReflection(U &&value)
90+
: temp_storage(
91+
std::is_lvalue_reference_v<U>
92+
? std::nullopt
93+
: std::optional<std::decay_t<U>>(std::forward<U>(value))),
94+
ref(temp_storage ? *temp_storage : value) {}
95+
96+
template <typename U>
97+
requires CompactCompatible<std::remove_cvref_t<U>>
98+
friend decltype(auto) as_compact(U &&value);
99+
100+
public:
101+
CompactReflection(const CompactReflection &) = delete;
102+
CompactReflection &operator=(const CompactReflection &) = delete;
103+
CompactReflection(CompactReflection &&) = delete;
104+
CompactReflection &operator=(CompactReflection &&) = delete;
105+
106+
friend ScaleEncoderStream &operator<<(ScaleEncoderStream &stream,
107+
const CompactReflection &value) {
108+
return stream << Compact<std::remove_cvref_t<T>>(value.ref);
109+
}
110+
friend ScaleDecoderStream &operator>>(ScaleDecoderStream &stream,
111+
const CompactReflection &value) {
112+
Compact<std::remove_cvref_t<T>> tmp;
113+
stream >> tmp;
114+
value.ref = untagged(tmp);
115+
return stream;
116+
}
117+
118+
private:
119+
std::optional<std::decay_t<T>> temp_storage;
120+
T &ref;
121+
};
122+
123+
template <typename T>
124+
requires CompactCompatible<std::remove_cvref_t<T>>
125+
decltype(auto) as_compact(T &&value) {
126+
return CompactReflection<decltype(value)>(
127+
std::forward<decltype(value)>(value));
128+
}
129+
68130
/// @brief OptionalBool is internal extended bool type
69131
enum class OptionalBool : uint8_t {
70132
NONE = 0u,

0 commit comments

Comments
 (0)