Ditto 4.8.0-rc.2
Loading...
Searching...
No Matches
any.hpp
1#ifndef _ANY_
2#define _ANY_
3
4#include <memory>
5
6namespace ditto {
7
15class any {
16private:
17 struct VirtualBase {
18 virtual ~VirtualBase() noexcept {}
19 virtual std::type_info const &virtual_type() const noexcept = 0;
20 virtual std::unique_ptr<VirtualBase> virtual_clone() const noexcept = 0;
21
22 template <typename T>
23 static std::unique_ptr<VirtualBase> upcast(T const &value) noexcept {
24 return std::unique_ptr<VirtualBase>(new ConcreteType<T>(value));
25 }
26 };
27
28 // main field of `any`:
29 std::unique_ptr<VirtualBase> erased_value;
30
31 // helper to go from `<T>` to `VirtualBase`.
32 template <typename T> struct ConcreteType : VirtualBase {
33 T value;
34
35 explicit ConcreteType(T const &val) noexcept : value(val) {}
36
37 std::type_info const &virtual_type() const noexcept override {
38 return typeid(T);
39 }
40
41 std::unique_ptr<VirtualBase> virtual_clone() const noexcept override {
42 return any::VirtualBase::upcast(value);
43 }
44 };
45
46 template <typename T> friend T any_cast(ditto::any const &operand);
47
48public:
49 any() noexcept;
50
51 template <typename T>
52 any(T const &value) noexcept
53 : erased_value(any::VirtualBase::upcast(value)) {}
54
55 any(any const &other) noexcept;
56
57 void swap(any &other) noexcept;
58
59 any &operator=(any const &other) noexcept;
60
61 std::type_info const &type() const noexcept;
62
63 bool has_value() const noexcept;
64
65 template <typename T> T as() const {
66 if (auto ptr =
67 dynamic_cast<any::ConcreteType<T> const *>(erased_value.get())) {
68 return ptr->value;
69 } else {
70 throw std::bad_cast();
71 }
72 }
73};
74
75template <typename T> T any_cast(ditto::any const &operand) {
76 return operand.as<T>();
77}
78
79} // namespace ditto
80
81#endif // _ANY_
Polyfill of std::any for C++11.
Definition any.hpp:15