// { dg-do run { target c++23 } } #include #if __cpp_lib_containers_ranges != 202202L # error "Feature-test macro __cpp_lib_containers_ranges has wrong value in " #endif #include #include #include #include void test_deduction_guide(char* p) { __gnu_test::test_input_range r(nullptr, nullptr); std::basic_string v(std::from_range, r); static_assert(std::is_same_v); using Alloc = __gnu_test::SimpleAllocator; Alloc alloc; std::basic_string v2(std::from_range, r, alloc); static_assert(std::is_same_v, Alloc>>); __gnu_test::test_input_range wr(nullptr, nullptr); std::basic_string w(std::from_range, wr); static_assert(std::is_same_v); using WAlloc = __gnu_test::SimpleAllocator; WAlloc walloc; std::basic_string w2(std::from_range, wr, walloc); static_assert(std::is_same_v, WAlloc>>); } template constexpr void do_test(Alloc alloc) { // The basic_string's value_type. using V = typename std::allocator_traits::value_type; using CT = std::char_traits; // The range's value_type. using T = std::ranges::range_value_t; T a[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}; auto eq = [](const std::basic_string& l, std::span r) { if (l.size() != r.size()) return false; for (auto i = 0u; i < l.size(); ++i) if (l[i] != r[i]) return false; return true; }; std::basic_string v0(std::from_range, Range(a, a+0)); VERIFY( v0.empty() ); VERIFY( v0.get_allocator() == Alloc() ); std::basic_string v4(std::from_range, Range(a, a+4)); VERIFY( eq(v4, {a, 4}) ); VERIFY( v4.get_allocator() == Alloc() ); std::basic_string v9(std::from_range, Range(a, a+9), alloc); VERIFY( eq(v9, {a, 9}) ); VERIFY( v9.get_allocator() == alloc ); std::basic_string v20(std::from_range, Range(a, a+20), alloc); VERIFY( eq(v20, {a, 20}) ); VERIFY( v20.get_allocator() == alloc ); } template constexpr void do_test_a() { do_test(std::allocator()); do_test(std::allocator()); if not consteval { do_test(__gnu_test::uneq_allocator(42)); do_test(__gnu_test::uneq_allocator(42)); } } constexpr bool test_ranges() { using namespace __gnu_test; do_test_a>(); do_test_a>(); do_test_a>(); do_test_a>(); do_test_a>(); do_test_a>(); do_test_a>(); do_test_a>(); do_test_a>(); // Not lvalue-convertible to char struct C { constexpr C(char v) : val(v) { } constexpr operator char() && { return val; } constexpr bool operator==(char b) const { return b == val; } char val; }; using rvalue_input_range = test_range; do_test(std::allocator()); return true; } int main() { test_ranges(); #if _GLIBCXX_USE_CXX11_ABI static_assert( test_ranges() ); #endif // _GLIBCXX_USE_CXX11_ABI }