Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / fusion / sequence / intrinsic / end.hpp
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_END_04052005_1141)
8 #define FUSION_END_04052005_1141
9
10 #include <boost/fusion/support/config.hpp>
11 #include <boost/blank.hpp>
12 #include <boost/utility/enable_if.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_end.hpp>
19
20 namespace boost { namespace fusion
21 {
22     // Special tags:
23     struct sequence_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 end_impl
33         {
34             template <typename Sequence>
35             struct apply
36               : mpl::if_<
37                     traits::is_segmented<Sequence>
38                   , detail::segmented_end<Sequence>
39                   , blank
40                 >::type
41             {};
42         };
43
44         template <>
45         struct end_impl<sequence_facade_tag>
46         {
47             template <typename Sequence>
48             struct apply : Sequence::template end<Sequence> {};
49         };
50
51         template <>
52         struct end_impl<boost_tuple_tag>;
53
54         template <>
55         struct end_impl<boost_array_tag>;
56
57         template <>
58         struct end_impl<mpl_sequence_tag>;
59
60         template <>
61         struct end_impl<std_pair_tag>;
62     }
63
64     namespace result_of
65     {
66         template <typename Sequence>
67         struct end
68             : extension::end_impl<typename detail::tag_of<Sequence>::type>::
69                 template apply<Sequence>
70         {};
71     }
72
73     template <typename Sequence>
74     BOOST_FUSION_GPU_ENABLED
75     inline typename
76         lazy_enable_if<
77             traits::is_sequence<Sequence>
78           , result_of::end<Sequence>
79         >::type const
80     end(Sequence& seq)
81     {
82         return result_of::end<Sequence>::call(seq);
83     }
84
85     template <typename Sequence>
86     BOOST_FUSION_GPU_ENABLED
87     inline typename
88         lazy_enable_if<
89             traits::is_sequence<Sequence>
90           , result_of::end<Sequence const>
91         >::type const
92     end(Sequence const& seq)
93     {
94         return result_of::end<Sequence const>::call(seq);
95     }
96 }}
97
98 #endif