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