File indexing completed on 2025-01-18 09:53:27
0001
0002
0003
0004
0005
0006
0007
0008
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
0027
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 }
0208 }
0209 }
0210 }
0211
0212 #endif