Teuchos_any.hpp

Go to the documentation of this file.
00001 // /////////////////////////////////////////////////////////////
00002 // Teuchos_any.hpp
00003 
00004 #ifndef TEUCHOS_ANY_HPP
00005 #define TEUCHOS_ANY_HPP
00006 
00011 #include "Teuchos_TestForException.hpp"
00012 
00013 //
00014 // This file was taken from the boost library which contained the
00015 // following notice:
00016 //
00017 // *************************************************************
00018 //
00019 // what:  variant type boost::any
00020 // who:   contributed by Kevlin Henney,
00021 //        with features contributed and bugs found by
00022 //        Ed Brey, Mark Rodgers, Peter Dimov, and James Curran
00023 // when:  July 2001
00024 // where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95
00025 //
00026 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
00027 //
00028 // Permission to use, copy, modify, and distribute this software for any
00029 // purpose is hereby granted without fee, provided that this copyright and
00030 // permissions notice appear in all copies and derivatives.
00031 //
00032 // This software is provided "as is" without express or implied warranty.
00033 //
00034 // *************************************************************
00035 //
00036 // RAB modified the file for use in Teuchos.  I changed the nature of
00037 // the any_cast<> to be easier to use.
00038 //
00039 
00040 namespace Teuchos {
00041 
00043 
00045 // ToDo: Finish documentation!
00046 
00047 class any
00048 {
00049 public:
00051   any()
00052     : content(0)
00053     {}
00054 
00056   template<typename ValueType>
00057   any(const ValueType & value)
00058     : content(new holder<ValueType>(value))
00059     {}
00060   
00062   any(const any & other)
00063     : content(other.content ? other.content->clone() : 0)
00064     {}
00065 
00067   ~any()
00068     {
00069       delete content;
00070     }
00071 
00073   any & swap(any & rhs)
00074     {
00075       std::swap(content, rhs.content);
00076       return *this;
00077     }
00078   
00080   template<typename ValueType>
00081   any & operator=(const ValueType & rhs)
00082     {
00083       any(rhs).swap(*this);
00084       return *this;
00085     }
00086   
00088   any & operator=(const any & rhs)
00089     {
00090       any(rhs).swap(*this);
00091       return *this;
00092     }
00093   
00095   bool empty() const
00096     {
00097       return !content;
00098     }
00099   
00101   const std::type_info & type() const
00102     {
00103       return content ? content->type() : typeid(void);
00104     }
00105 
00107   void print(std::ostream& os) const
00108     {
00109       if (content) content->print(os);
00110     }
00111 
00112 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00113 
00115 
00117   class placeholder
00118   {
00119   public:
00121     virtual ~placeholder() {}
00123     virtual const std::type_info & type() const = 0;
00125     virtual placeholder * clone() const = 0;
00127                 virtual void print(std::ostream & os) const = 0;
00128   };
00129   
00131   template<typename ValueType>
00132   class holder : public placeholder
00133   {
00134   public:
00136     holder(const ValueType & value)
00137       : held(value)
00138       {}
00140     virtual const std::type_info & type() const
00141       { return typeid(ValueType); }
00143     virtual placeholder * clone() const
00144       { return new holder(held); }
00146                 virtual void print(std::ostream & os) const
00147                         { os << held; }
00149     ValueType held;
00150   };
00151 
00153 
00154 public:
00155   // Danger: This is made public to allow any_cast to be non-friend
00156   placeholder* access_content()
00157     { return content; }
00158   const placeholder* access_content() const
00159     { return content; }
00160 #endif
00161 
00162 private:
00163 
00164   // /////////////////////////
00165   // Private data members
00166   
00167   placeholder * content;
00168 
00169 };
00170 
00174 class bad_any_cast : public std::runtime_error
00175 {
00176 public:
00177   bad_any_cast( const std::string msg ) : std::runtime_error(msg) {}
00178 };
00179 
00188 template<typename ValueType>
00189 ValueType& any_cast(any &operand)
00190 {
00191   TEST_FOR_EXCEPTION(
00192     operand.type() != typeid(ValueType), bad_any_cast
00193     ,"any_cast<" << typeid(ValueType).name() << "(operand): Error, cast to type \'"
00194     << typeid(any::holder<ValueType>).name() << "\' failed since the actual underlying type is \'"
00195     << typeid(*operand.access_content()).name() << "!"
00196     );
00197   any::holder<ValueType>
00198     *dyn_cast_content = dynamic_cast<any::holder<ValueType>*>(operand.access_content());
00199   TEST_FOR_EXCEPTION(
00200     !dyn_cast_content, std::logic_error
00201     ,"any_cast<" << typeid(ValueType).name() << "(operand): Error, cast to type \'"
00202     << typeid(any::holder<ValueType>).name() << "\' failed but should not have and the actual underlying type is \'"
00203     << typeid(*operand.access_content()).name() << "!"
00204     );
00205   return dyn_cast_content->held;
00206 }
00207 
00217 template<typename ValueType>
00218 const ValueType& any_cast(const any &operand)
00219 {
00220   return any_cast<ValueType>(const_cast<any&>(operand));
00221 }
00222 
00223 
00227 inline std::ostream & operator<<(std::ostream & os, const any &rhs)
00228 {
00229         rhs.print(os);
00230   return os;
00231 }
00232 
00233 } // namespace Teuchos
00234 
00235 #endif // TEUCHOS_ANY_HPP

Generated on Thu Sep 18 12:41:17 2008 for Teuchos - Trilinos Tools Package by doxygen 1.3.9.1