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-2012 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         template <typename ValueType>
    00218         ValueType get(void) const
    00219         {
    00220             if (!mContent)
    00221             {
    00222                 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
    00223                     "Bad cast from uninitialised Any",
    00224                     "Any::operator()");
    00225             }
    00226             else if(getType() == typeid(ValueType))
    00227             {
    00228                 return static_cast<Any::holder<ValueType> *>(mContent)->held;
    00229             }
    00230             else
    00231             {
    00232                 StringUtil::StrStreamType str;
    00233                 str << "Bad cast from type '" << getType().name() << "' "
    00234                     << "to '" << typeid(ValueType).name() << "'";
    00235                 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
    00236                      str.str(),
    00237                     "Any::operator()");
    00238             }
    00239         }
    00240
    00241     };
    00242
    00243
    00247     class AnyNumeric : public Any
    00248     {
    00249     public:
    00250         AnyNumeric()
    00251         : Any()
    00252         {
    00253         }
    00254
    00255         template<typename ValueType>
    00256         AnyNumeric(const ValueType & value)
    00257
    00258         {
    00259             mContent = OGRE_NEW_T(numholder<ValueType>, MEMCATEGORY_GENERAL)(value);
    00260         }
    00261
    00262         AnyNumeric(const AnyNumeric & other)
    00263             : Any()
    00264         {
    00265             mContent = other.mContent ? other.mContent->clone() : 0;
    00266         }
    00267
    00268     protected:
    00269         class numplaceholder : public Any::placeholder
    00270         {
    00271         public: // structors
    00272
    00273             ~numplaceholder()
    00274             {
    00275             }
    00276             virtual placeholder* add(placeholder* rhs) = 0;
    00277             virtual placeholder* subtract(placeholder* rhs) = 0;
    00278             virtual placeholder* multiply(placeholder* rhs) = 0;
    00279             virtual placeholder* multiply(Real factor) = 0;
    00280             virtual placeholder* divide(placeholder* rhs) = 0;
    00281         };
    00282
    00283         template<typename ValueType>
    00284         class numholder : public numplaceholder
    00285         {
    00286         public: // structors
    00287
    00288             numholder(const ValueType & value)
    00289                 : held(value)
    00290             {
    00291             }
    00292
    00293         public: // queries
    00294
    00295             virtual const std::type_info & getType() const
    00296             {
    00297                 return typeid(ValueType);
    00298             }
    00299
    00300             virtual placeholder * clone() const
    00301             {
    00302                 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held);
    00303             }
    00304
    00305             virtual placeholder* add(placeholder* rhs)
    00306             {
    00307                 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held + static_cast<numholder*>(rhs)->held);
    00308             }
    00309             virtual placeholder* subtract(placeholder* rhs)
    00310             {
    00311                 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held - static_cast<numholder*>(rhs)->held);
    00312             }
    00313             virtual placeholder* multiply(placeholder* rhs)
    00314             {
    00315                 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held * static_cast<numholder*>(rhs)->held);
    00316             }
    00317             virtual placeholder* multiply(Real factor)
    00318             {
    00319                 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held * factor);
    00320             }
    00321             virtual placeholder* divide(placeholder* rhs)
    00322             {
    00323                 return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held / static_cast<numholder*>(rhs)->held);
    00324             }
    00325             virtual void writeToStream(std::ostream& o)
    00326             {
    00327                 o << held;
    00328             }
    00329
    00330         public: // representation
    00331
    00332             ValueType held;
    00333
    00334         };
    00335
    00337         AnyNumeric(placeholder* pholder)
    00338         {
    00339             mContent = pholder;
    00340         }
    00341
    00342     public:
    00343         AnyNumeric & operator=(const AnyNumeric & rhs)
    00344         {
    00345             AnyNumeric(rhs).swap(*this);
    00346             return *this;
    00347         }
    00348         AnyNumeric operator+(const AnyNumeric& rhs) const
    00349         {
    00350             return AnyNumeric(
    00351                 static_cast<numplaceholder*>(mContent)->add(rhs.mContent));
    00352         }
    00353         AnyNumeric operator-(const AnyNumeric& rhs) const
    00354         {
    00355             return AnyNumeric(
    00356                 static_cast<numplaceholder*>(mContent)->subtract(rhs.mContent));
    00357         }
    00358         AnyNumeric operator*(const AnyNumeric& rhs) const
    00359         {
    00360             return AnyNumeric(
    00361                 static_cast<numplaceholder*>(mContent)->multiply(rhs.mContent));
    00362         }
    00363         AnyNumeric operator*(Real factor) const
    00364         {
    00365             return AnyNumeric(
    00366                 static_cast<numplaceholder*>(mContent)->multiply(factor));
    00367         }
    00368         AnyNumeric operator/(const AnyNumeric& rhs) const
    00369         {
    00370             return AnyNumeric(
    00371                 static_cast<numplaceholder*>(mContent)->divide(rhs.mContent));
    00372         }
    00373         AnyNumeric& operator+=(const AnyNumeric& rhs)
    00374         {
    00375             *this = AnyNumeric(
    00376                 static_cast<numplaceholder*>(mContent)->add(rhs.mContent));
    00377             return *this;
    00378         }
    00379         AnyNumeric& operator-=(const AnyNumeric& rhs)
    00380         {
    00381             *this = AnyNumeric(
    00382                 static_cast<numplaceholder*>(mContent)->subtract(rhs.mContent));
    00383             return *this;
    00384         }
    00385         AnyNumeric& operator*=(const AnyNumeric& rhs)
    00386         {
    00387             *this = AnyNumeric(
    00388                 static_cast<numplaceholder*>(mContent)->multiply(rhs.mContent));
    00389             return *this;
    00390         }
    00391         AnyNumeric& operator/=(const AnyNumeric& rhs)
    00392         {
    00393             *this = AnyNumeric(
    00394                 static_cast<numplaceholder*>(mContent)->divide(rhs.mContent));
    00395             return *this;
    00396         }
    00397
    00398
    00399
    00400
    00401     };
    00402
    00403
    00404     template<typename ValueType>
    00405     ValueType * any_cast(Any * operand)
    00406     {
    00407         return operand && (std::strcmp(operand->getType().name(), typeid(ValueType).name()) == 0)
    00408                     ? &static_cast<Any::holder<ValueType> *>(operand->mContent)->held
    00409                     : 0;
    00410     }
    00411
    00412     template<typename ValueType>
    00413     const ValueType * any_cast(const Any * operand)
    00414     {
    00415         return any_cast<ValueType>(const_cast<Any *>(operand));
    00416     }
    00417
    00418     template<typename ValueType>
    00419     ValueType any_cast(const Any & operand)
    00420     {
    00421         const ValueType * result = any_cast<ValueType>(&operand);
    00422         if(!result)
    00423         {
    00424             StringUtil::StrStreamType str;
    00425             str << "Bad cast from type '" << operand.getType().name() << "' "
    00426                 << "to '" << typeid(ValueType).name() << "'";
    00427             OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
    00428                 str.str(),
    00429                 "Ogre::any_cast");
    00430         }
    00431         return *result;
    00432     }
    00437 }
    00438
    00439 #endif
    00440

Copyright © 2012 Torus Knot Software Ltd
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Sun Sep 2 2012 07:27:20