ETL  0.04.19
_value.h
Go to the documentation of this file.
1 /* ========================================================================
2 ** Extended Template and Library
3 ** Abstraction for a Generic Value Type
4 ** $Id$
5 **
6 ** Copyright (c) 2002 Adrian Bentley
7 ** Copyright (c) 2010 Nikita Kitaev
8 **
9 ** This package is free software; you can redistribute it and/or
10 ** modify it under the terms of the GNU General Public License as
11 ** published by the Free Software Foundation; either version 2 of
12 ** the License, or (at your option) any later version.
13 **
14 ** This package is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 ** General Public License for more details.
18 **
19 ** === N O T E S ===========================================================
20 **
21 ** This is an internal header file, included by other ETL headers.
22 ** You should not attempt to use it directly.
23 **
24 ** ========================================================================= */
25 
26 /* === S T A R T =========================================================== */
27 
28 #ifndef __ETL__VALUE_H
29 #define __ETL__VALUE_H
30 
31 /* === H E A D E R S ======================================================= */
32 #include <algorithm>
33 #include <typeinfo>
34 #include <cassert>
35 
36 /* === M A C R O S ========================================================= */
37 
38 /* === T Y P E D E F S ===================================================== */
39 
40 /* === C L A S S E S & S T R U C T S ======================================= */
41 
51 template < typename T >
53 {
54 public:
55  typedef T value_type;
56 };
57 
59 
66 class value
67 {
69  {
70  virtual ~contentholder() {}
71  virtual contentholder *clone() const = 0;
72  virtual const std::type_info &type() const = 0;
73  };
74 
76 
77 public: //constructor interface
79  :content(0)
80  {
81  }
82 
83  value(const value &v)
84  :content( v.content ? v.content->clone() : 0 )
85  {
86  }
87 
88  /* Copies the object passed to it
89  */
90  template < typename T >
91  value(const T &v)
92  :content( new holder< typename value_store_type<T>::value_type >
93  (reinterpret_cast<const typename value_store_type<T>::value_type &>(v)) )
94  {
95  }
96 
97 public: //modifier interface
98 
99  value & swap(value & rhs)
100  {
101  std::swap(content, rhs.content);
102  return *this;
103  }
104 
105  template<typename ValueType>
106  value & operator=(const ValueType & rhs)
107  {
108  value(rhs).swap(*this);
109  return *this;
110  }
111 
112  value & operator=(const value & rhs)
113  {
114  value(rhs).swap(*this);
115  return *this;
116  }
117 
118 public: //query interface
119 
120  bool empty() const
121  {
122  return content == 0;
123  }
124 
125  const std::type_info & type() const
126  {
127  return content ? content->type() : typeid(void);
128  }
129 
130 private: //implementation interface
131 
132  template < typename T >
133  class holder : public contentholder
134  {
135  public: //representation
136  T obj;
137 
138  public: //constructor interface
139 
140  holder(const T &o)
141  :obj(o)
142  {
143  }
144 
145  holder(const holder<T> &h)
146  :obj(h.obj)
147  {
148  }
149 
150  public: //accessor interface
151  virtual contentholder *clone() const
152  {
153  return new holder(*this);
154  }
155 
156  virtual const std::type_info &type() const
157  {
158  return typeid(T);
159  }
160 
161  public: //allocation interface
162  void *operator new(size_t size)
163  {
164  assert(size == sizeof(holder<T>));
165 
166  //use pool allocation at some point
167  return malloc(size);
168  }
169 
170  void operator delete(void *p)
171  {
172  assert(p);
173  //use pool allocation at some point
174  return free(p);
175  }
176  };
177 
178  template < typename ValueType >
179  friend ValueType *value_cast(value *v);
180 };
181 
184 class bad_value_cast : public std::bad_cast
185 {
186 public:
187  virtual const char * what() const throw()
188  {
189  return "etl::bad_value_cast: " "failed conversion using boost::value_cast";
190  }
191 };
192 
199 template < typename ValueType >
200 ValueType *value_cast(value *v)
201 {
202  assert(v);
203 
204  return ( typeid(typename value_store_type<ValueType>::value_type) == v->type() )
205  ? &static_cast<value::holder<ValueType> *>(v->content)->obj
206  : 0;
207 }
208 
212 template < typename ValueType >
213 const ValueType * value_cast(const value *v)
214 {
215  return value_cast<ValueType>(const_cast<value *>(v));
216 }
217 
225 template < typename ValueType >
226 ValueType value_cast(const value &v)
227 {
228  const ValueType * result = value_cast<ValueType>(&v);
229  if(!result)
230  throw bad_value_cast();
231  return *result;
232 }
233 
235 
236 /* === E N D =============================================================== */
237 
238 #endif