any.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _ANY_H_
00023 #define _ANY_H_
00024
00025 #include <string>
00026 #include <typeinfo>
00027
00028 #include <dcl/strutils.h>
00029
00030 namespace dbp {
00031
00033
00038 class any {
00039 friend std::ostream& operator<<(std::ostream &str, const any &value);
00040 public:
00042 any(): pimpl(NULL) { }
00044 any(const any &other): pimpl(NULL) {
00045 if (other.pimpl)
00046 pimpl = other.pimpl->clone();
00047 }
00049 template <class T>
00050 any(const T &other) {
00051 pimpl = new impl<T>(other);
00052 }
00054 const any& operator=(const any &other) {
00055 if (pimpl) delete pimpl;
00056 if (other.pimpl)
00057 pimpl = other.pimpl->clone();
00058 else
00059 pimpl = NULL;
00060 return *this;
00061 }
00063 virtual ~any() {
00064 if (pimpl) delete pimpl;
00065 }
00067 void clear() {
00068 if (pimpl) delete pimpl;
00069 pimpl = NULL;
00070 }
00072
00075 bool empty() const {
00076 return (pimpl == NULL);
00077 }
00079
00083 const std::type_info& type() const {
00084 if (pimpl)
00085 return pimpl->type();
00086 else
00087 return typeid(void);
00088 }
00090
00093 std::string str() const {
00094 std::string tmp;
00095 if (pimpl)
00096 return pimpl->str();
00097 else
00098 return tmp;
00099 }
00101
00109 template <typename T>
00110 const T cast() {
00111 if (!pimpl) {
00112 T tmp;
00113 return tmp;
00114 } else {
00115 if (pimpl->type() != typeid(T)) {
00116 impl_int *saved = pimpl;
00117 pimpl = new impl<T>(*saved);
00118 if (saved) delete saved;
00119 }
00120 return static_cast<impl<T>* >(pimpl)->cast();
00121 }
00122 }
00124 bool operator==(const any &rhs) const {
00125 return (!pimpl && !rhs.pimpl) ||
00126 ((pimpl && rhs.pimpl) && (*pimpl == *(rhs.pimpl)));
00127 }
00128 private:
00129 class impl_int {
00130 public:
00131 virtual const std::type_info& type() const = 0;
00132 virtual impl_int* clone() const = 0;
00133 virtual bool operator==(const impl_int&) const = 0;
00134 virtual std::string str() const = 0;
00135 };
00136 template <class T>
00137 class impl: public impl_int {
00138 public:
00139 impl(const impl_int &value) {
00140 _value = from_string<T>(value.str());
00141 };
00142 impl(const T &value): _value(value) { };
00143 virtual const std::type_info& type() const {
00144 return typeid(_value);
00145 };
00146 virtual impl_int* clone() const {
00147 return new impl<T>(_value);
00148 };
00149 virtual bool operator==(const impl_int &other) const {
00150 return (_value == static_cast<impl>(other)._value);
00151 };
00152 virtual std::string str() const {
00153 return to_string<T>(_value);
00154 };
00155 const T cast() const {
00156 return _value;
00157 };
00158 private:
00159 T _value;
00160 };
00161 impl_int *pimpl;
00162 };
00163
00165 inline std::ostream& operator<<(std::ostream &str, const any &value) {
00166 str << value.str();
00167 return str;
00168 };
00169
00170 }
00171
00172 #endif
00173