Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/spirit/home/phoenix/stl/container/container.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DEPENDENCIES/generic/include/boost/spirit/home/phoenix/stl/container/container.hpp Tue Aug 05 11:11:38 2014 +0100 @@ -0,0 +1,706 @@ +/*============================================================================= + 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 PHOENIX_STL_CONTAINER_CONTAINER_HPP +#define PHOENIX_STL_CONTAINER_CONTAINER_HPP + +#include <boost/spirit/home/phoenix/stl/container/detail/container.hpp> +#include <boost/spirit/home/phoenix/function/function.hpp> +#include <boost/mpl/and.hpp> +#include <boost/mpl/not.hpp> +#include <boost/mpl/or.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. +// +// 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 C + , typename Arg1 = fusion::void_ + , typename Arg2 = fusion::void_ + , typename Arg3 = fusion::void_ + > + struct result + { + 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 const& arg1, Arg2 const& arg2) const + { + c.assign(arg1, arg2); + return c; + } + + template <typename C, typename Arg1, typename Arg2, typename Arg3> + C& operator()( + C& c + , Arg1 const& arg1 + , Arg2 const& arg2 + , Arg3 const& arg3) const + { + return c.assign(arg1, arg2, arg3); + } + }; + + struct at + { + template <typename C, typename Index> + struct result + { + typedef typename const_qualified_reference_of<C>::type type; + }; + + template <typename C, typename Index> + typename result<C, Index>::type + operator()(C& c, Index const& i) const + { + return c.at(i); + } + }; + + struct back + { + template <typename C> + struct result + { + typedef + typename const_qualified_reference_of<C>::type + type; + }; + + template <typename C> + typename result<C>::type + operator()(C& c) const + { + return c.back(); + } + }; + + struct begin + { + template <typename C> + struct result + { + typedef typename const_qualified_iterator_of<C>::type type; + }; + + template <typename C> + typename result<C>::type + operator()(C& c) const + { + return c.begin(); + } + }; + + struct capacity + { + template <typename C> + struct result + { + typedef typename size_type_of<C>::type type; + }; + + template <typename C> + typename result<C>::type + operator()(C const& c) const + { + return c.capacity(); + } + }; + + struct clear + { + template <typename C> + struct result + { + typedef void type; + }; + + template <typename C> + void operator()(C& c) const + { + return c.clear(); + } + }; + + struct empty + { + template <typename C> + struct result + { + typedef bool type; + }; + + template <typename C> + bool operator()(C const& c) const + { + return c.empty(); + } + }; + + struct end + { + template <typename C> + struct result + { + typedef typename const_qualified_iterator_of<C>::type type; + }; + + template <typename C> + typename result<C>::type + operator()(C& c) const + { + return c.end(); + } + }; + + struct erase + { + // 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. + // + // 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: + // + // 3) size_type M::erase(const Key& keyval); + // 4) void M::erase(iterator where); + // 5) void M::erase(iterator first, iterator last); + + template <typename C, typename Arg1, typename Arg2 = fusion::void_> + struct result + { + // 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... :* + + typedef + boost::mpl::eval_if< + boost::is_same<Arg1, typename iterator_of<C>::type> +#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1500) + , iterator_of<C> +#else + , boost::mpl::identity<void> +#endif + , size_type_of<C> + > + map_erase_result; + + typedef typename + boost::mpl::eval_if< + has_mapped_type<C> + , map_erase_result + , iterator_of<C> + >::type + type; + }; + + template <typename C, typename Arg1> + typename result<C, Arg1>::type + operator()(C& c, Arg1 const& arg1) const + { + return c.erase(arg1); + } + + template <typename C, typename Arg1, typename Arg2> + typename result<C, Arg1, Arg2>::type + operator()(C& c, Arg1 const& arg1, Arg2 const& arg2) const + { + return c.erase(arg1, arg2); + } + }; + + struct front + { + template <typename C> + struct result + { + typedef typename const_qualified_reference_of<C>::type type; + }; + + template <typename C> + typename result<C>::type + operator()(C& c) const + { + return c.front(); + } + }; + + struct get_allocator + { + template <typename C> + struct result + { + typedef typename allocator_type_of<C>::type type; + }; + + template <typename C> + typename result<C>::type + operator()(C const& c) const + { + return c.get_allocator(); + } + }; + + 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 C + , typename Arg1 + , typename Arg2 = fusion::void_ + , typename Arg3 = fusion::void_ + > + class result + { + struct pair_iterator_bool + { + typedef typename std::pair<typename C::iterator, bool> type; + }; + + typedef + boost::mpl::eval_if< + map_insert_returns_pair<C> + , pair_iterator_bool + , iterator_of<C> + > + choice_1; + + typedef + boost::mpl::eval_if< + boost::mpl::and_< + boost::is_same<Arg3, fusion::void_> + , boost::mpl::not_<boost::is_same<Arg1, Arg2> > > + , iterator_of<C> + , boost::mpl::identity<void> + > + choice_2; + + public: + + typedef typename + boost::mpl::eval_if< + boost::is_same<Arg2, fusion::void_> + , choice_1 + , choice_2 + >::type + type; + }; + + template <typename C, typename Arg1> + typename result<C, Arg1>::type + operator()(C& c, Arg1 const& arg1) const + { + return c.insert(arg1); + } + + template <typename C, typename Arg1, typename Arg2> + typename result<C, Arg1, Arg2>::type + operator()(C& c, Arg1 const& arg1, Arg2 const& arg2) const + { + return c.insert(arg1, arg2); + } + + template <typename C, typename Arg1, typename Arg2, typename Arg3> + typename result<C, Arg1, Arg2, Arg3>::type + operator()( + C& c, Arg1 const& arg1, Arg2 const& arg2, Arg3 const& arg3) const + { + return c.insert(arg1, arg2, arg3); + } + }; + + struct key_comp + { + template <typename C> + struct result + { + typedef typename key_compare_of<C>::type type; + }; + + template <typename C> + typename result<C>::type + operator()(C const& c) const + { + return c.key_comp(); + } + }; + + struct max_size + { + template <typename C> + struct result + { + typedef typename size_type_of<C>::type type; + }; + + template <typename C> + typename result<C>::type + operator()(C const& c) const + { + return c.max_size(); + } + }; + + struct pop_back + { + template <typename C> + struct result + { + typedef void type; + }; + + template <typename C> + void operator()(C& c) const + { + return c.pop_back(); + } + }; + + struct pop_front + { + template <typename C> + struct result + { + typedef void type; + }; + + template <typename C> + void operator()(C& c) const + { + return c.pop_front(); + } + }; + + struct push_back + { + template <typename C, typename Arg> + struct result + { + typedef void type; + }; + + template <typename C, typename Arg> + void operator()(C& c, Arg const& data) const + { + return c.push_back(data); + } + }; + + struct push_front + { + template <typename C, typename Arg> + struct result + { + typedef void type; + }; + + template <typename C, typename Arg> + void operator()(C& c, Arg const& data) const + { + return c.push_front(data); + } + }; + + struct rbegin + { + template <typename C> + struct result + { + typedef typename + const_qualified_reverse_iterator_of<C>::type + type; + }; + + template <typename C> + typename result<C>::type + operator()(C& c) const + { + return c.rbegin(); + } + }; + + struct rend + { + template <typename C> + struct result + { + typedef typename + const_qualified_reverse_iterator_of<C>::type + type; + }; + + template <typename C> + typename result<C>::type + operator()(C& c) const + { + return c.rend(); + } + }; + + struct reserve + { + + template <typename C, typename Arg> + struct result + { + typedef void type; + }; + + template <typename C, typename Arg> + void operator()(C& c, Arg const& count) const + { + return c.reserve(count); + } + }; + + struct resize + { + template <typename C, typename Arg1, typename Arg2 = fusion::void_> + struct result + { + typedef void type; + }; + + template <typename C, typename Arg1> + void operator()(C& c, Arg1 const& arg1) const + { + return c.resize(arg1); + } + + template <typename C, typename Arg1, typename Arg2> + void operator()(C& c, Arg1 const& arg1, Arg2 const& arg2) const + { + return c.resize(arg1, arg2); + } + }; + + struct size + { + template <typename C> + struct result + { + typedef typename size_type_of<C>::type type; + }; + + template <typename C> + typename result<C>::type + operator()(C const& c) const + { + return c.size(); + } + }; + + struct splice + { + template < + typename C + , typename Arg1 + , typename Arg2 + , typename Arg3 = fusion::void_ + , typename Arg4 = fusion::void_ + > + struct result + { + typedef void type; + }; + + template <typename C, typename Arg1, typename Arg2> + void operator()(C& c, Arg1 const& arg1, Arg2& arg2) const + { + c.splice(arg1, arg2); + } + + template < + typename C + , typename Arg1 + , typename Arg2 + , typename Arg3 + > + void operator()( + C& c + , Arg1 const& arg1 + , Arg2& arg2 + , Arg3 const& arg3 + ) const + { + c.splice(arg1, arg2, arg3); + } + + template < + typename C + , typename Arg1 + , typename Arg2 + , typename Arg3 + , typename Arg4 + > + void operator()( + C& c + , Arg1 const& arg1 + , Arg2& arg2 + , Arg3 const& arg3 + , Arg4 const& arg4 + ) const + { + c.splice(arg1, arg2, arg3, arg4); + } + }; + + struct value_comp + { + template <typename C> + struct result + { + typedef typename value_compare_of<C>::type type; + }; + + template <typename C> + typename result<C>::type + operator()(C const& c) const + { + return c.value_comp(); + } + }; + +} // namespace stl + +/////////////////////////////////////////////////////////////////////////////// +// +// The lazy functions themselves. +// +/////////////////////////////////////////////////////////////////////////////// +function<stl::assign> const assign = stl::assign(); +function<stl::at> const at = stl::at(); +function<stl::back> const back = stl::back(); +function<stl::begin> const begin = stl::begin(); +function<stl::capacity> const capacity = stl::capacity(); +function<stl::clear> const clear = stl::clear(); +function<stl::empty> const empty = stl::empty(); +function<stl::end> const end = stl::end(); +function<stl::erase> const erase = stl::erase(); +function<stl::front> const front = stl::front(); +function<stl::get_allocator> const get_allocator = stl::get_allocator(); +function<stl::insert> const insert = stl::insert(); +function<stl::key_comp> const key_comp = stl::key_comp(); +function<stl::max_size> const max_size = stl::max_size(); +function<stl::pop_back> const pop_back = stl::pop_back(); +function<stl::pop_front> const pop_front = stl::pop_front(); +function<stl::push_back> const push_back = stl::push_back(); +function<stl::push_front> const push_front = stl::push_front(); +function<stl::rbegin> const rbegin = stl::rbegin(); +function<stl::rend> const rend = stl::rend(); +function<stl::reserve> const reserve = stl::reserve(); +function<stl::resize> const resize = stl::resize(); +function<stl::size> const size = stl::size(); +function<stl::splice> const splice = stl::splice(); +function<stl::value_comp> const value_comp = stl::value_comp(); + +}} // namespace boost::phoenix + +#endif // PHOENIX_STL_CONTAINERS_HPP