williamr@2: 
williamr@2: #ifndef BOOST_MPL_PAIR_VIEW_HPP_INCLUDED
williamr@2: #define BOOST_MPL_PAIR_VIEW_HPP_INCLUDED
williamr@2: 
williamr@2: // Copyright David Abrahams 2003-2004
williamr@2: // Copyright Aleksey Gurtovoy 2004
williamr@2: //
williamr@2: // Distributed under the Boost Software License, Version 1.0. 
williamr@2: // (See accompanying file LICENSE_1_0.txt or copy at 
williamr@2: // http://www.boost.org/LICENSE_1_0.txt)
williamr@2: //
williamr@2: // See http://www.boost.org/libs/mpl for documentation.
williamr@2: 
williamr@2: // $Source: /cvsroot/boost/boost/boost/mpl/pair_view.hpp,v $
williamr@2: // $Date: 2004/11/28 01:56:21 $
williamr@2: // $Revision: 1.5 $
williamr@2: 
williamr@2: #include <boost/mpl/begin_end.hpp>
williamr@2: #include <boost/mpl/iterator_category.hpp>
williamr@2: #include <boost/mpl/advance.hpp>
williamr@2: #include <boost/mpl/distance.hpp>
williamr@2: #include <boost/mpl/next_prior.hpp>
williamr@2: #include <boost/mpl/deref.hpp>
williamr@2: #include <boost/mpl/min_max.hpp>
williamr@2: #include <boost/mpl/pair.hpp>
williamr@2: #include <boost/mpl/iterator_tags.hpp>
williamr@2: #include <boost/mpl/aux_/config/ctps.hpp>
williamr@2: #include <boost/mpl/aux_/na_spec.hpp>
williamr@2: 
williamr@2: namespace boost { namespace mpl {
williamr@2: 
williamr@2: namespace aux {
williamr@2: struct pair_iter_tag;
williamr@2: 
williamr@2: #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
williamr@2: 
williamr@2: template< typename Iter1, typename Iter2, typename Category >
williamr@2: struct pair_iter;
williamr@2: 
williamr@2: template< typename Category > struct prior_pair_iter
williamr@2: {
williamr@2:     template< typename Iter1, typename Iter2 > struct apply
williamr@2:     {
williamr@2:         typedef typename mpl::prior<Iter1>::type i1_;
williamr@2:         typedef typename mpl::prior<Iter2>::type i2_;
williamr@2:         typedef pair_iter<i1_,i2_,Category> type;
williamr@2:     };
williamr@2: };
williamr@2: 
williamr@2: template<> struct prior_pair_iter<forward_iterator_tag>
williamr@2: {
williamr@2:     template< typename Iter1, typename Iter2 > struct apply
williamr@2:     {
williamr@2:         typedef pair_iter<Iter1,Iter2,forward_iterator_tag> type;
williamr@2:     };
williamr@2: };
williamr@2: 
williamr@2: #endif
williamr@2: }
williamr@2: 
williamr@2: template< 
williamr@2:       typename Iter1
williamr@2:     , typename Iter2
williamr@2:     , typename Category
williamr@2:     >
williamr@2: struct pair_iter
williamr@2: {
williamr@2:     typedef aux::pair_iter_tag tag;
williamr@2:     typedef Category category;
williamr@2:     typedef Iter1 first;
williamr@2:     typedef Iter2 second;
williamr@2:     
williamr@2: #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
williamr@2:     typedef pair< 
williamr@2:           typename deref<Iter1>::type
williamr@2:         , typename deref<Iter2>::type
williamr@2:         > type;
williamr@2: 
williamr@2:     typedef typename mpl::next<Iter1>::type i1_;
williamr@2:     typedef typename mpl::next<Iter2>::type i2_;
williamr@2:     typedef pair_iter<i1_,i2_,Category> next;
williamr@2:     
williamr@2:     typedef apply_wrap2< aux::prior_pair_iter<Category>,Iter1,Iter2 >::type prior;
williamr@2: #endif
williamr@2: };
williamr@2: 
williamr@2: 
williamr@2: #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
williamr@2: 
williamr@2: template< typename Iter1, typename Iter2, typename C >
williamr@2: struct deref< pair_iter<Iter1,Iter2,C> >
williamr@2: {
williamr@2:     typedef pair< 
williamr@2:           typename deref<Iter1>::type
williamr@2:         , typename deref<Iter2>::type
williamr@2:         > type;
williamr@2: };
williamr@2: 
williamr@2: template< typename Iter1, typename Iter2, typename C >
williamr@2: struct next< pair_iter<Iter1,Iter2,C> >
williamr@2: {
williamr@2:     typedef typename mpl::next<Iter1>::type i1_;
williamr@2:     typedef typename mpl::next<Iter2>::type i2_;
williamr@2:     typedef pair_iter<i1_,i2_,C> type;
williamr@2: };
williamr@2: 
williamr@2: template< typename Iter1, typename Iter2, typename C >
williamr@2: struct prior< pair_iter<Iter1,Iter2,C> >
williamr@2: {
williamr@2:     typedef typename mpl::prior<Iter1>::type i1_;
williamr@2:     typedef typename mpl::prior<Iter2>::type i2_;
williamr@2:     typedef pair_iter<i1_,i2_,C> type;
williamr@2: };
williamr@2: 
williamr@2: #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
williamr@2: 
williamr@2: 
williamr@2: template<> struct advance_impl<aux::pair_iter_tag>
williamr@2: {
williamr@2:     template< typename Iter, typename D > struct apply
williamr@2:     {
williamr@2:         typedef typename mpl::advance< typename Iter::first,D >::type i1_;
williamr@2:         typedef typename mpl::advance< typename Iter::second,D >::type i2_;
williamr@2:         typedef pair_iter<i1_,i2_,typename Iter::category> type;
williamr@2:     };
williamr@2: };
williamr@2: 
williamr@2: template<> struct distance_impl<aux::pair_iter_tag>
williamr@2: {
williamr@2:     template< typename Iter1, typename Iter2 > struct apply
williamr@2:     {
williamr@2:         // agurt, 10/nov/04: MSVC 6.5 ICE-s on forwarding
williamr@2:         typedef typename mpl::distance<
williamr@2:               typename first<Iter1>::type
williamr@2:             , typename first<Iter2>::type
williamr@2:             >::type type;
williamr@2:     };
williamr@2: };
williamr@2: 
williamr@2: 
williamr@2: template<
williamr@2:       typename BOOST_MPL_AUX_NA_PARAM(Sequence1)
williamr@2:     , typename BOOST_MPL_AUX_NA_PARAM(Sequence2)
williamr@2:     >
williamr@2: struct pair_view
williamr@2: {
williamr@2:     typedef nested_begin_end_tag tag;
williamr@2: 
williamr@2:     typedef typename begin<Sequence1>::type iter1_;
williamr@2:     typedef typename begin<Sequence2>::type iter2_;
williamr@2:     typedef typename min<
williamr@2:           typename iterator_category<iter1_>::type
williamr@2:         , typename iterator_category<iter2_>::type
williamr@2:         >::type category_;
williamr@2:     
williamr@2:     typedef pair_iter<iter1_,iter2_,category_> begin;
williamr@2:     
williamr@2:     typedef pair_iter<
williamr@2:           typename end<Sequence1>::type
williamr@2:         , typename end<Sequence2>::type
williamr@2:         , category_
williamr@2:         > end;
williamr@2: };
williamr@2: 
williamr@2: BOOST_MPL_AUX_NA_SPEC(2, pair_view)
williamr@2: 
williamr@2: }}
williamr@2: 
williamr@2: #endif // BOOST_MPL_PAIR_VIEW_HPP_INCLUDED