Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogre_src_v1-9-0/OgreMain/include/OgreAny.h @ 148

Last change on this file since 148 was 148, checked in by patricwi, 6 years ago

Added new dependencies for ogre1.9 and cegui0.8

File size: 10.4 KB
Line 
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-2013 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{
48        /** \addtogroup Core
49        *  @{
50        */
51        /** \addtogroup General
52        *  @{
53        */
54        /** Variant type that can hold Any other type.
55        */
56        class Any
57    {
58    public: // constructors
59
60        Any()
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        {
85            std::swap(mContent, rhs.mContent);
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
122                void destroy()
123                {
124                        OGRE_DELETE_T(mContent, placeholder, MEMCATEGORY_GENERAL);
125                        mContent = NULL;
126                }
127
128    protected: // types
129
130                class placeholder
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            {
167                return OGRE_NEW_T(holder, MEMCATEGORY_GENERAL)(held);
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
185        placeholder * mContent;
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                        {
198                                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
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                        {
208                                StringUtil::StrStreamType str;
209                                str << "Bad cast from type '" << getType().name() << "' "
210                                        << "to '" << typeid(ValueType).name() << "'";
211                                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
212                                         str.str(), 
213                                        "Any::operator()");
214                        }
215                }
216
217                template <typename ValueType>
218                ValueType get(void) const
219                {
220                        if (!mContent) 
221                        {
222                                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
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                        {
232                                StringUtil::StrStreamType str;
233                                str << "Bad cast from type '" << getType().name() << "' "
234                                        << "to '" << typeid(ValueType).name() << "'";
235                                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
236                                         str.str(), 
237                                        "Any::operator()");
238                        }
239                }
240
241    };
242
243
244        /** Specialised Any class which has built in arithmetic operators, but can
245                hold only types which support operator +,-,* and / .
246        */
247        class AnyNumeric : public Any
248        {
249        public:
250                AnyNumeric()
251                : Any()
252                {
253                }
254
255                template<typename ValueType>
256                AnyNumeric(const ValueType & value)
257                       
258                {
259                        mContent = OGRE_NEW_T(numholder<ValueType>, MEMCATEGORY_GENERAL)(value);
260                }
261
262                AnyNumeric(const AnyNumeric & other)
263            : Any()
264                {
265                        mContent = other.mContent ? other.mContent->clone() : 0; 
266                }
267
268        protected:
269                class numplaceholder : public Any::placeholder
270                {
271                public: // structors
272
273                        ~numplaceholder()
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>
284                class numholder : public numplaceholder
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                        {
302                                return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held);
303                        }
304
305                        virtual placeholder* add(placeholder* rhs)
306                        {
307                                return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held + static_cast<numholder*>(rhs)->held);
308                        }
309                        virtual placeholder* subtract(placeholder* rhs)
310                        {
311                                return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held - static_cast<numholder*>(rhs)->held);
312                        }
313                        virtual placeholder* multiply(placeholder* rhs)
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                        }
321                        virtual placeholder* divide(placeholder* rhs)
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
336                /// Construct from holder
337                AnyNumeric(placeholder* pholder)
338                {
339                        mContent = pholder;
340                }
341
342        public:
343                AnyNumeric & operator=(const AnyNumeric & rhs)
344                {
345                        AnyNumeric(rhs).swap(*this);
346                        return *this;
347                }
348                AnyNumeric operator+(const AnyNumeric& rhs) const
349                {
350                        return AnyNumeric(
351                                static_cast<numplaceholder*>(mContent)->add(rhs.mContent));
352                }
353                AnyNumeric operator-(const AnyNumeric& rhs) const
354                {
355                        return AnyNumeric(
356                                static_cast<numplaceholder*>(mContent)->subtract(rhs.mContent));
357                }
358                AnyNumeric operator*(const AnyNumeric& rhs) const
359                {
360                        return AnyNumeric(
361                                static_cast<numplaceholder*>(mContent)->multiply(rhs.mContent));
362                }
363                AnyNumeric operator*(Real factor) const
364                {
365                        return AnyNumeric(
366                                static_cast<numplaceholder*>(mContent)->multiply(factor));
367                }
368                AnyNumeric operator/(const AnyNumeric& rhs) const
369                {
370                        return AnyNumeric(
371                                static_cast<numplaceholder*>(mContent)->divide(rhs.mContent));
372                }
373                AnyNumeric& operator+=(const AnyNumeric& rhs)
374                {
375                        *this = AnyNumeric(
376                                static_cast<numplaceholder*>(mContent)->add(rhs.mContent));
377                        return *this;
378                }
379                AnyNumeric& operator-=(const AnyNumeric& rhs)
380                {
381                        *this = AnyNumeric(
382                                static_cast<numplaceholder*>(mContent)->subtract(rhs.mContent));
383                        return *this;
384                }
385                AnyNumeric& operator*=(const AnyNumeric& rhs)
386                {
387                        *this = AnyNumeric(
388                                static_cast<numplaceholder*>(mContent)->multiply(rhs.mContent));
389                        return *this;
390                }
391                AnyNumeric& operator/=(const AnyNumeric& rhs)
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                {
424                        StringUtil::StrStreamType str;
425                        str << "Bad cast from type '" << operand.getType().name() << "' "
426                                << "to '" << typeid(ValueType).name() << "'";
427                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
428                                str.str(), 
429                                "Ogre::any_cast");
430                }
431        return *result;
432    }
433        /** @} */
434        /** @} */
435
436
437}
438
439#include "OgreHeaderSuffix.h"
440
441#endif
442
Note: See TracBrowser for help on using the repository browser.