Teuchos_any.hpp

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

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