Line |
Branch |
Exec |
Source |
1 |
|
|
// |
2 |
|
|
// Copyright (c) 2016-2019 Damian Jarek (damian dot jarek93 at gmail dot com) |
3 |
|
|
// Copyright (c) 2022 Vinnie Falco (vinnie dot falco at gmail dot com) |
4 |
|
|
// |
5 |
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying |
6 |
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
7 |
|
|
// |
8 |
|
|
// Official repository: https://github.com/boostorg/beast |
9 |
|
|
// |
10 |
|
|
|
11 |
|
|
#ifndef BOOST_URL_GRAMMAR_DETAIL_TUPLE_HPP |
12 |
|
|
#define BOOST_URL_GRAMMAR_DETAIL_TUPLE_HPP |
13 |
|
|
|
14 |
|
|
#include <boost/url/detail/config.hpp> |
15 |
|
|
#include <boost/url/error_types.hpp> |
16 |
|
|
#include <boost/core/empty_value.hpp> |
17 |
|
|
#include <boost/mp11/algorithm.hpp> |
18 |
|
|
#include <boost/mp11/function.hpp> |
19 |
|
|
#include <boost/mp11/integer_sequence.hpp> |
20 |
|
|
#include <boost/type_traits/remove_cv.hpp> |
21 |
|
|
#include <boost/type_traits/copy_cv.hpp> |
22 |
|
|
#include <cstdlib> |
23 |
|
|
#include <utility> |
24 |
|
|
|
25 |
|
|
#ifndef BOOST_URL_TUPLE_EBO |
26 |
|
|
// VFALCO No idea what causes it or how to fix it |
27 |
|
|
// https://devblogs.microsoft.com/cppblog/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/ |
28 |
|
|
#ifdef BOOST_MSVC |
29 |
|
|
#define BOOST_URL_TUPLE_EBO 0 |
30 |
|
|
#else |
31 |
|
|
#define BOOST_URL_TUPLE_EBO 1 |
32 |
|
|
#endif |
33 |
|
|
#endif |
34 |
|
|
|
35 |
|
|
namespace boost { |
36 |
|
|
namespace urls { |
37 |
|
|
namespace grammar { |
38 |
|
|
namespace detail { |
39 |
|
|
|
40 |
|
|
#if BOOST_URL_TUPLE_EBO |
41 |
|
|
template<std::size_t I, class T> |
42 |
|
|
struct tuple_element_impl |
43 |
|
|
: empty_value<T> |
44 |
|
|
{ |
45 |
|
|
constexpr |
46 |
|
59576 |
tuple_element_impl(T const& t) |
47 |
|
|
: empty_value<T>( |
48 |
|
59576 |
empty_init, t) |
49 |
|
|
{ |
50 |
|
59576 |
} |
51 |
|
|
|
52 |
|
|
constexpr |
53 |
|
|
tuple_element_impl(T&& t) |
54 |
|
|
: empty_value<T>( |
55 |
|
|
empty_init, |
56 |
|
|
std::move(t)) |
57 |
|
|
{ |
58 |
|
|
} |
59 |
|
|
}; |
60 |
|
|
#else |
61 |
|
|
template<std::size_t I, class T> |
62 |
|
|
struct tuple_element_impl |
63 |
|
|
{ |
64 |
|
|
T t_; |
65 |
|
|
|
66 |
|
|
constexpr |
67 |
|
|
tuple_element_impl(T const& t) |
68 |
|
|
: t_(t) |
69 |
|
|
{ |
70 |
|
|
} |
71 |
|
|
|
72 |
|
|
constexpr |
73 |
|
|
tuple_element_impl(T&& t) |
74 |
|
|
: t_(std::move(t)) |
75 |
|
|
{ |
76 |
|
|
} |
77 |
|
|
|
78 |
|
|
constexpr |
79 |
|
|
T& |
80 |
|
|
get() noexcept |
81 |
|
|
{ |
82 |
|
|
return t_; |
83 |
|
|
} |
84 |
|
|
|
85 |
|
|
constexpr |
86 |
|
|
T const& |
87 |
|
|
get() const noexcept |
88 |
|
|
{ |
89 |
|
|
return t_; |
90 |
|
|
} |
91 |
|
|
}; |
92 |
|
|
#endif |
93 |
|
|
|
94 |
|
|
template<std::size_t I, class T> |
95 |
|
|
struct tuple_element_impl<I, T&> |
96 |
|
|
{ |
97 |
|
|
T& t; |
98 |
|
|
|
99 |
|
|
constexpr |
100 |
|
|
tuple_element_impl(T& t_) |
101 |
|
|
: t(t_) |
102 |
|
|
{ |
103 |
|
|
} |
104 |
|
|
|
105 |
|
|
T& |
106 |
|
|
get() const noexcept |
107 |
|
|
{ |
108 |
|
|
return t; |
109 |
|
|
} |
110 |
|
|
}; |
111 |
|
|
|
112 |
|
|
template<class... Ts> |
113 |
|
|
struct tuple_impl; |
114 |
|
|
|
115 |
|
|
template<class... Ts, std::size_t... Is> |
116 |
|
|
struct tuple_impl< |
117 |
|
|
mp11::index_sequence<Is...>, Ts...> |
118 |
|
|
: tuple_element_impl<Is, Ts>... |
119 |
|
|
{ |
120 |
|
|
template<class... Us> |
121 |
|
|
constexpr |
122 |
|
|
explicit |
123 |
|
10818 |
tuple_impl(Us&&... us) |
124 |
|
|
: tuple_element_impl<Is, Ts>( |
125 |
|
10818 |
std::forward<Us>(us))... |
126 |
|
|
{ |
127 |
|
10818 |
} |
128 |
|
|
}; |
129 |
|
|
|
130 |
|
|
template<class... Ts> |
131 |
|
|
struct tuple |
132 |
|
|
: tuple_impl< |
133 |
|
|
mp11::index_sequence_for<Ts...>, Ts...> |
134 |
|
|
{ |
135 |
|
|
template<class... Us, |
136 |
|
|
typename std::enable_if< |
137 |
|
|
mp11::mp_bool< |
138 |
|
|
mp11::mp_all<std::is_constructible< |
139 |
|
|
Ts, Us>...>::value && |
140 |
|
|
! mp11::mp_all<std::is_convertible< |
141 |
|
|
Us, Ts>...>::value>::value, |
142 |
|
|
int>::type = 0 |
143 |
|
|
> |
144 |
|
|
constexpr |
145 |
|
|
explicit |
146 |
|
|
tuple(Us&&... us) noexcept |
147 |
|
|
: tuple_impl<mp11::index_sequence_for< |
148 |
|
|
Ts...>, Ts...>{std::forward<Us>(us)...} |
149 |
|
|
{ |
150 |
|
|
} |
151 |
|
|
|
152 |
|
|
template<class... Us, |
153 |
|
|
typename std::enable_if< |
154 |
|
|
mp11::mp_all<std::is_convertible< |
155 |
|
|
Us, Ts>...>::value, |
156 |
|
|
int>::type = 0 |
157 |
|
|
> |
158 |
|
|
constexpr |
159 |
|
10818 |
tuple(Us&&... us) noexcept |
160 |
|
|
: tuple_impl<mp11::index_sequence_for< |
161 |
|
10818 |
Ts...>, Ts...>{std::forward<Us>(us)...} |
162 |
|
|
{ |
163 |
|
10818 |
} |
164 |
|
|
}; |
165 |
|
|
|
166 |
|
|
//------------------------------------------------ |
167 |
|
|
|
168 |
|
|
template<std::size_t I, class T> |
169 |
|
|
constexpr |
170 |
|
|
T& |
171 |
|
|
get(tuple_element_impl<I, T>& te) |
172 |
|
|
{ |
173 |
|
|
return te.get(); |
174 |
|
|
} |
175 |
|
|
|
176 |
|
|
template<std::size_t I, class T> |
177 |
|
|
constexpr |
178 |
|
|
T const& |
179 |
|
24845 |
get(tuple_element_impl<I, T> const& te) |
180 |
|
|
{ |
181 |
|
24845 |
return te.get(); |
182 |
|
|
} |
183 |
|
|
|
184 |
|
|
template<std::size_t I, class T> |
185 |
|
|
constexpr |
186 |
|
|
T&& |
187 |
|
|
get(tuple_element_impl<I, T>&& te) |
188 |
|
|
{ |
189 |
|
|
return std::move(te.get()); |
190 |
|
|
} |
191 |
|
|
|
192 |
|
|
template<std::size_t I, class T> |
193 |
|
|
constexpr |
194 |
|
|
T& |
195 |
|
|
get(tuple_element_impl<I, T&>&& te) |
196 |
|
|
{ |
197 |
|
|
return te.get(); |
198 |
|
|
} |
199 |
|
|
|
200 |
|
|
template<std::size_t I, class T> |
201 |
|
|
using tuple_element = |
202 |
|
|
typename boost::copy_cv< |
203 |
|
|
mp11::mp_at_c<typename |
204 |
|
|
remove_cv<T>::type, |
205 |
|
|
I>, T>::type; |
206 |
|
|
|
207 |
|
|
} // detail |
208 |
|
|
} // grammar |
209 |
|
|
} // urls |
210 |
|
|
} // boost |
211 |
|
|
|
212 |
|
|
#endif |
213 |
|
|
|