//===----------------------------------------------------------------------===// // // 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 // // constexpr explicit(extent != dynamic_extent) span(std::initializer_list il); // Since C++26 #include #include #include #include #include #include #include "test_convertible.h" #include "test_macros.h" #if TEST_STD_VER >= 26 // SFINAE template concept ConstElementType = std::is_const_v; static_assert(ConstElementType>); static_assert(!ConstElementType>); static_assert(ConstElementType>); static_assert(!ConstElementType>); // Constructor constraings template concept HasInitializerListCtr = requires(I il) { std::span{il}; }; static_assert(HasInitializerListCtr, const int>); static_assert(!HasInitializerListCtr, int>); static_assert(HasInitializerListCtr, const int, 94>); static_assert(!HasInitializerListCtr, int, 94>); // Constructor conditionally explicit static_assert(!test_convertible, std::initializer_list>(), "This constructor must be explicit"); static_assert(std::is_constructible_v, std::initializer_list>); static_assert(test_convertible, std::initializer_list>(), "This constructor must not be explicit"); static_assert(std::is_constructible_v, std::initializer_list>); #endif struct Sink { constexpr Sink() = default; constexpr Sink(Sink*) {} }; constexpr std::size_t count(std::span sp) { return sp.size(); } template constexpr std::size_t count_n(std::span sp) { return sp.size(); } constexpr bool test() { #if TEST_STD_VER >= 26 // Dynamic extent { Sink a[10]; assert(count({a}) == 1); assert(count({a, a + 10}) == 2); assert(count({a, a + 1, a + 2}) == 3); assert(count(std::initializer_list{a[0], a[1], a[2], a[3]}) == 4); } #else { Sink a[10]; assert(count({a}) == 10); assert(count({a, a + 10}) == 10); assert(count_n<10>({a}) == 10); } #endif return true; } // Test P2447R4 "Annex C examples" constexpr int three(std::span sp) { return static_cast(sp.size()); } constexpr int four(std::span sp) { return static_cast(sp.size()); } bool test_P2447R4_annex_c_examples() { // 1. Overload resolution is affected // --> tested in "initializer_list.verify.cpp" // 2. The `initializer_list` ctor has high precedence // --> tested in "initializer_list.verify.cpp" // 3. Implicit two-argument construction with a highly convertible value_type #if TEST_STD_VER >= 26 { void* a[10]; assert(three({a, 0}) == 2); } { std::any a[10]; assert(four({a, a + 10}) == 2); } #else { void* a[10]; assert(three({a, 0}) == 0); } { std::any a[10]; assert(four({a, a + 10}) == 10); } #endif return true; } int main(int, char**) { assert(test()); static_assert(test()); assert(test_P2447R4_annex_c_examples()); return 0; }