OGRE  1.9.0
OgreAny.h
Go to the documentation of this file.
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4 (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2014 Torus Knot Software Ltd
8
9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal
11in the Software without restriction, including without limitation the rights
12to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13copies of the Software, and to permit persons to whom the Software is
14furnished to do so, subject to the following conditions:
15
16The above copyright notice and this permission notice shall be included in
17all copies or substantial portions of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25THE SOFTWARE.
26-----------------------------------------------------------------------------
27*/
28// -- Based on boost::any, original copyright information follows --
29// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
30//
31// Distributed under the Boost Software License, Version 1.0. (See
32// accompAnying file LICENSE_1_0.txt or copy at
33// http://www.boost.org/LICENSE_1_0.txt)
34// -- End original copyright --
35
36#ifndef __OGRE_ANY_H__
37#define __OGRE_ANY_H__
38
39#include "OgrePrerequisites.h"
40#include "OgreException.h"
41#include "OgreString.h"
42#include <algorithm>
43#include <typeinfo>
44#include "OgreHeaderPrefix.h"
45
46namespace Ogre
47{
56 class Any
57 {
58 public: // constructors
59
61 : mContent(0)
62 {
63 }
64
65 template<typename ValueType>
66 explicit Any(const ValueType & value)
67 : mContent(OGRE_NEW_T(holder<ValueType>, MEMCATEGORY_GENERAL)(value))
68 {
69 }
70
71 Any(const Any & other)
72 : mContent(other.mContent ? other.mContent->clone() : 0)
73 {
74 }
75
76 virtual ~Any()
77 {
78 destroy();
79 }
80
81 public: // modifiers
82
83 Any& swap(Any & rhs)
84 {
86 return *this;
87 }
88
89 template<typename ValueType>
90 Any& operator=(const ValueType & rhs)
91 {
92 Any(rhs).swap(*this);
93 return *this;
94 }
95
96 Any & operator=(const Any & rhs)
97 {
98 Any(rhs).swap(*this);
99 return *this;
100 }
101
102 public: // queries
103
104 bool isEmpty() const
105 {
106 return !mContent;
107 }
108
109 const std::type_info& getType() const
110 {
111 return mContent ? mContent->getType() : typeid(void);
112 }
113
114 inline friend std::ostream& operator <<
115 ( std::ostream& o, const Any& v )
116 {
117 if (v.mContent)
118 v.mContent->writeToStream(o);
119 return o;
120 }
121
127
128 protected: // types
129
131 {
132 public: // structors
133
134 virtual ~placeholder()
135 {
136 }
137
138 public: // queries
139
140 virtual const std::type_info& getType() const = 0;
141
142 virtual placeholder * clone() const = 0;
143
144 virtual void writeToStream(std::ostream& o) = 0;
145
146 };
147
148 template<typename ValueType>
149 class holder : public placeholder
150 {
151 public: // structors
152
153 holder(const ValueType & value)
154 : held(value)
155 {
156 }
157
158 public: // queries
159
160 virtual const std::type_info & getType() const
161 {
162 return typeid(ValueType);
163 }
164
165 virtual placeholder * clone() const
166 {
168 }
169
170 virtual void writeToStream(std::ostream& o)
171 {
172 o << held;
173 }
174
175
176 public: // representation
177
178 ValueType held;
179
180 };
181
182
183
184 protected: // representation
186
187 template<typename ValueType>
188 friend ValueType * any_cast(Any *);
189
190
191 public:
192
193 template<typename ValueType>
194 ValueType operator()() const
195 {
196 if (!mContent)
197 {
199 "Bad cast from uninitialised Any",
200 "Any::operator()");
201 }
202 else if(getType() == typeid(ValueType))
203 {
204 return static_cast<Any::holder<ValueType> *>(mContent)->held;
205 }
206 else
207 {
209 str << "Bad cast from type '" << getType().name() << "' "
210 << "to '" << typeid(ValueType).name() << "'";
212 str.str(),
213 "Any::operator()");
214 }
215 }
216
217 template <typename ValueType>
218 ValueType get(void) const
219 {
220 if (!mContent)
221 {
223 "Bad cast from uninitialised Any",
224 "Any::operator()");
225 }
226 else if(getType() == typeid(ValueType))
227 {
228 return static_cast<Any::holder<ValueType> *>(mContent)->held;
229 }
230 else
231 {
233 str << "Bad cast from type '" << getType().name() << "' "
234 << "to '" << typeid(ValueType).name() << "'";
236 str.str(),
237 "Any::operator()");
238 }
239 }
240
241 };
242
243
247 class AnyNumeric : public Any
248 {
249 public:
251 : Any()
252 {
253 }
254
255 template<typename ValueType>
256 AnyNumeric(const ValueType & value)
257
258 {
260 }
261
262 AnyNumeric(const AnyNumeric & other)
263 : Any()
264 {
265 mContent = other.mContent ? other.mContent->clone() : 0;
266 }
267
268 protected:
270 {
271 public: // structors
272
274 {
275 }
276 virtual placeholder* add(placeholder* rhs) = 0;
277 virtual placeholder* subtract(placeholder* rhs) = 0;
278 virtual placeholder* multiply(placeholder* rhs) = 0;
279 virtual placeholder* multiply(Real factor) = 0;
280 virtual placeholder* divide(placeholder* rhs) = 0;
281 };
282
283 template<typename ValueType>
285 {
286 public: // structors
287
288 numholder(const ValueType & value)
289 : held(value)
290 {
291 }
292
293 public: // queries
294
295 virtual const std::type_info & getType() const
296 {
297 return typeid(ValueType);
298 }
299
300 virtual placeholder * clone() const
301 {
303 }
304
306 {
307 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held + static_cast<numholder*>(rhs)->held);
308 }
310 {
311 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held - static_cast<numholder*>(rhs)->held);
312 }
314 {
315 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held * static_cast<numholder*>(rhs)->held);
316 }
317 virtual placeholder* multiply(Real factor)
318 {
319 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held * factor);
320 }
322 {
323 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held / static_cast<numholder*>(rhs)->held);
324 }
325 virtual void writeToStream(std::ostream& o)
326 {
327 o << held;
328 }
329
330 public: // representation
331
332 ValueType held;
333
334 };
335
338 {
339 mContent = pholder;
340 }
341
342 public:
344 {
345 AnyNumeric(rhs).swap(*this);
346 return *this;
347 }
349 {
350 return AnyNumeric(
351 static_cast<numplaceholder*>(mContent)->add(rhs.mContent));
352 }
354 {
355 return AnyNumeric(
356 static_cast<numplaceholder*>(mContent)->subtract(rhs.mContent));
357 }
359 {
360 return AnyNumeric(
361 static_cast<numplaceholder*>(mContent)->multiply(rhs.mContent));
362 }
364 {
365 return AnyNumeric(
366 static_cast<numplaceholder*>(mContent)->multiply(factor));
367 }
369 {
370 return AnyNumeric(
371 static_cast<numplaceholder*>(mContent)->divide(rhs.mContent));
372 }
374 {
375 *this = AnyNumeric(
376 static_cast<numplaceholder*>(mContent)->add(rhs.mContent));
377 return *this;
378 }
380 {
381 *this = AnyNumeric(
382 static_cast<numplaceholder*>(mContent)->subtract(rhs.mContent));
383 return *this;
384 }
386 {
387 *this = AnyNumeric(
388 static_cast<numplaceholder*>(mContent)->multiply(rhs.mContent));
389 return *this;
390 }
392 {
393 *this = AnyNumeric(
394 static_cast<numplaceholder*>(mContent)->divide(rhs.mContent));
395 return *this;
396 }
397
398
399
400
401 };
402
403
404 template<typename ValueType>
405 ValueType * any_cast(Any * operand)
406 {
407 return operand && (std::strcmp(operand->getType().name(), typeid(ValueType).name()) == 0)
408 ? &static_cast<Any::holder<ValueType> *>(operand->mContent)->held
409 : 0;
410 }
411
412 template<typename ValueType>
413 const ValueType * any_cast(const Any * operand)
414 {
415 return any_cast<ValueType>(const_cast<Any *>(operand));
416 }
417
418 template<typename ValueType>
419 ValueType any_cast(const Any & operand)
420 {
421 const ValueType * result = any_cast<ValueType>(&operand);
422 if(!result)
423 {
425 str << "Bad cast from type '" << operand.getType().name() << "' "
426 << "to '" << typeid(ValueType).name() << "'";
428 str.str(),
429 "Ogre::any_cast");
430 }
431 return *result;
432 }
437}
438
439#include "OgreHeaderSuffix.h"
440
441#endif
442
virtual placeholder * divide(placeholder *rhs)
Definition OgreAny.h:321
virtual void writeToStream(std::ostream &o)
Definition OgreAny.h:325
virtual placeholder * subtract(placeholder *rhs)
Definition OgreAny.h:309
virtual placeholder * add(placeholder *rhs)
Definition OgreAny.h:305
virtual placeholder * clone() const
Definition OgreAny.h:300
numholder(const ValueType &value)
Definition OgreAny.h:288
virtual const std::type_info & getType() const
Definition OgreAny.h:295
virtual placeholder * multiply(Real factor)
Definition OgreAny.h:317
virtual placeholder * multiply(placeholder *rhs)
Definition OgreAny.h:313
virtual placeholder * multiply(placeholder *rhs)=0
virtual placeholder * divide(placeholder *rhs)=0
virtual placeholder * subtract(placeholder *rhs)=0
virtual placeholder * add(placeholder *rhs)=0
virtual placeholder * multiply(Real factor)=0
Specialised Any class which has built in arithmetic operators, but can hold only types which support ...
Definition OgreAny.h:248
AnyNumeric operator+(const AnyNumeric &rhs) const
Definition OgreAny.h:348
AnyNumeric & operator-=(const AnyNumeric &rhs)
Definition OgreAny.h:379
AnyNumeric & operator+=(const AnyNumeric &rhs)
Definition OgreAny.h:373
AnyNumeric(const ValueType &value)
Definition OgreAny.h:256
AnyNumeric(placeholder *pholder)
Construct from holder.
Definition OgreAny.h:337
AnyNumeric operator*(const AnyNumeric &rhs) const
Definition OgreAny.h:358
AnyNumeric(const AnyNumeric &other)
Definition OgreAny.h:262
AnyNumeric operator/(const AnyNumeric &rhs) const
Definition OgreAny.h:368
AnyNumeric operator-(const AnyNumeric &rhs) const
Definition OgreAny.h:353
AnyNumeric & operator*=(const AnyNumeric &rhs)
Definition OgreAny.h:385
AnyNumeric operator*(Real factor) const
Definition OgreAny.h:363
AnyNumeric & operator/=(const AnyNumeric &rhs)
Definition OgreAny.h:391
AnyNumeric & operator=(const AnyNumeric &rhs)
Definition OgreAny.h:343
virtual void writeToStream(std::ostream &o)
Definition OgreAny.h:170
virtual placeholder * clone() const
Definition OgreAny.h:165
ValueType held
Definition OgreAny.h:178
holder(const ValueType &value)
Definition OgreAny.h:153
virtual const std::type_info & getType() const
Definition OgreAny.h:160
virtual const std::type_info & getType() const =0
virtual placeholder * clone() const =0
virtual void writeToStream(std::ostream &o)=0
virtual ~placeholder()
Definition OgreAny.h:134
Variant type that can hold Any other type.
Definition OgreAny.h:57
void destroy()
Definition OgreAny.h:122
ValueType get(void) const
Definition OgreAny.h:218
Any & swap(Any &rhs)
Definition OgreAny.h:83
Any(const ValueType &value)
Definition OgreAny.h:66
Any & operator=(const Any &rhs)
Definition OgreAny.h:96
Any(const Any &other)
Definition OgreAny.h:71
bool isEmpty() const
Definition OgreAny.h:104
placeholder * mContent
Definition OgreAny.h:185
const std::type_info & getType() const
Definition OgreAny.h:109
friend ValueType * any_cast(Any *)
Definition OgreAny.h:405
ValueType operator()() const
Definition OgreAny.h:194
Any & operator=(const ValueType &rhs)
Definition OgreAny.h:90
virtual ~Any()
Definition OgreAny.h:76
StringStream StrStreamType
Definition OgreString.h:78
ValueType * any_cast(Any *operand)
Definition OgreAny.h:405
#define OGRE_EXCEPT(code, desc, src)
#define OGRE_DELETE_T(ptr, T, category)
Free the memory allocated with OGRE_NEW_T. Category is required to be restated to ensure the matching...
#define OGRE_NEW_T(T, category)
Allocate space for one primitive type, external type or non-virtual type with constructor parameters.
@ MEMCATEGORY_GENERAL
General purpose.
float Real
Software floating point type.
void swap(Ogre::SmallVectorImpl< T > &LHS, Ogre::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.