diff options
Diffstat (limited to 'boost/phoenix/stl/container')
-rw-r--r-- | boost/phoenix/stl/container/container.hpp | 39 | ||||
-rw-r--r-- | boost/phoenix/stl/container/detail/container.hpp | 42 |
2 files changed, 57 insertions, 24 deletions
diff --git a/boost/phoenix/stl/container/container.hpp b/boost/phoenix/stl/container/container.hpp index 907b0eb6cd..d2b8c24ac0 100644 --- a/boost/phoenix/stl/container/container.hpp +++ b/boost/phoenix/stl/container/container.hpp @@ -33,7 +33,7 @@ namespace boost { namespace phoenix // Lazy functions are provided for all of the member functions of the // following containers: // -// deque - list - map - multimap - vector. +// deque - list - map - multimap - vector - set - multiset. // // Indeed, should *your* class have member functions with the same names // and signatures as those listed below, then it will automatically be @@ -286,32 +286,25 @@ namespace boost { namespace phoenix template <typename C, typename Arg1, typename Arg2 = mpl::void_> struct erase { - // BOOST_MSVC #if branch here in map_erase_result non- - // standard behavior. The return type should be void but - // VC7.1 prefers to return iterator_of<C>. As a result, - // VC7.1 complains of error C2562: - // boost::phoenix::stl::erase::operator() 'void' function - // returning a value. Oh well... :* - + // MSVC and libc++ always returns iterator even in C++03 mode. typedef - boost::mpl::eval_if_c< - boost::is_same< - typename remove_reference<Arg1>::type - , typename iterator_of<C>::type - >::value -#if defined(BOOST_MSVC)// && (BOOST_MSVC <= 1500) + boost::mpl::eval_if< + is_key_type_of<C, Arg1> + , size_type_of<C> +#if defined(BOOST_MSVC) /*&& (BOOST_MSVC <= 1500)*/ \ + && (defined(BOOST_LIBSTDCXX11) && 40500 <= BOOST_LIBSTDCXX_VERSION) \ + && defined(_LIBCPP_VERSION) , iterator_of<C> #else , boost::mpl::identity<void> #endif - , size_type_of<C> > - map_erase_result; + assoc_erase_result; typedef typename boost::mpl::eval_if_c< - has_mapped_type<C>::value - , map_erase_result + has_key_type<C>::value + , assoc_erase_result , iterator_of<C> >::type type; @@ -322,18 +315,20 @@ namespace boost { namespace phoenix { // This mouthful can differentiate between the generic erase // functions (Container == std::deque, std::list, std::vector) and - // that specific to the two map-types, std::map and std::multimap. + // that specific to Associative Containers. // // where C is a std::deque, std::list, std::vector: // // 1) iterator C::erase(iterator where); // 2) iterator C::erase(iterator first, iterator last); // - // where M is a std::map or std::multimap: + // where C is a std::map, std::multimap, std::set, or std::multiset: // // 3) size_type M::erase(const Key& keyval); - // 4) void M::erase(iterator where); - // 5) void M::erase(iterator first, iterator last); + // 4-a) void M::erase(iterator where); + // 4-b) iterator M::erase(iterator where); + // 5-a) void M::erase(iterator first, iterator last); + // 5-b) iterator M::erase(iterator first, iterator last); template <typename Sig> struct result; diff --git a/boost/phoenix/stl/container/detail/container.hpp b/boost/phoenix/stl/container/detail/container.hpp index fb6cad2fe9..b92472b237 100644 --- a/boost/phoenix/stl/container/detail/container.hpp +++ b/boost/phoenix/stl/container/detail/container.hpp @@ -12,6 +12,7 @@ #include <boost/mpl/eval_if.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/type_traits/is_const.hpp> +#include <boost/type_traits/is_convertible.hpp> namespace boost { namespace phoenix { namespace stl { @@ -110,8 +111,8 @@ namespace boost { namespace phoenix { namespace stl // // 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". +// Given a container C, determine if it is a map, multimap, unordered_map, +// or unordered_multimap by checking if it has a member type named "mapped_type". // /////////////////////////////////////////////////////////////////////////////// namespace stl_impl @@ -135,6 +136,43 @@ namespace boost { namespace phoenix { namespace stl /////////////////////////////////////////////////////////////////////////////// // +// has_key_type<C> +// +// Given a container C, determine if it is a Associative Container +// by checking if it has a member type named "key_type". +// +/////////////////////////////////////////////////////////////////////////////// + namespace stl_impl + { + template <typename C> + one has_key_type(typename C::key_type(*)()); + + template <typename C> + two has_key_type(...); + } + + template <typename C> + struct has_key_type + : boost::mpl::bool_< + sizeof(stl_impl::has_key_type<C>(0)) == sizeof(stl_impl::one) + > + {}; + +/////////////////////////////////////////////////////////////////////////////// +// +// is_key_type_of<C, Arg> +// +// Lazy evaluation friendly predicate. +// +/////////////////////////////////////////////////////////////////////////////// + + template <typename C, typename Arg> + struct is_key_type_of + : boost::is_convertible<Arg, typename key_type_of<C>::type> + {}; + +/////////////////////////////////////////////////////////////////////////////// +// // map_insert_returns_pair<C> // // Distinguish a map from a multimap by checking the return type |