DPC++ Runtime
Runtime libraries for oneAPI DPC++
tuple.hpp
Go to the documentation of this file.
1 //== tuple.hpp - limited trivially copy constructible implementation- C++ --==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 // ===--------------------------------------------------------------------=== //
8 
9 #pragma once
10 
12 
13 #include <cassert>
14 #include <iterator>
15 #include <tuple>
16 #include <type_traits>
17 
18 namespace sycl {
20 namespace detail {
21 
22 template <typename... T> struct tuple;
23 
24 template <typename T, typename... Ts, std::size_t... Is>
25 std::tuple<Ts...> get_tuple_tail_impl(const std::tuple<T, Ts...> &Tuple,
26  const std::index_sequence<Is...> &) {
27  return std::tuple<Ts...>(std::get<Is + 1>(Tuple)...);
28 }
29 
30 template <typename T, typename... Ts>
31 std::tuple<Ts...> get_tuple_tail(const std::tuple<T, Ts...> &Tuple) {
33  Tuple, std::make_index_sequence<sizeof...(Ts)>());
34 }
35 
36 template <typename... Ts> constexpr tuple<Ts...> make_tuple(Ts... Args) {
37  return sycl::detail::tuple<Ts...>{Args...};
38 }
39 
40 template <typename... Ts> auto tie(Ts &...Args) {
41  return sycl::detail::tuple<Ts &...>(Args...);
42 }
43 
44 template <std::size_t N, typename T> struct tuple_element;
45 
46 template <std::size_t N, typename T, typename... Rest>
47 struct tuple_element<N, tuple<T, Rest...>>
48  : tuple_element<N - 1, tuple<Rest...>> {};
49 
50 template <typename T, typename... Rest>
51 struct tuple_element<0, tuple<T, Rest...>> {
52  using type = T;
53 };
54 
55 template <std::size_t I, class T>
57 
58 // Functor returning reference to the selected element of the tuple.
59 template <size_t N> struct get {
60  template <typename... Ts>
61  constexpr auto operator()(tuple<Ts...> &Tuple) const
62  -> decltype(get<N - 1>()(Tuple.next)) {
63  return get<N - 1>()(Tuple.next);
64  }
65 
66  template <typename... Ts>
67  constexpr auto operator()(const tuple<Ts...> &Tuple) const
68  -> decltype(get<N - 1>()(Tuple.next)) {
69  return get<N - 1>()(Tuple.next);
70  }
71 };
72 
73 // Functor returning reference to selected element of the tuple.
74 // Specialization stopping the recursion.
75 template <> struct get<0> {
76  template <typename... Ts>
77  using ret_type = typename tuple_element<0, tuple<Ts...>>::type;
78 
79  template <typename... Ts>
80  constexpr ret_type<Ts...> &operator()(tuple<Ts...> &Tuple) const noexcept {
81  return Tuple.holder.value;
82  }
83 
84  template <typename... Ts>
85  constexpr ret_type<Ts...> const &
86  operator()(const tuple<Ts...> &Tuple) const noexcept {
87  return Tuple.holder.value;
88  }
89 };
90 
91 template <typename T> struct TupleValueHolder {
92  TupleValueHolder() = default;
93  TupleValueHolder(const T &Value) : value(Value) {}
94  T value;
95 };
96 
97 // Tuple needs to be trivially_copy_assignable. Define operator= if necessary.
98 template <typename T,
99  bool = std::is_trivially_copy_assignable_v<TupleValueHolder<T>>>
102 };
103 
104 template <typename T>
107 
110  this->value = RHS.value;
111  return *this;
112  }
113 };
114 
115 template <typename T, typename... Ts> struct tuple<T, Ts...> {
117  tuple<Ts...> next;
118 
119  using tuple_type = std::tuple<T, Ts...>;
120 
121  tuple() = default;
122  tuple(const tuple &) = default;
123  template <typename UT, typename... UTs>
125  : holder(RHS.holder.value), next(RHS.next) {}
126 
127  tuple(const T &Value, const Ts &...Next) : holder(Value), next(Next...) {}
128 
129  // required to convert std::tuple to inner tuple in user-provided functor
130  tuple(const std::tuple<T, Ts...> &RHS)
131  : holder(std::get<0>(RHS)), next(sycl::detail::get_tuple_tail(RHS)) {}
132 
133  // Convert to std::tuple with the same template arguments.
134  operator std::tuple<T, Ts...>() const {
135  return to_std_tuple(*this, std::make_index_sequence<sizeof...(Ts) + 1>());
136  }
137 
138  // Convert to std::tuple with different template arguments.
139  template <typename UT, typename... UTs>
140  operator std::tuple<UT, UTs...>() const {
141  return to_std_tuple(static_cast<tuple<UT, UTs...>>(*this),
142  std::make_index_sequence<sizeof...(Ts) + 1>());
143  }
144 
145  template <typename UT, typename... UTs>
147  holder.value = RHS.holder.value;
148  next = RHS.next;
149  return *this;
150  }
151 
152  // if T is deduced with reference, compiler generates deleted operator= and,
153  // since "template operator=" is not considered as operator= overload
154  // the deleted operator= has a preference during lookup
155  tuple &operator=(const detail::tuple<T, Ts...> &) = default;
156 
157  // Convert std::tuple to sycl::detail::tuple
158  template <typename UT, typename... UTs>
159  tuple &operator=(const std::tuple<UT, UTs...> &RHS) {
160  holder.value = std::get<0>(RHS);
161  next = sycl::detail::get_tuple_tail(RHS);
162  return *this;
163  }
164 
165  friend bool operator==(const tuple &LHS, const tuple &RHS) {
166  return LHS.holder.value == RHS.holder.value && LHS.next == RHS.next;
167  }
168  friend bool operator!=(const tuple &LHS, const tuple &RHS) {
169  return !(LHS == RHS);
170  }
171 
172  template <typename UT, typename... UTs, std::size_t... Is>
173  static std::tuple<UT, UTs...> to_std_tuple(const tuple<UT, UTs...> &Tuple,
174  std::index_sequence<Is...>) {
175  return std::tuple<UT, UTs...>(get<Is>()(Tuple)...);
176  }
177 };
178 
179 template <> struct tuple<> {
180  using tuple_type = std::tuple<>;
181 
182  tuple() = default;
183  tuple(const tuple &) = default;
184  tuple(const std::tuple<> &) {}
185 
186  tuple &operator=(const tuple &) = default;
187  tuple &operator=(const std::tuple<> &) { return *this; }
188  friend bool operator==(const tuple &, const tuple &) { return true; }
189 };
190 
191 } // namespace detail
192 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
193 } // namespace sycl
194 
195 namespace std {
196 
197 template <size_t I, typename... Types>
198 constexpr typename tuple_element<I, tuple<Types...>>::type &
199 get(sycl::detail::tuple<Types...> &Arg) noexcept {
200  return sycl::detail::get<I>()(Arg);
201 }
202 
203 template <size_t I, typename... Types>
204 constexpr typename tuple_element<I, tuple<Types...>>::type const &
205 get(const sycl::detail::tuple<Types...> &Arg) noexcept {
206  return sycl::detail::get<I>()(Arg);
207 }
208 
209 } // namespace std
sycl::_V1::detail::get< 0 >::operator()
constexpr ret_type< Ts... > & operator()(tuple< Ts... > &Tuple) const noexcept
Definition: tuple.hpp:80
T
sycl::_V1::detail::get_tuple_tail_impl
std::tuple< Ts... > get_tuple_tail_impl(const std::tuple< T, Ts... > &Tuple, const std::index_sequence< Is... > &)
Definition: tuple.hpp:25
sycl::_V1::detail::tuple< T, Ts... >::tuple
tuple(const T &Value, const Ts &...Next)
Definition: tuple.hpp:127
__SYCL_INLINE_VER_NAMESPACE
#define __SYCL_INLINE_VER_NAMESPACE(X)
Definition: defines_elementary.hpp:11
sycl::_V1::detail::tuple< T, Ts... >::operator==
friend bool operator==(const tuple &LHS, const tuple &RHS)
Definition: tuple.hpp:165
sycl::_V1::detail::tuple<>::operator=
tuple & operator=(const std::tuple<> &)
Definition: tuple.hpp:187
sycl::_V1::detail::TupleCopyAssignableValueHolder< T, false >::operator=
TupleCopyAssignableValueHolder & operator=(const TupleCopyAssignableValueHolder &RHS)
Definition: tuple.hpp:109
sycl::_V1::detail::tie
auto tie(Ts &...Args)
Definition: tuple.hpp:40
sycl::_V1::detail::tuple_element
Definition: tuple.hpp:44
sycl::_V1::detail::tuple
Definition: tuple.hpp:22
sycl
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14
sycl::_V1::detail::tuple< T, Ts... >::to_std_tuple
static std::tuple< UT, UTs... > to_std_tuple(const tuple< UT, UTs... > &Tuple, std::index_sequence< Is... >)
Definition: tuple.hpp:173
sycl::_V1::detail::make_tuple
constexpr tuple< Ts... > make_tuple(Ts... Args)
Definition: tuple.hpp:36
sycl::_V1::detail::get::operator()
constexpr auto operator()(const tuple< Ts... > &Tuple) const -> decltype(get< N - 1 >()(Tuple.next))
Definition: tuple.hpp:67
sycl::_V1::detail::tuple< T, Ts... >::tuple
tuple(const tuple< UT, UTs... > &RHS)
Definition: tuple.hpp:124
sycl::_V1::detail::tuple<>::operator==
friend bool operator==(const tuple &, const tuple &)
Definition: tuple.hpp:188
sycl::_V1::detail::tuple< T, Ts... >::tuple_type
std::tuple< T, Ts... > tuple_type
Definition: tuple.hpp:119
sycl::_V1::detail::tuple<>::tuple
tuple(const std::tuple<> &)
Definition: tuple.hpp:184
sycl::_V1::detail::tuple< T, Ts... >::tuple
tuple(const std::tuple< T, Ts... > &RHS)
Definition: tuple.hpp:130
sycl::_V1::detail::get_tuple_tail
std::tuple< Ts... > get_tuple_tail(const std::tuple< T, Ts... > &Tuple)
Definition: tuple.hpp:31
sycl::_V1::detail::tuple<>::tuple_type
std::tuple<> tuple_type
Definition: tuple.hpp:180
std::get
constexpr tuple_element< I, tuple< Types... > >::type & get(sycl::detail::tuple< Types... > &Arg) noexcept
Definition: tuple.hpp:199
defines_elementary.hpp
sycl::_V1::detail::TupleCopyAssignableValueHolder
Definition: tuple.hpp:100
sycl::_V1::detail::tuple_element< 0, tuple< T, Rest... > >::type
T type
Definition: tuple.hpp:52
sycl::_V1::ext::oneapi::experimental::operator=
annotated_arg & operator=(annotated_arg &)=default
sycl::_V1::detail::tuple< T, Ts... >::next
tuple< Ts... > next
Definition: tuple.hpp:117
sycl::_V1::detail::TupleValueHolder::value
T value
Definition: tuple.hpp:94
sycl::_V1::detail::TupleValueHolder
Definition: tuple.hpp:91
sycl::_V1::detail::tuple< T, Ts... >::operator=
tuple & operator=(const detail::tuple< UT, UTs... > &RHS)
Definition: tuple.hpp:146
sycl::_V1::detail::get< 0 >::operator()
constexpr const ret_type< Ts... > & operator()(const tuple< Ts... > &Tuple) const noexcept
Definition: tuple.hpp:86
sycl::_V1::detail::tuple< T, Ts... >::operator!=
friend bool operator!=(const tuple &LHS, const tuple &RHS)
Definition: tuple.hpp:168
sycl::_V1::detail::get< 0 >::ret_type
typename tuple_element< 0, tuple< Ts... > >::type ret_type
Definition: tuple.hpp:77
sycl::_V1::detail::TupleValueHolder::TupleValueHolder
TupleValueHolder(const T &Value)
Definition: tuple.hpp:93
std
Definition: accessor.hpp:3910
sycl::_V1::detail::tuple_element_t
typename tuple_element< I, T >::type tuple_element_t
Definition: tuple.hpp:56
sycl::_V1::detail::tuple< T, Ts... >::operator=
tuple & operator=(const std::tuple< UT, UTs... > &RHS)
Definition: tuple.hpp:159
sycl::_V1::detail::get::operator()
constexpr auto operator()(tuple< Ts... > &Tuple) const -> decltype(get< N - 1 >()(Tuple.next))
Definition: tuple.hpp:61
sycl::_V1::detail::tuple< T, Ts... >::holder
TupleCopyAssignableValueHolder< T > holder
Definition: tuple.hpp:116
sycl::_V1::detail::get
Definition: tuple.hpp:59
sycl::_V1::detail::tuple< T, Ts... >
Definition: tuple.hpp:115