1 /*=============================================================================
2     Copyright (c) 2003 Joel de Guzman
3     Copyright (c) 2004 Peder Holt
4 
5     Use, modification and distribution is subject to the Boost Software
6     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7     http://www.boost.org/LICENSE_1_0.txt)
8 ==============================================================================*/
9 #if !defined(FUSION_SEQUENCE_END_HPP)
10 #define FUSION_SEQUENCE_END_HPP
11 
12 #include <boost/spirit/fusion/detail/config.hpp>
13 #include <boost/spirit/fusion/sequence/as_fusion_sequence.hpp>
14 #include <boost/type_traits/is_const.hpp>
15 
16 namespace boost { namespace fusion
17 {
18     namespace meta
19     {
20         template <typename Tag>
21         struct end_impl
22         {
23             template <typename Sequence>
24             struct apply {
25                 typedef int type;
26             };
27         };
28 
29         template <typename Sequence>
30         struct end
31         {
32             typedef as_fusion_sequence<Sequence> seq_converter;
33             typedef typename seq_converter::type seq;
34 
35             typedef typename
36                 end_impl<typename seq::tag>::
37                     template apply<seq>::type
38             type;
39         };
40     }
41 
42 #if BOOST_WORKAROUND(BOOST_MSVC,<=1300)
43     namespace detail {
44         template <typename Sequence>
45         inline typename meta::end<Sequence const>::type
end(Sequence const & seq,mpl::true_)46         end(Sequence const& seq,mpl::true_)
47         {
48             typedef meta::end<Sequence const> end_meta;
49             return meta::end_impl<BOOST_DEDUCED_TYPENAME end_meta::seq::tag>::
50                 template apply<BOOST_DEDUCED_TYPENAME end_meta::seq const>::call(
51                     end_meta::seq_converter::convert_const(seq));
52         }
53 
54         template <typename Sequence>
55         inline typename meta::end<Sequence>::type
end(Sequence & seq,mpl::false_)56         end(Sequence& seq,mpl::false_)
57         {
58             typedef meta::end<Sequence> end_meta;
59             return meta::end_impl<BOOST_DEDUCED_TYPENAME end_meta::seq::tag>::
60                 template apply<BOOST_DEDUCED_TYPENAME end_meta::seq>::call(
61                     end_meta::seq_converter::convert(seq));
62         }
63 
64     }
65     template <typename Sequence>
66     inline typename meta::end<Sequence>::type
end(Sequence & seq)67     end(Sequence& seq)
68     {
69         return detail::end(seq,is_const<Sequence>());
70     }
71 #else
72     template <typename Sequence>
73     inline typename meta::end<Sequence const>::type
end(Sequence const & seq)74     end(Sequence const& seq)
75     {
76         typedef meta::end<Sequence const> end_meta;
77         return meta::end_impl<typename end_meta::seq::tag>::
78             template apply<typename end_meta::seq const>::call(
79                 end_meta::seq_converter::convert_const(seq));
80     }
81 
82     template <typename Sequence>
83     inline typename meta::end<Sequence>::type
end(Sequence & seq)84     end(Sequence& seq)
85     {
86         typedef meta::end<Sequence> end_meta;
87         return meta::end_impl<typename end_meta::seq::tag>::
88             template apply<typename end_meta::seq>::call(
89                 end_meta::seq_converter::convert(seq));
90     }
91 #endif
92 }}
93 
94 #endif
95