Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/nall/any.hpp
2 views
1
#ifndef NALL_ANY_HPP
2
#define NALL_ANY_HPP
3
4
#include <typeinfo>
5
#include <nall/type_traits.hpp>
6
7
namespace nall {
8
struct any {
9
bool empty() const { return container; }
10
const std::type_info& type() const { return container ? container->type() : typeid(void); }
11
12
template<typename T> any& operator=(const T& value_) {
13
typedef typename type_if<
14
std::is_array<T>::value,
15
typename std::remove_extent<typename std::add_const<T>::type>::type*,
16
T
17
>::type auto_t;
18
19
if(type() == typeid(auto_t)) {
20
static_cast<holder<auto_t>*>(container)->value = (auto_t)value_;
21
} else {
22
if(container) delete container;
23
container = new holder<auto_t>((auto_t)value_);
24
}
25
26
return *this;
27
}
28
29
any() : container(0) {}
30
template<typename T> any(const T& value_) : container(0) { operator=(value_); }
31
32
private:
33
struct placeholder {
34
virtual const std::type_info& type() const = 0;
35
} *container;
36
37
template<typename T> struct holder : placeholder {
38
T value;
39
const std::type_info& type() const { return typeid(T); }
40
holder(const T& value_) : value(value_) {}
41
};
42
43
template<typename T> friend T any_cast(any&);
44
template<typename T> friend T any_cast(const any&);
45
template<typename T> friend T* any_cast(any*);
46
template<typename T> friend const T* any_cast(const any*);
47
};
48
49
template<typename T> T any_cast(any &value) {
50
typedef typename std::remove_reference<T>::type nonref;
51
if(value.type() != typeid(nonref)) throw;
52
return static_cast<any::holder<nonref>*>(value.container)->value;
53
}
54
55
template<typename T> T any_cast(const any &value) {
56
typedef const typename std::remove_reference<T>::type nonref;
57
if(value.type() != typeid(nonref)) throw;
58
return static_cast<any::holder<nonref>*>(value.container)->value;
59
}
60
61
template<typename T> T* any_cast(any *value) {
62
if(!value || value->type() != typeid(T)) return 0;
63
return &static_cast<any::holder<T>*>(value->container)->value;
64
}
65
66
template<typename T> const T* any_cast(const any *value) {
67
if(!value || value->type() != typeid(T)) return 0;
68
return &static_cast<any::holder<T>*>(value->container)->value;
69
}
70
}
71
72
#endif
73
74