1
+ #include < vector>
2
+
3
+ /* Helper functions */
4
+ std::vector<int > getData () { return {1 , 2 , 3 }; }
5
+ std::vector<int > processData (const std::vector<int > &input) { return input; }
6
+ std::vector<int > getContainer () { return {4 , 5 , 6 }; }
7
+
8
+ class MyContainer {
9
+ public:
10
+ MyContainer () = default ;
11
+ MyContainer (std::vector<int > data) : data_(data) {}
12
+ std::vector<int >::iterator begin () { return data_.begin (); }
13
+ std::vector<int >::iterator end () { return data_.end (); }
14
+
15
+ private:
16
+ std::vector<int > data_{7 , 8 , 9 };
17
+ };
18
+
19
+ class ConvertibleToVector {
20
+ public:
21
+ operator std::vector<int >() const { return {}; }
22
+ std::array<int , 3 >::iterator begin () { return data_.begin (); }
23
+ std::array<int , 3 >::iterator end () { return data_.end (); }
24
+
25
+ private:
26
+ std::array<int , 3 > data_{7 , 8 , 9 };
27
+ };
28
+
29
+ std::vector<int > operator +(const std::vector<int > &a,
30
+ const std::vector<int > &b) {
31
+ std::vector<int > result = a;
32
+ result.insert (result.end (), b.begin (), b.end ());
33
+ return result;
34
+ }
35
+
36
+ std::vector<int > convertToIntVector (std::vector<int > vector) { return vector; }
37
+
38
+ int main () {
39
+ std::vector<int > localVec = {1 , 2 , 3 };
40
+ std::vector<int > *vecPtr = &localVec;
41
+ ConvertibleToVector convertible;
42
+
43
+ /* ========== 1. EXPLICIT FUNCTION CALLS ========== */
44
+
45
+ for (auto x : getContainer ()) { // COMPLIANT: 1 function call only
46
+ }
47
+
48
+ for (auto x : processData (getData ())) { // NON_COMPLIANT: 2 function calls
49
+ }
50
+
51
+ /* ========== 2. OBJECT CREATION (CONSTRUCTOR CALLS) ========== */
52
+
53
+ for (auto x :
54
+ std::vector<int >{1 , 2 , 3 }) { // COMPLIANT: 1 constructor call only
55
+ }
56
+
57
+ for (auto x : MyContainer ()) { // COMPLIANT: 1 constructor call only
58
+ }
59
+
60
+ for (auto x : std::string (" hello" )) { // COMPLIANT: 1 constructor call only
61
+ }
62
+
63
+ for (auto x : std::vector<int >(
64
+ getData ())) { // NON-COMPLIANT: 1 constructor + 1 function call
65
+ }
66
+
67
+ for (auto x : MyContainer (processData (
68
+ localVec))) { // NON-COMPLIANT: 1 constructor + 1 function call
69
+ }
70
+
71
+ auto data = std::vector<int >(getData ());
72
+ for (auto x : data) { // NON-COMPLIANT: 1 constructor + 1 function call
73
+ }
74
+
75
+ MyContainer myContainer = MyContainer (processData (localVec));
76
+ for (auto x : myContainer) { // NON-COMPLIANT: 1 constructor + 1 function call
77
+ }
78
+
79
+ /* ========== 3. OPERATOR OVERLOADING ========== */
80
+
81
+ std::vector<int > anotherVec = {4 , 5 , 6 };
82
+ for (auto x : localVec + anotherVec) { // COMPLIANT: 1 operator+ call only
83
+ }
84
+
85
+ std::vector<int > vec1 = {1 }, vec2 = {2 }, vec3 = {3 };
86
+ for (auto x : (vec1 + vec2) + vec3) { // NON-COMPLIANT: 2 operator+ calls
87
+ }
88
+
89
+ for (auto x :
90
+ getData () +
91
+ processData (
92
+ localVec)) { // NON-COMPLIANT: 2 function calls + 1 operator call
93
+ }
94
+
95
+ std::vector<int > vec1 = {1 }, vec2 = {2 }, vec3 = {3 };
96
+ std::vector<int > appendedVector = (vec1 + vec2) + vec3;
97
+ for (auto x : appendedVector) { // COMPLIANT: 0 calls
98
+ }
99
+
100
+ std::vector<int > appendedVector2 = getData () + processData (localVec);
101
+ for (auto x : appendedVector2) { // COMPLIANT: 0 calls
102
+ }
103
+
104
+ /* ========== 4. IMPLICIT CONVERSIONS ========== */
105
+
106
+ ConvertibleToVector convertible;
107
+ for (auto x : convertible) { // COMPLIANT: 1 conversion operator call only
108
+ }
109
+
110
+ for (auto x :
111
+ convertToIntVector (convertible)) { // NON_COMPLIANT: 1 function call + 1
112
+ // conversion operator call
113
+ }
114
+
115
+ for (auto x :
116
+ convertToIntVector (convertible)) { // NON_COMPLIANT: 1 function call + 1
117
+ // conversion operator call
118
+ }
119
+
120
+ std::vector<int > intVector1 = convertToIntVector (convertible);
121
+ for (auto x : intVector1) { // NON_COMPLIANT: 1 function call + 1
122
+ // conversion operator call
123
+ }
124
+
125
+ std::vector<int > intVector2 = convertToIntVector (convertible);
126
+ for (auto x : intVector2) { // NON_COMPLIANT: 1 function call + 1
127
+ // conversion operator call
128
+ }
129
+ }
0 commit comments