1 
2 #ifndef BOOST_MPL_PAIR_VIEW_HPP_INCLUDED
3 #define BOOST_MPL_PAIR_VIEW_HPP_INCLUDED
4 
5 // Copyright David Abrahams 2003-2004
6 // Copyright Aleksey Gurtovoy 2004
7 //
8 // Distributed under the Boost Software License, Version 1.0.
9 // (See accompanying file LICENSE_1_0.txt or copy at
10 // http://www.boost.org/LICENSE_1_0.txt)
11 //
12 // See http://www.boost.org/libs/mpl for documentation.
13 
14 // $Id$
15 // $Date$
16 // $Revision$
17 
18 #include <boost/mpl/begin_end.hpp>
19 #include <boost/mpl/iterator_category.hpp>
20 #include <boost/mpl/advance.hpp>
21 #include <boost/mpl/distance.hpp>
22 #include <boost/mpl/next_prior.hpp>
23 #include <boost/mpl/deref.hpp>
24 #include <boost/mpl/min_max.hpp>
25 #include <boost/mpl/pair.hpp>
26 #include <boost/mpl/iterator_tags.hpp>
27 #include <boost/mpl/aux_/config/ctps.hpp>
28 #include <boost/mpl/aux_/na_spec.hpp>
29 
30 namespace boost { namespace mpl {
31 
32 namespace aux {
33 struct pair_iter_tag;
34 
35 #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
36 
37 template< typename Iter1, typename Iter2, typename Category >
38 struct pair_iter;
39 
40 template< typename Category > struct prior_pair_iter
41 {
42     template< typename Iter1, typename Iter2 > struct apply
43     {
44         typedef typename mpl::prior<Iter1>::type i1_;
45         typedef typename mpl::prior<Iter2>::type i2_;
46         typedef pair_iter<i1_,i2_,Category> type;
47     };
48 };
49 
50 template<> struct prior_pair_iter<forward_iterator_tag>
51 {
52     template< typename Iter1, typename Iter2 > struct apply
53     {
54         typedef pair_iter<Iter1,Iter2,forward_iterator_tag> type;
55     };
56 };
57 
58 #endif
59 }
60 
61 template<
62       typename Iter1
63     , typename Iter2
64     , typename Category
65     >
66 struct pair_iter
67 {
68     typedef aux::pair_iter_tag tag;
69     typedef Category category;
70     typedef Iter1 first;
71     typedef Iter2 second;
72 
73 #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
74     typedef pair<
75           typename deref<Iter1>::type
76         , typename deref<Iter2>::type
77         > type;
78 
79     typedef typename mpl::next<Iter1>::type i1_;
80     typedef typename mpl::next<Iter2>::type i2_;
81     typedef pair_iter<i1_,i2_,Category> next;
82 
83     typedef apply_wrap2< aux::prior_pair_iter<Category>,Iter1,Iter2 >::type prior;
84 #endif
85 };
86 
87 
88 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
89 
90 template< typename Iter1, typename Iter2, typename C >
91 struct deref< pair_iter<Iter1,Iter2,C> >
92 {
93     typedef pair<
94           typename deref<Iter1>::type
95         , typename deref<Iter2>::type
96         > type;
97 };
98 
99 template< typename Iter1, typename Iter2, typename C >
100 struct next< pair_iter<Iter1,Iter2,C> >
101 {
102     typedef typename mpl::next<Iter1>::type i1_;
103     typedef typename mpl::next<Iter2>::type i2_;
104     typedef pair_iter<i1_,i2_,C> type;
105 };
106 
107 template< typename Iter1, typename Iter2, typename C >
108 struct prior< pair_iter<Iter1,Iter2,C> >
109 {
110     typedef typename mpl::prior<Iter1>::type i1_;
111     typedef typename mpl::prior<Iter2>::type i2_;
112     typedef pair_iter<i1_,i2_,C> type;
113 };
114 
115 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
116 
117 
118 template<> struct advance_impl<aux::pair_iter_tag>
119 {
120     template< typename Iter, typename D > struct apply
121     {
122         typedef typename mpl::advance< typename Iter::first,D >::type i1_;
123         typedef typename mpl::advance< typename Iter::second,D >::type i2_;
124         typedef pair_iter<i1_,i2_,typename Iter::category> type;
125     };
126 };
127 
128 template<> struct distance_impl<aux::pair_iter_tag>
129 {
130     template< typename Iter1, typename Iter2 > struct apply
131     {
132         // agurt, 10/nov/04: MSVC 6.5 ICE-s on forwarding
133         typedef typename mpl::distance<
134               typename first<Iter1>::type
135             , typename first<Iter2>::type
136             >::type type;
137     };
138 };
139 
140 
141 template<
142       typename BOOST_MPL_AUX_NA_PARAM(Sequence1)
143     , typename BOOST_MPL_AUX_NA_PARAM(Sequence2)
144     >
145 struct pair_view
146 {
147     typedef nested_begin_end_tag tag;
148 
149     typedef typename begin<Sequence1>::type iter1_;
150     typedef typename begin<Sequence2>::type iter2_;
151     typedef typename min<
152           typename iterator_category<iter1_>::type
153         , typename iterator_category<iter2_>::type
154         >::type category_;
155 
156     typedef pair_iter<iter1_,iter2_,category_> begin;
157 
158     typedef pair_iter<
159           typename end<Sequence1>::type
160         , typename end<Sequence2>::type
161         , category_
162         > end;
163 };
164 
165 BOOST_MPL_AUX_NA_SPEC(2, pair_view)
166 
167 }}
168 
169 #endif // BOOST_MPL_PAIR_VIEW_HPP_INCLUDED
170