From: Marc D. <ma...@us...> - 2004-12-28 23:01:07
|
Update of /cvsroot/pclasses/pclasses2/include/pclasses/Util In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26991/include/pclasses/Util Added Files: Any.h Log Message: added Any class to Util module --- NEW FILE: Any.h --- /* * P::Classes - Portable C++ Application Framework * Copyright (C) 2000-2003 Christian Prochnow <cp...@se...> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Based on boost::any Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. */ #ifndef _P_Util_Any_h_ #define _P_Util_Any_h_ #include <algorithm> #include <typeinfo> #include <iostream> namespace P { namespace Util { //! Container that can hold every type /*! \ingroup core */ class Any { public: Any() : m_data(0) { } Any(const Any& val) : m_data(val.m_data ? val.m_data->clone() : 0) { } template <typename ValueType> Any(const ValueType& val) : m_data(new holder<ValueType>(val)) { } ~Any() { if(m_data) delete m_data; } Any& swap(Any& rhs) { std::swap(m_data, rhs.m_data); return *this; } template <typename ValueType> Any& operator=(const ValueType& rhs) { Any(rhs).swap(*this); return *this; } Any& operator=(const Any& rhs) { Any(rhs).swap(*this); return *this; } inline bool empty() const { return !m_data; } const std::type_info& type() const { return m_data ? m_data->type() : typeid(void); } template <typename ValueType> friend ValueType* any_cast(Any* val); friend std::ostream& operator<<(std::ostream& os, const Any& val); private: class holder_iface { public: virtual ~holder_iface() { } virtual const std::type_info& type() const = 0; virtual holder_iface* clone() const = 0; virtual void output(std::ostream& os) const = 0; }; template <typename ValueType> class holder: public holder_iface { public: holder(const ValueType& val) : m_value(val) { } virtual const std::type_info& type() const { return typeid(ValueType); } virtual holder_iface* clone() const { return new holder(m_value); } virtual void output(std::ostream& os) const { os << m_value; } private: ValueType m_value; }; private: holder_iface* m_data; }; //! Bad any-cast /*! \ingroup core */ class BadAnyCast: public std::bad_cast { public: virtual const char* what() const throw() { return "BadAnyCast: failed conversion using P::any_cast"; } }; //! Cast from any to type /*! \ingroup core */ template <typename ValueType> ValueType* any_cast(Any* operand) { return operand && operand->type() == typeid(ValueType) ? &static_cast<Any::holder<ValueType>*>(operand->m_data)->m_value : 0; } //! Cast from any to const-type /*! \ingroup core */ template <typename ValueType> const ValueType* any_cast(const Any* operand) { return any_cast<ValueType>(const_cast<Any*>(operand)); } //! Cast from any to value /*! \ingroup core */ template <typename ValueType> ValueType any_cast(const Any& operand) throw(BadAnyCast) { const ValueType* result = any_cast<ValueType>(&operand); if(!result) throw BadAnyCast(); return *result; } //! Any stream output operator /*! \ingroup core */ std::ostream& operator<<(std::ostream& os, const Any& val) { val.m_data->output(os); return os; } } } #endif |