xtd 0.2.0
any.h
Go to the documentation of this file.
1 #pragma once
4 #if defined(__cpp_lib_any) || __cplusplus >= 201703l
6 #include <any>
7 #else
8 #include <typeinfo>
9 #include <utility>
10 
11 namespace 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
132 
std::type_info type
Stores information about a type.
Definition: types.h:217
Indicates that all styles except allow_binary_specifier, allow_octal_specifier and allow_hex_specifie...