|
Teuchos Package Browser (Single Doxygen Collection)
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 // Redistribution and use in source and binary forms, with or without 00012 // modification, are permitted provided that the following conditions are 00013 // met: 00014 // 00015 // 1. Redistributions of source code must retain the above copyright 00016 // notice, this list of conditions and the following disclaimer. 00017 // 00018 // 2. Redistributions in binary form must reproduce the above copyright 00019 // notice, this list of conditions and the following disclaimer in the 00020 // documentation and/or other materials provided with the distribution. 00021 // 00022 // 3. Neither the name of the Corporation nor the names of the 00023 // contributors may be used to endorse or promote products derived from 00024 // this software without specific prior written permission. 00025 // 00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00037 // 00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00039 // 00040 // *********************************************************************** 00041 // @HEADER 00042 */ 00043 00044 #ifndef TEUCHOS_ANY_HPP 00045 #define TEUCHOS_ANY_HPP 00046 00051 #include "Teuchos_Assert.hpp" 00052 #include "Teuchos_TypeNameTraits.hpp" 00053 00054 // 00055 // This file was taken from the boost library which contained the 00056 // following notice: 00057 // 00058 // ************************************************************* 00059 // 00060 // what: variant type boost::any 00061 // who: contributed by Kevlin Henney, 00062 // with features contributed and bugs found by 00063 // Ed Brey, Mark Rodgers, Peter Dimov, and James Curran 00064 // when: July 2001 00065 // where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95 00066 // 00067 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. 00068 // 00069 // Permission to use, copy, modify, and distribute this software for any 00070 // purpose is hereby granted without fee, provided that this copyright and 00071 // permissions notice appear in all copies and derivatives. 00072 // 00073 // This software is provided "as is" without express or implied warranty. 00074 // 00075 // ************************************************************* 00076 // 00077 // RAB modified the file for use in Teuchos. I changed the nature of 00078 // the any_cast<> to be easier to use. 00079 // 00080 00081 namespace Teuchos { 00082 00086 class TEUCHOSCORE_LIB_DLL_EXPORT any 00087 { 00088 public: 00090 any() 00091 : content(0) 00092 {} 00093 00095 template<typename ValueType> 00096 explicit any(const ValueType & value) 00097 : content(new holder<ValueType>(value)) 00098 {} 00099 00101 any(const any & other) 00102 : content(other.content ? other.content->clone() : 0) 00103 {} 00104 00106 ~any() 00107 { 00108 delete content; 00109 } 00110 00112 any & swap(any & rhs) 00113 { 00114 std::swap(content, rhs.content); 00115 return *this; 00116 } 00117 00119 template<typename ValueType> 00120 any & operator=(const ValueType & rhs) 00121 { 00122 any(rhs).swap(*this); 00123 return *this; 00124 } 00125 00127 any & operator=(const any & rhs) 00128 { 00129 any(rhs).swap(*this); 00130 return *this; 00131 } 00132 00134 bool empty() const 00135 { 00136 return !content; 00137 } 00138 00140 const std::type_info & type() const 00141 { 00142 return content ? content->type() : typeid(void); 00143 } 00144 00146 std::string typeName() const 00147 { 00148 return content ? content->typeName() : "NONE"; 00149 } 00150 00152 bool same( const any &other ) const 00153 { 00154 if( this->empty() && other.empty() ) 00155 return true; 00156 else if( this->empty() && !other.empty() ) 00157 return false; 00158 else if( !this->empty() && other.empty() ) 00159 return false; 00160 // !this->empty() && !other.empty() 00161 return content->same(*other.content); 00162 } 00163 00165 void print(std::ostream& os) const 00166 { 00167 if (content) content->print(os); 00168 } 00169 00170 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00171 00173 00175 class placeholder 00176 { 00177 public: 00179 virtual ~placeholder() {} 00181 virtual const std::type_info & type() const = 0; 00183 virtual std::string typeName() const = 0; 00185 virtual placeholder * clone() const = 0; 00187 virtual bool same( const placeholder &other ) const = 0; 00189 virtual void print(std::ostream & os) const = 0; 00190 }; 00191 00193 template<typename ValueType> 00194 class holder : public placeholder 00195 { 00196 public: 00198 holder(const ValueType & value) 00199 : held(value) 00200 {} 00202 const std::type_info & type() const 00203 { return typeid(ValueType); } 00205 std::string typeName() const 00206 { return TypeNameTraits<ValueType>::name(); } 00208 placeholder * clone() const 00209 { return new holder(held); } 00211 bool same( const placeholder &other ) const 00212 { 00213 if( type() != other.type() ) { 00214 return false; 00215 } 00216 // type() == other.type() 00217 const ValueType 00218 &other_held = dynamic_cast<const holder<ValueType>&>(other).held; 00219 return held == other_held; 00220 } 00222 void print(std::ostream & os) const 00223 { os << held; } 00225 ValueType held; 00226 }; 00227 00229 00230 public: 00231 // Danger: This is made public to allow any_cast to be non-friend 00232 placeholder* access_content() 00233 { return content; } 00234 const placeholder* access_content() const 00235 { return content; } 00236 #endif 00237 00238 private: 00239 00240 // ///////////////////////// 00241 // Private data members 00242 00243 placeholder * content; 00244 00245 }; 00246 00250 class bad_any_cast : public std::runtime_error 00251 { 00252 public: 00253 bad_any_cast( const std::string msg ) : std::runtime_error(msg) {} 00254 }; 00255 00264 template<typename ValueType> 00265 ValueType& any_cast(any &operand) 00266 { 00267 const std::string ValueTypeName = TypeNameTraits<ValueType>::name(); 00268 TEUCHOS_TEST_FOR_EXCEPTION( 00269 operand.type() != typeid(ValueType), bad_any_cast, 00270 "any_cast<"<<ValueTypeName<<">(operand): Error, cast to type " 00271 << "any::holder<"<<ValueTypeName<<"> failed since the actual underlying type is \'" 00272 << typeName(*operand.access_content()) << "!" 00273 ); 00274 TEUCHOS_TEST_FOR_EXCEPTION( 00275 !operand.access_content(), bad_any_cast 00276 ,"any_cast<"<<ValueTypeName<<">(operand): Error, cast to type " 00277 << "any::holder<"<<ValueTypeName<<"> failed because the content is NULL" 00278 ); 00279 any::holder<ValueType> 00280 *dyn_cast_content = dynamic_cast<any::holder<ValueType>*>(operand.access_content()); 00281 TEUCHOS_TEST_FOR_EXCEPTION( 00282 !dyn_cast_content, std::logic_error 00283 ,"any_cast<"<<ValueTypeName <<">(operand): Error, cast to type " 00284 << "any::holder<"<<ValueTypeName<<"> failed but should not have and the actual underlying type is \'" 00285 << typeName(*operand.access_content()) << "!" 00286 << " The problem might be related to incompatible RTTI systems in static and shared libraries!" 00287 ); 00288 return dyn_cast_content->held; 00289 } 00290 00300 template<typename ValueType> 00301 const ValueType& any_cast(const any &operand) 00302 { 00303 return any_cast<ValueType>(const_cast<any&>(operand)); 00304 } 00305 00309 inline std::string toString(const any &rhs) 00310 { 00311 std::ostringstream oss; 00312 rhs.print(oss); 00313 return oss.str(); 00314 } 00315 00319 inline bool operator==( const any &a, const any &b ) 00320 { 00321 return a.same(b); 00322 } 00323 00327 inline bool operator!=( const any &a, const any &b ) 00328 { 00329 return !a.same(b); 00330 } 00331 00335 inline std::ostream & operator<<(std::ostream & os, const any &rhs) 00336 { 00337 rhs.print(os); 00338 return os; 00339 } 00340 00341 } // namespace Teuchos 00342 00343 #endif // TEUCHOS_ANY_HPP
1.7.6.1