RobotsIO
Loading...
Searching...
No Matches
any.h
1
51#ifndef ROBOTSIO_ANY_H
52#define ROBOTSIO_ANY_H
53
54#include <algorithm>
55#include <memory>
56#include <stdexcept>
57#include <typeinfo>
58#include <type_traits>
59
60
61namespace RobotsIO
62{
63namespace Utils
64{
65
75class any
76{
77public:
81 any() noexcept :
82 content(0)
83 { }
84
85
91 any(const any& other) :
92 content(other.content ? other.content->clone() : 0)
93 { }
94
95
101 any(any&& other) noexcept :
102 content(other.content)
103 {
104 other.content = 0;
105 }
106
107
113 template<typename ValueType>
114 any(const ValueType& value) :
115 content(new holder<typename std::remove_cv<typename std::decay<const ValueType>::type>::type>(value))
116 { }
117
118
124 template<typename ValueType>
125 any(ValueType&& value, typename std::enable_if<!std::is_same<any&, ValueType>::value>::type* = 0, typename std::enable_if<!std::is_const<ValueType>::value>::type* = 0) :
126 content(new holder<typename std::decay<ValueType>::type>(static_cast<ValueType&&>(value)))
127 { }
128
129
133 ~any() noexcept
134 {
135 delete content;
136 }
137
138
145 any& operator=(const any& rhs)
146 {
147 any(rhs).swap(*this);
148 return *this;
149 }
150
151
159 any& operator=(any&& rhs) noexcept
160 {
161 rhs.swap(*this);
162 any().swap(rhs);
163 return *this;
164 }
165
166
175 template <class ValueType>
176 any& operator=(ValueType&& rhs)
177 {
178 any(static_cast<ValueType&&>(rhs)).swap(*this);
179 return *this;
180 }
181
182
186 void reset() noexcept
187 {
188 any().swap(*this);
189 }
190
191
197 any& swap(any& rhs) noexcept
198 {
199 std::swap(content, rhs.content);
200 return *this;
201 }
202
208 bool has_value() const noexcept
209 {
210 return content;
211 }
212
213
219 const std::type_info& type() const noexcept
220 {
221 return content ? content->type() : typeid(void);
222 }
223
224
225private:
226 class placeholder
227 {
228 public:
229 virtual ~placeholder()
230 { }
231
232 public:
233 virtual const std::type_info& type() const noexcept = 0;
234
235 virtual placeholder* clone() const = 0;
236
237 };
238
239
240 template<typename ValueType>
241 class holder : public placeholder
242 {
243 public:
244 holder(const ValueType& value) :
245 held(value)
246 { }
247
248
249 holder(ValueType&& value) :
250 held(static_cast<ValueType&&>(value))
251 { }
252
253
254 virtual const std::type_info& type() const noexcept
255 {
256 return typeid(ValueType);
257 }
258
259
260 virtual placeholder* clone() const
261 {
262 return new holder(held);
263 }
264
265
266 ValueType held;
267
268 private:
269 holder& operator=(const holder &);
270 };
271
272
273private:
274 template<typename ValueType>
275 friend ValueType* any_cast(any*) noexcept;
276
277 placeholder* content;
278};
279
280
287inline void swap(any& lhs, any& rhs) noexcept
288{
289 lhs.swap(rhs);
290}
291
292
296class bad_any_cast : public std::bad_cast
297{
298public:
306 virtual const char* what() const noexcept override
307 {
308 return "bad any_cast";
309 }
310};
311
312
321template<typename ValueType>
322ValueType* any_cast(any* operand) noexcept
323{
324 return operand && operand->type() == typeid(ValueType) ? std::addressof(static_cast<any::holder<typename std::remove_cv<ValueType>::type>*>(operand->content)->held) : 0;
325}
326
327
336template<typename ValueType>
337inline const ValueType* any_cast(const any* operand) noexcept
338{
339 return any_cast<ValueType>(const_cast<any*>(operand));
340}
341
342
351template<typename ValueType>
352ValueType any_cast(any& operand)
353{
354 typedef typename std::remove_reference<ValueType>::type nonref;
355
356 nonref* result = any_cast<nonref>(std::addressof(operand));
357 if(!result)
358 throw bad_any_cast();
359
360 typedef typename std::conditional<std::is_reference<ValueType>::value, ValueType, typename std::add_lvalue_reference<ValueType>::type>::type ref_type;
361
362 return static_cast<ref_type>(*result);
363}
364
365
374template<typename ValueType>
375inline ValueType any_cast(const any& operand)
376{
377 typedef typename std::remove_reference<ValueType>::type nonref;
378 return any_cast<const nonref&>(const_cast<any&>(operand));
379}
380
381
390template<typename ValueType>
391inline ValueType any_cast(any&& operand)
392{
393 static_assert(std::is_rvalue_reference<ValueType&&>::value || std::is_const<typename std::remove_reference<ValueType>::type>::value,
394 "any_cast shall not be used for getting nonconst references to temporary objects");
395
396 return any_cast<ValueType>(operand);
397}
398
399}
400}
401
402#endif /* ROBOTSIO_ANY_H */
any() noexcept
Definition: any.h:81
any(any &&other) noexcept
Definition: any.h:101
any & operator=(ValueType &&rhs)
Definition: any.h:176
any(const ValueType &value)
Definition: any.h:114
~any() noexcept
Definition: any.h:133
friend ValueType * any_cast(any *) noexcept
Definition: any.h:322
any(const any &other)
Definition: any.h:91
any & operator=(any &&rhs) noexcept
Definition: any.h:159
any & operator=(const any &rhs)
Definition: any.h:145
void reset() noexcept
Definition: any.h:186
any(ValueType &&value, typename std::enable_if<!std::is_same< any &, ValueType >::value >::type *=0, typename std::enable_if<!std::is_const< ValueType >::value >::type *=0)
Definition: any.h:125
bool has_value() const noexcept
Definition: any.h:208
any & swap(any &rhs) noexcept
Definition: any.h:197
const std::type_info & type() const noexcept
Definition: any.h:219
virtual const char * what() const noexcept override
Definition: any.h:306