GCC Code Coverage Report


Directory: libs/url/
File: boost/url/grammar/detail/tuple.hpp
Date: 2024-08-20 16:05:55
Exec Total Coverage
Lines: 11 11 100.0%
Functions: 73 73 100.0%
Branches: 0 0 -%

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 59762 tuple_element_impl(T const& t)
47 : empty_value<T>(
48 59762 empty_init, t)
49 {
50 59762 }
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 10847 tuple_impl(Us&&... us)
124 : tuple_element_impl<Is, Ts>(
125 10847 std::forward<Us>(us))...
126 {
127 10847 }
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 10847 tuple(Us&&... us) noexcept
160 : tuple_impl<mp11::index_sequence_for<
161 10847 Ts...>, Ts...>{std::forward<Us>(us)...}
162 {
163 10847 }
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 24887 get(tuple_element_impl<I, T> const& te)
180 {
181 24887 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