Any.hpp

Go to the documentation of this file.
00001 #pragma ident "$Id: Any.hpp 2938 2011-10-23 19:39:11Z yanweignss $"
00002 
00008 #ifndef GPSTK_ANY_HPP
00009 #define GPSTK_ANY_HPP
00010 
00011 //============================================================================
00012 //
00013 //  This file is part of GPSTk, the GPS Toolkit.
00014 //
00015 //  The GPSTk is free software; you can redistribute it and/or modify
00016 //  it under the terms of the GNU Lesser General Public License as published
00017 //  by the Free Software Foundation; either version 2.1 of the License, or
00018 //  any later version.
00019 //
00020 //  The GPSTk is distributed in the hope that it will be useful,
00021 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 //  GNU Lesser General Public License for more details.
00024 //
00025 //  You should have received a copy of the GNU Lesser General Public
00026 //  License along with GPSTk; if not, write to the Free Software Foundation,
00027 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00028 //
00029 //  Wei Yan - Chinese Academy of Sciences . 2011
00030 //
00031 //============================================================================
00032 
00033 #include <algorithm>
00034 #include <typeinfo>
00035 #include "Exception.hpp"
00036 
00037 namespace gpstk
00038 {
00045    class Any
00046    {
00047    public:
00048       Any():_content(0){}
00049 
00050       template <typename ValueType>
00051       Any(const ValueType& value):_content(new Holder<ValueType>(value)) {}
00052 
00053       Any(const Any& other):_content(other._content ? other._content->clone() : 0){}
00054 
00055       ~Any(){delete _content;}
00056 
00057       Any& swap(Any& rhs)
00058       {
00059          std::swap(_content, rhs._content);
00060          return *this;
00061       }
00062 
00063       template <typename ValueType>
00064       Any& operator = (const ValueType& rhs)
00065       {
00066          Any(rhs).swap(*this);
00067          return *this;
00068       }
00069 
00070       Any& operator = (const Any& rhs)
00071       {
00072          Any(rhs).swap(*this);
00073          return *this;
00074       }
00075 
00076       bool empty() const
00077       {
00078          return !_content;
00079       }
00080 
00081       const std::type_info& type() const
00082       {
00083          return _content ? _content->type() : typeid(void);
00084       }
00085 
00086    private:
00087       class Placeholder
00088       {
00089       public:
00090          virtual ~Placeholder(){}
00091 
00092          virtual const std::type_info& type() const = 0;
00093          virtual Placeholder* clone() const = 0;
00094       };
00095 
00096       template <typename ValueType>
00097       class Holder: public Placeholder
00098       {
00099       public: 
00100          Holder(const ValueType& value):_held(value){}
00101 
00102          virtual const std::type_info& type() const
00103          {
00104             return typeid(ValueType);
00105          }
00106 
00107          virtual Placeholder* clone() const
00108          {
00109             return new Holder(_held);
00110          }
00111 
00112          ValueType _held;
00113       };
00114 
00115    private:
00116       template <typename ValueType>
00117       friend ValueType* AnyCast(Any*);
00118 
00119       template <typename ValueType>
00120       friend ValueType* UnsafeAnyCast(Any*);
00121 
00122       Placeholder* _content;
00123    };
00124 
00125 
00132    template <typename ValueType>
00133    ValueType* AnyCast(Any* operand)
00134    {
00135       return operand && operand->type() == typeid(ValueType)
00136          ? &static_cast<Any::Holder<ValueType>*>(operand->_content)->_held
00137          : 0;
00138    }
00139 
00140 
00147    template <typename ValueType>
00148    const ValueType* AnyCast(const Any* operand)     
00149    {
00150       return AnyCast<ValueType>(const_cast<Any*>(operand));
00151    }
00152 
00153 
00162    template <typename ValueType>
00163    ValueType AnyCast(const Any& operand)
00164    {
00165       ValueType* result = AnyCast<ValueType>(const_cast<Any*>(&operand));
00166       if (!result) throw Exception("Failed to convert between const Any types");
00167       return *result;
00168    }
00169 
00178    template <typename ValueType>
00179    ValueType AnyCast(Any& operand)
00180    {
00181       ValueType* result = AnyCast<ValueType>(&operand);
00182       if (!result) throw Exception("Failed to convert between Any types");
00183       return *result;
00184    }
00185 
00190    template <typename ValueType>
00191    const ValueType& RefAnyCast(const Any & operand)
00192    {
00193       ValueType* result = AnyCast<ValueType>(const_cast<Any*>(&operand));
00194       if (!result) throw Exception("RefAnyCast: Failed to convert between const Any types");
00195       return *result;
00196    }
00197 
00198 
00203    template <typename ValueType>
00204    ValueType& RefAnyCast(Any& operand)
00205    {
00206       ValueType* result = AnyCast<ValueType>(&operand);
00207       if (!result) throw Exception("RefAnyCast: Failed to convert between Any types");
00208       return *result;
00209    }
00210 
00216    template <typename ValueType>
00217    ValueType* UnsafeAnyCast(Any* operand)    
00218    {
00219       return &static_cast<Any::Holder<ValueType>*>(operand->_content)->_held;
00220    }
00221 
00227    template <typename ValueType>
00228    const ValueType* UnsafeAnyCast(const Any* operand)
00229    {
00230       return AnyCast<ValueType>(const_cast<Any*>(operand));
00231    }
00232    
00233 }   // End of namespace gpstk
00234 
00235 
00236 #endif  //GPSTK_ANY_HPP
00237 

Generated on Tue May 22 03:30:56 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1