/*============================================================================= Copyright (c) 2004 Angus Leeming Copyright (c) 2004 Joel de Guzman Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ==============================================================================*/ #ifndef BOOST_PHOENIX_CONTAINER_DETAIL_CONTAINER_HPP #define BOOST_PHOENIX_CONTAINER_DETAIL_CONTAINER_HPP #include #include #include #include namespace boost { namespace phoenix { namespace stl { /////////////////////////////////////////////////////////////////////////////// // // Metafunctions "value_type_of", "key_type_of" etc. // // These metafunctions define a typedef "type" that returns the nested // type if it exists. If not then the typedef returns void. // // For example, "value_type_of >::type" is "int" whilst // "value_type_of::type" is "void". // // I use a macro to define structs "value_type_of" etc simply to cut // down on the amount of code. The macro is #undef-ed immediately after // its final use. // /////////////////////////////////////////////////////////////////c////////////// #define MEMBER_TYPE_OF(MEMBER_TYPE) \ template \ struct BOOST_PP_CAT(MEMBER_TYPE, _of) \ { \ typedef typename C::MEMBER_TYPE type; \ } MEMBER_TYPE_OF(allocator_type); MEMBER_TYPE_OF(const_iterator); MEMBER_TYPE_OF(const_reference); MEMBER_TYPE_OF(const_reverse_iterator); MEMBER_TYPE_OF(container_type); MEMBER_TYPE_OF(data_type); MEMBER_TYPE_OF(iterator); MEMBER_TYPE_OF(key_compare); MEMBER_TYPE_OF(key_type); MEMBER_TYPE_OF(reference); MEMBER_TYPE_OF(reverse_iterator); MEMBER_TYPE_OF(size_type); MEMBER_TYPE_OF(value_compare); MEMBER_TYPE_OF(value_type); #undef MEMBER_TYPE_OF /////////////////////////////////////////////////////////////////////////////// // // Const-Qualified types. // // Many of the stl member functions have const and non-const // overloaded versions that return distinct types. For example: // // iterator begin(); // const_iterator begin() const; // // The three class templates defined below, // const_qualified_reference_of, const_qualified_iterator_of // and const_qualified_reverse_iterator_of provide a means to extract // this return type automatically. // /////////////////////////////////////////////////////////////////////////////// template struct const_qualified_reference_of { typedef typename boost::mpl::eval_if_c< boost::is_const::value , const_reference_of , reference_of >::type type; }; template struct const_qualified_iterator_of { typedef typename boost::mpl::eval_if_c< boost::is_const::value , const_iterator_of , iterator_of >::type type; }; template struct const_qualified_reverse_iterator_of { typedef typename boost::mpl::eval_if_c< boost::is_const::value , const_reverse_iterator_of , reverse_iterator_of >::type type; }; /////////////////////////////////////////////////////////////////////////////// // // has_mapped_type // // Given a container C, determine if it is a map or multimap // by checking if it has a member type named "mapped_type". // /////////////////////////////////////////////////////////////////////////////// namespace stl_impl { struct one { char a[1]; }; struct two { char a[2]; }; template one has_mapped_type(typename C::mapped_type(*)()); template two has_mapped_type(...); template struct enable_if_is_void {}; template<> struct enable_if_is_void { typedef void type; }; template struct disable_if_is_void { typedef T type; }; template<> struct disable_if_is_void {}; } template struct has_mapped_type : boost::mpl::bool_< sizeof(stl_impl::has_mapped_type(0)) == sizeof(stl_impl::one) > {}; /////////////////////////////////////////////////////////////////////////////// // // map_insert_returns_pair // // Distinguish a map from a multimap by checking the return type // of its "insert" member function. A map returns a pair while // a multimap returns an iterator. // /////////////////////////////////////////////////////////////////////////////// namespace stl_impl { // Cool implementation of map_insert_returns_pair by Daniel Wallin. // Thanks Daniel!!! I owe you a Pizza! template one map_insert_returns_pair_check(std::pair const&); template two map_insert_returns_pair_check(T const&); template struct map_insert_returns_pair { static typename C::value_type const& get; BOOST_STATIC_CONSTANT(int, value = sizeof( map_insert_returns_pair_check(((C*)0)->insert(get)))); typedef boost::mpl::bool_ type; }; } template struct map_insert_returns_pair : stl_impl::map_insert_returns_pair::type {}; }}} // namespace boost::phoenix::stl #endif // BOOST_PHOENIX_STL_CONTAINER_TRAITS_HPP