43852d79c609a85844dab248d4bc3efe86d78d42
[platform/upstream/boost.git] / boost / fusion / view / zip_view / detail / begin_impl.hpp
1 /*=============================================================================
2     Copyright (c) 2001-2011 Joel de Guzman
3     Copyright (c) 2006 Dan Marsden
4
5     Distributed under the Boost Software License, Version 1.0. (See accompanying 
6     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 ==============================================================================*/
8 #if !defined(FUSION_BEGIN_IMPL_20060123_2147)
9 #define FUSION_BEGIN_IMPL_20060123_2147
10
11 #include <boost/fusion/sequence/intrinsic/begin.hpp>
12 #include <boost/fusion/view/zip_view/zip_view_iterator_fwd.hpp>
13 #include <boost/fusion/algorithm/transformation/transform.hpp>
14 #include <boost/type_traits/remove_reference.hpp>
15 #include <boost/type_traits/is_reference.hpp>
16 #include <boost/type_traits/is_same.hpp>
17 #include <boost/mpl/assert.hpp>
18 #include <boost/mpl/eval_if.hpp>
19 #include <boost/mpl/identity.hpp>
20 #include <boost/fusion/support/unused.hpp>
21
22 namespace boost { namespace fusion {
23
24     struct zip_view_tag;
25
26     namespace detail
27     {
28         struct poly_begin
29         {
30             template<typename T>
31             struct result;
32
33             template<typename SeqRef>
34             struct result<poly_begin(SeqRef)>
35                 : mpl::eval_if<is_same<SeqRef, unused_type const&>,
36                                mpl::identity<unused_type>,
37                                result_of::begin<typename remove_reference<SeqRef>::type> >
38             {
39                 BOOST_MPL_ASSERT((is_reference<SeqRef>));
40             };
41
42             template<typename Seq>
43             typename result<poly_begin(Seq&)>::type
44             operator()(Seq& seq) const
45             {
46                 return fusion::begin(seq);
47             }
48
49             template<typename Seq>
50             typename result<poly_begin(Seq const&)>::type
51             operator()(Seq const& seq) const
52             {
53                 return fusion::begin(seq);
54             }
55
56             unused_type operator()(unused_type const&) const
57             {
58                 return unused_type();
59             }
60         };
61     }
62
63     namespace extension
64     {
65         template<typename Tag>
66         struct begin_impl;
67
68         template<>
69         struct begin_impl<zip_view_tag>
70         {
71             template<typename Sequence>
72             struct apply
73             {
74                 typedef zip_view_iterator<
75                     typename result_of::transform<typename Sequence::sequences, detail::poly_begin>::type,
76                     typename Sequence::category> type;
77
78                 static type
79                 call(Sequence& sequence)
80                 {
81                     return type(
82                         fusion::transform(sequence.sequences_, detail::poly_begin()));
83                 }
84             };
85
86
87             
88         };
89     }
90 }}
91
92 #endif