1 | |
---|
2 | #ifndef BOOST_MPL_AUX_BEGIN_END_IMPL_HPP_INCLUDED |
---|
3 | #define BOOST_MPL_AUX_BEGIN_END_IMPL_HPP_INCLUDED |
---|
4 | |
---|
5 | // Copyright Aleksey Gurtovoy 2000-2004 |
---|
6 | // |
---|
7 | // Distributed under the Boost Software License, Version 1.0. |
---|
8 | // (See accompanying file LICENSE_1_0.txt or copy at |
---|
9 | // http://www.boost.org/LICENSE_1_0.txt) |
---|
10 | // |
---|
11 | // See http://www.boost.org/libs/mpl for documentation. |
---|
12 | |
---|
13 | // $Id: begin_end_impl.hpp 49267 2008-10-11 06:19:02Z agurtovoy $ |
---|
14 | // $Date: 2008-10-11 02:19:02 -0400 (Sat, 11 Oct 2008) $ |
---|
15 | // $Revision: 49267 $ |
---|
16 | |
---|
17 | #include <boost/mpl/begin_end_fwd.hpp> |
---|
18 | #include <boost/mpl/sequence_tag_fwd.hpp> |
---|
19 | #include <boost/mpl/void.hpp> |
---|
20 | #include <boost/mpl/eval_if.hpp> |
---|
21 | #include <boost/mpl/aux_/has_begin.hpp> |
---|
22 | #include <boost/mpl/aux_/na.hpp> |
---|
23 | #include <boost/mpl/aux_/traits_lambda_spec.hpp> |
---|
24 | #include <boost/mpl/aux_/config/eti.hpp> |
---|
25 | |
---|
26 | namespace boost { namespace mpl { |
---|
27 | |
---|
28 | |
---|
29 | namespace aux { |
---|
30 | |
---|
31 | template< typename Sequence > |
---|
32 | struct begin_type |
---|
33 | { |
---|
34 | typedef typename Sequence::begin type; |
---|
35 | }; |
---|
36 | template< typename Sequence > |
---|
37 | struct end_type |
---|
38 | { |
---|
39 | typedef typename Sequence::end type; |
---|
40 | }; |
---|
41 | |
---|
42 | } |
---|
43 | |
---|
44 | // default implementation; conrete sequences might override it by |
---|
45 | // specializing either the 'begin_impl/end_impl' or the primary |
---|
46 | // 'begin/end' templates |
---|
47 | |
---|
48 | template< typename Tag > |
---|
49 | struct begin_impl |
---|
50 | { |
---|
51 | template< typename Sequence > struct apply |
---|
52 | { |
---|
53 | typedef typename eval_if<aux::has_begin<Sequence, true_>, |
---|
54 | aux::begin_type<Sequence>, void_>::type type; |
---|
55 | }; |
---|
56 | }; |
---|
57 | |
---|
58 | template< typename Tag > |
---|
59 | struct end_impl |
---|
60 | { |
---|
61 | template< typename Sequence > struct apply |
---|
62 | { |
---|
63 | typedef typename eval_if<aux::has_begin<Sequence, true_>, |
---|
64 | aux::end_type<Sequence>, void_>::type type; |
---|
65 | }; |
---|
66 | }; |
---|
67 | |
---|
68 | // specialize 'begin_trait/end_trait' for two pre-defined tags |
---|
69 | |
---|
70 | # define AUX778076_IMPL_SPEC(name, tag, result) \ |
---|
71 | template<> \ |
---|
72 | struct name##_impl<tag> \ |
---|
73 | { \ |
---|
74 | template< typename Sequence > struct apply \ |
---|
75 | { \ |
---|
76 | typedef result type; \ |
---|
77 | }; \ |
---|
78 | }; \ |
---|
79 | /**/ |
---|
80 | |
---|
81 | // a sequence with nested 'begin/end' typedefs; just query them |
---|
82 | AUX778076_IMPL_SPEC(begin, nested_begin_end_tag, typename Sequence::begin) |
---|
83 | AUX778076_IMPL_SPEC(end, nested_begin_end_tag, typename Sequence::end) |
---|
84 | |
---|
85 | // if a type 'T' does not contain 'begin/end' or 'tag' members |
---|
86 | // and doesn't specialize either 'begin/end' or 'begin_impl/end_impl' |
---|
87 | // templates, then we end up here |
---|
88 | AUX778076_IMPL_SPEC(begin, non_sequence_tag, void_) |
---|
89 | AUX778076_IMPL_SPEC(end, non_sequence_tag, void_) |
---|
90 | AUX778076_IMPL_SPEC(begin, na, void_) |
---|
91 | AUX778076_IMPL_SPEC(end, na, void_) |
---|
92 | |
---|
93 | # undef AUX778076_IMPL_SPEC |
---|
94 | |
---|
95 | |
---|
96 | BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(1,begin_impl) |
---|
97 | BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(1,end_impl) |
---|
98 | |
---|
99 | }} |
---|
100 | |
---|
101 | #endif // BOOST_MPL_AUX_BEGIN_END_IMPL_HPP_INCLUDED |
---|