at_key.hpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 Joel de Guzman
  3. Copyright (c) 2006 Dan Marsden
  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(BOOST_FUSION_AT_KEY_20060304_1755)
  8. #define BOOST_FUSION_AT_KEY_20060304_1755
  9. #include <boost/fusion/support/config.hpp>
  10. #include <boost/type_traits/is_const.hpp>
  11. #include <boost/fusion/sequence/intrinsic_fwd.hpp>
  12. #include <boost/fusion/sequence/intrinsic/has_key.hpp>
  13. #include <boost/fusion/algorithm/query/find.hpp>
  14. #include <boost/fusion/iterator/deref_data.hpp>
  15. #include <boost/fusion/support/tag_of.hpp>
  16. #include <boost/fusion/support/category_of.hpp>
  17. #include <boost/fusion/support/detail/access.hpp>
  18. #include <boost/mpl/empty_base.hpp>
  19. #include <boost/mpl/if.hpp>
  20. #include <boost/mpl/or.hpp>
  21. namespace boost { namespace fusion
  22. {
  23. // Special tags:
  24. struct sequence_facade_tag;
  25. struct boost_array_tag; // boost::array tag
  26. struct mpl_sequence_tag; // mpl sequence tag
  27. struct std_pair_tag; // std::pair tag
  28. namespace extension
  29. {
  30. template <typename Tag>
  31. struct at_key_impl
  32. {
  33. template <typename Seq, typename Key>
  34. struct apply
  35. {
  36. typedef typename
  37. result_of::deref_data<
  38. typename result_of::find<Seq, Key>::type
  39. >::type
  40. type;
  41. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  42. static type
  43. call(Seq& seq)
  44. {
  45. return fusion::deref_data(fusion::find<Key>(seq));
  46. }
  47. };
  48. };
  49. template <>
  50. struct at_key_impl<sequence_facade_tag>
  51. {
  52. template <typename Sequence, typename Key>
  53. struct apply : Sequence::template at_key_impl<Sequence, Key> {};
  54. };
  55. template <>
  56. struct at_key_impl<boost_array_tag>;
  57. template <>
  58. struct at_key_impl<mpl_sequence_tag>;
  59. template <>
  60. struct at_key_impl<std_pair_tag>;
  61. }
  62. namespace detail
  63. {
  64. template <typename Sequence, typename Key, typename Tag>
  65. struct at_key_impl
  66. : mpl::if_<
  67. mpl::or_<
  68. typename extension::has_key_impl<Tag>::template apply<Sequence, Key>
  69. , traits::is_unbounded<Sequence>
  70. >
  71. , typename extension::at_key_impl<Tag>::template apply<Sequence, Key>
  72. , mpl::empty_base
  73. >::type
  74. {};
  75. }
  76. namespace result_of
  77. {
  78. template <typename Sequence, typename Key>
  79. struct at_key
  80. : detail::at_key_impl<Sequence, Key, typename detail::tag_of<Sequence>::type>
  81. {};
  82. }
  83. template <typename Key, typename Sequence>
  84. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  85. inline typename
  86. lazy_disable_if<
  87. is_const<Sequence>
  88. , result_of::at_key<Sequence, Key>
  89. >::type
  90. at_key(Sequence& seq)
  91. {
  92. return result_of::at_key<Sequence, Key>::call(seq);
  93. }
  94. template <typename Key, typename Sequence>
  95. BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
  96. inline typename result_of::at_key<Sequence const, Key>::type
  97. at_key(Sequence const& seq)
  98. {
  99. return result_of::at_key<Sequence const, Key>::call(seq);
  100. }
  101. }}
  102. #endif