00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _pany_h_
00023 #define _pany_h_
00024
00025 #include <algorithm>
00026 #include <typeinfo>
00027 #include <iostream>
00028
00029 namespace P {
00030
00032
00035 class Any {
00036 public:
00037 Any()
00038 : m_data(0)
00039 { }
00040
00041 Any(const Any& val)
00042 : m_data(val.m_data ? val.m_data->clone() : 0)
00043 { }
00044
00045 template <typename ValueType>
00046 Any(const ValueType& val)
00047 : m_data(new holder<ValueType>(val))
00048 { }
00049
00050 ~Any()
00051 {
00052 if(m_data)
00053 delete m_data;
00054 }
00055
00056 Any& swap(Any& rhs)
00057 {
00058 std::swap(m_data, rhs.m_data);
00059 return *this;
00060 }
00061
00062 template <typename ValueType>
00063 Any& operator=(const ValueType& rhs)
00064 {
00065 Any(rhs).swap(*this);
00066 return *this;
00067 }
00068
00069 Any& operator=(const Any& rhs)
00070 {
00071 Any(rhs).swap(*this);
00072 return *this;
00073 }
00074
00075 inline bool empty() const
00076 { return !m_data; }
00077
00078 const std::type_info& type() const
00079 { return m_data ? m_data->type() : typeid(void); }
00080
00081 template <typename ValueType>
00082 friend ValueType* any_cast(Any* val);
00083
00084 friend std::ostream& operator<<(std::ostream& os, const Any& val);
00085
00086 private:
00087
00088 class holder_iface {
00089 public:
00090 virtual ~holder_iface()
00091 { }
00092
00093 virtual const std::type_info& type() const = 0;
00094 virtual holder_iface* clone() const = 0;
00095 virtual void output(std::ostream& os) const = 0;
00096 };
00097
00098 template <typename ValueType>
00099 class holder: public holder_iface {
00100 public:
00101 holder(const ValueType& val)
00102 : m_value(val)
00103 { }
00104
00105 virtual const std::type_info& type() const
00106 { return typeid(ValueType); }
00107
00108 virtual holder_iface* clone() const
00109 { return new holder(m_value); }
00110
00111 virtual void output(std::ostream& os) const
00112 { os << m_value; }
00113
00114 private:
00115 ValueType m_value;
00116 };
00117
00118 private:
00119 holder_iface* m_data;
00120
00121 };
00122
00124
00127 class BadAnyCast: public std::bad_cast {
00128 public:
00129 virtual const char* what() const throw()
00130 { return "BadAnyCast: failed conversion using P::any_cast"; }
00131 };
00132
00134
00137 template <typename ValueType>
00138 ValueType* any_cast(Any* operand)
00139 {
00140 return operand && operand->type() == typeid(ValueType) ?
00141 &static_cast<Any::holder<ValueType>*>(operand->m_data)->m_value : 0;
00142 }
00143
00145
00148 template <typename ValueType>
00149 const ValueType* any_cast(const Any* operand)
00150 {
00151 return any_cast<ValueType>(const_cast<Any*>(operand));
00152 }
00153
00155
00158 template <typename ValueType>
00159 ValueType any_cast(const Any& operand) throw(BadAnyCast)
00160 {
00161 const ValueType* result = any_cast<ValueType>(&operand);
00162 if(!result)
00163 throw BadAnyCast();
00164
00165 return *result;
00166 }
00167
00169
00172 std::ostream& operator<<(std::ostream& os, const Any& val)
00173 {
00174 val.m_data->output(os);
00175 return os;
00176 }
00177
00178 }
00179
00180 #endif