sl@0: //----------------------------------------------------------------------------- sl@0: // boost variant/get.hpp header file sl@0: // See http://www.boost.org for updates, documentation, and revision history. sl@0: //----------------------------------------------------------------------------- sl@0: // sl@0: // Copyright (c) 2003 sl@0: // Eric Friedman, Itay Maman sl@0: // sl@0: // Distributed under the Boost Software License, Version 1.0. (See sl@0: // accompanying file LICENSE_1_0.txt or copy at sl@0: // http://www.boost.org/LICENSE_1_0.txt) sl@0: sl@0: #ifndef BOOST_VARIANT_GET_HPP sl@0: #define BOOST_VARIANT_GET_HPP sl@0: sl@0: #include sl@0: sl@0: #include "boost/config.hpp" sl@0: #include "boost/detail/workaround.hpp" sl@0: #include "boost/utility/addressof.hpp" sl@0: #include "boost/variant/variant_fwd.hpp" sl@0: sl@0: #include "boost/type_traits/add_reference.hpp" sl@0: #include "boost/type_traits/add_pointer.hpp" sl@0: sl@0: #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) sl@0: # include "boost/mpl/bool.hpp" sl@0: # include "boost/mpl/or.hpp" sl@0: # include "boost/type_traits/is_same.hpp" sl@0: #endif sl@0: sl@0: namespace boost { sl@0: sl@0: ////////////////////////////////////////////////////////////////////////// sl@0: // class bad_get sl@0: // sl@0: // The exception thrown in the event of a failed get of a value. sl@0: // sl@0: class bad_get sl@0: : public std::exception sl@0: { sl@0: public: // std::exception implementation sl@0: sl@0: virtual const char * what() const throw() sl@0: { sl@0: return "boost::bad_get: " sl@0: "failed value get using boost::get"; sl@0: } sl@0: sl@0: }; sl@0: sl@0: ////////////////////////////////////////////////////////////////////////// sl@0: // function template get sl@0: // sl@0: // Retrieves content of given variant object if content is of type T. sl@0: // Otherwise: pointer ver. returns 0; reference ver. throws bad_get. sl@0: // sl@0: sl@0: namespace detail { namespace variant { sl@0: sl@0: // (detail) class template get_visitor sl@0: // sl@0: // Generic static visitor that: if the value is of the specified type, sl@0: // returns a pointer to the value it visits; else a null pointer. sl@0: // sl@0: template sl@0: struct get_visitor sl@0: { sl@0: private: // private typedefs sl@0: sl@0: typedef typename add_pointer::type pointer; sl@0: typedef typename add_reference::type reference; sl@0: sl@0: public: // visitor typedefs sl@0: sl@0: typedef pointer result_type; sl@0: sl@0: public: // visitor interfaces sl@0: sl@0: #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) sl@0: sl@0: pointer operator()(reference operand) const sl@0: { sl@0: return boost::addressof(operand); sl@0: } sl@0: sl@0: template sl@0: pointer operator()(const U&) const sl@0: { sl@0: return static_cast(0); sl@0: } sl@0: sl@0: #else // MSVC6 sl@0: sl@0: private: // helpers, for visitor interfaces (below) sl@0: sl@0: pointer execute_impl(reference operand, mpl::true_) const sl@0: { sl@0: return boost::addressof(operand); sl@0: } sl@0: sl@0: template sl@0: pointer execute_impl(const U& operand, mpl::false_) const sl@0: { sl@0: return static_cast(0); sl@0: } sl@0: sl@0: public: // visitor interfaces sl@0: sl@0: template sl@0: pointer operator()(U& operand) const sl@0: { sl@0: // MSVC6 finds normal implementation (above) ambiguous, sl@0: // so we must explicitly disambiguate sl@0: sl@0: typedef typename mpl::or_< sl@0: is_same sl@0: , is_same sl@0: >::type U_is_T; sl@0: sl@0: return execute_impl(operand, U_is_T()); sl@0: } sl@0: sl@0: #endif // MSVC6 workaround sl@0: sl@0: }; sl@0: sl@0: }} // namespace detail::variant sl@0: sl@0: #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551)) sl@0: # define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \ sl@0: BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t) sl@0: #else sl@0: # define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \ sl@0: , t* = 0 sl@0: #endif sl@0: sl@0: template sl@0: inline sl@0: typename add_pointer::type sl@0: get( sl@0: boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand sl@0: BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) sl@0: ) sl@0: { sl@0: typedef typename add_pointer::type U_ptr; sl@0: if (!operand) return static_cast(0); sl@0: sl@0: detail::variant::get_visitor v; sl@0: return operand->apply_visitor(v); sl@0: } sl@0: sl@0: template sl@0: inline sl@0: typename add_pointer::type sl@0: get( sl@0: const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand sl@0: BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) sl@0: ) sl@0: { sl@0: typedef typename add_pointer::type U_ptr; sl@0: if (!operand) return static_cast(0); sl@0: sl@0: detail::variant::get_visitor v; sl@0: return operand->apply_visitor(v); sl@0: } sl@0: sl@0: template sl@0: inline sl@0: typename add_reference::type sl@0: get( sl@0: boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand sl@0: BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) sl@0: ) sl@0: { sl@0: typedef typename add_pointer::type U_ptr; sl@0: U_ptr result = get(&operand); sl@0: sl@0: if (!result) sl@0: throw bad_get(); sl@0: return *result; sl@0: } sl@0: sl@0: template sl@0: inline sl@0: typename add_reference::type sl@0: get( sl@0: const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand sl@0: BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U) sl@0: ) sl@0: { sl@0: typedef typename add_pointer::type U_ptr; sl@0: U_ptr result = get(&operand); sl@0: sl@0: if (!result) sl@0: throw bad_get(); sl@0: return *result; sl@0: } sl@0: sl@0: } // namespace boost sl@0: sl@0: #endif // BOOST_VARIANT_GET_HPP