at.hpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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_05042005_0722)
  7. #define FUSION_AT_05042005_0722
  8. #include <boost/fusion/support/config.hpp>
  9. #include <boost/mpl/int.hpp>
  10. #include <boost/mpl/if.hpp>
  11. #include <boost/mpl/or.hpp>
  12. #include <boost/mpl/less.hpp>
  13. #include <boost/mpl/empty_base.hpp>
  14. #include <boost/type_traits/is_const.hpp>
  15. #include <boost/fusion/sequence/intrinsic_fwd.hpp>
  16. #include <boost/fusion/support/tag_of.hpp>
  17. #include <boost/fusion/support/category_of.hpp>
  18. namespace boost { namespace fusion
  19. {
  20. // Special tags:
  21. struct sequence_facade_tag;
  22. struct boost_tuple_tag; // boost::tuples::tuple tag
  23. struct boost_array_tag; // boost::array tag
  24. struct mpl_sequence_tag; // mpl sequence tag
  25. struct std_pair_tag; // std::pair tag
  26. struct std_tuple_tag; // std::tuple tag
  27. namespace extension
  28. {
  29. template <typename Tag>
  30. struct at_impl
  31. {
  32. template <typename Sequence, typename N>
  33. struct apply;
  34. };
  35. template <>
  36. struct at_impl<sequence_facade_tag>
  37. {
  38. template <typename Sequence, typename N>
  39. struct apply : Sequence::template at<Sequence, N> {};
  40. };
  41. template <>
  42. struct at_impl<boost_tuple_tag>;
  43. template <>
  44. struct at_impl<boost_array_tag>;
  45. template <>
  46. struct at_impl<mpl_sequence_tag>;
  47. template <>
  48. struct at_impl<std_pair_tag>;
  49. template <>
  50. struct at_impl<std_tuple_tag>;
  51. }
  52. namespace detail
  53. {
  54. template <typename Sequence, typename N, typename Tag>
  55. struct at_impl
  56. : mpl::if_<
  57. mpl::or_<
  58. mpl::less<N, typename extension::size_impl<Tag>::template apply<Sequence>::type>
  59. , traits::is_unbounded<Sequence>
  60. >
  61. , typename extension::at_impl<Tag>::template apply<Sequence, N>
  62. , mpl::empty_base
  63. >::type
  64. {};
  65. }
  66. namespace result_of
  67. {
  68. template <typename Sequence, typename N>
  69. struct at
  70. : detail::at_impl<Sequence, N, typename detail::tag_of<Sequence>::type>
  71. {};
  72. template <typename Sequence, int N>
  73. struct at_c
  74. : at<Sequence, mpl::int_<N> >
  75. {};
  76. }
  77. template <typename N, typename Sequence>
  78. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  79. inline typename
  80. lazy_disable_if<
  81. is_const<Sequence>
  82. , result_of::at<Sequence, N>
  83. >::type
  84. at(Sequence& seq)
  85. {
  86. return result_of::at<Sequence, N>::call(seq);
  87. }
  88. template <typename N, typename Sequence>
  89. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  90. inline typename result_of::at<Sequence const, N>::type
  91. at(Sequence const& seq)
  92. {
  93. return result_of::at<Sequence const, N>::call(seq);
  94. }
  95. template <int N, typename Sequence>
  96. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  97. inline typename
  98. lazy_disable_if<
  99. is_const<Sequence>
  100. , result_of::at_c<Sequence, N>
  101. >::type
  102. at_c(Sequence& seq)
  103. {
  104. return result_of::at_c<Sequence, N>::call(seq);
  105. }
  106. template <int N, typename Sequence>
  107. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  108. inline typename result_of::at_c<Sequence const, N>::type
  109. at_c(Sequence const& seq)
  110. {
  111. return result_of::at_c<Sequence const, N>::call(seq);
  112. }
  113. }}
  114. #endif