| /*============================================================================= |
| Copyright (c) 2001-2006 Joel de Guzman |
| Copyright (c) 2008 Eric Niebler |
| |
| 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_PROTO_DETAIL_FUSION_REVERSE_EAH_01_22_2008 |
| #define BOOST_PROTO_DETAIL_FUSION_REVERSE_EAH_01_22_2008 |
| |
| #include <boost/spirit/fusion/detail/access.hpp> |
| #include <boost/spirit/fusion/iterator/as_fusion_iterator.hpp> |
| #include <boost/spirit/fusion/iterator/detail/iterator_base.hpp> |
| #include <boost/spirit/fusion/sequence/detail/sequence_base.hpp> |
| #include <boost/spirit/fusion/iterator/next.hpp> |
| #include <boost/spirit/fusion/iterator/prior.hpp> |
| #include <boost/spirit/fusion/iterator/deref.hpp> |
| #include <boost/spirit/fusion/iterator/value_of.hpp> |
| #include <boost/spirit/fusion/sequence/begin.hpp> |
| #include <boost/spirit/fusion/sequence/end.hpp> |
| |
| namespace boost { namespace fusion |
| { |
| struct reverse_view_tag; |
| struct reverse_view_iterator_tag; |
| |
| template <typename First> |
| struct reverse_view_iterator |
| : iterator_base<reverse_view_iterator<First> > |
| { |
| typedef as_fusion_iterator<First> converter; |
| typedef typename converter::type first_type; |
| typedef reverse_view_iterator_tag tag; |
| |
| reverse_view_iterator(First const& first) |
| : first(converter::convert(first)) {} |
| |
| first_type first; |
| }; |
| |
| template <typename Sequence> |
| struct reverse_view : sequence_base<reverse_view<Sequence> > |
| { |
| typedef as_fusion_sequence<Sequence> seq_converter; |
| typedef typename seq_converter::type seq; |
| |
| typedef reverse_view_tag tag; |
| typedef typename meta::begin<seq>::type first_type; |
| typedef typename meta::end<seq>::type last_type; |
| |
| reverse_view(Sequence& seq) |
| : first(fusion::begin(seq)) |
| , last(fusion::end(seq)) |
| {} |
| |
| first_type first; |
| last_type last; |
| }; |
| |
| namespace meta |
| { |
| template <> |
| struct deref_impl<reverse_view_iterator_tag> |
| { |
| template <typename Iterator> |
| struct apply |
| { |
| typedef typename |
| meta::deref< |
| typename meta::prior< |
| typename Iterator::first_type |
| >::type |
| >::type |
| type; |
| |
| static type |
| call(Iterator const& i) |
| { |
| return *fusion::prior(i.first); |
| } |
| }; |
| }; |
| |
| template <> |
| struct prior_impl<reverse_view_iterator_tag> |
| { |
| template <typename Iterator> |
| struct apply |
| { |
| typedef typename Iterator::first_type first_type; |
| typedef typename next_impl<typename first_type::tag>:: |
| template apply<first_type> |
| wrapped; |
| |
| typedef reverse_view_iterator<typename wrapped::type> type; |
| |
| static type |
| call(Iterator const& i) |
| { |
| return type(wrapped::call(i.first)); |
| } |
| }; |
| }; |
| |
| template <> |
| struct next_impl<reverse_view_iterator_tag> |
| { |
| template <typename Iterator> |
| struct apply |
| { |
| typedef typename Iterator::first_type first_type; |
| typedef typename prior_impl<typename first_type::tag>:: |
| template apply<first_type> |
| wrapped; |
| |
| typedef reverse_view_iterator<typename wrapped::type> type; |
| |
| static type |
| call(Iterator const& i) |
| { |
| return type(wrapped::call(i.first)); |
| } |
| }; |
| }; |
| |
| template <> |
| struct value_impl<reverse_view_iterator_tag> |
| { |
| template <typename Iterator> |
| struct apply |
| { |
| typedef typename |
| meta::value_of< |
| typename meta::prior< |
| typename Iterator::first_type |
| >::type |
| >::type |
| type; |
| }; |
| }; |
| |
| template <> |
| struct begin_impl<reverse_view_tag> |
| { |
| template <typename Sequence> |
| struct apply |
| { |
| typedef reverse_view_iterator<typename Sequence::last_type> type; |
| |
| static type |
| call(Sequence const& s) |
| { |
| return type(s.last); |
| } |
| }; |
| }; |
| |
| template <> |
| struct end_impl<reverse_view_tag> |
| { |
| template <typename Sequence> |
| struct apply |
| { |
| typedef reverse_view_iterator<typename Sequence::first_type> type; |
| |
| static type |
| call(Sequence const& s) |
| { |
| return type(s.first); |
| } |
| }; |
| }; |
| |
| template <typename Sequence> |
| struct reverse |
| { |
| typedef reverse_view<Sequence> type; |
| }; |
| } |
| |
| template <typename Sequence> |
| inline reverse_view<Sequence const> |
| reverse(Sequence const& view) |
| { |
| return reverse_view<Sequence const>(view); |
| } |
| }} |
| |
| #endif |