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_AT_IMPL_07172005_0726) |
8 | #define FUSION_AT_IMPL_07172005_0726 |
9 | |
10 | #include <boost/fusion/support/config.hpp> |
11 | #include <boost/fusion/support/detail/access.hpp> |
12 | #include <boost/type_traits/is_const.hpp> |
13 | #include <boost/type_traits/add_const.hpp> |
14 | #include <boost/mpl/if.hpp> |
15 | #include <boost/mpl/bool.hpp> |
16 | |
17 | namespace boost { namespace fusion |
18 | { |
19 | namespace detail |
20 | { |
21 | template <typename Cons> |
22 | struct cons_deref |
23 | { |
24 | typedef typename Cons::car_type type; |
25 | }; |
26 | |
27 | template <typename Cons, int I> |
28 | struct cons_advance |
29 | { |
30 | typedef typename |
31 | cons_advance<Cons, I-1>::type::cdr_type |
32 | type; |
33 | }; |
34 | |
35 | template <typename Cons> |
36 | struct cons_advance<Cons, 0> |
37 | { |
38 | typedef Cons type; |
39 | }; |
40 | |
41 | template <typename Cons> |
42 | struct cons_advance<Cons, 1> |
43 | { |
44 | typedef typename Cons::cdr_type type; |
45 | }; |
46 | |
47 | template <typename Cons> |
48 | struct cons_advance<Cons, 2> |
49 | { |
50 | #if BOOST_WORKAROUND(BOOST_MSVC, > 1400) // VC8 and above |
51 | typedef typename Cons::cdr_type::cdr_type type; |
52 | #else |
53 | typedef typename Cons::cdr_type _a; |
54 | typedef typename _a::cdr_type type; |
55 | #endif |
56 | }; |
57 | |
58 | template <typename Cons> |
59 | struct cons_advance<Cons, 3> |
60 | { |
61 | #if BOOST_WORKAROUND(BOOST_MSVC, > 1400) // VC8 and above |
62 | typedef typename Cons::cdr_type::cdr_type::cdr_type type; |
63 | #else |
64 | typedef typename Cons::cdr_type _a; |
65 | typedef typename _a::cdr_type _b; |
66 | typedef typename _b::cdr_type type; |
67 | #endif |
68 | }; |
69 | |
70 | template <typename Cons> |
71 | struct cons_advance<Cons, 4> |
72 | { |
73 | #if BOOST_WORKAROUND(BOOST_MSVC, > 1400) // VC8 and above |
74 | typedef typename Cons::cdr_type::cdr_type::cdr_type::cdr_type type; |
75 | #else |
76 | typedef typename Cons::cdr_type _a; |
77 | typedef typename _a::cdr_type _b; |
78 | typedef typename _b::cdr_type _c; |
79 | typedef typename _c::cdr_type type; |
80 | #endif |
81 | }; |
82 | } |
83 | |
84 | struct cons_tag; |
85 | |
86 | namespace extension |
87 | { |
88 | template <typename Tag> |
89 | struct at_impl; |
90 | |
91 | template <> |
92 | struct at_impl<cons_tag> |
93 | { |
94 | template <typename Sequence, typename N> |
95 | struct apply |
96 | { |
97 | typedef typename detail::cons_deref< |
98 | typename detail::cons_advance<Sequence, N::value>::type>::type |
99 | element; |
100 | |
101 | typedef typename |
102 | mpl::if_< |
103 | is_const<Sequence> |
104 | , typename detail::cref_result<element>::type |
105 | , typename detail::ref_result<element>::type |
106 | >::type |
107 | type; |
108 | |
109 | template <typename Cons, int N2> |
110 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
111 | static type |
112 | call(Cons& s, mpl::int_<N2>) |
113 | { |
114 | return call(s.cdr, mpl::int_<N2-1>()); |
115 | } |
116 | |
117 | template <typename Cons> |
118 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
119 | static type |
120 | call(Cons& s, mpl::int_<0>) |
121 | { |
122 | return s.car; |
123 | } |
124 | |
125 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
126 | static type |
127 | call(Sequence& s) |
128 | { |
129 | return call(s, mpl::int_<N::value>()); |
130 | } |
131 | }; |
132 | }; |
133 | } |
134 | }} |
135 | |
136 | #endif |
137 | |