tuple.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*==============================================================================
  2. Copyright (c) 2005-2008 Hartmut Kaiser
  3. Copyright (c) 2005-2010 Joel de Guzman
  4. Copyright (c) 2010 Thomas Heller
  5. Copyright (c) 2021 Beojan Stanislaus
  6. Distributed under the Boost Software License, Version 1.0. (See accompanying
  7. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  8. ==============================================================================*/
  9. #ifndef BOOST_PHOENIX_STL_TUPLE_H_
  10. #define BOOST_PHOENIX_STL_TUPLE_H_
  11. #if __cplusplus >= 201402L \
  12. || (defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190024210)
  13. #include <tuple>
  14. #include <boost/phoenix/core/argument.hpp>
  15. #include <boost/phoenix/core/call.hpp>
  16. #include <boost/phoenix/core/expression.hpp>
  17. #include <boost/phoenix/core/limits.hpp>
  18. #include <boost/phoenix/core/meta_grammar.hpp>
  19. // Lazy functions for std::tuple (and similar)
  20. // get will work wherever it is accessible through ADL
  21. // Cribbing from functions in object
  22. namespace boost { namespace phoenix { namespace tuple_detail
  23. {
  24. // Wrappers to pass a type or an index
  25. template<typename T>
  26. struct type_wrap
  27. {
  28. typedef T type;
  29. };
  30. template<int N>
  31. struct idx_wrap
  32. {
  33. static constexpr int idx = N;
  34. };
  35. }}} // namespace boost::phoenix::tuple_detail
  36. BOOST_PHOENIX_DEFINE_EXPRESSION(
  37. (boost)(phoenix)(get_with_type),
  38. (proto::terminal<tuple_detail::type_wrap<proto::_> >)(meta_grammar))
  39. BOOST_PHOENIX_DEFINE_EXPRESSION(
  40. (boost)(phoenix)(get_with_idx),
  41. (proto::terminal<proto::_>)(meta_grammar))
  42. namespace boost { namespace phoenix {
  43. namespace impl {
  44. struct get_with_type
  45. {
  46. // Don't need to use result_of protocol since this only works with C++11+
  47. // anyway
  48. template<typename T, typename Expr, typename Context>
  49. auto& operator()(T, const Expr& t, const Context& ctx) const
  50. {
  51. using std::get; // Prevents the next line from being a syntax error <
  52. // C++20
  53. using T_ = typename proto::result_of::value<T>::type;
  54. return get<typename T_::type>(boost::phoenix::eval(t, ctx));
  55. }
  56. };
  57. struct get_with_idx
  58. {
  59. // Don't need to use result_of protocol since this only works with C++11+
  60. // anyway
  61. template<typename T, typename Expr, typename Context>
  62. auto& operator()(T, const Expr& t, const Context& ctx) const
  63. {
  64. using std::get; // Prevents the next line from being a syntax error <
  65. // C++20
  66. using T_ = typename proto::result_of::value<T>::type;
  67. return get<T_::idx>(boost::phoenix::eval(t, ctx));
  68. }
  69. };
  70. }
  71. template<typename Dummy>
  72. struct default_actions::when<rule::get_with_type, Dummy>
  73. : call<impl::get_with_type, Dummy>
  74. {};
  75. template<typename Dummy>
  76. struct default_actions::when<rule::get_with_idx, Dummy>
  77. : call<impl::get_with_idx, Dummy>
  78. {};
  79. template<typename T, typename Tuple>
  80. inline typename expression::get_with_type<tuple_detail::type_wrap<T>, Tuple>::
  81. type const
  82. get_(const Tuple& t)
  83. {
  84. return expression::get_with_type<tuple_detail::type_wrap<T>, Tuple>::make(
  85. tuple_detail::type_wrap<T>(), t);
  86. }
  87. template<int N, typename Tuple>
  88. inline typename expression::get_with_idx<tuple_detail::idx_wrap<N>, Tuple>::
  89. type const
  90. get_(const Tuple& t)
  91. {
  92. return expression::get_with_idx<tuple_detail::idx_wrap<N>, Tuple>::make(
  93. tuple_detail::idx_wrap<N>(), t);
  94. }
  95. #if 0 // Disabled this for now due to ODR viaolations $$$ Fix Me $$$
  96. // Make unpacked argument placeholders
  97. namespace placeholders {
  98. #define BOOST_PP_LOCAL_LIMITS (1, BOOST_PHOENIX_ARG_LIMIT)
  99. #define BOOST_PP_LOCAL_MACRO(N) \
  100. const auto uarg##N = \
  101. boost::phoenix::get_<(N)-1>(boost::phoenix::placeholders::arg1);
  102. #include BOOST_PP_LOCAL_ITERATE()
  103. }
  104. #endif
  105. }} // namespace boost::phoenix
  106. #endif // C++ 14
  107. #endif // BOOST_PHOENIX_STL_TUPLE_H_