1 /*=============================================================================
2     Copyright (c) 2001-2011 Joel de Guzman
3 
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 #if !defined(FUSION_BEGIN_04052005_1132)
8 #define FUSION_BEGIN_04052005_1132
9 
10 #include <boost/fusion/support/config.hpp>
11 #include <boost/utility/enable_if.hpp>
12 #include <boost/mpl/empty_base.hpp>
13 #include <boost/mpl/if.hpp>
14 #include <boost/fusion/sequence/intrinsic_fwd.hpp>
15 #include <boost/fusion/support/tag_of.hpp>
16 #include <boost/fusion/support/is_sequence.hpp>
17 #include <boost/fusion/support/is_segmented.hpp>
18 #include <boost/fusion/sequence/intrinsic/detail/segmented_begin.hpp>
19 
20 namespace boost { namespace fusion
21 {
22     // Special tags:
23     struct sequence_facade_tag; // iterator facade tag
24     struct boost_tuple_tag; // boost::tuples::tuple tag
25     struct boost_array_tag; // boost::array tag
26     struct mpl_sequence_tag; // mpl sequence tag
27     struct std_pair_tag; // std::pair tag
28 
29     namespace extension
30     {
31         template <typename Tag>
32         struct begin_impl
33         {
34             template <typename Sequence>
35             struct apply
36               : mpl::if_<
37                     traits::is_segmented<Sequence>
38                   , detail::segmented_begin<Sequence>
39                   , mpl::empty_base
40                 >::type
41             {};
42         };
43 
44         template <>
45         struct begin_impl<sequence_facade_tag>
46         {
47             template <typename Sequence>
48             struct apply : Sequence::template begin<Sequence> {};
49         };
50 
51         template <>
52         struct begin_impl<boost_tuple_tag>;
53 
54         template <>
55         struct begin_impl<boost_array_tag>;
56 
57         template <>
58         struct begin_impl<mpl_sequence_tag>;
59 
60         template <>
61         struct begin_impl<std_pair_tag>;
62     }
63 
64     namespace result_of
65     {
66         template <typename Sequence>
67         struct begin
68             : extension::begin_impl<typename detail::tag_of<Sequence>::type>::
69                 template apply<Sequence>
70         {};
71     }
72 
73     template <typename Sequence>
74     BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
75     inline typename
76         lazy_enable_if<
77             traits::is_sequence<Sequence>
78           , result_of::begin<Sequence>
79         >::type const
begin(Sequence & seq)80     begin(Sequence& seq)
81     {
82         return result_of::begin<Sequence>::call(seq);
83     }
84 
85     template <typename Sequence>
86     BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
87     inline typename
88         lazy_enable_if<
89             traits::is_sequence<Sequence>
90           , result_of::begin<Sequence const>
91         >::type const
begin(Sequence const & seq)92     begin(Sequence const& seq)
93     {
94         return result_of::begin<Sequence const>::call(seq);
95     }
96 }}
97 
98 #endif
99