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