22 #ifndef GEARS_UTILITY_ANY_HPP
23 #define GEARS_UTILITY_ANY_HPP
25 #include <type_traits>
33 struct bad_any_cast :
public std::bad_cast {
34 virtual const char* what() const noexcept {
35 return "bad_any_cast";
85 using Decayed =
typename std::decay<T>::type;
89 virtual std::unique_ptr<base> clone()
const = 0;
92 std::unique_ptr<base> obj;
95 struct object : base {
96 static_assert(std::is_copy_constructible<Decayed<T>>(),
"Concept violation: T is not CopyConstructible");
98 object(U&& v): value(std::forward<U>(v)) {}
101 std::unique_ptr<base> clone()
const {
102 return std::unique_ptr<base>(
new object<T>(value));
106 std::unique_ptr<base> clone()
const {
107 return obj ? obj->clone() :
nullptr;
115 any() noexcept =
default;
128 any(T&& actual) noexcept: obj(new(std::nothrow)
object<Decayed<T>>(std::forward<T>(actual))) {}
133 any(
const any& other): obj(other.clone()) {}
138 any(
any&& other): obj(std::move(other.obj)) {}
168 explicit operator bool()
const {
169 return static_cast<bool>(obj);
185 auto ptr =
dynamic_cast<object<Decayed<T>
>*>(obj.get());
200 const Decayed<T>&
as()
const {
201 auto ptr =
dynamic_cast<object<Decayed<T>
>*>(obj.get());
203 throw detail::bad_any_cast();
209 auto ptr =
dynamic_cast<object<Decayed<T>
>*>(obj.get());
211 throw detail::bad_any_cast();
228 inline auto any_cast(
const any&
object) -> decltype(
object.as<T>()) {
229 return object.as<T>();
234 #endif // GEARS_UTILITY_ANY_HPP