blob: 629e0073aa565da2f8d111bff343dd20c2519837 [file] [log] [blame]
// Copyright Alexander Nasonov 2007-2008
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <iostream>
#include <ostream>
#include <string>
#include <boost/scope_exit.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/typeof/std/string.hpp>
#include <boost/test/unit_test.hpp>
using namespace boost::unit_test;
std::string g_str;
template<int Dummy = 0>
struct Holder
{
static long g_long;
};
template<int Dummy> long Holder<Dummy>::g_long;
void test_non_local()
{
// ... and one local variable as well:
int i = 0;
BOOST_SCOPE_EXIT( (i) )
{
BOOST_CHECK(i == 0);
BOOST_CHECK(Holder<>::g_long == 3);
BOOST_CHECK(g_str == "try: g_str");
} BOOST_SCOPE_EXIT_END
BOOST_SCOPE_EXIT( (&i) )
{
BOOST_CHECK(i == 3);
BOOST_CHECK(Holder<>::g_long == 3);
BOOST_CHECK(g_str == "try: g_str");
} BOOST_SCOPE_EXIT_END
{
g_str = "";
Holder<>::g_long = 1;
BOOST_SCOPE_EXIT( (&i) )
{
i = 1;
g_str = "g_str";
} BOOST_SCOPE_EXIT_END
BOOST_SCOPE_EXIT( (&i) )
{
try
{
i = 2;
Holder<>::g_long = 2;
throw 0;
} catch(...) {}
} BOOST_SCOPE_EXIT_END
BOOST_CHECK(i == 0);
BOOST_CHECK(g_str == "");
BOOST_CHECK(Holder<>::g_long == 1);
}
BOOST_CHECK(Holder<>::g_long == 2);
BOOST_CHECK(g_str == "g_str");
BOOST_CHECK(i == 1); // Check that first declared is executed last
BOOST_SCOPE_EXIT( (&i) )
{
BOOST_CHECK(i == 3);
BOOST_CHECK(Holder<>::g_long == 3);
BOOST_CHECK(g_str == "try: g_str");
} BOOST_SCOPE_EXIT_END
BOOST_SCOPE_EXIT( (i) )
{
BOOST_CHECK(i == 1);
BOOST_CHECK(Holder<>::g_long == 3);
BOOST_CHECK(g_str == "try: g_str");
} BOOST_SCOPE_EXIT_END
try
{
BOOST_SCOPE_EXIT( (&i) )
{
i = 3;
g_str = "try: g_str";
} BOOST_SCOPE_EXIT_END
BOOST_SCOPE_EXIT( (&i) )
{
i = 4;
Holder<>::g_long = 3;
} BOOST_SCOPE_EXIT_END
BOOST_CHECK(i == 1);
BOOST_CHECK(g_str == "g_str");
BOOST_CHECK(Holder<>::g_long == 2);
throw 0;
}
catch(int)
{
BOOST_CHECK(Holder<>::g_long == 3);
BOOST_CHECK(g_str == "try: g_str");
BOOST_CHECK(i == 3); // Check that first declared is executed last
}
}
bool foo()
{
return true;
}
void test_types()
{
bool (*pf)() = 0;
bool (&rf)() = foo;
bool results[2] = {};
{
BOOST_SCOPE_EXIT( (&results)(&pf)(&rf) )
{
results[0] = pf();
results[1] = rf();
}
BOOST_SCOPE_EXIT_END
pf = &foo;
BOOST_CHECK(results[0] == false);
BOOST_CHECK(results[1] == false);
}
BOOST_CHECK(results[0] == true);
BOOST_CHECK(results[1] == true);
{
BOOST_SCOPE_EXIT( (&results)(pf) )
{
results[0] = !pf();
results[1] = !pf();
}
BOOST_SCOPE_EXIT_END
pf = 0;
BOOST_CHECK(results[0] == true);
BOOST_CHECK(results[1] == true);
}
BOOST_CHECK(results[0] == false);
BOOST_CHECK(results[1] == false);
}
test_suite* init_unit_test_suite( int, char* [] )
{
framework::master_test_suite().p_name.value = "Unit test for ScopeExit";
framework::master_test_suite().add( BOOST_TEST_CASE( &test_non_local ));
framework::master_test_suite().add( BOOST_TEST_CASE( &test_types ));
return 0;
}