174 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			174 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | /*============================================================================= | ||
|  |     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 <utility> | ||
|  | #include <boost/mpl/eval_if.hpp> | ||
|  | #include <boost/type_traits/is_same.hpp> | ||
|  | #include <boost/type_traits/is_const.hpp> | ||
|  | 
 | ||
|  | 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<std::vector<int> >::type" is "int" whilst | ||
|  | //      "value_type_of<double>::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 <typename C>                                                       \ | ||
|  |     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 <typename C> | ||
|  |     struct const_qualified_reference_of | ||
|  |     { | ||
|  |         typedef typename | ||
|  |             boost::mpl::eval_if_c< | ||
|  |                 boost::is_const<C>::value | ||
|  |               , const_reference_of<C> | ||
|  |               , reference_of<C> | ||
|  |             >::type | ||
|  |         type; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template <typename C> | ||
|  |     struct const_qualified_iterator_of | ||
|  |     { | ||
|  |         typedef typename | ||
|  |             boost::mpl::eval_if_c< | ||
|  |                 boost::is_const<C>::value | ||
|  |               , const_iterator_of<C> | ||
|  |               , iterator_of<C> | ||
|  |             >::type | ||
|  |         type; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template <typename C> | ||
|  |     struct const_qualified_reverse_iterator_of | ||
|  |     { | ||
|  |         typedef typename | ||
|  |             boost::mpl::eval_if_c< | ||
|  |                 boost::is_const<C>::value | ||
|  |               , const_reverse_iterator_of<C> | ||
|  |               , reverse_iterator_of<C> | ||
|  |             >::type | ||
|  |         type; | ||
|  |     }; | ||
|  | 
 | ||
|  | /////////////////////////////////////////////////////////////////////////////// | ||
|  | // | ||
|  | //  has_mapped_type<C> | ||
|  | // | ||
|  | //      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 <typename C> | ||
|  |         one has_mapped_type(typename C::mapped_type(*)()); | ||
|  | 
 | ||
|  |         template <typename C> | ||
|  |         two has_mapped_type(...); | ||
|  |     } | ||
|  | 
 | ||
|  |     template <typename C> | ||
|  |     struct has_mapped_type | ||
|  |         : boost::mpl::bool_< | ||
|  |             sizeof(stl_impl::has_mapped_type<C>(0)) == sizeof(stl_impl::one) | ||
|  |         > | ||
|  |     {}; | ||
|  | 
 | ||
|  | /////////////////////////////////////////////////////////////////////////////// | ||
|  | // | ||
|  | //  map_insert_returns_pair<C> | ||
|  | // | ||
|  | //      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<class A, class B> | ||
|  |         one map_insert_returns_pair_check(std::pair<A,B> const&); | ||
|  | 
 | ||
|  |         template <typename T> | ||
|  |         two map_insert_returns_pair_check(T const&); | ||
|  | 
 | ||
|  |         template <typename C> | ||
|  |         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_<value == sizeof(one)> type; | ||
|  |         }; | ||
|  |     } | ||
|  | 
 | ||
|  |     template <typename C> | ||
|  |     struct map_insert_returns_pair | ||
|  |         : stl_impl::map_insert_returns_pair<C>::type {}; | ||
|  | 
 | ||
|  | }}} // namespace boost::phoenix::stl | ||
|  | 
 | ||
|  | #endif // BOOST_PHOENIX_STL_CONTAINER_TRAITS_HPP |