1 2 // Copyright (C) 2006-2009, 2012 Alexander Nasonov 3 // Copyright (C) 2012 Lorenzo Caminiti 4 // Distributed under the Boost Software License, Version 1.0 5 // (see accompanying file LICENSE_1_0.txt or a copy at 6 // http://www.boost.org/LICENSE_1_0.txt) 7 // Home at http://www.boost.org/libs/scope_exit 8 9 #include <boost/scope_exit.hpp> 10 #include <boost/config.hpp> 11 #include <boost/typeof/typeof.hpp> 12 #include <boost/typeof/std/string.hpp> 13 #include <boost/detail/lightweight_test.hpp> 14 #include <iostream> 15 #include <ostream> 16 #include <string> 17 18 std::string g_str; 19 20 template<int Dummy = 0> 21 struct Holder { 22 static long g_long; 23 }; 24 25 template<int Dummy> long Holder<Dummy>::g_long; 26 test_non_local(void)27void test_non_local(void) { 28 // ... and one local variable as well: 29 int i = 0; 30 31 BOOST_SCOPE_EXIT(void) { 32 BOOST_TEST(Holder<>::g_long == 3); 33 } BOOST_SCOPE_EXIT_END 34 35 BOOST_SCOPE_EXIT( (i) ) { 36 BOOST_TEST(i == 0); 37 BOOST_TEST(Holder<>::g_long == 3); 38 BOOST_TEST(g_str == "try: g_str"); 39 } BOOST_SCOPE_EXIT_END 40 41 BOOST_SCOPE_EXIT( (&i) ) { 42 BOOST_TEST(i == 3); 43 BOOST_TEST(Holder<>::g_long == 3); 44 BOOST_TEST(g_str == "try: g_str"); 45 } BOOST_SCOPE_EXIT_END 46 47 { 48 g_str = ""; 49 Holder<>::g_long = 1; 50 51 BOOST_SCOPE_EXIT( (&i) ) { 52 i = 1; 53 g_str = "g_str"; 54 } BOOST_SCOPE_EXIT_END 55 56 BOOST_SCOPE_EXIT( (&i) ) { 57 try { 58 i = 2; 59 Holder<>::g_long = 2; 60 throw 0; 61 } catch(...) {} 62 } BOOST_SCOPE_EXIT_END 63 64 BOOST_TEST(i == 0); 65 BOOST_TEST(g_str == ""); 66 BOOST_TEST(Holder<>::g_long == 1); 67 } 68 69 BOOST_TEST(Holder<>::g_long == 2); 70 BOOST_TEST(g_str == "g_str"); 71 BOOST_TEST(i == 1); // Check that first declared is executed last. 72 73 BOOST_SCOPE_EXIT( (&i) ) { 74 BOOST_TEST(i == 3); 75 BOOST_TEST(Holder<>::g_long == 3); 76 BOOST_TEST(g_str == "try: g_str"); 77 } BOOST_SCOPE_EXIT_END 78 79 BOOST_SCOPE_EXIT( (i) ) { 80 BOOST_TEST(i == 1); 81 BOOST_TEST(Holder<>::g_long == 3); 82 BOOST_TEST(g_str == "try: g_str"); 83 } BOOST_SCOPE_EXIT_END 84 85 try { 86 BOOST_SCOPE_EXIT( (&i) ) { 87 i = 3; 88 g_str = "try: g_str"; 89 } BOOST_SCOPE_EXIT_END 90 91 BOOST_SCOPE_EXIT( (&i) ) { 92 i = 4; 93 Holder<>::g_long = 3; 94 } BOOST_SCOPE_EXIT_END 95 96 BOOST_TEST(i == 1); 97 BOOST_TEST(g_str == "g_str"); 98 BOOST_TEST(Holder<>::g_long == 2); 99 100 throw 0; 101 } catch(int) { 102 BOOST_TEST(Holder<>::g_long == 3); 103 BOOST_TEST(g_str == "try: g_str"); 104 BOOST_TEST(i == 3); // Check that first declared is executed last. 105 } 106 } 107 foo(void)108bool foo(void) { return true; } 109 foo2(void)110bool foo2(void) { return false; } 111 test_types(void)112void test_types(void) { 113 bool (*pf)(void) = 0; 114 bool (&rf)(void) = foo; 115 bool results[2] = {}; 116 117 { 118 BOOST_SCOPE_EXIT( (&results) (&pf) (&rf) ) { 119 results[0] = pf(); 120 results[1] = rf(); 121 } 122 BOOST_SCOPE_EXIT_END 123 124 pf = &foo; 125 126 BOOST_TEST(results[0] == false); 127 BOOST_TEST(results[1] == false); 128 } 129 130 BOOST_TEST(results[0] == true); 131 BOOST_TEST(results[1] == true); 132 133 { 134 BOOST_SCOPE_EXIT( (&results) (pf) ) { 135 results[0] = !pf(); 136 results[1] = !pf(); 137 pf = &foo2; // modify a copy 138 } 139 BOOST_SCOPE_EXIT_END 140 141 pf = 0; 142 143 BOOST_TEST(results[0] == true); 144 BOOST_TEST(results[1] == true); 145 } 146 147 BOOST_TEST(pf == 0); 148 BOOST_TEST(results[0] == false); 149 BOOST_TEST(results[1] == false); 150 } 151 test_capture_all(void)152void test_capture_all(void) { 153 #ifndef BOOST_NO_CXX11_LAMBDAS 154 int i = 0, j = 1; 155 156 { 157 BOOST_SCOPE_EXIT_ALL(=) { 158 i = j = 1; // modify copies 159 }; 160 } 161 BOOST_TEST(i == 0); 162 BOOST_TEST(j == 1); 163 164 { 165 BOOST_SCOPE_EXIT_ALL(&) { 166 i = 1; 167 j = 2; 168 }; 169 BOOST_TEST(i == 0); 170 BOOST_TEST(j == 1); 171 } 172 BOOST_TEST(i == 1); 173 BOOST_TEST(j == 2); 174 175 { 176 BOOST_SCOPE_EXIT_ALL(=, &j) { 177 i = 2; // modify a copy 178 j = 3; 179 }; 180 BOOST_TEST(i == 1); 181 BOOST_TEST(j == 2); 182 } 183 BOOST_TEST(i == 1); 184 BOOST_TEST(j == 3); 185 #endif // lambdas 186 } 187 main(void)188int main(void) { 189 test_non_local(); 190 test_types(); 191 test_capture_all(); 192 return boost::report_errors(); 193 } 194 195