LRT14  1.0
 All Classes Namespaces Functions Variables Enumerations Enumerator
Generic.h
1 #ifndef RHESUS_GENERIC_H_
2 #define RHESUS_GENERIC_H_
3 
4 #include "../Defines.h"
5 #include "remove_reference.h"
6 #include <typeinfo>
7 
8 namespace Rhesus
9 {
10 namespace Toolkit
11 {
12 namespace Utilities
13 {
14 
20  class Generic
21  {
22 
23  private:
24  struct placeholder
25  {
26  virtual ~placeholder() {}
27 
28  virtual const std::type_info& type() const = 0;
29  };
30 
31  template<typename T>
32  struct holder : public placeholder
33  {
34  T val;
35 
36  holder(T value)
37  : val(value)
38  {
39  }
40 
41  const std::type_info& type() const
42  {
43  return typeid(T);
44  }
45  };
46 
47  placeholder* m_storedValue;
48 
49  public:
50 
51  Generic()
52  : m_storedValue(NULL)
53  {
54  }
55 
56  Generic(const Generic& other)
57  : m_storedValue(other.m_storedValue ? other.m_storedValue : NULL)
58  {
59 
60  }
61 
62  template<typename T>
63  Generic(const T& value)
64  : m_storedValue(new holder<T>(value))
65  {
66  }
67 
68  ~Generic()
69  {
70  DELETE(m_storedValue);
71  }
72 
76  bool isEmpty()
77  {
78  return m_storedValue == NULL;
79  }
80 
81  template<typename T>
82  Generic& operator=(const T& rhs)
83  {
84  m_storedValue = Generic(rhs).m_storedValue;
85 
86  return *this;
87  }
88 
89  Generic& operator=(Generic rhs)
90  {
91  m_storedValue = rhs.m_storedValue;
92 
93  return *this;
94  }
95 
96  placeholder* Held()
97  {
98  return m_storedValue;
99  }
100 
101  const std::type_info& type() const
102  {
103  return (m_storedValue) ? m_storedValue->type() : typeid(void);
104  }
105  };
106 
107  template<typename T>
108  T* generic_cast(Generic* var)
109  {
110  return (var && typeid(T) == var->type()) ? &(static_cast<Generic::holder<T>*>(var->Held())->val) :
111  0;
112  }
113 
114  template<typename T>
115  inline const T* generic_cast(const Generic* var)
116  {
117  return generic_cast<T>(const_cast<Generic*>(var));
118  }
119 
120  template<typename T>
121  T generic_cast(Generic& var)
122  {
123  typedef typename remove_reference<T>::type nonref;
124 
125  nonref* res = generic_cast<nonref>(&var);
126 
127  if(!res) throw std::exception(); // change this to a more descriptive exception later
128 
129  return *res;
130  }
131 
132  template<typename T>
133  inline T generic_cast(const Generic& var)
134  {
135  typedef typename remove_reference<T>::type nonref;
136 
137  return generic_cast<const nonref&>(const_cast<Generic&>(var));
138  }
139 
140  template<typename T>
141  inline T* unsafe_generic_cast(Generic* var)
142  {
143  return &(static_cast<Generic::holder<T>*>(var->m_storedValue)->val);
144  }
145 
146  template<typename T>
147  inline const T* unsafe_generic_cast(const Generic* var)
148  {
149  return unsafe_generic_cast<T>(const_cast<Generic*>(var));
150  }
151 }
152 }
153 }
154 
155 #endif