any.h

00001 /*
00002  * any.h
00003  * This file is part of dbPager Classes Library (DCL)
00004  *
00005  * Copyright (c) 2008 Dennis Prochko <wolfsoft@mail.ru>
00006  *
00007  * DCL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation version 3.
00010  *
00011  * DCL is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with DCL; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor,
00019  * Boston, MA  02110-1301  USA
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 } // namespace
00171 
00172 #endif /*_ANY_H_*/
00173 

 
Support This Project
SourceForge.net Logo