123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828 |
- /*=============================================================================
- 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_STL_CONTAINER_CONTAINER_HPP
- #define BOOST_PHOENIX_STL_CONTAINER_CONTAINER_HPP
- #include <boost/phoenix/core/limits.hpp>
- #include <boost/mpl/and.hpp>
- #include <boost/mpl/not.hpp>
- #include <boost/mpl/or.hpp>
- #include <boost/mpl/void.hpp>
- #include <boost/phoenix/stl/container/detail/container.hpp>
- #include <boost/phoenix/function/adapt_callable.hpp>
- #include <boost/type_traits/is_const.hpp>
- namespace boost { namespace phoenix
- {
- ///////////////////////////////////////////////////////////////////////////////
- //
- // STL container member functions
- //
- // Lazy functions for STL container member functions
- //
- // These functions provide a mechanism for the lazy evaluation of the
- // public member functions of the STL containers. For an overview of
- // what is meant by 'lazy evaluation', see the comments in operators.hpp
- // and functions.hpp.
- //
- // Lazy functions are provided for all of the member functions of the
- // following containers:
- //
- // 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
- // supported. To summarize, lazy functions are provided for member
- // functions:
- //
- // assign - at - back - begin - capacity - clear - empty - end -
- // erase - front - get_allocator - insert - key_comp - max_size -
- // pop_back - pop_front - push_back - push_front - rbegin - rend -
- // reserve - resize . size - splice - value_comp.
- //
- // The lazy functions' names are the same as the corresponding member
- // function. Sample usage:
- //
- // "Normal" version "Lazy" version
- // ---------------- --------------
- // my_vector.at(5) phoenix::at(arg1, 5)
- // my_list.size() phoenix::size(arg1)
- // my_vector1.swap(my_vector2) phoenix::swap(arg1, arg2)
- //
- // Notice that member functions with names that clash with a
- // function in stl algorithms are absent. This will be provided
- // in Phoenix's algorithm module.
- //
- // No support is provided here for lazy versions of operator+=,
- // operator[] etc. Such operators are not specific to STL containers and
- // lazy versions can therefore be found in operators.hpp.
- //
- ///////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Lazy member function implementaions.
- //
- // The structs below provide the guts of the implementation. Thereafter,
- // the corresponding lazy function itself is simply:
- //
- // function<stl::assign> const assign = stl::assign();
- //
- // The structs provide a nested "result" class template whose
- // "type" typedef enables the lazy function to ascertain the type
- // to be returned when it is invoked.
- //
- // They also provide operator() member functions with signatures
- // corresponding to those of the underlying member function of
- // the STL container.
- //
- ///////////////////////////////////////////////////////////////////////////////
- namespace stl
- {
- struct assign
- {
- template <typename Sig>
- struct result;
- template <
- typename This
- , typename C
- , typename Arg1
- >
- struct result<This(C&, Arg1&)>
- {
- typedef typename add_reference<C>::type type;
- };
- template <
- typename This
- , typename C
- , typename Arg1
- , typename Arg2
- >
- struct result<This(C&, Arg1, Arg2)>
- {
- typedef typename add_reference<C>::type type;
- };
- template <
- typename This
- , typename C
- , typename Arg1
- , typename Arg2
- , typename Arg3
- >
- struct result<This(C&, Arg1, Arg2, Arg3)>
- {
- typedef typename add_reference<C>::type type;
- };
- template <typename C, typename Arg1>
- C& operator()(C& c, Arg1 const & arg1) const
- {
- c.assign(arg1);
- return c;
- }
- template <typename C, typename Arg1, typename Arg2>
- C& operator()(C& c, Arg1 arg1, Arg2 arg2) const
- {
- c.assign(arg1, arg2);
- return c;
- }
- template <typename C, typename Arg1, typename Arg2, typename Arg3>
- C& operator()(
- C& c
- , Arg1 arg1
- , Arg2 arg2
- , Arg3 const & arg3
- ) const
- {
- return c.assign(arg1, arg2, arg3);
- }
- };
- struct at_impl
- {
- template <typename Sig>
- struct result;
- template <typename This, typename C, typename Index>
- struct result<This(C&, Index)>
- {
- //typedef typename const_qualified_reference_of<C>::type type;
- typedef typename C::value_type & type;
- };
- template <typename C, typename Index>
- typename result<at_impl(C&, Index const&)>::type
- operator()(C& c, Index const &i) const
- {
- return c.at(i);
- }
- template <typename This, typename C, typename Index>
- struct result<This(C const&, Index)>
- {
- typedef typename C::value_type const & type;
- };
- template <typename C, typename Index>
- typename result<at_impl(C const&, Index const&)>::type
- operator()(C const& c, Index const &i) const
- {
- return c.at(i);
- }
- };
- struct back
- {
- template <typename Sig>
- struct result;
- template <typename This, typename C>
- struct result<This(C&)>
- {
- typedef
- typename const_qualified_reference_of<C>::type
- type;
- };
- template <typename C>
- typename result<back(C&)>::type
- operator()(C& c) const
- {
- return c.back();
- }
- };
- struct begin
- {
- template <typename Sig>
- struct result;
- template <typename This, typename C>
- struct result<This(C&)>
- {
- typedef typename const_qualified_iterator_of<C>::type type;
- };
- template <typename C>
- typename result<begin(C&)>::type
- operator()(C& c) const
- {
- return c.begin();
- }
- };
- struct capacity
- {
- template <typename Sig>
- struct result;
- template <typename This, typename C>
- struct result<This(C&)>
- {
- typedef typename size_type_of<C>::type type;
- };
- template <typename C>
- typename result<capacity(C&)>::type
- operator()(C const& c) const
- {
- return c.capacity();
- }
- };
- struct clear
- {
- typedef void result_type;
- template <typename C>
- void operator()(C& c) const
- {
- return c.clear();
- }
- };
- struct empty
- {
- typedef bool result_type;
- template <typename C>
- bool operator()(C const& c) const
- {
- return c.empty();
- }
- };
- struct end
- {
- template <typename Sig>
- struct result;
- template <typename This, typename C>
- struct result<This(C&)>
- {
- typedef typename const_qualified_iterator_of<C>::type type;
- };
- template <typename C>
- typename result<end(C&)>::type
- operator()(C& c) const
- {
- return c.end();
- }
- };
- namespace result_of
- {
- template <typename C, typename Arg1, typename Arg2 = mpl::void_>
- struct erase
- {
- // MSVC and libc++ always returns iterator even in C++03 mode.
- typedef
- 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
- >
- assoc_erase_result;
- typedef typename
- boost::mpl::eval_if_c<
- has_key_type<C>::value
- , assoc_erase_result
- , iterator_of<C>
- >::type
- type;
- };
- }
- struct erase
- {
- // This mouthful can differentiate between the generic erase
- // functions (Container == std::deque, std::list, std::vector) and
- // 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 C is a std::map, std::multimap, std::set, or std::multiset:
- //
- // 3) size_type M::erase(const Key& keyval);
- // 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;
- template <typename This, typename C, typename Arg1>
- struct result<This(C&, Arg1)>
- : result_of::erase<C, Arg1>
- {};
- template <typename This, typename C, typename Arg1, typename Arg2>
- struct result<This(C&, Arg1, Arg2)>
- : result_of::erase<C, Arg1, Arg2>
- {};
- template <typename C, typename Arg1>
- typename result_of::erase<C, Arg1>::type
- operator()(C& c, Arg1 arg1) const
- {
- typedef typename result_of::erase<C, Arg1>::type result_type;
- return static_cast<result_type>(c.erase(arg1));
- }
- template <typename C, typename Arg1, typename Arg2>
- typename result_of::erase<C, Arg1, Arg2>::type
- operator()(C& c, Arg1 arg1, Arg2 arg2) const
- {
- typedef typename result_of::erase<C, Arg1, Arg2>::type result_type;
- return static_cast<result_type>(c.erase(arg1, arg2));
- }
- };
- struct front
- {
- template <typename Sig>
- struct result;
- template <typename This, typename C>
- struct result<This(C&)>
- {
- typedef typename const_qualified_reference_of<C>::type type;
- };
- template <typename C>
- typename result<front(C&)>::type
- operator()(C& c) const
- {
- return c.front();
- }
- };
- struct get_allocator
- {
- template <typename Sig>
- struct result;
- template <typename This, typename C>
- struct result<This(C&)>
- {
- typedef typename allocator_type_of<C>::type type;
- };
- template <typename C>
- typename result<get_allocator(C const&)>::type
- operator()(C& c) const
- {
- return c.get_allocator();
- }
- };
- namespace result_of
- {
- template <
- typename C
- , typename Arg1
- , typename Arg2 = mpl::void_
- , typename Arg3 = mpl::void_
- >
- class insert
- {
- struct pair_iterator_bool
- {
- typedef typename std::pair<typename C::iterator, bool> type;
- };
- typedef
- boost::mpl::eval_if<
- map_insert_returns_pair<typename remove_const<C>::type>
- , pair_iterator_bool
- , iterator_of<C>
- >
- choice_1;
- typedef
- boost::mpl::eval_if_c<
- boost::mpl::and_<
- boost::is_same<Arg3, mpl::void_>
- , boost::mpl::not_<boost::is_same<Arg1, Arg2> >
- >::value
- , iterator_of<C>
- , boost::mpl::identity<void>
- >
- choice_2;
- public:
- typedef typename
- boost::mpl::eval_if_c<
- boost::is_same<Arg2, mpl::void_>::value
- , choice_1
- , choice_2
- >::type
- type;
- };
- }
- struct insert
- {
- // This mouthful can differentiate between the generic insert
- // functions (Container == deque, list, vector) and those
- // specific to the two map-types, std::map and std::multimap.
- //
- // where C is a std::deque, std::list, std::vector:
- //
- // 1) iterator C::insert(iterator where, value_type value);
- // 2) void C::insert(
- // iterator where, size_type count, value_type value);
- // 3) template <typename Iter>
- // void C::insert(iterator where, Iter first, Iter last);
- //
- // where M is a std::map and MM is a std::multimap:
- //
- // 4) pair<iterator, bool> M::insert(value_type const&);
- // 5) iterator MM::insert(value_type const&);
- //
- // where M is a std::map or std::multimap:
- //
- // 6) template <typename Iter>
- // void M::insert(Iter first, Iter last);
- template <typename Sig>
- struct result;
- template <
- typename This
- , typename C
- , typename Arg1
- >
- struct result<This(C &, Arg1)>
- : result_of::insert<C, Arg1>
- {};
- template <
- typename This
- , typename C
- , typename Arg1
- , typename Arg2
- >
- struct result<This(C &, Arg1, Arg2)>
- : result_of::insert<C, Arg1, Arg2>
- {};
- template <
- typename This
- , typename C
- , typename Arg1
- , typename Arg2
- , typename Arg3
- >
- struct result<This(C &, Arg1, Arg2, Arg3)>
- : result_of::insert<C, Arg1, Arg2, Arg3>
- {};
- template <typename C, typename Arg1>
- typename result<insert(C&, Arg1)>::type
- operator()(C& c, Arg1 arg1) const
- {
- return c.insert(arg1);
- }
- template <typename C, typename Arg1, typename Arg2>
- typename result<insert(C&, Arg1, Arg2)>::type
- operator()(C& c, Arg1 arg1, Arg2 arg2) const
- {
- typedef typename result<insert(C&, Arg1, Arg2)>::type result_type;
- return static_cast<result_type>(c.insert(arg1, arg2));
- }
- template <typename C, typename Arg1, typename Arg2, typename Arg3>
- typename result<insert(C&, Arg1, Arg2, Arg3)>::type
- operator()(C& c, Arg1 arg1, Arg2 arg2, Arg3 arg3) const
- {
- typedef typename result<insert(C&, Arg1, Arg2, Arg3)>::type result_type;
- return static_cast<result_type>(c.insert(arg1, arg2, arg3));
- }
- };
- namespace result_of
- {
- template <typename C>
- struct key_comp
- {
- typedef typename key_compare_of<C>::type type;
- };
- }
- struct key_comp
- {
- template <typename Sig>
- struct result;
- template <typename This, typename C>
- struct result<This(C&)>
- : result_of::key_comp<C>
- {};
- template <typename C>
- typename result_of::key_comp<C>::type
- operator()(C& c) const
- {
- return c.key_comp();
- }
- };
- struct max_size
- {
- template <typename Sig>
- struct result;
- template <typename This, typename C>
- struct result<This(C&)>
- {
- typedef typename size_type_of<C>::type type;
- };
- template <typename C>
- typename result<max_size(C const&)>::type
- operator()(C& c) const
- {
- return c.max_size();
- }
- };
- struct pop_back
- {
- typedef void result_type;
- template <typename C>
- void operator()(C& c) const
- {
- return c.pop_back();
- }
- };
- struct pop_front
- {
- typedef void result_type;
- template <typename C>
- void operator()(C& c) const
- {
- return c.pop_front();
- }
- };
- struct push_back
- {
- typedef void result_type;
- template <typename C, typename Arg>
- void operator()(C& c, Arg const& data) const
- {
- return c.push_back(data);
- }
- };
- struct push_front
- {
- typedef void result_type;
- template <typename C, typename Arg>
- void operator()(C& c, Arg const& data) const
- {
- return c.push_front(data);
- }
- };
- struct rbegin
- {
- template <typename Sig>
- struct result;
- template <typename This, typename C>
- struct result<This(C&)>
- {
- typedef typename
- const_qualified_reverse_iterator_of<C>::type
- type;
- };
- template <typename C>
- typename result<rbegin(C&)>::type
- operator()(C& c) const
- {
- return c.rbegin();
- }
- };
- struct rend
- {
- template <typename Sig>
- struct result;
- template <typename This, typename C>
- struct result<This(C&)>
- {
- typedef typename
- const_qualified_reverse_iterator_of<C>::type
- type;
- };
- template <typename C>
- typename result<rend(C&)>::type
- operator()(C& c) const
- {
- return c.rend();
- }
- };
- struct reserve
- {
- typedef void result_type;
- template <typename C, typename Arg>
- void operator()(C& c, Arg const& count) const
- {
- c.reserve(count);
- }
- };
- struct resize
- {
- typedef void result_type;
- template <typename C, typename Arg1>
- void operator()(C& c, Arg1 const& arg1) const
- {
- c.resize(arg1);
- }
- template <typename C, typename Arg1, typename Arg2>
- void operator()(C& c, Arg1 const& arg1, Arg2 const& arg2) const
- {
- c.resize(arg1, arg2);
- }
- };
- struct size
- {
- template <typename Sig>
- struct result;
- template <typename This, typename C>
- struct result<This(C&)>
- {
- typedef typename size_type_of<C>::type type;
- };
- template <typename C>
- typename result<size(C&)>::type
- operator()(C& c) const
- {
- return c.size();
- }
- };
- struct splice
- {
- typedef void result_type;
- template <typename C, typename Arg1, typename Arg2>
- void operator()(C& c, Arg1 arg1, Arg2 &arg2) const
- {
- c.splice(arg1, arg2);
- }
- template <
- typename C
- , typename Arg1
- , typename Arg2
- , typename Arg3
- >
- void operator()(
- C& c
- , Arg1 arg1
- , Arg2 & arg2
- , Arg3 arg3
- ) const
- {
- c.splice(arg1, arg2, arg3);
- }
- template <
- typename C
- , typename Arg1
- , typename Arg2
- , typename Arg3
- , typename Arg4
- >
- void operator()(
- C c
- , Arg1 arg1
- , Arg2 & arg2
- , Arg3 arg3
- , Arg4 arg4
- ) const
- {
- c.splice(arg1, arg2, arg3, arg4);
- }
- };
- namespace result_of
- {
- template <typename C>
- struct value_comp
- {
- typedef typename value_compare_of<C>::type type;
- };
- }
- struct value_comp
- {
- template <typename Sig>
- struct result;
- template <typename This, typename C>
- struct result<This(C&)>
- : result_of::value_comp<C>
- {};
- template <typename C>
- typename result_of::value_comp<C>::type
- operator()(C& c) const
- {
- return c.value_comp();
- }
- };
- } // namespace stl
- ///////////////////////////////////////////////////////////////////////////////
- //
- // The lazy functions themselves.
- //
- ///////////////////////////////////////////////////////////////////////////////
- namespace adl_barrier
- {
- BOOST_PHOENIX_ADAPT_CALLABLE(assign, boost::phoenix::stl::assign, 2)
- BOOST_PHOENIX_ADAPT_CALLABLE(assign, boost::phoenix::stl::assign, 3)
- BOOST_PHOENIX_ADAPT_CALLABLE(assign, boost::phoenix::stl::assign, 4)
- BOOST_PHOENIX_ADAPT_CALLABLE(at, ::boost::phoenix::stl::at_impl, 2)
- BOOST_PHOENIX_ADAPT_CALLABLE(back, stl::back, 1)
- BOOST_PHOENIX_ADAPT_CALLABLE(begin, stl::begin, 1)
- BOOST_PHOENIX_ADAPT_CALLABLE(capacity, stl::capacity, 1)
- BOOST_PHOENIX_ADAPT_CALLABLE(clear, stl::clear, 1)
- BOOST_PHOENIX_ADAPT_CALLABLE(empty, stl::empty, 1)
- BOOST_PHOENIX_ADAPT_CALLABLE(end, stl::end, 1)
- BOOST_PHOENIX_ADAPT_CALLABLE(erase, stl::erase, 2)
- BOOST_PHOENIX_ADAPT_CALLABLE(erase, stl::erase, 3)
- BOOST_PHOENIX_ADAPT_CALLABLE(front, stl::front, 1)
- BOOST_PHOENIX_ADAPT_CALLABLE(get_allocator, stl::get_allocator, 1)
- BOOST_PHOENIX_ADAPT_CALLABLE(insert, stl::insert, 2)
- BOOST_PHOENIX_ADAPT_CALLABLE(insert, stl::insert, 3)
- BOOST_PHOENIX_ADAPT_CALLABLE(insert, stl::insert, 4)
- BOOST_PHOENIX_ADAPT_CALLABLE(key_comp, stl::key_comp, 1)
- BOOST_PHOENIX_ADAPT_CALLABLE(max_size, stl::max_size, 1)
- BOOST_PHOENIX_ADAPT_CALLABLE(pop_back, stl::pop_back, 1)
- BOOST_PHOENIX_ADAPT_CALLABLE(pop_front, stl::pop_front, 1)
- BOOST_PHOENIX_ADAPT_CALLABLE(push_back, stl::push_back, 2)
- BOOST_PHOENIX_ADAPT_CALLABLE(push_front, stl::push_front, 2)
- BOOST_PHOENIX_ADAPT_CALLABLE(rbegin, stl::rbegin, 1)
- BOOST_PHOENIX_ADAPT_CALLABLE(rend, stl::rend, 1)
- BOOST_PHOENIX_ADAPT_CALLABLE(reserve, stl::reserve, 2)
- BOOST_PHOENIX_ADAPT_CALLABLE(resize, stl::resize, 2)
- BOOST_PHOENIX_ADAPT_CALLABLE(resize, stl::resize, 3)
- BOOST_PHOENIX_ADAPT_CALLABLE(size, stl::size, 1)
- BOOST_PHOENIX_ADAPT_CALLABLE(splice, stl::splice, 2)
- BOOST_PHOENIX_ADAPT_CALLABLE(splice, stl::splice, 3)
- BOOST_PHOENIX_ADAPT_CALLABLE(splice, stl::splice, 4)
- BOOST_PHOENIX_ADAPT_CALLABLE(splice, stl::splice, 5)
- BOOST_PHOENIX_ADAPT_CALLABLE(value_comp, stl::value_comp, 1)
- }
- using namespace phoenix::adl_barrier;
- }} // namespace boost::phoenix
- #endif // BOOST_PHOENIX_STL_CONTAINERS_HPP
|