blob: 8cef0cb4e0698e5a881e47f43280e77afb52fdd1 [file] [log] [blame]
// constructor_tests.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// 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)
//
// For more information, see www.boost.org
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/bind.hpp"
#include "boost/lambda/construct.hpp"
#include <iostream>
#include <algorithm>
#include <vector>
#ifdef BOOST_MSVC
#pragma warning(disable:4512)
#endif
using namespace boost::lambda;
namespace bl = boost::lambda;
template<class T>
bool check_tuple(int n, const T& t)
{
return (t.get_head() == n) && check_tuple(n+1, t.get_tail());
}
template <>
bool check_tuple(int /*n*/, const null_type& ) { return true; }
void constructor_all_lengths()
{
bool ok;
ok = check_tuple(
1,
bind(constructor<tuple<int> >(),
1)()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int> >(),
1, 2)()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int> >(),
1, 2, 3)()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int> >(),
1, 2, 3, 4)()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int, int> >(),
1, 2, 3, 4, 5)()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6)()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6, 7)()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6, 7, 8)()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6, 7, 8, 9)()
);
BOOST_CHECK(ok);
}
void new_ptr_all_lengths()
{
bool ok;
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int> >(),
1))()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int> >(),
1, 2))()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int> >(),
1, 2, 3))()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int> >(),
1, 2, 3, 4))()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int, int> >(),
1, 2, 3, 4, 5))()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6))()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6, 7))()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6, 7, 8))()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6, 7, 8, 9))()
);
BOOST_CHECK(ok);
}
class is_destructor_called {
bool& b;
public:
is_destructor_called(bool& bb) : b(bb) { b = false; }
~is_destructor_called() { b = true; }
};
void test_destructor ()
{
char space[sizeof(is_destructor_called)];
bool flag = false;
is_destructor_called* idc = new(space) is_destructor_called(flag);
BOOST_CHECK(flag == false);
bind(destructor(), _1)(idc);
BOOST_CHECK(flag == true);
idc = new(space) is_destructor_called(flag);
BOOST_CHECK(flag == false);
bind(destructor(), _1)(*idc);
BOOST_CHECK(flag == true);
}
class count_deletes {
public:
static int count;
~count_deletes() { ++count; }
};
int count_deletes::count = 0;
void test_news_and_deletes ()
{
int* i[10];
std::for_each(i, i+10, _1 = bind(new_ptr<int>(), 2));
int count_errors = 0;
std::for_each(i, i+10, (*_1 == 2) || ++var(count_errors));
BOOST_CHECK(count_errors == 0);
count_deletes* ct[10];
std::for_each(ct, ct+10, _1 = bind(new_ptr<count_deletes>()));
count_deletes::count = 0;
std::for_each(ct, ct+10, bind(delete_ptr(), _1));
BOOST_CHECK(count_deletes::count == 10);
}
void test_array_new_and_delete()
{
count_deletes* c;
(_1 = bind(new_array<count_deletes>(), 5))(c);
count_deletes::count = 0;
bind(delete_array(), _1)(c);
BOOST_CHECK(count_deletes::count == 5);
}
void delayed_construction()
{
std::vector<int> x(3);
std::vector<int> y(3);
std::fill(x.begin(), x.end(), 0);
std::fill(y.begin(), y.end(), 1);
std::vector<std::pair<int, int> > v;
std::transform(x.begin(), x.end(), y.begin(), std::back_inserter(v),
bl::bind(constructor<std::pair<int, int> >(), _1, _2) );
}
int test_main(int, char *[]) {
constructor_all_lengths();
new_ptr_all_lengths();
delayed_construction();
test_destructor();
test_news_and_deletes();
test_array_new_and_delete();
return 0;
}