Kagome
Polkadot Runtime Engine in C++17
tagged.hpp
Go to the documentation of this file.
1 
6 #ifndef KAGOME_TAGGED
7 #define KAGOME_TAGGED
8 
9 #include <type_traits>
10 #include <utility>
11 
12 #include <scale/scale.hpp>
13 
14 namespace kagome {
15 
16  template <typename T, typename = std::enable_if<std::is_scalar_v<T>>>
17  struct Wrapper {
18  template <typename... Args>
19  Wrapper(Args &&...args) : value(std::forward<T>(args)...) {}
20 
21  protected:
22  T value;
23  };
24 
25  template <typename T,
26  typename Tag,
27  typename Base =
28  std::conditional_t<std::is_scalar_v<T>, Wrapper<T>, T>>
29  class Tagged : public Base {
30  public:
31  typedef Tag tag;
32 
33  template <typename... Args>
34  explicit Tagged(Args &&...args) : Base(std::forward<Args>(args)...) {}
35 
36  Tagged(T &&value) noexcept(not std::is_lvalue_reference_v<decltype(value)>)
37  : Base(std::forward<T>(value)) {}
38 
39  Tagged &operator=(T &&value) noexcept(
40  not std::is_lvalue_reference_v<decltype(value)>) {
41  if constexpr (std::is_scalar_v<T>) {
42  this->Wrapper<T>::value = std::forward<T>(value);
43  } else {
44  static_cast<Base &>(*this) = std::forward<T>(value);
45  }
46  return *this;
47  }
48 
49  template <typename Out>
50  explicit operator Out() {
51  if constexpr (std::is_scalar_v<T>) {
52  return this->Wrapper<T>::value;
53  } else {
54  return *this;
55  }
56  }
57 
58  private:
59  friend inline ::scale::ScaleEncoderStream &operator<<(
60  ::scale::ScaleEncoderStream &s, const Tagged<T, Tag> &tagged) {
61  if constexpr (std::is_scalar_v<T>) {
62  return s << tagged.Wrapper<T>::value;
63  } else {
64  return s << static_cast<const T &>(tagged);
65  }
66  }
67 
68  friend inline ::scale::ScaleDecoderStream &operator>>(
69  ::scale::ScaleDecoderStream &s, Tagged<T, Tag> &tagged) {
70  if constexpr (std::is_scalar_v<T>) {
71  return s >> tagged.Wrapper<T>::value;
72  } else {
73  return s >> static_cast<T &>(tagged);
74  }
75  }
76  };
77 
78 } // namespace kagome
79 
80 #endif // KAGOME_TAGGED
Tagged(T &&value) noexcept(not std::is_lvalue_reference_v< decltype(value)>)
Definition: tagged.hpp:36
Wrapper(Args &&...args)
Definition: tagged.hpp:19
STL namespace.
Tagged & operator=(T &&value) noexcept(not std::is_lvalue_reference_v< decltype(value)>)
Definition: tagged.hpp:39
Tagged(Args &&...args)
Definition: tagged.hpp:34
friend::scale::ScaleDecoderStream & operator>>(::scale::ScaleDecoderStream &s, Tagged< T, Tag > &tagged)
Definition: tagged.hpp:68
friend::scale::ScaleEncoderStream & operator<<(::scale::ScaleEncoderStream &s, const Tagged< T, Tag > &tagged)
Definition: tagged.hpp:59