Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:27

0001 //
0002 // Copyright (c) 2016-2019 Damian Jarek (damian dot jarek93 at gmail dot com)
0003 // Copyright (c) 2022 Vinnie Falco (vinnie dot falco at gmail dot com)
0004 //
0005 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0006 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 // Official repository: https://github.com/boostorg/beast
0009 //
0010 
0011 #ifndef BOOST_URL_GRAMMAR_DETAIL_TUPLE_HPP
0012 #define BOOST_URL_GRAMMAR_DETAIL_TUPLE_HPP
0013 
0014 #include <boost/url/detail/config.hpp>
0015 #include <boost/url/error_types.hpp>
0016 #include <boost/core/empty_value.hpp>
0017 #include <boost/mp11/algorithm.hpp>
0018 #include <boost/mp11/function.hpp>
0019 #include <boost/mp11/integer_sequence.hpp>
0020 #include <boost/type_traits/remove_cv.hpp>
0021 #include <boost/type_traits/copy_cv.hpp>
0022 #include <cstdlib>
0023 #include <utility>
0024 
0025 #ifndef BOOST_URL_TUPLE_EBO
0026 // VFALCO No idea what causes it or how to fix it
0027 // https://devblogs.microsoft.com/cppblog/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/
0028 #ifdef BOOST_MSVC
0029 #define BOOST_URL_TUPLE_EBO 0
0030 #else
0031 #define BOOST_URL_TUPLE_EBO 1
0032 #endif
0033 #endif
0034 
0035 namespace boost {
0036 namespace urls {
0037 namespace grammar {
0038 namespace detail {
0039 
0040 #if BOOST_URL_TUPLE_EBO
0041 template<std::size_t I, class T>
0042 struct tuple_element_impl
0043     : empty_value<T>
0044 {
0045     constexpr
0046     tuple_element_impl(T const& t)
0047         : empty_value<T>(
0048             empty_init, t)
0049     {
0050     }
0051 
0052     constexpr
0053     tuple_element_impl(T&& t)
0054         : empty_value<T>(
0055             empty_init,
0056                 std::move(t))
0057     {
0058     }
0059 };
0060 #else
0061 template<std::size_t I, class T>
0062 struct tuple_element_impl
0063 {
0064     T t_;
0065 
0066     constexpr
0067     tuple_element_impl(T const& t)
0068         : t_(t)
0069     {
0070     }
0071 
0072     constexpr
0073     tuple_element_impl(T&& t)
0074         : t_(std::move(t))
0075     {
0076     }
0077 
0078     constexpr
0079     T&
0080     get() noexcept
0081     {
0082         return t_;
0083     }
0084 
0085     constexpr
0086     T const&
0087     get() const noexcept
0088     {
0089         return t_;
0090     }
0091 };
0092 #endif
0093 
0094 template<std::size_t I, class T>
0095 struct tuple_element_impl<I, T&>
0096 {
0097     T& t;
0098 
0099     constexpr
0100     tuple_element_impl(T& t_)
0101         : t(t_)
0102     {
0103     }
0104 
0105     T&
0106     get() const noexcept
0107     {
0108         return t;
0109     }
0110 };
0111 
0112 template<class... Ts>
0113 struct tuple_impl;
0114 
0115 template<class... Ts, std::size_t... Is>
0116 struct tuple_impl<
0117     mp11::index_sequence<Is...>, Ts...>
0118   : tuple_element_impl<Is, Ts>...
0119 {
0120     template<class... Us>
0121     constexpr
0122     explicit
0123     tuple_impl(Us&&... us)
0124         : tuple_element_impl<Is, Ts>(
0125             std::forward<Us>(us))...
0126     {
0127     }
0128 };
0129 
0130 template<class... Ts>
0131 struct tuple
0132     : tuple_impl<
0133         mp11::index_sequence_for<Ts...>, Ts...>
0134 {
0135     template<class... Us,
0136         typename std::enable_if<
0137             mp11::mp_bool<
0138                 mp11::mp_all<std::is_constructible<
0139                     Ts, Us>...>::value &&
0140                 ! mp11::mp_all<std::is_convertible<
0141                     Us, Ts>...>::value>::value,
0142             int>::type = 0
0143     >
0144     constexpr
0145     explicit
0146     tuple(Us&&... us) noexcept
0147       : tuple_impl<mp11::index_sequence_for<
0148             Ts...>, Ts...>{std::forward<Us>(us)...}
0149     {
0150     }
0151 
0152     template<class... Us,
0153         typename std::enable_if<
0154             mp11::mp_all<std::is_convertible<
0155                 Us, Ts>...>::value,
0156             int>::type = 0
0157     >
0158     constexpr
0159     tuple(Us&&... us) noexcept
0160       : tuple_impl<mp11::index_sequence_for<
0161             Ts...>, Ts...>{std::forward<Us>(us)...}
0162     {
0163     }
0164 };
0165 
0166 //------------------------------------------------
0167 
0168 template<std::size_t I, class T>
0169 constexpr
0170 T&
0171 get(tuple_element_impl<I, T>& te)
0172 {
0173     return te.get();
0174 }
0175 
0176 template<std::size_t I, class T>
0177 constexpr
0178 T const&
0179 get(tuple_element_impl<I, T> const& te)
0180 {
0181     return te.get();
0182 }
0183 
0184 template<std::size_t I, class T>
0185 constexpr
0186 T&&
0187 get(tuple_element_impl<I, T>&& te)
0188 {
0189     return std::move(te.get());
0190 }
0191 
0192 template<std::size_t I, class T>
0193 constexpr
0194 T&
0195 get(tuple_element_impl<I, T&>&& te)
0196 {
0197     return te.get();
0198 }
0199 
0200 template<std::size_t I, class T>
0201 using tuple_element =
0202     typename boost::copy_cv<
0203         mp11::mp_at_c<typename
0204             remove_cv<T>::type,
0205             I>, T>::type;
0206 
0207 } // detail
0208 } // grammar
0209 } // urls
0210 } // boost
0211 
0212 #endif