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 callboost::fusion::extension::at_impl::apply112 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 callboost::fusion::extension::at_impl::apply120 call(Cons& s, mpl::int_<0>) 121 { 122 return s.car; 123 } 124 125 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED 126 static type callboost::fusion::extension::at_impl::apply127 call(Sequence& s) 128 { 129 return call(s, mpl::int_<N::value>()); 130 } 131 }; 132 }; 133 } 134 }} 135 136 #endif 137