IDS peak ICV v1.2.0
Loading...
Searching...
No Matches
peak_common_any.hpp
Go to the documentation of this file.
1
11#pragma once
12
14#include <peak_common_c/detail/peak_common_defines.h>
15
16#include <type_traits>
17#include <memory>
18#include <string>
19
20namespace peak
21{
22namespace common
23{
24
35class Any
36{
37 struct Placeholder
38 {
39 virtual ~Placeholder() = default;
40
41 PEAK_COMMON_NO_DISCARD virtual const std::type_info& Type() const = 0;
42 PEAK_COMMON_NO_DISCARD virtual std::unique_ptr<Placeholder> Clone() const = 0;
43 };
44
45 template <typename T>
46 struct Holder : public Placeholder
47 {
48 T value;
49
50 explicit Holder(const T& val)
51 : value(val)
52 {}
53
54 explicit Holder(T&& val)
55 : value(std::move(val))
56 {}
57
58 PEAK_COMMON_NO_DISCARD const std::type_info& Type() const override
59 {
60 return typeid(T);
61 }
62
63 PEAK_COMMON_NO_DISCARD std::unique_ptr<Placeholder> Clone() const override
64 {
65 return std::make_unique<Holder<T>>(value);
66 }
67 };
68
69 std::unique_ptr<Placeholder> m_content;
70
71public:
77 Any() = default;
78
87 template <typename T>
88 explicit Any(const T& value)
89 : m_content(std::make_unique<Holder<typename std::decay_t<T>>>(value))
90 {}
91
100 template <typename T>
101 explicit Any(T&& value
103 ,
104 typename std::enable_if<!std::is_same<Any, typename std::decay<T>::type>::value>::type* = nullptr
106 )
107 : m_content(std::make_unique<Holder<typename std::decay_t<T>>>(std::forward<T>(value)))
108 {}
109
115 Any(const Any& other)
116 : m_content(other.m_content ? other.m_content->Clone() : nullptr)
117 {}
118
124 Any(Any&& other) noexcept = default;
125
131 Any& operator=(const Any& other)
132 {
133 if (this != &other)
134 {
135 m_content = other.m_content ? other.m_content->Clone() : nullptr;
136 }
137 return *this;
138 }
139
145 Any& operator=(Any&& other) noexcept = default;
146
152 void Reset()
153 {
154 m_content.reset();
155 }
156
164 PEAK_COMMON_NO_DISCARD const std::type_info& GetType() const
165 {
166 return m_content ? m_content->Type() : typeid(void);
167 }
168
178 template <typename T>
180 {
181 using namespace std::string_literals;
182
183 if (typeid(T) != GetType())
184 {
186 "Casting from "s + GetType().name() + " to the given type " + typeid(T).name() + " is not supported!");
187 }
188 return static_cast<Holder<T>*>(m_content.get())->value;
189 }
190
200 template <typename T>
201 PEAK_COMMON_NO_DISCARD const T& AnyCast() const
202 {
203 using namespace std::string_literals;
204
205 if (typeid(T) != GetType())
206 {
208 "Casting from "s + GetType().name() + " to the given type " + typeid(T).name() + " is not supported!");
209 }
210 return static_cast<const Holder<T>*>(m_content.get())->value;
211 }
212
220 PEAK_COMMON_NO_DISCARD bool HasValue() const
221 {
222 return m_content != nullptr;
223 }
224};
225
226} // namespace common
227} // namespace peak
A type-erased container for any copyable value.
Any & operator=(const Any &other)
Copy assignment operator.
Any()=default
Default constructor. Constructs an empty Any object.
const std::type_info & GetType() const
Gets the type of the stored value.
void Reset()
Clears the stored value.
Any(T &&value)
Constructs an Any from a rvalue reference.
const T & AnyCast() const
Const version of AnyCast.
Any(Any &&other) noexcept=default
Move constructor.
Any(const Any &other)
Copy constructor.
Any(const T &value)
Constructs an Any from a const reference.
Any & operator=(Any &&other) noexcept=default
Move assignment operator.
T & AnyCast()
Casts the stored value to the specified type.
bool HasValue() const
Checks if the Any contains a value.
Thrown when a cast to an incompatible type is attempted.