1 | // RUN: %check_clang_tidy %s modernize-use-emplace %t -- \ |
2 | // RUN: -config="{CheckOptions: \ |
3 | // RUN: {modernize-use-emplace.IgnoreImplicitConstructors: \ |
4 | // RUN: true}}" |
5 | |
6 | namespace std { |
7 | template <typename E> |
8 | class initializer_list |
9 | { |
10 | public: |
11 | const E *a, *b; |
12 | initializer_list() noexcept {} |
13 | }; |
14 | |
15 | template <typename T> |
16 | class vector { |
17 | public: |
18 | vector() = default; |
19 | vector(initializer_list<T>) {} |
20 | |
21 | void push_back(const T &) {} |
22 | void push_back(T &&) {} |
23 | |
24 | template <typename... Args> |
25 | void emplace_back(Args &&... args){}; |
26 | ~vector(); |
27 | }; |
28 | |
29 | } // namespace std |
30 | |
31 | void testInts() { |
32 | std::vector<int> v; |
33 | v.push_back(42); |
34 | v.push_back(int(42)); |
35 | v.push_back(int{42}); |
36 | v.push_back(42.0); |
37 | int z; |
38 | v.push_back(z); |
39 | } |
40 | |
41 | struct Something { |
42 | Something(int a, int b = 41) {} |
43 | Something() {} |
44 | void push_back(Something); |
45 | int getInt() { return 42; } |
46 | }; |
47 | |
48 | struct Convertable { |
49 | operator Something() { return Something{}; } |
50 | }; |
51 | |
52 | struct Zoz { |
53 | Zoz(Something, int = 42) {} |
54 | }; |
55 | |
56 | Zoz getZoz(Something s) { return Zoz(s); } |
57 | |
58 | void test_Something() { |
59 | std::vector<Something> v; |
60 | |
61 | v.push_back(Something(1, 2)); |
62 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back instead of push_back [modernize-use-emplace] |
63 | // CHECK-FIXES: v.emplace_back(1, 2); |
64 | |
65 | v.push_back(Something{1, 2}); |
66 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
67 | // CHECK-FIXES: v.emplace_back(1, 2); |
68 | |
69 | v.push_back(Something()); |
70 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
71 | // CHECK-FIXES: v.emplace_back(); |
72 | |
73 | v.push_back(Something{}); |
74 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
75 | // CHECK-FIXES: v.emplace_back(); |
76 | |
77 | Something Different; |
78 | v.push_back(Something(Different.getInt(), 42)); |
79 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
80 | // CHECK-FIXES: v.emplace_back(Different.getInt(), 42); |
81 | |
82 | v.push_back(Different.getInt()); |
83 | v.push_back(42); |
84 | |
85 | Something temporary(42, 42); |
86 | temporary.push_back(temporary); |
87 | v.push_back(temporary); |
88 | |
89 | v.push_back(Convertable()); |
90 | v.push_back(Convertable{}); |
91 | Convertable s; |
92 | v.push_back(s); |
93 | } |
94 | |
95 | template <typename ElemType> |
96 | void dependOnElem() { |
97 | std::vector<ElemType> v; |
98 | v.push_back(ElemType(42)); |
99 | } |
100 | |
101 | template <typename ContainerType> |
102 | void dependOnContainer() { |
103 | ContainerType v; |
104 | v.push_back(Something(42)); |
105 | } |
106 | |
107 | void callDependent() { |
108 | dependOnElem<Something>(); |
109 | dependOnContainer<std::vector<Something>>(); |
110 | } |
111 | |
112 | void test2() { |
113 | std::vector<Zoz> v; |
114 | v.push_back(Zoz(Something(21, 37))); |
115 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
116 | // CHECK-FIXES: v.emplace_back(Something(21, 37)); |
117 | |
118 | v.push_back(Zoz(Something(21, 37), 42)); |
119 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back |
120 | // CHECK-FIXES: v.emplace_back(Something(21, 37), 42); |
121 | |
122 | v.push_back(getZoz(s: Something(1, 2))); |
123 | } |
124 | |