Spaces:
Sleeping
Sleeping
| /*************************************************************************************************** | |
| * Copyright (c) 2023 - 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | |
| * SPDX-License-Identifier: BSD-3-Clause | |
| * | |
| * Redistribution and use in source and binary forms, with or without | |
| * modification, are permitted provided that the following conditions are met: | |
| * | |
| * 1. Redistributions of source code must retain the above copyright notice, this | |
| * list of conditions and the following disclaimer. | |
| * | |
| * 2. Redistributions in binary form must reproduce the above copyright notice, | |
| * this list of conditions and the following disclaimer in the documentation | |
| * and/or other materials provided with the distribution. | |
| * | |
| * 3. Neither the name of the copyright holder nor the names of its | |
| * contributors may be used to endorse or promote products derived from | |
| * this software without specific prior written permission. | |
| * | |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
| * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| * | |
| **************************************************************************************************/ | |
| namespace cute | |
| { | |
| template <class T, size_t N> | |
| struct array | |
| { | |
| using element_type = T; | |
| using value_type = remove_cv_t<T>; | |
| using size_type = size_t; | |
| using difference_type = ptrdiff_t; | |
| using reference = element_type&; | |
| using const_reference = const element_type&; | |
| using pointer = element_type*; | |
| using const_pointer = const element_type*; | |
| using iterator = pointer; | |
| using const_iterator = const_pointer; | |
| CUTE_HOST_DEVICE constexpr | |
| reference operator[](size_type pos) | |
| { | |
| return begin()[pos]; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| const_reference operator[](size_type pos) const | |
| { | |
| return begin()[pos]; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| reference front() | |
| { | |
| return *begin(); | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| const_reference front() const | |
| { | |
| return *begin(); | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| reference back() | |
| { | |
| // return *rbegin(); | |
| return operator[](N-1); | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| const_reference back() const | |
| { | |
| // return *rbegin(); | |
| return operator[](N-1); | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| T* data() | |
| { | |
| return __elems_; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| T const* data() const | |
| { | |
| return __elems_; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| iterator begin() | |
| { | |
| return data(); | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| const_iterator begin() const | |
| { | |
| return data(); | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| const_iterator cbegin() | |
| { | |
| return begin(); | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| const_iterator cbegin() const | |
| { | |
| return begin(); | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| iterator end() | |
| { | |
| return data() + size(); | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| const_iterator end() const | |
| { | |
| return data() + size(); | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| const_iterator cend() | |
| { | |
| return end(); | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| const_iterator cend() const | |
| { | |
| return end(); | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| bool empty() const | |
| { | |
| return size() == 0; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| size_type size() const | |
| { | |
| return N; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| size_type max_size() const | |
| { | |
| return size(); | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| void fill(const T& value) | |
| { | |
| for (auto& e : *this) { | |
| e = value; | |
| } | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| void clear() | |
| { | |
| fill(T(0)); | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| void swap(array& other) | |
| { | |
| using CUTE_STL_NAMESPACE::swap; | |
| for (size_type i = 0; i < size(); ++i) { | |
| swap((*this)[i], other[i]); | |
| } | |
| } | |
| element_type __elems_[N]; | |
| }; | |
| template <class T> | |
| struct array<T, 0> | |
| { | |
| using element_type = T; | |
| using value_type = remove_cv_t<T>; | |
| using size_type = size_t; | |
| using difference_type = ptrdiff_t; | |
| using reference = element_type&; | |
| using const_reference = const element_type&; | |
| using pointer = element_type*; | |
| using const_pointer = const element_type*; | |
| using const_iterator = const_pointer; | |
| using iterator = pointer; | |
| CUTE_HOST_DEVICE constexpr | |
| reference operator[](size_type pos) | |
| { | |
| return begin()[pos]; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| const_reference operator[](size_type pos) const | |
| { | |
| return begin()[pos]; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| reference front() | |
| { | |
| return *begin(); | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| const_reference front() const | |
| { | |
| return *begin(); | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| reference back() | |
| { | |
| return *begin(); | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| const_reference back() const | |
| { | |
| return *begin(); | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| T* data() | |
| { | |
| return nullptr; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| T const* data() const | |
| { | |
| return nullptr; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| iterator begin() | |
| { | |
| return nullptr; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| const_iterator begin() const | |
| { | |
| return nullptr; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| const_iterator cbegin() | |
| { | |
| return nullptr; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| const_iterator cbegin() const | |
| { | |
| return nullptr; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| iterator end() | |
| { | |
| return nullptr; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| const_iterator end() const | |
| { | |
| return nullptr; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| const_iterator cend() | |
| { | |
| return nullptr; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| const_iterator cend() const | |
| { | |
| return nullptr; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| bool empty() const | |
| { | |
| return true; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| size_type size() const | |
| { | |
| return 0; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| size_type max_size() const | |
| { | |
| return 0; | |
| } | |
| CUTE_HOST_DEVICE constexpr | |
| void fill(const T& value) | |
| {} | |
| CUTE_HOST_DEVICE constexpr | |
| void clear() | |
| {} | |
| CUTE_HOST_DEVICE constexpr | |
| void swap(array& other) | |
| {} | |
| }; | |
| template <class T, size_t N> | |
| CUTE_HOST_DEVICE constexpr | |
| bool operator==(array<T,N> const& lhs, array<T,N> const& rhs) | |
| { | |
| for (size_t i = 0; i < N; ++i) { | |
| if (lhs[i] != rhs[i]) { | |
| return false; | |
| } | |
| } | |
| return true; | |
| } | |
| template <class T, size_t N> | |
| CUTE_HOST_DEVICE constexpr | |
| void clear(array<T,N>& a) | |
| { | |
| a.fill(T(0)); | |
| } | |
| template <class T, size_t N> | |
| CUTE_HOST_DEVICE constexpr | |
| void fill(array<T,N>& a, T const& value) | |
| { | |
| a.fill(value); | |
| } | |
| template <class T, size_t N> | |
| CUTE_HOST_DEVICE constexpr | |
| void swap(array<T,N>& a, array<T,N>& b) | |
| { | |
| a.swap(b); | |
| } | |
| /// @return A cute::array of the elements of @c t in reverse order. | |
| template <class T, size_t N> | |
| CUTE_HOST_DEVICE constexpr | |
| cute::array<T,N> reverse(cute::array<T,N> const& t) | |
| { | |
| if constexpr (N == 0u) { | |
| return t; | |
| } else { | |
| cute::array<T,N> t_r{}; | |
| for (size_t k = 0; k < N; ++k) { | |
| t_r[k] = t[N - k - 1]; | |
| } | |
| return t_r; | |
| } | |
| } | |
| } // end cute | |
| // | |
| // Specialize tuple-related functionality for cute::array | |
| // | |
| namespace cute | |
| { | |
| template <size_t I, class T, size_t N> | |
| CUTE_HOST_DEVICE constexpr | |
| T& get(array<T,N>& a) | |
| { | |
| static_assert(I < N, "Index out of range"); | |
| return a[I]; | |
| } | |
| template <size_t I, class T, size_t N> | |
| CUTE_HOST_DEVICE constexpr | |
| T const& get(array<T,N> const& a) | |
| { | |
| static_assert(I < N, "Index out of range"); | |
| return a[I]; | |
| } | |
| template <size_t I, class T, size_t N> | |
| CUTE_HOST_DEVICE constexpr | |
| T&& get(array<T,N>&& a) | |
| { | |
| static_assert(I < N, "Index out of range"); | |
| return cute::move(a[I]); | |
| } | |
| } // end namespace cute | |
| namespace CUTE_STL_NAMESPACE | |
| { | |
| template <class T, size_t N> | |
| struct tuple_size<cute::array<T,N>> | |
| : CUTE_STL_NAMESPACE::integral_constant<size_t, N> | |
| {}; | |
| template <size_t I, class T, size_t N> | |
| struct tuple_element<I, cute::array<T,N>> | |
| { | |
| using type = T; | |
| }; | |
| template <class T, size_t N> | |
| struct tuple_size<cute::array<T,N> const> | |
| : CUTE_STL_NAMESPACE::integral_constant<size_t, N> | |
| {}; | |
| template <size_t I, class T, size_t N> | |
| struct tuple_element<I, cute::array<T,N> const> | |
| { | |
| using type = T; | |
| }; | |
| } // end namespace CUTE_STL_NAMESPACE | |
| namespace std | |
| { | |
| template <class... _Tp> | |
| struct tuple_size; | |
| template <size_t _Ip, class... _Tp> | |
| struct tuple_element; | |
| template <class T, size_t N> | |
| struct tuple_size<cute::array<T,N>> | |
| : CUTE_STL_NAMESPACE::integral_constant<size_t, N> | |
| {}; | |
| template <size_t I, class T, size_t N> | |
| struct tuple_element<I, cute::array<T,N>> | |
| { | |
| using type = T; | |
| }; | |
| template <class T, size_t N> | |
| struct tuple_size<cute::array<T,N> const> | |
| : CUTE_STL_NAMESPACE::integral_constant<size_t, N> | |
| {}; | |
| template <size_t I, class T, size_t N> | |
| struct tuple_element<I, cute::array<T,N> const> | |
| { | |
| using type = T; | |
| }; | |
| } // end namespace std | |