| 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
 |