at_impl.hpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. ==============================================================================*/
  6. #if !defined(FUSION_AT_IMPL_07172005_0726)
  7. #define FUSION_AT_IMPL_07172005_0726
  8. #include <boost/fusion/support/config.hpp>
  9. #include <boost/fusion/support/detail/access.hpp>
  10. #include <boost/type_traits/is_const.hpp>
  11. #include <boost/type_traits/add_const.hpp>
  12. #include <boost/mpl/if.hpp>
  13. #include <boost/mpl/bool.hpp>
  14. namespace boost { namespace fusion
  15. {
  16. namespace detail
  17. {
  18. template <typename Cons>
  19. struct cons_deref
  20. {
  21. typedef typename Cons::car_type type;
  22. };
  23. template <typename Cons, int I>
  24. struct cons_advance
  25. {
  26. typedef typename
  27. cons_advance<Cons, I-1>::type::cdr_type
  28. type;
  29. };
  30. template <typename Cons>
  31. struct cons_advance<Cons, 0>
  32. {
  33. typedef Cons type;
  34. };
  35. template <typename Cons>
  36. struct cons_advance<Cons, 1>
  37. {
  38. typedef typename Cons::cdr_type type;
  39. };
  40. template <typename Cons>
  41. struct cons_advance<Cons, 2>
  42. {
  43. #if BOOST_WORKAROUND(BOOST_MSVC, > 1400) // VC8 and above
  44. typedef typename Cons::cdr_type::cdr_type type;
  45. #else
  46. typedef typename Cons::cdr_type _a;
  47. typedef typename _a::cdr_type type;
  48. #endif
  49. };
  50. template <typename Cons>
  51. struct cons_advance<Cons, 3>
  52. {
  53. #if BOOST_WORKAROUND(BOOST_MSVC, > 1400) // VC8 and above
  54. typedef typename Cons::cdr_type::cdr_type::cdr_type type;
  55. #else
  56. typedef typename Cons::cdr_type _a;
  57. typedef typename _a::cdr_type _b;
  58. typedef typename _b::cdr_type type;
  59. #endif
  60. };
  61. template <typename Cons>
  62. struct cons_advance<Cons, 4>
  63. {
  64. #if BOOST_WORKAROUND(BOOST_MSVC, > 1400) // VC8 and above
  65. typedef typename Cons::cdr_type::cdr_type::cdr_type::cdr_type type;
  66. #else
  67. typedef typename Cons::cdr_type _a;
  68. typedef typename _a::cdr_type _b;
  69. typedef typename _b::cdr_type _c;
  70. typedef typename _c::cdr_type type;
  71. #endif
  72. };
  73. }
  74. struct cons_tag;
  75. namespace extension
  76. {
  77. template <typename Tag>
  78. struct at_impl;
  79. template <>
  80. struct at_impl<cons_tag>
  81. {
  82. template <typename Sequence, typename N>
  83. struct apply
  84. {
  85. typedef typename detail::cons_deref<
  86. typename detail::cons_advance<Sequence, N::value>::type>::type
  87. element;
  88. typedef typename
  89. mpl::if_<
  90. is_const<Sequence>
  91. , typename detail::cref_result<element>::type
  92. , typename detail::ref_result<element>::type
  93. >::type
  94. type;
  95. template <typename Cons, int N2>
  96. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  97. static type
  98. call(Cons& s, mpl::int_<N2>)
  99. {
  100. return call(s.cdr, mpl::int_<N2-1>());
  101. }
  102. template <typename Cons>
  103. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  104. static type
  105. call(Cons& s, mpl::int_<0>)
  106. {
  107. return s.car;
  108. }
  109. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  110. static type
  111. call(Sequence& s)
  112. {
  113. return call(s, mpl::int_<N::value>());
  114. }
  115. };
  116. };
  117. }
  118. }}
  119. #endif