-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathAny.h
81 lines (77 loc) · 1.85 KB
/
Any.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#ifndef ANY_H
#define ANY_H
#include <typeinfo>
class Any {
private:
struct IHolder {
const type_info *info;
IHolder(const type_info* _info): info(_info){}
virtual ~IHolder(){}
virtual void* getPtr() = 0;
virtual IHolder* clone() = 0;
};
template<typename T>
struct Holder:
public IHolder {
T value;
explicit Holder(const T &val): IHolder(&typeid(T)), value(val){}
virtual void* getPtr(){ return &value;}
virtual IHolder* clone() { return new Holder(value);}
};
public:
Any(): m_holder(NULL) {
}
Any(const Any& o): m_holder(NULL) {
*this = o;
}
Any(Any&& o): m_holder(NULL) {
*this = forward<Any>(o);
}
Any& operator = (const Any& o) {
if (this != &o) {
this->~Any();
if (o.m_holder != NULL) m_holder = o.m_holder->clone();
else m_holder = NULL;
}
return *this;
}
Any& operator = (Any &&o) {
if (this != &o) {
this->~Any();
m_holder = o.m_holder;
o.m_holder = NULL;
}
return *this;
}
~Any() {
delete m_holder;
m_holder = NULL;
}
template<typename T>
Any(const T& v) {
m_holder = new Holder<T>(v);
}
template<typename T>
Any& operator = (const T &v) {
delete m_holder;
m_holder = new Holder<T>(v);
return *this;
}
template<typename T>
T& get() {
ASSERT(&typeid(T) == m_holder->info);
return *(T*)m_holder->getPtr();
}
template<typename T>
const T& get() const {
ASSERT(&typeid(T) == m_holder->info);
return *(T*)m_holder->getPtr();
}
template<typename T>
bool isTypeOf() const {
return &typeid(T) == m_holder->info;
}
private:
IHolder *m_holder;
};
#endif