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