siplasplas
A library for C++ reflection and introspection
universal_reference.hpp
1 #ifndef SIPLASPLAS_UTILITY_UNIVERSALREFERENCE_HPP
2 #define SIPLASPLAS_UTILITY_UNIVERSALREFERENCE_HPP
3 
4 #include <type_traits>
5 #include <bitset>
6 
7 namespace cpp
8 {
9 
27 template<typename T,
28  bool IsLvalueReference,
29  bool IsConst
30 >
32 {
33 public:
34  using ValueType = T;
35 
36  UniversalReference(const ValueType& lvalueRef) :
37  _ref{&lvalueRef}
38  {}
39 
43  const ValueType& get() const
44  {
45  return *_ref;
46  }
47 
48 private:
49  const T* _ref;
50 };
51 
58 template<typename T>
60  T,
61  true,
62  false
63 >
64 {
65 public:
66  using ValueType = T;
67 
68  UniversalReference(ValueType& lvalueRef) :
69  _ref{&lvalueRef}
70  {}
71 
75  ValueType& get() const
76  {
77  return *_ref;
78  }
79 private:
80  T* _ref;
81 };
82 
89 template<typename T>
91  T,
92  false,
93  false
94 >
95 {
96 public:
97  using ValueType = T;
98 
99  UniversalReference(ValueType&& rvalueRef) :
100  _object{std::move(rvalueRef)}
101  {}
102 
106  ValueType& get()
107  {
108  return _object;
109  }
110 
114  const ValueType& get() const
115  {
116  return _object;
117  }
118 
119 private:
120  ValueType _object;
121 };
122 
138 template<typename T>
139 auto universalReference(T&& value) ->
140 UniversalReference<
141  std::decay_t<T>,
142  std::is_lvalue_reference<T>::value,
143  std::is_const<std::remove_reference_t<T>>::value
144 >
145 {
146  return { std::forward<T>(value) };
147 }
148 
149 }
150 
151 #endif // SIPLASPLAS_UTILITY_UNIVERSALREFERENCE_HPP
auto universalReference(T &&value) -> UniversalReference< std::decay_t< T >, std::is_lvalue_reference< T >::value, std::is_const< std::remove_reference_t< T >>::value >
Creates an universal reference to the given value.
Definition: universal_reference.hpp:139
Definition: canary_allocator.hpp:7
Implements a copyable wrapper of an universal reference.
Definition: universal_reference.hpp:31