diff options
author | Chris Robinson <[email protected]> | 2023-05-05 06:46:00 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2023-05-05 06:46:00 -0700 |
commit | 3ec03cadd2b5059e54e5e9b8f4d506b4c6ce727d (patch) | |
tree | 623b8e96f8acca9d55fb96b74e8d832877b27451 /common/alspan.h | |
parent | c14ca5f3aa6da354440a60656062f6bc68d6fca6 (diff) |
Use deduction guides instead of helper functions for spans
Diffstat (limited to 'common/alspan.h')
-rw-r--r-- | common/alspan.h | 46 |
1 files changed, 20 insertions, 26 deletions
diff --git a/common/alspan.h b/common/alspan.h index 42b3e057..f75bc84f 100644 --- a/common/alspan.h +++ b/common/alspan.h @@ -39,12 +39,15 @@ namespace detail_ { std::void_t<decltype(std::size(std::declval<T>())),decltype(std::data(std::declval<T>()))>> = true; + template<typename C> + constexpr bool is_valid_container_type = !is_span_v<C> && !is_std_array_v<C> + && !std::is_array<C>::value && has_size_and_data<C>; + template<typename T, typename U> constexpr bool is_array_compatible = std::is_convertible<T(*)[],U(*)[]>::value; template<typename C, typename T> - constexpr bool is_valid_container = !is_span_v<C> && !is_std_array_v<C> - && !std::is_array<C>::value && has_size_and_data<C> + constexpr bool is_valid_container = is_valid_container_type<C> && is_array_compatible<std::remove_pointer_t<decltype(std::data(std::declval<C&>()))>,T>; } // namespace detail_ @@ -297,30 +300,21 @@ constexpr inline auto span<T,E>::subspan(size_t offset, size_t count) const span<element_type>{mData+offset, mData+offset+count}; } -/* Helpers to deal with the lack of user-defined deduction guides (C++17). */ -template<typename T, typename U> -constexpr auto as_span(T ptr, U count_or_end) -{ - using value_type = typename std::pointer_traits<T>::element_type; - return span<value_type>{ptr, count_or_end}; -} -template<typename T, size_t N> -constexpr auto as_span(T (&arr)[N]) noexcept { return span<T,N>{std::data(arr), std::size(arr)}; } -template<typename T, size_t N> -constexpr auto as_span(std::array<T,N> &arr) noexcept -{ return span<T,N>{std::data(arr), std::size(arr)}; } -template<typename T, size_t N> -constexpr auto as_span(const std::array<T,N> &arr) noexcept -{ return span<std::add_const_t<T>,N>{std::data(arr), std::size(arr)}; } -template<typename U, REQUIRES(!detail_::is_span_v<U> && !detail_::is_std_array_v<U> - && !std::is_array<U>::value && detail_::has_size_and_data<U>)> -constexpr auto as_span(U&& cont) -{ - using value_type = std::remove_pointer_t<decltype(std::data(std::declval<U&>()))>; - return span<value_type>{std::data(cont), std::size(cont)}; -} -template<typename T, size_t N> -constexpr auto as_span(span<T,N> span_) noexcept { return span_; } + +template<typename T, typename EndOrSize> +span(T, EndOrSize) -> span<std::remove_reference_t<decltype(*std::declval<T&>())>>; + +template<typename T, std::size_t N> +span(T (&)[N]) -> span<T, N>; + +template<typename T, std::size_t N> +span(std::array<T, N>&) -> span<T, N>; + +template<typename T, std::size_t N> +span(const std::array<T, N>&) -> span<const T, N>; + +template<typename C, REQUIRES(detail_::is_valid_container_type<C>)> +span(C&&) -> span<std::remove_reference_t<decltype(*std::data(std::declval<C&>()))>>; #undef REQUIRES |