Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members | Related Pages | Examples

pany.h

Go to the documentation of this file.
00001 /*
00002  *   P::Classes - Portable C++ Application Framework
00003  *   Copyright (C) 2000-2003  Christian Prochnow <cproch@seculogix.de>
00004  *
00005  *   This library is free software; you can redistribute it and/or
00006  *   modify it under the terms of the GNU Lesser General Public
00007  *   License as published by the Free Software Foundation; either
00008  *   version 2 of the License, or (at your option) any later version.
00009  *
00010  *   This library is distributed in the hope that it will be useful,
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  *   Lesser General Public License for more details.
00014  *
00015  *   You should have received a copy of the GNU Lesser General Public
00016  *   License along with this library; if not, write to the Free Software
00017  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  *
00019  *   Based on boost::any Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
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

Generated on Fri Mar 12 21:08:30 2004 for P::Classes by doxygen 1.3.3