//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 // // template // constexpr explicit(see below) extents(const extents&) noexcept; // // Constraints: // * sizeof...(OtherExtents) == rank() is true. // * ((OtherExtents == dynamic_extent || Extents == dynamic_extent || // OtherExtents == Extents) && ...) is true. // // Preconditions: // * other.extent(r) equals Er for each r for which Er is a static extent, and // * either // - sizeof...(OtherExtents) is zero, or // - other.extent(r) is representable as a value of type index_type for // every rank index r of other. // // Remarks: The expression inside explicit is equivalent to: // (((Extents != dynamic_extent) && (OtherExtents == dynamic_extent)) || ... ) || // (numeric_limits::max() < numeric_limits::max()) #include #include #include #include #include template constexpr void test_implicit_conversion(To dest, From src) { assert(dest == src); } template constexpr void test_conversion(From src) { To dest(src); assert(dest == src); if constexpr (implicit) { dest = src; assert(dest == src); test_implicit_conversion(src, src); } } template constexpr void test_conversion() { constexpr size_t D = std::dynamic_extent; constexpr bool idx_convertible = static_cast(std::numeric_limits::max()) >= static_cast(std::numeric_limits::max()); // clang-format off test_conversion>(std::extents()); test_conversion>(std::extents(5)); test_conversion>(std::extents(5)); test_conversion>(std::extents()); test_conversion>(std::extents(5, 5)); test_conversion>(std::extents(5, 5)); test_conversion>(std::extents(5)); test_conversion>(std::extents()); test_conversion>(std::extents(5, 7)); test_conversion>( std::extents(5, 7, 8, 9, 1)); test_conversion>(std::extents(5)); test_conversion>(std::extents()); // clang-format on } constexpr void test_no_implicit_conversion() { constexpr size_t D = std::dynamic_extent; // Sanity check that one static to dynamic conversion works static_assert(std::is_constructible_v, std::extents>, ""); static_assert(std::is_convertible_v, std::extents>, ""); // Check that dynamic to static conversion only works explicitly only static_assert(std::is_constructible_v, std::extents>, ""); static_assert(!std::is_convertible_v, std::extents>, ""); // Sanity check that one static to dynamic conversion works static_assert(std::is_constructible_v, std::extents>, ""); static_assert(std::is_convertible_v, std::extents>, ""); // Check that dynamic to static conversion only works explicitly only static_assert(std::is_constructible_v, std::extents>, ""); static_assert(!std::is_convertible_v, std::extents>, ""); // Sanity check that smaller index_type to larger index_type conversion works static_assert(std::is_constructible_v, std::extents>, ""); static_assert(std::is_convertible_v, std::extents>, ""); // Check that larger index_type to smaller index_type conversion works explicitly only static_assert(std::is_constructible_v, std::extents>, ""); static_assert(!std::is_convertible_v, std::extents>, ""); } constexpr void test_rank_mismatch() { constexpr size_t D = std::dynamic_extent; static_assert(!std::is_constructible_v, std::extents>, ""); static_assert(!std::is_constructible_v, std::extents>, ""); static_assert(!std::is_constructible_v, std::extents>, ""); static_assert(!std::is_constructible_v, std::extents>, ""); } constexpr void test_static_extent_mismatch() { constexpr size_t D = std::dynamic_extent; static_assert(!std::is_constructible_v, std::extents>, ""); static_assert(!std::is_constructible_v, std::extents>, ""); static_assert(!std::is_constructible_v, std::extents>, ""); } constexpr bool test() { test_conversion(); test_conversion(); test_conversion(); test_conversion(); test_no_implicit_conversion(); test_rank_mismatch(); test_static_extent_mismatch(); return true; } int main(int, char**) { test(); static_assert(test()); return 0; }