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