00001 /* 00002 * Copyright (C) 2006-2011, SRI International (R) 00003 * 00004 * This program is free software: you can redistribute it and/or modify 00005 * it under the terms of the GNU Lesser General Public License as published by 00006 * the Free Software Foundation, either version 3 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public License 00015 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #pragma once 00019 00020 #ifndef __OpenKarto_Any_h__ 00021 #define __OpenKarto_Any_h__ 00022 00023 #include <algorithm> 00024 #include <typeinfo> 00025 00026 #include <OpenKarto/Exception.h> 00027 00028 namespace karto 00029 { 00030 00032 00033 00037 00038 // The following code is from the boost library with the following license 00039 // and modified to fit into the KartoSDK 00040 00041 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. 00042 // 00043 // Distributed under the Boost Software License, Version 1.0. (See 00044 // accompAnying file LICENSE_1_0.txt or copy at 00045 // http://www.boost.org/LICENSE_1_0.txt) 00046 // -- End original copyright -- 00047 00051 00055 class Any 00056 { 00057 public: 00061 Any() 00062 : m_pContent(NULL) 00063 { 00064 } 00065 00071 template<typename T> 00072 Any(const T& rValue) 00073 : m_pContent(new Holder<T>(rValue)) 00074 { 00075 } 00076 00083 Any(const Any& rOther) 00084 : m_pContent(rOther.m_pContent ? rOther.m_pContent->Clone() : NULL) 00085 { 00086 } 00087 00091 ~Any() 00092 { 00093 delete m_pContent; 00094 } 00095 00096 public: 00102 Any& Swap(Any& rOther) 00103 { 00104 std::swap(m_pContent, rOther.m_pContent); 00105 return *this; 00106 } 00107 00111 template<typename T> 00112 Any & operator=(const T& rOther) 00113 { 00114 Any(rOther).Swap(*this); 00115 return *this; 00116 } 00117 00121 Any& operator=(const Any& rOther) 00122 { 00123 Any(rOther).Swap(*this); 00124 return *this; 00125 } 00126 00127 public: 00132 kt_bool IsEmpty() const 00133 { 00134 return !m_pContent; 00135 } 00136 00140 const std::type_info& GetType() const 00141 { 00142 return m_pContent ? m_pContent->GetType() : typeid(void); 00143 } 00144 00145 private: 00146 class PlaceHolder 00147 { 00148 public: 00149 00150 virtual ~PlaceHolder() 00151 { 00152 } 00153 00154 public: 00155 virtual const std::type_info & GetType() const = 0; 00156 00157 virtual PlaceHolder * Clone() const = 0; 00158 }; 00159 00160 template<typename T> 00161 class Holder : public PlaceHolder 00162 { 00163 public: 00164 Holder(const T & value) 00165 : held(value) 00166 { 00167 } 00168 00169 public: 00170 virtual const std::type_info & GetType() const 00171 { 00172 return typeid(T); 00173 } 00174 00175 virtual PlaceHolder * Clone() const 00176 { 00177 return new Holder(held); 00178 } 00179 00180 public: 00181 T held; 00182 00183 private: 00184 Holder & operator=(const Holder &); 00185 }; 00186 00187 public: 00191 static const Any Empty; 00192 00193 private: 00194 template<typename T> 00195 friend T * any_cast(Any *); 00196 00197 PlaceHolder* m_pContent; 00198 }; // class Any 00199 00205 template<typename T> 00206 T * any_cast(Any* pAny) 00207 { 00208 return pAny && pAny->GetType() == typeid(T) ? &static_cast<Any::Holder<T> *>(pAny->m_pContent)->held : NULL; 00209 } 00210 00216 template<typename T> 00217 inline const T * any_cast(const Any* pAny) 00218 { 00219 return any_cast<T>(const_cast<Any*>(pAny)); 00220 } 00221 00228 template<typename T> 00229 inline T any_cast(const Any& rAny) 00230 { 00231 const T* pResult = any_cast<T>(&rAny); 00232 if (!pResult) 00233 { 00234 throw karto::Exception("Unable to perform any_cast"); 00235 } 00236 00237 return *pResult; 00238 } 00239 00241 00242 } 00243 00244 #endif // __OpenKarto_Any_h__