/* * Copyright 2008-2025 NVIDIA Corporation * Modifications Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*! \file tuple.h * \brief A type encapsulating a heterogeneous collection of elements. */ /* * Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying NOTICE file for the complete license) * * For more information, see http://www.boost.org */ #pragma once #include #if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC) # pragma GCC system_header #elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG) # pragma clang system_header #elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC) # pragma system_header #endif // no system header #include _THRUST_STD_INCLUDE(tuple) #if !_THRUST_HAS_DEVICE_SYSTEM_STD # include # include #endif THRUST_NAMESPACE_BEGIN // define null_type for backwards compatibility struct THRUST_DEPRECATED_BECAUSE("Please remove null_type from parameters to tuple<...>") null_type {}; THRUST_SUPPRESS_DEPRECATED_PUSH #ifndef THRUST_DOXYGEN_INVOKED THRUST_HOST_DEVICE inline bool operator==(const null_type&, const null_type&) { return true; } THRUST_HOST_DEVICE inline bool operator>=(const null_type&, const null_type&) { return true; } THRUST_HOST_DEVICE inline bool operator<=(const null_type&, const null_type&) { return true; } THRUST_HOST_DEVICE inline bool operator!=(const null_type&, const null_type&) { return false; } THRUST_HOST_DEVICE inline bool operator<(const null_type&, const null_type&) { return false; } THRUST_HOST_DEVICE inline bool operator>(const null_type&, const null_type&) { return false; } #endif THRUST_SUPPRESS_DEPRECATED_POP THRUST_NAMESPACE_END // If 'libcudacxx' or 'libhipcxx' is available (_THRUST_HAS_DEVICE_SYSTEM_STD), we will // use the implementations provided there. Otherwise we will fall back to an older // implementation of thrust::tuple. #if _THRUST_HAS_DEVICE_SYSTEM_STD THRUST_NAMESPACE_BEGIN /*! \addtogroup utility * \{ */ /*! \addtogroup tuple * \{ */ /*! This metafunction returns the type of a * \p tuple's Nth element. * * \tparam N This parameter selects the element of interest. * \tparam T A \c tuple type of interest. * * \see pair * \see tuple */ # ifdef THRUST_DOXYGEN_INVOKED // Provide a fake alias for doxygen template using tuple_element = _THRUST_STD::tuple_element; # else // ^^^ THRUST_DOXYGEN_INVOKED ^^^ / vvv !THRUST_DOXYGEN_INVOKED vvv using _THRUST_STD::tuple_element; # endif // THRUST_DOXYGEN_INVOKED /*! This metafunction returns the number of elements * of a \p tuple type of interest. * * \tparam T A \c tuple type of interest. * * \see pair * \see tuple */ # ifdef THRUST_DOXYGEN_INVOKED // Provide a fake alias for doxygen template using tuple_size = _THRUST_STD::tuple_size; # else // ^^^ THRUST_DOXYGEN_INVOKED ^^^ / vvv !THRUST_DOXYGEN_INVOKED vvv using _THRUST_STD::tuple_size; # endif // THRUST_DOXYGEN_INVOKED /*! \brief \p tuple is a heterogeneous, fixed-size collection of values. * An instantiation of \p tuple with two arguments is similar to an * instantiation of \p pair with the same two arguments. Individual elements * of a \p tuple may be accessed with the \p get function. * * \tparam Ts The type of the N \c tuple element. Thrust's \p tuple * type currently supports up to ten elements. * * The following code snippet demonstrates how to create a new \p tuple object * and inspect and modify the value of its elements. * * \code * #include * #include * * int main() { * // Create a tuple containing an `int`, a `float`, and a string. * thrust::tuple t(13, 0.1f, "thrust"); * * // Individual members are accessed with the free function `get`. * std::cout << "The first element's value is " << thrust::get<0>(t) << std::endl; * * // ... or the member function `get`. * std::cout << "The second element's value is " << t.get<1>() << std::endl; * * // We can also modify elements with the same function. * thrust::get<0>(t) += 10; * } * \endcode * * \see pair * \see get * \see make_tuple * \see tuple_element * \see tuple_size * \see tie */ # ifdef THRUST_DOXYGEN_INVOKED // Provide a fake alias for doxygen template using tuple = _THRUST_STD::tuple; # else // ^^^ THRUST_DOXYGEN_INVOKED ^^^ / vvv !THRUST_DOXYGEN_INVOKED vvv using _THRUST_STD::tuple; # endif // THRUST_DOXYGEN_INVOKED using _THRUST_STD::get; using _THRUST_STD::make_tuple; using _THRUST_STD::tie; /*! \endcond */ /*! \} // tuple */ /*! \} // utility */ THRUST_NAMESPACE_END _THRUST_STD_NAMESPACE_BEGIN THRUST_SUPPRESS_DEPRECATED_PUSH template <> struct tuple_size> : tuple_size> {}; template struct tuple_size> : tuple_size> {}; template struct tuple_size> : tuple_size> {}; template struct tuple_size> : tuple_size> {}; template struct tuple_size> : tuple_size> {}; template struct tuple_size> : tuple_size> {}; template struct tuple_size> : tuple_size> {}; template struct tuple_size< tuple> : tuple_size> {}; template struct tuple_size> : tuple_size> {}; template struct tuple_size> : tuple_size> {}; THRUST_SUPPRESS_DEPRECATED_POP _THRUST_STD_NAMESPACE_END #else # include # include THRUST_NAMESPACE_BEGIN THRUST_SUPPRESS_DEPRECATED_PUSH /*! \addtogroup utility * \{ */ /*! \addtogroup tuple * \{ */ /*! This metafunction returns the type of a * \p tuple's Nth element. * * \tparam N This parameter selects the element of interest. * \tparam T A \c tuple type of interest. * * \see pair * \see tuple */ template struct tuple_element; /*! This metafunction returns the number of elements * of a \p tuple type of interest. * * \tparam T A \c tuple type of interest. * * \see pair * \see tuple */ template struct tuple_size; // get function for non-const cons-lists, returns a reference to the element /*! The \p get function returns a reference to a \p tuple element of * interest. * * \param t A reference to a \p tuple of interest. * \return A reference to \p t's Nth element. * * \tparam N The index of the element of interest. * * The following code snippet demonstrates how to use \p get to print * the value of a \p tuple element. * * \code * #include * #include * ... * thrust::tuple t(13, "thrust"); * * std::cout << "The 1st value of t is " << thrust::get<0>(t) << std::endl; * \endcode * * \see pair * \see tuple */ template THRUST_HOST_DEVICE inline typename access_traits>::type>::non_const_type get(detail::cons& t); /*! The \p get function returns a \c const reference to a \p tuple element of * interest. * * \param t A reference to a \p tuple of interest. * \return A \c const reference to \p t's Nth element. * * \tparam N The index of the element of interest. * * The following code snippet demonstrates how to use \p get to print * the value of a \p tuple element. * * \code * #include * #include * ... * thrust::tuple t(13, "thrust"); * * std::cout << "The 1st value of t is " << thrust::get<0>(t) << std::endl; * \endcode * * \see pair * \see tuple */ template THRUST_HOST_DEVICE inline typename access_traits>::type>::const_type get(const detail::cons& t); /*! Constructs a \p tuple from a variadic list of types \p Ts, allowing the \p tuple to deduce * its type as \p tuple based on the types of the provided arguments. * * \tparam Ts... The parameter pack of types that will determine the tuple's type. * \note This deduction guide enables automatic type deduction for variadic arguments * when constructing a \p tuple. * \see tuple */ template THRUST_HOST_DEVICE tuple(Ts...) -> tuple; /*! \cond */ /*! A \p pair is a structure template holding two elements of types \p T1 and \p T2. * * \tparam T1 The type of the first element in the \p pair. * \tparam T2 The type of the second element in the \p pair. * \note \p pair is used to store two heterogeneous values and can be converted to a \p tuple. * \see tuple */ template struct pair; /*! \endcond */ /*! Constructs a \p tuple from a \p pair, unpacking its elements to initialize * the tuple as \p tuple. * * \tparam T1 The type of the first element in the \p pair. * \tparam T2 The type of the second element in the \p pair. * \note This deduction guide allows a \p tuple to be created directly from a \p pair, * simplifying the type conversion. * \see pair * \see tuple */ template THRUST_HOST_DEVICE tuple(pair) -> tuple; /*! \brief \p tuple is a class template that can be instantiated with up to ten * arguments. Each template argument specifies the type of element in the \p * tuple. Consequently, tuples are heterogeneous, fixed-size collections of * values. An instantiation of \p tuple with two arguments is similar to an * instantiation of \p pair with the same two arguments. Individual elements * of a \p tuple may be accessed with the \p get function. * * \tparam TN The type of the N \c tuple element. Thrust's \p tuple * type currently supports up to ten elements. * * The following code snippet demonstrates how to create a new \p tuple object * and inspect and modify the value of its elements. * * \code * #include * #include * * int main() { * // Create a tuple containing an `int`, a `float`, and a string. * thrust::tuple t(13, 0.1f, "thrust"); * * // Individual members are accessed with the free function `get`. * std::cout << "The first element's value is " << thrust::get<0>(t) << std::endl; * * // ... or the member function `get`. * std::cout << "The second element's value is " << t.get<1>() << std::endl; * * // We can also modify elements with the same function. * thrust::get<0>(t) += 10; * } * \endcode * * \see pair * \see get * \see make_tuple * \see tuple_element * \see tuple_size * \see tie */ template class tuple /*! \cond */ : public detail::map_tuple_to_cons::type /*! \endcond */ { /*! \cond */ private: using inherited = typename detail::map_tuple_to_cons::type; /*! \endcond */ public: /*! \p tuple's no-argument constructor initializes each element. */ inline THRUST_HOST_DEVICE tuple(void) {} /*! \p tuple's one-argument constructor copy constructs the first element from the given parameter * and intializes all other elements. * \param t0 The value to assign to this \p tuple's first element. */ inline THRUST_HOST_DEVICE tuple(typename access_traits::parameter_type t0) : inherited( t0, static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type())) {} /*! \p tuple's one-argument constructor copy constructs the first two elements from the given parameters * and intializes all other elements. * \param t0 The value to assign to this \p tuple's first element. * \param t1 The value to assign to this \p tuple's second element. * \note \p tuple's constructor has ten variants of this form, the rest of which are ommitted here for brevity. */ inline THRUST_HOST_DEVICE tuple(typename access_traits::parameter_type t0, typename access_traits::parameter_type t1) : inherited( t0, t1, static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type())) {} /*! \cond */ inline THRUST_HOST_DEVICE tuple(typename access_traits::parameter_type t0, typename access_traits::parameter_type t1, typename access_traits::parameter_type t2) : inherited( t0, t1, t2, static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type())) {} inline THRUST_HOST_DEVICE tuple(typename access_traits::parameter_type t0, typename access_traits::parameter_type t1, typename access_traits::parameter_type t2, typename access_traits::parameter_type t3) : inherited( t0, t1, t2, t3, static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type())) {} inline THRUST_HOST_DEVICE tuple(typename access_traits::parameter_type t0, typename access_traits::parameter_type t1, typename access_traits::parameter_type t2, typename access_traits::parameter_type t3, typename access_traits::parameter_type t4) : inherited( t0, t1, t2, t3, t4, static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type())) {} inline THRUST_HOST_DEVICE tuple(typename access_traits::parameter_type t0, typename access_traits::parameter_type t1, typename access_traits::parameter_type t2, typename access_traits::parameter_type t3, typename access_traits::parameter_type t4, typename access_traits::parameter_type t5) : inherited( t0, t1, t2, t3, t4, t5, static_cast(null_type()), static_cast(null_type()), static_cast(null_type()), static_cast(null_type())) {} inline THRUST_HOST_DEVICE tuple(typename access_traits::parameter_type t0, typename access_traits::parameter_type t1, typename access_traits::parameter_type t2, typename access_traits::parameter_type t3, typename access_traits::parameter_type t4, typename access_traits::parameter_type t5, typename access_traits::parameter_type t6) : inherited( t0, t1, t2, t3, t4, t5, t6, static_cast(null_type()), static_cast(null_type()), static_cast(null_type())) {} inline THRUST_HOST_DEVICE tuple( typename access_traits::parameter_type t0, typename access_traits::parameter_type t1, typename access_traits::parameter_type t2, typename access_traits::parameter_type t3, typename access_traits::parameter_type t4, typename access_traits::parameter_type t5, typename access_traits::parameter_type t6, typename access_traits::parameter_type t7) : inherited( t0, t1, t2, t3, t4, t5, t6, t7, static_cast(null_type()), static_cast(null_type())) {} inline THRUST_HOST_DEVICE tuple( typename access_traits::parameter_type t0, typename access_traits::parameter_type t1, typename access_traits::parameter_type t2, typename access_traits::parameter_type t3, typename access_traits::parameter_type t4, typename access_traits::parameter_type t5, typename access_traits::parameter_type t6, typename access_traits::parameter_type t7, typename access_traits::parameter_type t8) : inherited(t0, t1, t2, t3, t4, t5, t6, t7, t8, static_cast(null_type())) {} inline THRUST_HOST_DEVICE tuple( typename access_traits::parameter_type t0, typename access_traits::parameter_type t1, typename access_traits::parameter_type t2, typename access_traits::parameter_type t3, typename access_traits::parameter_type t4, typename access_traits::parameter_type t5, typename access_traits::parameter_type t6, typename access_traits::parameter_type t7, typename access_traits::parameter_type t8, typename access_traits::parameter_type t9) : inherited(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9) {} template inline THRUST_HOST_DEVICE tuple(const detail::cons& p) : inherited(p) {} THRUST_EXEC_CHECK_DISABLE template inline THRUST_HOST_DEVICE tuple& operator=(const detail::cons& k) { inherited::operator=(k); return *this; } /*! \endcond */ /*! This assignment operator allows assigning the first two elements of this \p tuple from a \p pair. * \param k A \p pair to assign from. */ THRUST_EXEC_CHECK_DISABLE template THRUST_HOST_DEVICE inline tuple& operator=(const thrust::pair& k) { // BOOST_STATIC_ASSERT(length::value == 2);// check_length = 2 this->head = k.first; this->tail.head = k.second; return *this; } /*! \p swap swaps the elements of two tuples. * * \param t The other tuple with which to swap. */ inline THRUST_HOST_DEVICE void swap(tuple& t) { inherited::swap(t); } }; /*! \cond */ template <> class tuple : public null_type { public: using inherited = null_type; }; /*! \endcond */ /*! This version of \p make_tuple creates a new \c tuple object from a * single object. * * \param t0 The object to copy from. * \return A \p tuple object with a single member which is a copy of \p t0. */ template THRUST_HOST_DEVICE inline typename detail::make_tuple_mapper::type make_tuple(const T0& t0); /*! This version of \p make_tuple creates a new \c tuple object from two * objects. * * \param t0 The first object to copy from. * \param t1 The second object to copy from. * \return A \p tuple object with two members which are copies of \p t0 * and \p t1. * * \note \p make_tuple has ten variants, the rest of which are omitted here * for brevity. */ template THRUST_HOST_DEVICE inline typename detail::make_tuple_mapper::type make_tuple(const T0& t0, const T1& t1); /*! This version of \p tie creates a new \c tuple whose single element is * a reference which refers to this function's argument. * * \param t0 The object to reference. * \return A \p tuple object with one member which is a reference to \p t0. */ template THRUST_HOST_DEVICE inline tuple tie(T0& t0); /*! This version of \p tie creates a new \c tuple of references object which * refers to this function's arguments. * * \param t0 The first object to reference. * \param t1 The second object to reference. * \return A \p tuple object with two members which are references to \p t0 * and \p t1. * * \note \p tie has ten variants, the rest of which are omitted here for * brevity. */ template THRUST_HOST_DEVICE inline tuple tie(T0& t0, T1& t1); /*! \p swap swaps the contents of two tuples. * * \param x The first \p tuple to swap. * \param y The second \p tuple to swap. */ template inline THRUST_HOST_DEVICE void swap(tuple& x, tuple& y); /*! \cond */ template THRUST_HOST_DEVICE inline typename detail::make_tuple_mapper::type make_tuple(const T0& t0, const T1& t1, const T2& t2); template THRUST_HOST_DEVICE inline typename detail::make_tuple_mapper::type make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3); template THRUST_HOST_DEVICE inline typename detail::make_tuple_mapper::type make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4); template THRUST_HOST_DEVICE inline typename detail::make_tuple_mapper::type make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5); template THRUST_HOST_DEVICE inline typename detail::make_tuple_mapper::type make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6); template THRUST_HOST_DEVICE inline typename detail::make_tuple_mapper::type make_tuple( const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7); template THRUST_HOST_DEVICE inline typename detail::make_tuple_mapper::type make_tuple( const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7, const T8& t8); template THRUST_HOST_DEVICE inline typename detail::make_tuple_mapper::type make_tuple( const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7, const T8& t8, const T9& t9); template THRUST_HOST_DEVICE inline tuple tie(T0& t0, T1& t1, T2& t2); template THRUST_HOST_DEVICE inline tuple tie(T0& t0, T1& t1, T2& t2, T3& t3); template THRUST_HOST_DEVICE inline tuple tie(T0& t0, T1& t1, T2& t2, T3& t3, T4& t4); template THRUST_HOST_DEVICE inline tuple tie(T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5); template THRUST_HOST_DEVICE inline tuple tie(T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6); template THRUST_HOST_DEVICE inline tuple tie(T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7); template THRUST_HOST_DEVICE inline tuple tie(T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8); template THRUST_HOST_DEVICE inline tuple tie(T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, T9& t9); /*! \endcond */ /*! \} // tuple */ /*! \} // utility */ THRUST_SUPPRESS_DEPRECATED_POP THRUST_NAMESPACE_END _THRUST_STD_NAMESPACE_BEGIN template struct tuple_size> : std::tuple_size> {}; template struct tuple_element> : std::tuple_element> {}; THRUST_SUPPRESS_DEPRECATED_PUSH template <> struct tuple_size> : std::integral_constant {}; template struct tuple_size> : std::integral_constant {}; template struct tuple_size> : std::integral_constant {}; template struct tuple_size> : std::integral_constant {}; template struct tuple_size> : std::integral_constant {}; template struct tuple_size> : std::integral_constant {}; template struct tuple_size> : std::integral_constant {}; template struct tuple_size> : std::integral_constant {}; template struct tuple_size> : std::integral_constant {}; template struct tuple_size> : std::integral_constant {}; THRUST_SUPPRESS_DEPRECATED_POP _THRUST_STD_NAMESPACE_END #endif // _THRUST_HAS_DEVICE_SYSTEM_STD