any.h

00001 /***************************************************************************
00002  *   clipsmm C++ wrapper for the CLIPS c library                           *
00003  *   Copyright (C) 2006 by Rick L. Vinyard, Jr.                            *
00004  *   rvinyard@cs.nmsu.edu                                                  *
00005  *                                                                         *
00006  *   This program is free software; you can redistribute it and/or modify  *
00007  *   it under the terms of version 2 of the GNU General Public License as  *
00008  *   published by the Free Software Foundation.                            *
00009  *                                                                         *
00010  *   This program 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         *
00013  *   GNU 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                 *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA              *
00019  ***************************************************************************/
00020 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
00021 //
00022 // Permission to use, copy, modify, and distribute this software for any
00023 // purpose is hereby granted without fee, provided that this copyright and
00024 // permissions notice appear in all copies and derivatives.
00025 //
00026 // This software is provided "as is" without express or implied warranty.
00027 
00028 // See http://www.boost.org/libs/any for Documentation.
00029 
00030 #ifndef CLIPSANY_H
00031 #define CLIPSANY_H
00032 
00033 // what:  variant type boost::any
00034 // who:   contributed by Kevlin Henney,
00035 //        with features contributed and bugs found by
00036 //        Ed Brey, Mark Rodgers, Peter Dimov, and James Curran
00037 // when:  July 2001
00038 // where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95
00039 
00040 #include <algorithm>
00041 #include <typeinfo>
00042 
00043 // #include "boost/config.hpp"
00044 
00045 namespace CLIPS
00046 {
00047     class any
00048     {
00049     public: // structors
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: // modifiers
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: // queries
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: // types
00106 
00107         class placeholder
00108         {
00109         public: // structors
00110 
00111             virtual ~placeholder()
00112             {
00113             }
00114 
00115         public: // queries
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: // structors
00127 
00128             holder(const ValueType & value)
00129               : held(value)
00130             {
00131             }
00132 
00133         public: // queries
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: // representation
00146 
00147             ValueType held;
00148 
00149         };
00150 
00151     private: // representation
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

Generated on Sun Nov 12 11:55:35 2006 by  doxygen 1.5.1