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