1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10
11 // Test that the "mandates" requirements on the given container are checked correctly using `static_assert`.
12
13 #include <ranges>
14 #include <vector>
15
16 template <bool HasDefaultCtr = true, bool HasSingleArgCtr = true,
17 bool HasInsert = true, bool HasInsertWithRightSignature = true,
18 bool HasPushBack = true, bool HasPushBackWithRightSignature = true>
19 struct Container {
20 using value_type = int;
21
beginContainer22 int* begin() const { return nullptr; }
endContainer23 int* end() const { return nullptr; }
24
25 Container()
26 requires HasDefaultCtr = default;
27
ContainerContainer28 Container(int)
29 requires HasSingleArgCtr {
30 }
31
insertContainer32 int* insert(int*, int)
33 requires (HasInsert && HasInsertWithRightSignature) {
34 return nullptr;
35 }
36
insertContainer37 int* insert()
38 requires (HasInsert && !HasInsertWithRightSignature) {
39 return nullptr;
40 }
41
push_backContainer42 void push_back(int)
43 requires (HasPushBack && HasPushBackWithRightSignature) {
44 }
45
push_backContainer46 void push_back()
47 requires (HasPushBack && !HasPushBackWithRightSignature) {
48 }
49
50 };
51
test()52 void test() {
53 using R = std::vector<int>;
54 R in = {1, 2, 3};
55
56 // Case 4 -- default-construct (or construct from the extra arguments) and insert.
57 { // All constraints satisfied.
58 using C = Container<>;
59 (void)std::ranges::to<C>(in);
60 (void)std::ranges::to<C>(in, 1);
61 (void)std::ranges::to<C>(in, 1.0);
62 }
63
64 { // No default constructor.
65 using C = Container</*HasDefaultCtr=*/false>;
66 (void)std::ranges::to<C>(in); //expected-error-re@*:* {{static assertion failed{{.*}}ranges::to: unable to convert to the given container type}}
67 }
68
69 { // No single-argument constructor.
70 using C = Container</*HasDefaultCtr=*/true, /*HasSingleArgCtr=*/false>;
71 (void)std::ranges::to<C>(in, 1); //expected-error-re@*:* {{static assertion failed{{.*}}ranges::to: unable to convert to the given container type}}
72 }
73
74 { // No `insert` and no `push_back`.
75 using C = Container</*HasDefaultCtr=*/true, /*HasSingleArgCtr=*/true,
76 /*HasInsert=*/false, /*HasInsertWithRightSignature=*/false,
77 /*HasPushBack=*/false, /*HasPushBackWithRightSignature=*/false>;
78 (void)std::ranges::to<C>(in); //expected-error-re@*:* {{static assertion failed{{.*}}ranges::to: unable to convert to the given container type}}
79 }
80
81 { // No `push_back`, `insert` has a wrong signature.
82 using C = Container</*HasDefaultCtr=*/true, /*HasSingleArgCtr=*/true,
83 /*HasInsert=*/true, /*HasInsertWithRightSignature=*/false,
84 /*HasPushBack=*/false, /*HasPushBackWithRightSignature=*/false>;
85 (void)std::ranges::to<C>(in); //expected-error-re@*:* {{static assertion failed{{.*}}ranges::to: unable to convert to the given container type}}
86 }
87
88 { // No `insert`, `push_back` has a wrong signature.
89 using C = Container</*HasDefaultCtr=*/true, /*HasSingleArgCtr=*/true,
90 /*HasInsert=*/false, /*HasInsertWithRightSignature=*/false,
91 /*HasPushBack=*/true, /*HasPushBackWithRightSignature=*/false>;
92 (void)std::ranges::to<C>(in); //expected-error-re@*:* {{static assertion failed{{.*}}ranges::to: unable to convert to the given container type}}
93 }
94 }
95