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