xtd 0.2.0
Loading...
Searching...
No Matches
any.h
Go to the documentation of this file.
1
3#pragma once
5#if defined(__cpp_lib_any) || __cplusplus >= 201703l
6#include <any>
7#else
8#include <typeinfo>
9#include <utility>
10
11namespace std {
12 class any;
13 template <typename value_t>
14 value_t any_cast(const any& any);
15
16 template <typename value_t>
17 value_t* any_cast(any* any) noexcept;
18
19 template <typename value_t>
20 const value_t* any_cast(const any* any) noexcept;
21
22 class bad_any_cast : public std::bad_cast {
23 public:
24 const char* what() const noexcept override {return "bad any cast";}
25 };
26
27 class any {
28 public:
29 any() noexcept = default;
30 any(const any& other) : content(other.content ? other.content->clone() : nullptr) {}
31 template <typename value_t>
32 any(const value_t& value) : content(new derived<value_t>(value)) {}
33 template <typename value_t>
34 any(value_t&& value) : content(new derived<value_t>(std::move(value))) {}
35
36 ~any() {reset();}
37
38 any& operator=(const any& other) {
39 if (this == &other) return *this;
40 reset();
41 content = other.content ? other.content->clone() : nullptr;
42 return *this;
43 }
44
45 any& operator=(const any&& other) noexcept {
46 if (this == &other) return *this;
47 reset();
48 content = other.content ? std::move(other.content) : nullptr;
49 return *this;
50 }
51
52 template <typename value_t>
53 any& operator=(const value_t& value) {
54 reset();
55 content = new derived<value_t>(value);
56 return *this;
57 }
58
59 bool has_value() const noexcept {return content != nullptr;}
60
61 const std::type_info& type() const noexcept {return content ? content->type : typeid(void);}
62
63 void reset() noexcept {delete content;}
64
65 private:
66 template <typename value_t>
67 friend value_t any_cast(const any& any);
68
69 template <typename value_t>
70 friend value_t* any_cast(any* any) noexcept;
71
72 template <typename value_t>
73 friend const value_t* any_cast(const any* any) noexcept;
74
75 template <typename value_t>
76 value_t& value() {
77 return static_cast<derived<value_t>*>(content)->data;
78 }
79
80 template <typename value_t>
81 const value_t& value() const {
82 return static_cast<derived<value_t>*>(content)->data;
83 }
84
85 struct base {
86 base(const type_info& type) : type(type) {}
87 virtual ~base() {}
88 virtual base* clone() const = 0;
89
90 const type_info& type;
91 };
92
93 template <typename value_t>
94 struct derived : public base {
95 derived(const value_t& value) : base(typeid(value)), data(value) {}
96 value_t data;
97
98 value_t& operator*() {return data;}
99
100 base* clone() const override {
101 return new derived<value_t>(*this);
102 }
103 };
104
105 base* content = nullptr;
106 };
107
108 template <typename value_t>
109 value_t any_cast(const any& any) {
110 if (!any.has_value() || typeid(value_t) != any.type()) throw bad_any_cast();
111 return any.value<value_t>();
112 }
113
114 template <typename value_t>
115 value_t* any_cast(any* any) noexcept {
116 if (any == nullptr || !any->has_value() || typeid(value_t) != any->type()) return nullptr;
117 return any->value<value_t>();
118 }
119
120 template <typename value_t>
121 const value_t* any_cast(const any* any) noexcept {
122 if (any == nullptr || !any->has_value() || typeid(value_t) != any->type()) return nullptr;
123 return any->value<value_t>();
124 }
125
126 template <typename value_t>
127 any make_any(value_t&& value) {
128 return any(std::forward<value_t>(value));
129 }
130}
131#endif
std::type_info type
Stores information about a type.
Definition types.h:219
@ any
Indicates that all styles except allow_binary_specifier, allow_octal_specifier and allow_hex_specifie...
@ other
The operating system is other.