LRT14  1.0
 All Classes Namespaces Functions Variables Enumerations Enumerator
Generic.hpp
1 #ifndef RHESUS_GENERIC_H_
2 #define RHESUS_GENERIC_H_
3 
4 #include "../Defines.h"
5 #include "remove_reference.hpp"
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 
73  bool isEmpty()
74  {
75  return m_storedValue == NULL;
76  }
77 
78  template<typename T>
79  Generic& operator=(const T& rhs)
80  {
81  m_storedValue = Generic(rhs).m_storedValue;
82 
83  return *this;
84  }
85 
86  Generic& operator=(Generic rhs)
87  {
88  m_storedValue = rhs.m_storedValue;
89 
90  return *this;
91  }
92 
93  placeholder* Held()
94  {
95  return m_storedValue;
96  }
97 
98  const std::type_info& type() const
99  {
100  return (m_storedValue) ? m_storedValue->type() : typeid(void);
101  }
102  };
103 
104  template<typename T>
105  T* generic_cast(Generic* var)
106  {
107  return (var && typeid(T) == var->type()) ? &(static_cast<Generic::holder<T>*>(var->Held())->val) :
108  0;
109  }
110 
111  template<typename T>
112  inline const T* generic_cast(const Generic* var)
113  {
114  return generic_cast<T>(const_cast<Generic*>(var));
115  }
116 
117  template<typename T>
118  T generic_cast(Generic& var)
119  {
120  typedef typename remove_reference<T>::type nonref;
121 
122  nonref* res = generic_cast<nonref>(&var);
123 
124  if(!res) throw std::exception(); // change this to a more descriptive exception later
125 
126  return *res;
127  }
128 
129  template<typename T>
130  inline T generic_cast(const Generic& var)
131  {
132  typedef typename remove_reference<T>::type nonref;
133 
134  return generic_cast<const nonref&>(const_cast<Generic&>(var));
135  }
136 
137  template<typename T>
138  inline T* unsafe_generic_cast(Generic* var)
139  {
140  return &(static_cast<Generic::holder<T>*>(var->m_storedValue)->val);
141  }
142 
143  template<typename T>
144  inline const T* unsafe_generic_cast(const Generic* var)
145  {
146  return unsafe_generic_cast<T>(const_cast<Generic*>(var));
147  }
148 }
149 }
150 }
151 
152 #endif