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