]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/24_iterators/range_operations/100768.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 24_iterators / range_operations / 100768.cc
CommitLineData
a945c346 1// Copyright (C) 2021-2024 Free Software Foundation, Inc.
a49a045b
JW
2//
3// This file is part of the GNU ISO C++ Library. This library is free
4// software; you can redistribute it and/or modify it under the
5// terms of the GNU General Public License as published by the
6// Free Software Foundation; either version 3, or (at your option)
7// any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License along
15// with this library; see the file COPYING3. If not see
16// <http://www.gnu.org/licenses/>.
17
a49a045b
JW
18// { dg-do compile { target c++20 } }
19
20// PR libstdc++/100768 - Range iterator operations should be function objects
21
22#include <iterator>
23#include <ranges>
24
25namespace ns1
26{
27 struct R { };
28 void check_adl(R) { }
29}
30
31namespace ns2
32{
33 using ns1::R;
34
35 struct A { };
36
37 template<typename I>
38 R advance(I, ...) { return R{}; }
39
40 template<typename I>
41 R distance(I, ...) { return R{}; }
42
43 template<typename I>
44 R next(I, ...) { return R{}; }
45
46 template<typename I>
47 R prev(I, ...) { return R{}; }
48}
49
50template<typename T, typename U> struct associated { };
51
52void
53test02()
54{
55 // This type has both ns2 and std::ranges as associated namespaces.
56 using X = associated<ns2::A, std::ranges::dangling>;
57
58 X range[1];
59 X* iter = range;
60 X* const sentinel = iter + 1;
61
62 // [range.iter.op.general] p2 says: "The function templates defined in
63 // [range.iter.ops] are not found by argument-dependent name lookup."
64 //
65 // If we do not meet that requirement then the following will find those
66 // function templates (because std::ranges is an associated namespace),
67 // and the calls to check_adl will be ill-formed.
68 check_adl( advance(iter, 1) );
69 check_adl( advance(iter, 1, sentinel) );
70 check_adl( distance(iter, sentinel) );
71 check_adl( distance(range) );
72 check_adl( next(iter) );
73 check_adl( next(iter, 1) );
74 check_adl( next(iter, sentinel) );
75 check_adl( next(iter, 1, sentinel) );
76 check_adl( prev(iter) );
77 check_adl( prev(iter, 1) );
78 check_adl( prev(iter, 1, sentinel) );
79}
80
81namespace ns3
82{
83 struct A { };
84
85 void advance(A*, int) = delete;
86 void advance(A*, int, A*) = delete;
87
88 void distance(A*, A*) = delete;
89 void distance(A(&)[1]) = delete;
90
91 void next(A*) = delete;
92 void next(A*, int) = delete;
93 void next(A*, A*) = delete;
94 void next(A*, int, A*) = delete;
95
96 void prev(A*) = delete;
97 void prev(A*, int) = delete;
98 void prev(A*, int, A*) = delete;
99}
100
101void
102test01()
103{
104 ns3::A range[1];
105 ns3::A* iter = range;
106 ns3::A* const sentinel = iter + 1;
107
108 // [range.iter.op.general] p2 also says: "When found by unqualified name
109 // lookup for the postfix-expression in a function call, they inhibit
110 // argument-dependent name lookup."
111 //
112 // If we do not meet that requirement then the following will find the
113 // deleted overloads in namespace ns3 (because it is an associated namespace
114 // and those functions are exact matches for the arguments).
115 using namespace std::ranges;
240b01b0
JW
116 (void) advance(iter, 1);
117 (void) advance(iter, 3, sentinel);
118 (void) distance(iter, sentinel);
119 (void) distance(range);
120 (void) next(iter);
121 (void) next(iter, -1);
122 (void) next(iter, sentinel);
123 (void) next(iter, 5, sentinel);
124 (void) prev(iter);
125 (void) prev(iter, 0);
126 (void) prev(iter, 0, sentinel);
a49a045b 127}