diff --git a/array.h b/array.h index f146e11..fe02bfb 100644 --- a/array.h +++ b/array.h @@ -97,7 +97,7 @@ namespace internal { // Workaround CUDA not supporting std::declval. // https://stackoverflow.com/questions/31969644/compilation-error-with-nvcc-and-c11-need-minimal-failing-example template -NDARRAY_HOST_DEVICE typename std::add_rvalue_reference::type declval() noexcept; +NDARRAY_HOST_DEVICE typename std::add_rvalue_reference_t declval() noexcept; NDARRAY_INLINE constexpr index_t abs(index_t x) { return x >= 0 ? x : -x; } @@ -810,7 +810,7 @@ NDARRAY_HOST_DEVICE void resolve_unknown_strides(AllDims& all_dims) {} template NDARRAY_HOST_DEVICE void resolve_unknown_strides(AllDims& all_dims, Dim0& dim0, Dims&... dims) { if (is_dynamic(dim0.stride())) { - constexpr size_t rank = std::tuple_size::value; + constexpr size_t rank = std::tuple_size_v; dim0.set_stride(find_stride(dim0.extent(), all_dims, make_index_sequence())); } resolve_unknown_strides(all_dims, dims...); @@ -858,7 +858,7 @@ template struct all_of_any_type : std::true_type {}; template struct all_of_any_type, Arg, Args...> { - static constexpr bool value = any(std::is_constructible::value...) && + static constexpr bool value = any(std::is_constructible_v...) && all_of_any_type, Args...>::value; }; @@ -885,7 +885,8 @@ NDARRAY_HOST_DEVICE T convert_dims(const U& u, internal::index_sequence) // Check that the dimensions in src_dims are either copied to the dst shape (not sliced), // or are trivial slices (they are extent 1). template -NDARRAY_HOST_DEVICE bool is_trivial_slice(const SrcDims& src_dims, internal::index_sequence) { +NDARRAY_HOST_DEVICE bool is_trivial_slice( + const SrcDims& src_dims, internal::index_sequence) { return all((Is < DstRank || std::get(src_dims).extent() == 1)...); } @@ -934,7 +935,7 @@ class shape { using dims_type = std::tuple; /** Number of dims in this shape. */ - static constexpr size_t rank() { return std::tuple_size::value; } + static constexpr size_t rank() { return std::tuple_size_v; } /** A shape is scalar if its rank is 0. */ static constexpr bool is_scalar() { return rank() == 0; } @@ -945,7 +946,7 @@ class shape { using size_type = size_t; // We use this a lot here. Make an alias for it. - using dim_indices = decltype(internal::make_index_sequence::value>()); + using dim_indices = decltype(internal::make_index_sequence>()); private: dims_type dims_; @@ -1350,11 +1351,11 @@ NDARRAY_HOST_DEVICE auto make_compact_dims(const Dims& dims, index_sequence::type::Stride == 1 - ? static_abs(std::tuple_element::type::Extent) + variadic_max(std::tuple_element_t::Stride == 1 + ? static_abs(std::tuple_element_t::Extent) : dynamic...); - constexpr bool AnyStrideGreaterThanOne = any((std::tuple_element::type::Stride > 1)...); - constexpr bool AllDynamic = all(is_dynamic(std::tuple_element::type::Stride)...); + constexpr bool AnyStrideGreaterThanOne = any((std::tuple_element_t::Stride > 1)...); + constexpr bool AllDynamic = all(is_dynamic(std::tuple_element_t::Stride)...); constexpr index_t NextStride = AnyStrideGreaterThanOne ? dynamic : (AllDynamic ? 1 : MinStride); return make_compact_dims(std::get(dims)...); } @@ -1401,11 +1402,11 @@ constexpr size_t index_of() { // Similar to std::get, but returns a one-element tuple if I is // in bounds, or an empty tuple if not. -template ::value), int> = 0> +template ), int> = 0> NDARRAY_INLINE NDARRAY_HOST_DEVICE auto get_or_empty(const T& t) { return std::make_tuple(std::get(t)); } -template = std::tuple_size::value), int> = 0> +template = std::tuple_size_v), int> = 0> NDARRAY_INLINE NDARRAY_HOST_DEVICE std::tuple<> get_or_empty(const T& t) { return std::tuple<>(); } @@ -1421,8 +1422,7 @@ NDARRAY_HOST_DEVICE auto unshuffle(const std::tuple& t) { } template -using enable_if_shapes_compatible = - std::enable_if_t::value>; +using enable_if_shapes_compatible = std::enable_if_t>; template using enable_if_shapes_explicitly_compatible = @@ -1484,8 +1484,8 @@ NDARRAY_HOST_DEVICE bool is_compatible(const ShapeSrc& src) { template > NDARRAY_HOST_DEVICE ShapeDst convert_shape(const ShapeSrc& src) { - assert(internal::is_trivial_slice( - src.dims(), typename ShapeSrc::dim_indices())); + assert( + internal::is_trivial_slice(src.dims(), typename ShapeSrc::dim_indices())); return internal::convert_dims( src.dims(), typename ShapeDst::dim_indices()); } @@ -1512,7 +1512,7 @@ NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_index_in_order(const Shape& sha internal::for_each_index_in_order(fn, shape.dims(), typename Shape::dim_indices()); } template ::type&>> + class = internal::enable_if_callable&>> NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_value_in_order( const Shape& shape, Ptr base, Fn&& fn) { // TODO: This is losing compile-time constant extents and strides info @@ -1525,8 +1525,8 @@ NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_value_in_order( * simultaneously. `shape` defines the loop nest, while `shape_a` and `shape_b` * define the memory layout of `base_a` and `base_b`. */ template ::type&, - typename std::remove_pointer::type&>> + class = internal::enable_if_callable&, + typename std::remove_pointer_t&>> NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_value_in_order(const Shape& shape, const ShapeA& shape_a, PtrA base_a, const ShapeB& shape_b, PtrB base_b, Fn&& fn) { base_a += shape_a[shape.min()]; @@ -2141,9 +2141,7 @@ class array { array(const Shape& shape, const T& value, const Alloc& alloc) : array(alloc) { assign(shape, value); } - array(const Shape& shape, const T& value) : array() { - assign(shape, value); - } + array(const Shape& shape, const T& value) : array() { assign(shape, value); } /** Construct an array with a particular `shape`, allocated by `alloc`, with * default constructed elements. */ @@ -2411,7 +2409,7 @@ class array { * does not call the destructor or constructor for newly inaccessible or newly * accessible elements, respectively. */ void set_shape(const Shape& new_shape, index_t offset = 0) { - static_assert(std::is_trivial::value, "set_shape is broken for non-trivial types."); + static_assert(std::is_trivial_v, "set_shape is broken for non-trivial types."); assert(new_shape.is_resolved()); assert(new_shape.is_subset_of(shape_, -offset)); shape_ = new_shape; @@ -2552,7 +2550,7 @@ void copy(const array& src, array::type>, + class Alloc = std::allocator>, class = internal::enable_if_shapes_copy_compatible> auto make_copy( const array_ref& src, const ShapeDst& shape, const Alloc& alloc = Alloc()) { @@ -2569,7 +2567,7 @@ auto make_copy(const array& src, const ShapeDst& shape, /** Make a copy of the `src` array or array_ref with a compact version of `src`'s * shape. */ -template ::type>> +template >> auto make_compact_copy(const array_ref& src, const Alloc& alloc = Alloc()) { return make_copy(src, make_compact(src.shape()), alloc); } @@ -2761,7 +2759,7 @@ array move_reinterpret_shape( array&& from, const NewShape& new_shape, index_t offset = 0) { // TODO: Use enable_if to implement this check. It is difficult to do due to // the friend declaration. - static_assert(std::is_trivial::value, "move_reinterpret_shape is broken for non-trivial types."); + static_assert(std::is_trivial_v, "move_reinterpret_shape is broken for non-trivial types."); assert(new_shape.is_subset_of(from.shape(), offset)); array result; assert(result.alloc_ == from.get_allocator()); @@ -2934,13 +2932,13 @@ class uninitialized_allocator : public BaseAlloc { /** Allocator equivalent to `std::allocator` that does not default * construct values. */ -template ::value>> +template >> using uninitialized_std_allocator = uninitialized_allocator>; /** Allocator equivalent to `auto_allocator` that * does not default construct values. */ template ::value>> + class = std::enable_if_t>> using uninitialized_auto_allocator = uninitialized_allocator>; } // namespace nda