|
Teuchos - Trilinos Tools Package Version of the Day
|
00001 /* 00002 // @HEADER 00003 // *********************************************************************** 00004 // 00005 // Teuchos: Common Tools Package 00006 // Copyright (2004) Sandia Corporation 00007 // 00008 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00009 // license for use of this work by or on behalf of the U.S. Government. 00010 // 00011 // This library is free software; you can redistribute it and/or modify 00012 // it under the terms of the GNU Lesser General Public License as 00013 // published by the Free Software Foundation; either version 2.1 of the 00014 // License, or (at your option) any later version. 00015 // 00016 // This library is distributed in the hope that it will be useful, but 00017 // WITHOUT ANY WARRANTY; without even the implied warranty of 00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 // Lesser General Public License for more details. 00020 // 00021 // You should have received a copy of the GNU Lesser General Public 00022 // License along with this library; if not, write to the Free Software 00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00024 // USA 00025 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00026 // 00027 // *********************************************************************** 00028 // @HEADER 00029 */ 00030 00031 #ifndef TEUCHOS_ANY_HPP 00032 #define TEUCHOS_ANY_HPP 00033 00038 #include "Teuchos_TestForException.hpp" 00039 #include "Teuchos_TypeNameTraits.hpp" 00040 00041 // 00042 // This file was taken from the boost library which contained the 00043 // following notice: 00044 // 00045 // ************************************************************* 00046 // 00047 // what: variant type boost::any 00048 // who: contributed by Kevlin Henney, 00049 // with features contributed and bugs found by 00050 // Ed Brey, Mark Rodgers, Peter Dimov, and James Curran 00051 // when: July 2001 00052 // where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95 00053 // 00054 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. 00055 // 00056 // Permission to use, copy, modify, and distribute this software for any 00057 // purpose is hereby granted without fee, provided that this copyright and 00058 // permissions notice appear in all copies and derivatives. 00059 // 00060 // This software is provided "as is" without express or implied warranty. 00061 // 00062 // ************************************************************* 00063 // 00064 // RAB modified the file for use in Teuchos. I changed the nature of 00065 // the any_cast<> to be easier to use. 00066 // 00067 00068 namespace Teuchos { 00069 00073 class TEUCHOS_LIB_DLL_EXPORT any 00074 { 00075 public: 00077 any() 00078 : content(0) 00079 {} 00080 00082 template<typename ValueType> 00083 explicit any(const ValueType & value) 00084 : content(new holder<ValueType>(value)) 00085 {} 00086 00088 any(const any & other) 00089 : content(other.content ? other.content->clone() : 0) 00090 {} 00091 00093 ~any() 00094 { 00095 delete content; 00096 } 00097 00099 any & swap(any & rhs) 00100 { 00101 std::swap(content, rhs.content); 00102 return *this; 00103 } 00104 00106 template<typename ValueType> 00107 any & operator=(const ValueType & rhs) 00108 { 00109 any(rhs).swap(*this); 00110 return *this; 00111 } 00112 00114 any & operator=(const any & rhs) 00115 { 00116 any(rhs).swap(*this); 00117 return *this; 00118 } 00119 00121 bool empty() const 00122 { 00123 return !content; 00124 } 00125 00127 const std::type_info & type() const 00128 { 00129 return content ? content->type() : typeid(void); 00130 } 00131 00133 std::string typeName() const 00134 { 00135 return content ? content->typeName() : "NONE"; 00136 } 00137 00139 bool same( const any &other ) const 00140 { 00141 if( this->empty() && other.empty() ) 00142 return true; 00143 else if( this->empty() && !other.empty() ) 00144 return false; 00145 else if( !this->empty() && other.empty() ) 00146 return false; 00147 // !this->empty() && !other.empty() 00148 return content->same(*other.content); 00149 } 00150 00152 void print(std::ostream& os) const 00153 { 00154 if (content) content->print(os); 00155 } 00156 00157 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00158 00160 00162 class placeholder 00163 { 00164 public: 00166 virtual ~placeholder() {} 00168 virtual const std::type_info & type() const = 0; 00170 virtual std::string typeName() const = 0; 00172 virtual placeholder * clone() const = 0; 00174 virtual bool same( const placeholder &other ) const = 0; 00176 virtual void print(std::ostream & os) const = 0; 00177 }; 00178 00180 template<typename ValueType> 00181 class holder : public placeholder 00182 { 00183 public: 00185 holder(const ValueType & value) 00186 : held(value) 00187 {} 00189 const std::type_info & type() const 00190 { return typeid(ValueType); } 00192 std::string typeName() const 00193 { return TypeNameTraits<ValueType>::name(); } 00195 placeholder * clone() const 00196 { return new holder(held); } 00198 bool same( const placeholder &other ) const 00199 { 00200 if( type() != other.type() ) { 00201 return false; 00202 } 00203 // type() == other.type() 00204 const ValueType 00205 &other_held = dynamic_cast<const holder<ValueType>&>(other).held; 00206 return held == other_held; 00207 } 00209 void print(std::ostream & os) const 00210 { os << held; } 00212 ValueType held; 00213 }; 00214 00216 00217 public: 00218 // Danger: This is made public to allow any_cast to be non-friend 00219 placeholder* access_content() 00220 { return content; } 00221 const placeholder* access_content() const 00222 { return content; } 00223 #endif 00224 00225 private: 00226 00227 // ///////////////////////// 00228 // Private data members 00229 00230 placeholder * content; 00231 00232 }; 00233 00237 class bad_any_cast : public std::runtime_error 00238 { 00239 public: 00240 bad_any_cast( const std::string msg ) : std::runtime_error(msg) {} 00241 }; 00242 00251 template<typename ValueType> 00252 ValueType& any_cast(any &operand) 00253 { 00254 const std::string ValueTypeName = TypeNameTraits<ValueType>::name(); 00255 TEST_FOR_EXCEPTION( 00256 operand.type() != typeid(ValueType), bad_any_cast 00257 ,"any_cast<"<<ValueTypeName<<">(operand): Error, cast to type " 00258 << "any::holder<"<<ValueTypeName<<"> failed since the actual underlying type is \'" 00259 << typeName(*operand.access_content()) << "!" 00260 ); 00261 TEST_FOR_EXCEPTION( 00262 !operand.access_content(), bad_any_cast 00263 ,"any_cast<"<<ValueTypeName<<">(operand): Error, cast to type " 00264 << "any::holder<"<<ValueTypeName<<"> failed because the content is NULL" 00265 ); 00266 any::holder<ValueType> 00267 *dyn_cast_content = dynamic_cast<any::holder<ValueType>*>(operand.access_content()); 00268 TEST_FOR_EXCEPTION( 00269 !dyn_cast_content, std::logic_error 00270 ,"any_cast<"<<ValueTypeName <<">(operand): Error, cast to type " 00271 << "any::holder<"<<ValueTypeName<<"> failed but should not have and the actual underlying type is \'" 00272 << typeName(*operand.access_content()) << "!" 00273 << " The problem might be related to incompatible RTTI systems in static and shared libraries!" 00274 ); 00275 return dyn_cast_content->held; 00276 } 00277 00287 template<typename ValueType> 00288 const ValueType& any_cast(const any &operand) 00289 { 00290 return any_cast<ValueType>(const_cast<any&>(operand)); 00291 } 00292 00296 inline std::string toString(const any &rhs) 00297 { 00298 std::ostringstream oss; 00299 rhs.print(oss); 00300 return oss.str(); 00301 } 00302 00306 inline bool operator==( const any &a, const any &b ) 00307 { 00308 return a.same(b); 00309 } 00310 00314 inline bool operator!=( const any &a, const any &b ) 00315 { 00316 return !a.same(b); 00317 } 00318 00322 inline std::ostream & operator<<(std::ostream & os, const any &rhs) 00323 { 00324 rhs.print(os); 00325 return os; 00326 } 00327 00328 } // namespace Teuchos 00329 00330 #endif // TEUCHOS_ANY_HPP
1.7.4