how_subcases_work.cpp (2563B)
1 /* THE OUTPUT IS: 2 3 creating empty vector 4 + 2 5 == size: 2 6 + 2 7 == size: 4 8 9 creating empty vector 10 + 2 11 == size: 2 12 + 1 13 == size: 3 14 15 creating empty vector 16 + 1 17 == size: 1 18 19 */ 20 21 #include <iostream> 22 #include <vector> 23 #include <set> 24 25 using namespace std; 26 27 set<pair<const char*, int> > passed_subcases; 28 set<int> entered_levels; 29 int current_level; 30 bool has_skipped; 31 32 struct Subcase { 33 Subcase(const char* file, int line) 34 : m_entered(false) 35 , m_file(file) 36 , m_line(line) 37 { 38 m_entered = false; 39 40 // if we have already completed it 41 if(passed_subcases.count(pair<const char*, int>(file, line)) != 0) 42 return; 43 44 // if a Subcase on the same level has already been entered 45 if(entered_levels.count(current_level) != 0) { 46 has_skipped = true; 47 return; 48 } 49 50 entered_levels.insert(current_level++); 51 52 m_entered = true; 53 } 54 55 ~Subcase() { 56 if(m_entered) { 57 current_level--; 58 // only mark the subcase as passed if no subcases have been skipped 59 if(has_skipped == false) 60 passed_subcases.insert(pair<const char*, int>(m_file, m_line)); 61 } 62 } 63 64 operator bool() const { return m_entered; } 65 66 bool m_entered; 67 const char* m_file; 68 int m_line; 69 }; 70 71 #define STR_CONCAT_IMPL(s1, s2) s1##s2 72 #define STR_CONCAT(s1, s2) STR_CONCAT_IMPL(s1, s2) 73 #define ANON_VAR STR_CONCAT(anon, __LINE__) 74 75 #define subcase(title) if(const Subcase& ANON_VAR = Subcase(__FILE__, __LINE__)) 76 77 void test() { 78 cout << endl << "creating empty vector" << endl; 79 vector<int> data; 80 81 subcase("size should grow to 2") { 82 cout << "+ 2" << endl; 83 data.push_back(42); 84 data.push_back(10); 85 cout << "== size: " << data.size() << endl; 86 87 subcase("size should grow to 4") { 88 cout << "+ 2" << endl; 89 data.push_back(666); 90 data.push_back(100); 91 cout << "== size: " << data.size() << endl; 92 } 93 subcase("size should grow to 3") { 94 cout << "+ 1" << endl; 95 data.push_back(666); 96 cout << "== size: " << data.size() << endl; 97 } 98 } 99 subcase("size should grow to 1") { 100 cout << "+ 1" << endl; 101 data.push_back(42); 102 cout << "== size: " << data.size() << endl; 103 } 104 } 105 106 int main() { 107 passed_subcases.clear(); 108 do { 109 has_skipped = false; 110 current_level = 0; 111 entered_levels.clear(); 112 test(); 113 } while(has_skipped == true); 114 115 return 0; 116 }