# OgreAny.h

Go to the documentation of this file.

    00001 /*
    00002 -----------------------------------------------------------------------------
    00003 This source file is part of OGRE
    00004     (Object-oriented Graphics Rendering Engine)
    00005 For the latest info, see http://www.ogre3d.org/
    00006
    00007 Copyright (c) 2000-2009 Torus Knot Software Ltd
    00008
    00009 Permission is hereby granted, free of charge, to any person obtaining a copy
    00010 of this software and associated documentation files (the "Software"), to deal
    00011 in the Software without restriction, including without limitation the rights
    00012 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    00013 copies of the Software, and to permit persons to whom the Software is
    00014 furnished to do so, subject to the following conditions:
    00015
    00016 The above copyright notice and this permission notice shall be included in
    00017 all copies or substantial portions of the Software.
    00018
    00019 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    00020 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    00021 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    00022 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    00023 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    00024 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    00025 THE SOFTWARE.
    00026 -----------------------------------------------------------------------------
    00027 */
    00028 // -- Based on boost::any, original copyright information follows --
    00029 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
    00030 //
    00031 // Distributed under the Boost Software License, Version 1.0. (See
    00032 // accompAnying file LICENSE_1_0.txt or copy at
    00033 // http://www.boost.org/LICENSE_1_0.txt)
    00034 // -- End original copyright --
    00035
    00036 #ifndef __OGRE_ANY_H__
    00037 #define __OGRE_ANY_H__
    00038
    00039 #include "OgrePrerequisites.h"
    00040 #include "OgreException.h"
    00041 #include "OgreString.h"
    00042 #include <algorithm>
    00043 #include <typeinfo>
    00044
    00045
    00046 namespace Ogre
    00047 {
    00056     class Any
    00057     {
    00058     public: // constructors
    00059
    00060         Any()
    00061           : mContent(0)
    00062         {
    00063         }
    00064
    00065         template<typename ValueType>
    00066         explicit Any(const ValueType & value)
    00067           : mContent(OGRE_NEW_T(holder<ValueType>, MEMCATEGORY_GENERAL)(value))
    00068         {
    00069         }
    00070
    00071         Any(const Any & other)
    00072           : mContent(other.mContent ? other.mContent->clone() : 0)
    00073         {
    00074         }
    00075
    00076         virtual ~Any()
    00077         {
    00078             destroy();
    00079         }
    00080
    00081     public: // modifiers
    00082
    00083         Any& swap(Any & rhs)
    00084         {
    00085             std::swap(mContent, rhs.mContent);
    00086             return *this;
    00087         }
    00088
    00089         template<typename ValueType>
    00090         Any& operator=(const ValueType & rhs)
    00091         {
    00092             Any(rhs).swap(*this);
    00093             return *this;
    00094         }
    00095
    00096         Any & operator=(const Any & rhs)
    00097         {
    00098             Any(rhs).swap(*this);
    00099             return *this;
    00100         }
    00101
    00102     public: // queries
    00103
    00104         bool isEmpty() const
    00105         {
    00106             return !mContent;
    00107         }
    00108
    00109         const std::type_info& getType() const
    00110         {
    00111             return mContent ? mContent->getType() : typeid(void);
    00112         }
    00113
    00114         inline friend std::ostream& operator <<
    00115             ( std::ostream& o, const Any& v )
    00116         {
    00117             if (v.mContent)
    00118                 v.mContent->writeToStream(o);
    00119             return o;
    00120         }
    00121
    00122         void destroy()
    00123         {
    00124             OGRE_DELETE_T(mContent, placeholder, MEMCATEGORY_GENERAL);
    00125             mContent = NULL;
    00126         }
    00127
    00128     protected: // types
    00129
    00130         class placeholder
    00131         {
    00132         public: // structors
    00133
    00134             virtual ~placeholder()
    00135             {
    00136             }
    00137
    00138         public: // queries
    00139
    00140             virtual const std::type_info& getType() const = 0;
    00141
    00142             virtual placeholder * clone() const = 0;
    00143
    00144             virtual void writeToStream(std::ostream& o) = 0;
    00145
    00146         };
    00147
    00148         template<typename ValueType>
    00149         class holder : public placeholder
    00150         {
    00151         public: // structors
    00152
    00153             holder(const ValueType & value)
    00154               : held(value)
    00155             {
    00156             }
    00157
    00158         public: // queries
    00159
    00160             virtual const std::type_info & getType() const
    00161             {
    00162                 return typeid(ValueType);
    00163             }
    00164
    00165             virtual placeholder * clone() const
    00166             {
    00167                 return OGRE_NEW_T(holder, MEMCATEGORY_GENERAL)(held);
    00168             }
    00169
    00170             virtual void writeToStream(std::ostream& o)
    00171             {
    00172                 o << held;
    00173             }
    00174
    00175
    00176         public: // representation
    00177
    00178             ValueType held;
    00179
    00180         };
    00181
    00182
    00183
    00184     protected: // representation
    00185         placeholder * mContent;
    00186
    00187         template<typename ValueType>
    00188         friend ValueType * any_cast(Any *);
    00189
    00190
    00191     public:
    00192
    00193         template<typename ValueType>
    00194         ValueType operator()() const
    00195         {
    00196             if (!mContent)
    00197             {
    00198                 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
    00199                     "Bad cast from uninitialised Any",
    00200                     "Any::operator()");
    00201             }
    00202             else if(getType() == typeid(ValueType))
    00203             {
    00204                 return static_cast<Any::holder<ValueType> *>(mContent)->held;
    00205             }
    00206             else
    00207             {
    00208                 StringUtil::StrStreamType str;
    00209                 str << "Bad cast from type '" << getType().name() << "' "
    00210                     << "to '" << typeid(ValueType).name() << "'";
    00211                 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
    00212                      str.str(),
    00213                     "Any::operator()");
    00214             }
    00215         }
    00216
    00217
    00218
    00219     };
    00220
    00221
    00225     class AnyNumeric : public Any
    00226     {
    00227     public:
    00228         AnyNumeric()
    00229         : Any()
    00230         {
    00231         }
    00232
    00233         template<typename ValueType>
    00234         AnyNumeric(const ValueType & value)
    00235
    00236         {
    00237             mContent = OGRE_NEW_T(numholder<ValueType>, MEMCATEGORY_GENERAL)(value);
    00238         }
    00239
    00240         AnyNumeric(const AnyNumeric & other)
    00241             : Any()
    00242         {
    00243             mContent = other.mContent ? other.mContent->clone() : 0;
    00244         }
    00245
    00246     protected:
    00247         class numplaceholder : public Any::placeholder
    00248         {
    00249         public: // structors
    00250
    00251             ~numplaceholder()
    00252             {
    00253             }
    00254             virtual placeholder* add(placeholder* rhs) = 0;
    00255             virtual placeholder* subtract(placeholder* rhs) = 0;
    00256             virtual placeholder* multiply(placeholder* rhs) = 0;
    00257             virtual placeholder* multiply(Real factor) = 0;
    00258             virtual placeholder* divide(placeholder* rhs) = 0;
    00259         };
    00260
    00261         template<typename ValueType>
    00262         class numholder : public numplaceholder
    00263         {
    00264         public: // structors
    00265
    00266             numholder(const ValueType & value)
    00267                 : held(value)
    00268             {
    00269             }
    00270
    00271         public: // queries
    00272
    00273             virtual const std::type_info & getType() const
    00274             {
    00275                 return typeid(ValueType);
    00276             }
    00277
    00278             virtual placeholder * clone() const
    00279             {
    00280                 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held);
    00281             }
    00282
    00283             virtual placeholder* add(placeholder* rhs)
    00284             {
    00285                 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held + static_cast<numholder*>(rhs)->held);
    00286             }
    00287             virtual placeholder* subtract(placeholder* rhs)
    00288             {
    00289                 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held - static_cast<numholder*>(rhs)->held);
    00290             }
    00291             virtual placeholder* multiply(placeholder* rhs)
    00292             {
    00293                 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held * static_cast<numholder*>(rhs)->held);
    00294             }
    00295             virtual placeholder* multiply(Real factor)
    00296             {
    00297                 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held * factor);
    00298             }
    00299             virtual placeholder* divide(placeholder* rhs)
    00300             {
    00301                 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held / static_cast<numholder*>(rhs)->held);
    00302             }
    00303             virtual void writeToStream(std::ostream& o)
    00304             {
    00305                 o << held;
    00306             }
    00307
    00308         public: // representation
    00309
    00310             ValueType held;
    00311
    00312         };
    00313
    00315         AnyNumeric(placeholder* pholder)
    00316         {
    00317             mContent = pholder;
    00318         }
    00319
    00320     public:
    00321         AnyNumeric & operator=(const AnyNumeric & rhs)
    00322         {
    00323             AnyNumeric(rhs).swap(*this);
    00324             return *this;
    00325         }
    00326         AnyNumeric operator+(const AnyNumeric& rhs) const
    00327         {
    00328             return AnyNumeric(
    00329                 static_cast<numplaceholder*>(mContent)->add(rhs.mContent));
    00330         }
    00331         AnyNumeric operator-(const AnyNumeric& rhs) const
    00332         {
    00333             return AnyNumeric(
    00334                 static_cast<numplaceholder*>(mContent)->subtract(rhs.mContent));
    00335         }
    00336         AnyNumeric operator*(const AnyNumeric& rhs) const
    00337         {
    00338             return AnyNumeric(
    00339                 static_cast<numplaceholder*>(mContent)->multiply(rhs.mContent));
    00340         }
    00341         AnyNumeric operator*(Real factor) const
    00342         {
    00343             return AnyNumeric(
    00344                 static_cast<numplaceholder*>(mContent)->multiply(factor));
    00345         }
    00346         AnyNumeric operator/(const AnyNumeric& rhs) const
    00347         {
    00348             return AnyNumeric(
    00349                 static_cast<numplaceholder*>(mContent)->divide(rhs.mContent));
    00350         }
    00351         AnyNumeric& operator+=(const AnyNumeric& rhs)
    00352         {
    00353             *this = AnyNumeric(
    00354                 static_cast<numplaceholder*>(mContent)->add(rhs.mContent));
    00355             return *this;
    00356         }
    00357         AnyNumeric& operator-=(const AnyNumeric& rhs)
    00358         {
    00359             *this = AnyNumeric(
    00360                 static_cast<numplaceholder*>(mContent)->subtract(rhs.mContent));
    00361             return *this;
    00362         }
    00363         AnyNumeric& operator*=(const AnyNumeric& rhs)
    00364         {
    00365             *this = AnyNumeric(
    00366                 static_cast<numplaceholder*>(mContent)->multiply(rhs.mContent));
    00367             return *this;
    00368         }
    00369         AnyNumeric& operator/=(const AnyNumeric& rhs)
    00370         {
    00371             *this = AnyNumeric(
    00372                 static_cast<numplaceholder*>(mContent)->divide(rhs.mContent));
    00373             return *this;
    00374         }
    00375
    00376
    00377
    00378
    00379     };
    00380
    00381
    00382     template<typename ValueType>
    00383     ValueType * any_cast(Any * operand)
    00384     {
    00385         return operand && operand->getType() == typeid(ValueType)
    00386                     ? &static_cast<Any::holder<ValueType> *>(operand->mContent)->held
    00387                     : 0;
    00388     }
    00389
    00390     template<typename ValueType>
    00391     const ValueType * any_cast(const Any * operand)
    00392     {
    00393         return any_cast<ValueType>(const_cast<Any *>(operand));
    00394     }
    00395
    00396     template<typename ValueType>
    00397     ValueType any_cast(const Any & operand)
    00398     {
    00399         const ValueType * result = any_cast<ValueType>(&operand);
    00400         if(!result)
    00401         {
    00402             StringUtil::StrStreamType str;
    00403             str << "Bad cast from type '" << operand.getType().name() << "' "
    00404                 << "to '" << typeid(ValueType).name() << "'";
    00405             OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
    00406                 str.str(),
    00407                 "Ogre::any_cast");
    00408         }
    00409         return *result;
    00410     }
    00415 }
    00416
    00417 #endif
    00418

Copyright © 2008 Torus Knot Software Ltd
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Wed Nov 3 2010 19:24:51