1 //
2 // Copyright (c) 2016-2019 Damian Jarek (damian dot jarek93 at gmail dot com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/boostorg/beast
8 //
9
10 #ifndef BOOST_BEAST_DETAIL_TUPLE_HPP
11 #define BOOST_BEAST_DETAIL_TUPLE_HPP
12
13 #include <boost/mp11/integer_sequence.hpp>
14 #include <boost/mp11/algorithm.hpp>
15 #include <boost/type_traits/remove_cv.hpp>
16 #include <boost/type_traits/copy_cv.hpp>
17 #include <cstdlib>
18 #include <utility>
19
20 namespace boost {
21 namespace beast {
22 namespace detail {
23
24 template<std::size_t I, class T>
25 struct tuple_element_impl
26 {
27 T t;
28
tuple_element_implboost::beast::detail::tuple_element_impl29 tuple_element_impl(T const& t_)
30 : t(t_)
31 {
32 }
33
tuple_element_implboost::beast::detail::tuple_element_impl34 tuple_element_impl(T&& t_)
35 : t(std::move(t_))
36 {
37 }
38 };
39
40 template<std::size_t I, class T>
41 struct tuple_element_impl<I, T&>
42 {
43 T& t;
44
tuple_element_implboost::beast::detail::tuple_element_impl45 tuple_element_impl(T& t_)
46 : t(t_)
47 {
48 }
49 };
50
51 template<class... Ts>
52 struct tuple_impl;
53
54 template<class... Ts, std::size_t... Is>
55 struct tuple_impl<
56 boost::mp11::index_sequence<Is...>, Ts...>
57 : tuple_element_impl<Is, Ts>...
58 {
59 template<class... Us>
tuple_implboost::beast::detail::tuple_impl60 explicit tuple_impl(Us&&... us)
61 : tuple_element_impl<Is, Ts>(
62 std::forward<Us>(us))...
63 {
64 }
65 };
66
67 template<class... Ts>
68 struct tuple : tuple_impl<
69 boost::mp11::index_sequence_for<Ts...>, Ts...>
70 {
71 template<class... Us>
tupleboost::beast::detail::tuple72 explicit tuple(Us&&... us)
73 : tuple_impl<
74 boost::mp11::index_sequence_for<Ts...>, Ts...>{
75 std::forward<Us>(us)...}
76 {
77 }
78 };
79
80 template<std::size_t I, class T>
81 T&
get(tuple_element_impl<I,T> & te)82 get(tuple_element_impl<I, T>& te)
83 {
84 return te.t;
85 }
86
87 template<std::size_t I, class T>
88 T const&
get(tuple_element_impl<I,T> const & te)89 get(tuple_element_impl<I, T> const& te)
90 {
91 return te.t;
92 }
93
94 template<std::size_t I, class T>
95 T&&
get(tuple_element_impl<I,T> && te)96 get(tuple_element_impl<I, T>&& te)
97 {
98 return std::move(te.t);
99 }
100
101 template<std::size_t I, class T>
102 T&
get(tuple_element_impl<I,T &> && te)103 get(tuple_element_impl<I, T&>&& te)
104 {
105 return te.t;
106 }
107
108 template <std::size_t I, class T>
109 using tuple_element = typename boost::copy_cv<
110 mp11::mp_at_c<typename remove_cv<T>::type, I>, T>::type;
111
112 } // detail
113 } // beast
114 } // boost
115
116 #endif
117