Sirikata
|
00001 /* Sirikata Utilities -- Sirikata Utilities 00002 * Any.hpp 00003 * 00004 * Copyright (c) 2009, Daniel Reiter Horn 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions are 00009 * met: 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in 00014 * the documentation and/or other materials provided with the 00015 * distribution. 00016 * * Neither the name of Sirikata nor the names of its contributors may 00017 * be used to endorse or promote products derived from this software 00018 * without specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 00021 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00022 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00023 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 00024 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 */ 00032 #ifndef _ANY_HPP_ 00033 #define _ANY_HPP_ 00034 #include <typeinfo> 00035 namespace Sirikata { 00036 class Any { 00037 public: 00038 class Holder{ 00039 friend class Any; 00040 public: 00041 virtual ~Holder(){}; 00042 protected: 00043 00044 virtual Holder * clone()const=0; 00045 virtual const std::type_info& typeOf()const=0; 00046 }; 00047 private: 00048 template <class T> class SubHolder:public Holder{ 00049 friend class Any; 00050 T mValue; 00051 public: 00052 SubHolder(const T&val):mValue(val) {} 00053 virtual ~SubHolder(){} 00054 virtual const std::type_info&typeOf()const { 00055 return typeid(T); 00056 } 00057 virtual Holder *clone()const { 00058 return new SubHolder<T>(mValue); 00059 } 00060 }; 00061 Holder * mHolder; 00062 public: 00063 Any() { 00064 mHolder=NULL; 00065 } 00066 template <class T> Any&operator =(const T&other) { 00067 delete mHolder; 00068 mHolder = new SubHolder<T>(other); 00069 return *this; 00070 } 00071 Any&operator =(const Any&other) { 00072 mHolder=other.mHolder?other.mHolder->clone():NULL; 00073 return *this; 00074 } 00075 Any(const Any&other) { 00076 mHolder=other.mHolder?other.mHolder->clone():NULL; 00077 } 00078 Any(const Any*other) { 00079 mHolder=other?(other->mHolder?other->mHolder->clone():NULL):NULL; 00080 } 00081 Any(Any*other) { 00082 mHolder=other?(other->mHolder?other->mHolder->clone():NULL):NULL; 00083 } 00084 template <class T> Any(const T&other) { 00085 mHolder = new SubHolder<T>(other); 00086 } 00087 ~Any() { 00088 delete mHolder; 00089 } 00090 bool empty() { 00091 return mHolder==NULL; 00092 } 00098 Holder* newAndDoNotFree(const Any&value){ 00099 Holder *retval=mHolder; 00100 mHolder=value.mHolder?value.mHolder->clone():NULL; 00101 return retval; 00102 } 00103 const std::type_info&typeOf() const { 00104 return mHolder?mHolder->typeOf():typeid(void); 00105 } 00106 template <class T> T& as () { 00107 // Dereference first so the dynamic_cast will throw bad_cast on failure. 00108 return dynamic_cast<SubHolder<T>&>(*mHolder).mValue; 00109 } 00110 template <class T> T& unsafeAs () { 00111 return static_cast<SubHolder<T>*>(mHolder)->mValue; 00112 } 00113 template <class T> const T& as () const{ 00114 // Dereference first so the dynamic_cast will throw bad_cast on failure. 00115 return dynamic_cast<const SubHolder<T>&>(*mHolder)->mValue; 00116 } 00117 template <class T> const T& unsafeAs () const{ 00118 return static_cast<const SubHolder<T>*>(mHolder)->mValue; 00119 } 00120 }; 00121 } 00122 #endif