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

source code of boost/libs/phoenix/include/boost/phoenix/stl/tuple.hpp