00001 #ifndef TEUCHOS_ANY_HPP
00002 #define TEUCHOS_ANY_HPP
00003
00008 #include "Teuchos_TestForException.hpp"
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 namespace Teuchos {
00038
00041
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
00152 placeholder* access_content()
00153 { return content; }
00154 const placeholder* access_content() const
00155 { return content; }
00156 #endif
00157
00158 private:
00159
00160
00161
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 }
00230
00231 #endif // TEUCHOS_ANY_HPP