commit 44ae5a9a800526d977f2c0cf5d65a9b3c7a2170d Author: Jaakko Järvi Date: Thu Nov 15 20:38:57 2001 +0000 lambda_development branch creation [SVN r11708] diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..3e84d7c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,96 @@ +* text=auto !eol svneol=native#text/plain +*.gitattributes text svneol=native#text/plain + +# Scriptish formats +*.bat text svneol=native#text/plain +*.bsh text svneol=native#text/x-beanshell +*.cgi text svneol=native#text/plain +*.cmd text svneol=native#text/plain +*.js text svneol=native#text/javascript +*.php text svneol=native#text/x-php +*.pl text svneol=native#text/x-perl +*.pm text svneol=native#text/x-perl +*.py text svneol=native#text/x-python +*.sh eol=lf svneol=LF#text/x-sh +configure eol=lf svneol=LF#text/x-sh + +# Image formats +*.bmp binary svneol=unset#image/bmp +*.gif binary svneol=unset#image/gif +*.ico binary svneol=unset#image/ico +*.jpeg binary svneol=unset#image/jpeg +*.jpg binary svneol=unset#image/jpeg +*.png binary svneol=unset#image/png +*.tif binary svneol=unset#image/tiff +*.tiff binary svneol=unset#image/tiff +*.svg text svneol=native#image/svg%2Bxml + +# Data formats +*.pdf binary svneol=unset#application/pdf +*.avi binary svneol=unset#video/avi +*.doc binary svneol=unset#application/msword +*.dsp text svneol=crlf#text/plain +*.dsw text svneol=crlf#text/plain +*.eps binary svneol=unset#application/postscript +*.gz binary svneol=unset#application/gzip +*.mov binary svneol=unset#video/quicktime +*.mp3 binary svneol=unset#audio/mpeg +*.ppt binary svneol=unset#application/vnd.ms-powerpoint +*.ps binary svneol=unset#application/postscript +*.psd binary svneol=unset#application/photoshop +*.rdf binary svneol=unset#text/rdf +*.rss text svneol=unset#text/xml +*.rtf binary svneol=unset#text/rtf +*.sln text svneol=native#text/plain +*.swf binary svneol=unset#application/x-shockwave-flash +*.tgz binary svneol=unset#application/gzip +*.vcproj text svneol=native#text/xml +*.vcxproj text svneol=native#text/xml +*.vsprops text svneol=native#text/xml +*.wav binary svneol=unset#audio/wav +*.xls binary svneol=unset#application/vnd.ms-excel +*.zip binary svneol=unset#application/zip + +# Text formats +.htaccess text svneol=native#text/plain +*.bbk text svneol=native#text/xml +*.cmake text svneol=native#text/plain +*.css text svneol=native#text/css +*.dtd text svneol=native#text/xml +*.htm text svneol=native#text/html +*.html text svneol=native#text/html +*.ini text svneol=native#text/plain +*.log text svneol=native#text/plain +*.mak text svneol=native#text/plain +*.qbk text svneol=native#text/plain +*.rst text svneol=native#text/plain +*.sql text svneol=native#text/x-sql +*.txt text svneol=native#text/plain +*.xhtml text svneol=native#text/xhtml%2Bxml +*.xml text svneol=native#text/xml +*.xsd text svneol=native#text/xml +*.xsl text svneol=native#text/xml +*.xslt text svneol=native#text/xml +*.xul text svneol=native#text/xul +*.yml text svneol=native#text/plain +boost-no-inspect text svneol=native#text/plain +CHANGES text svneol=native#text/plain +COPYING text svneol=native#text/plain +INSTALL text svneol=native#text/plain +Jamfile text svneol=native#text/plain +Jamroot text svneol=native#text/plain +Jamfile.v2 text svneol=native#text/plain +Jamrules text svneol=native#text/plain +Makefile* text svneol=native#text/plain +README text svneol=native#text/plain +TODO text svneol=native#text/plain + +# Code formats +*.c text svneol=native#text/plain +*.cpp text svneol=native#text/plain +*.h text svneol=native#text/plain +*.hpp text svneol=native#text/plain +*.ipp text svneol=native#text/plain +*.tpp text svneol=native#text/plain +*.jam text svneol=native#text/plain +*.java text svneol=native#text/plain diff --git a/test/bind_tests_advanced.cpp b/test/bind_tests_advanced.cpp new file mode 100644 index 0000000..d3fe1b6 --- /dev/null +++ b/test/bind_tests_advanced.cpp @@ -0,0 +1,89 @@ +// basic_test.cpp -------------------------------- + +#define BOOST_INCLUDE_MAIN // for testing, include rather than link +#include // see "Header Implementation Option" + +#include "boost/lambda/bind.hpp" + + +#include + +int sum_of_args_0() { return 0; } +int sum_of_args_1(int a) { return a; } +int sum_of_args_2(int a, int b) { return a+b; } +int sum_of_args_3(int a, int b, int c) { return a+b+c; } +int sum_of_args_4(int a, int b, int c, int d) { return a+b+c+d; } +int sum_of_args_5(int a, int b, int c, int d, int e) { return a+b+c+d+e; } +int sum_of_args_6(int a, int b, int c, int d, int e, int f) { return a+b+c+d+e+f; } +int sum_of_args_7(int a, int b, int c, int d, int e, int f, int g) { return a+b+c+d+e+f+g; } +int sum_of_args_8(int a, int b, int c, int d, int e, int f, int g, int h) { return a+b+c+d+e+f+g+h; } +int sum_of_args_9(int a, int b, int c, int d, int e, int f, int g, int h, int i) { return a+b+c+d+e+f+g+h+i; } + + +int product_of_args_2(int a, int b) { return a*b; } + +typedef int (*fptr_type)(int, int); +fptr_type sum_or_product(bool x) { + return x ? sum_of_args_2 : product_of_args_2; +} + +struct X { + typedef fptr_type (*result_type)(bool x); + result_type operator()() { return sum_or_product; } +}; + +// ---------------------------- + + + +struct test { + + typedef int result_type; + + template + int operator()(const T1& t1, const T2& t2) const { + return t1(t2); + } +}; + + +int test_main(int, char *[]) { + + using namespace std; + using namespace boost::tuples; + using namespace boost::lambda; + + int i = 1; int j = 2; int k = 3; + +// protect prevents the expansion of lambda functor + BOOST_TEST(protect(bind(sum_of_args_1, 3))()()==3); + + test t; + BOOST_TEST(bind(t, protect(bind(sum_of_args_1, _1)), 9)()==9); + + +// bind calls can be nested (the target function can be a lambda functor) +// The interpretation is, that the innermost lambda functor returns something +// that is bindable (another lambda functor, function pointer ...) + bool condition; + + condition = true; + BOOST_TEST(bind(bind(sum_or_product, _1), 1, 2)(condition)==3); + BOOST_TEST(bind(bind(sum_or_product, _1), _2, _3)(condition, j, k)==5); + + condition = false; + BOOST_TEST(bind(bind(sum_or_product, _1), 1, 2)(condition)==2); + BOOST_TEST(bind(bind(sum_or_product, _1), _2, _3)(condition, j, k)==6); + X x; + BOOST_TEST(bind(bind(bind(boost::ref(x)), _1), _2, _3)(condition, j, k)==6); + +// lambda functor is a function object, and can therefore be used +// as an argument to another lambda functors function call object. +// However, bindable function objects must define the typdef result_type. +// ret adds this to a lambda functor: + + BOOST_TEST(bind(_1)(ret(bind(sum_of_args_1, 3)))==3); + + + return 0; +} diff --git a/test/bind_tests_simple.cpp b/test/bind_tests_simple.cpp new file mode 100644 index 0000000..b975d0a --- /dev/null +++ b/test/bind_tests_simple.cpp @@ -0,0 +1,132 @@ +// bind_tests_simple.cpp -------------------------------- + +#define BOOST_INCLUDE_MAIN // for testing, include rather than link +#include // see "Header Implementation Option" + +#include "boost/lambda/bind.hpp" + +#include + + using namespace std; + using namespace boost::lambda; + + +int sum_of_args_0() { return 0; } +int sum_of_args_1(int a) { return a; } +int sum_of_args_2(int a, int b) { return a+b; } +int sum_of_args_3(int a, int b, int c) { return a+b+c; } +int sum_of_args_4(int a, int b, int c, int d) { return a+b+c+d; } +int sum_of_args_5(int a, int b, int c, int d, int e) { return a+b+c+d+e; } +int sum_of_args_6(int a, int b, int c, int d, int e, int f) { return a+b+c+d+e+f; } +int sum_of_args_7(int a, int b, int c, int d, int e, int f, int g) { return a+b+c+d+e+f+g; } +int sum_of_args_8(int a, int b, int c, int d, int e, int f, int g, int h) { return a+b+c+d+e+f+g+h; } +int sum_of_args_9(int a, int b, int c, int d, int e, int f, int g, int h, int i) { return a+b+c+d+e+f+g+h+i; } + + +// ---------------------------- + +class A { + int i; +public: + A(int n) : i(n) {}; + int add(const int& j) { return i + j; } +}; + +void test_member_functions() +{ + using boost::ref; + A a(10); + int i = 1; + + BOOST_TEST(bind(&A::add, ref(a), _1)(i) == 11); + BOOST_TEST(bind(&A::add, &a, _1)(i) == 11); + BOOST_TEST(bind(&A::add, _1, 1)(a) == 11); + BOOST_TEST(bind(&A::add, _1, 1)(make_const(&a)) == 11); + + // This should fail, as lambda functors store arguments as const + // bind(&A::add, a, _1); +} + +int test_main(int, char *[]) { + + int i = 1; int j = 2; int k = 3; + + // bind all parameters + BOOST_TEST(bind(sum_of_args_0)()==0); + BOOST_TEST(bind(sum_of_args_1, 1)()==1); + BOOST_TEST(bind(sum_of_args_2, 1, 2)()==3); + BOOST_TEST(bind(sum_of_args_3, 1, 2, 3)()==6); + BOOST_TEST(bind(sum_of_args_4, 1, 2, 3, 4)()==10); + BOOST_TEST(bind(sum_of_args_5, 1, 2, 3, 4, 5)()==15); + BOOST_TEST(bind(sum_of_args_6, 1, 2, 3, 4, 5, 6)()==21); + BOOST_TEST(bind(sum_of_args_7, 1, 2, 3, 4, 5, 6, 7)()==28); + BOOST_TEST(bind(sum_of_args_8, 1, 2, 3, 4, 5, 6, 7, 8)()==36); + BOOST_TEST(bind(sum_of_args_9, 1, 2, 3, 4, 5, 6, 7, 8, 9)()==45); + + // first parameter open + BOOST_TEST(bind(sum_of_args_0)()==0); + BOOST_TEST(bind(sum_of_args_1, _1)(i)==1); + BOOST_TEST(bind(sum_of_args_2, _1, 2)(i)==3); + BOOST_TEST(bind(sum_of_args_3, _1, 2, 3)(i)==6); + BOOST_TEST(bind(sum_of_args_4, _1, 2, 3, 4)(i)==10); + BOOST_TEST(bind(sum_of_args_5, _1, 2, 3, 4, 5)(i)==15); + BOOST_TEST(bind(sum_of_args_6, _1, 2, 3, 4, 5, 6)(i)==21); + BOOST_TEST(bind(sum_of_args_7, _1, 2, 3, 4, 5, 6, 7)(i)==28); + BOOST_TEST(bind(sum_of_args_8, _1, 2, 3, 4, 5, 6, 7, 8)(i)==36); + BOOST_TEST(bind(sum_of_args_9, _1, 2, 3, 4, 5, 6, 7, 8, 9)(i)==45); + + // two open arguments + BOOST_TEST(bind(sum_of_args_0)()==0); + BOOST_TEST(bind(sum_of_args_1, _1)(i)==1); + BOOST_TEST(bind(sum_of_args_2, _1, _2)(i, j)==3); + BOOST_TEST(bind(sum_of_args_3, _1, _2, 3)(i, j)==6); + BOOST_TEST(bind(sum_of_args_4, _1, _2, 3, 4)(i, j)==10); + BOOST_TEST(bind(sum_of_args_5, _1, _2, 3, 4, 5)(i, j)==15); + BOOST_TEST(bind(sum_of_args_6, _1, _2, 3, 4, 5, 6)(i, j)==21); + BOOST_TEST(bind(sum_of_args_7, _1, _2, 3, 4, 5, 6, 7)(i, j)==28); + BOOST_TEST(bind(sum_of_args_8, _1, _2, 3, 4, 5, 6, 7, 8)(i, j)==36); + BOOST_TEST(bind(sum_of_args_9, _1, _2, 3, 4, 5, 6, 7, 8, 9)(i, j)==45); + + // three open arguments + BOOST_TEST(bind(sum_of_args_0)()==0); + BOOST_TEST(bind(sum_of_args_1, _1)(i)==1); + BOOST_TEST(bind(sum_of_args_2, _1, _2)(i, j)==3); + BOOST_TEST(bind(sum_of_args_3, _1, _2, _3)(i, j, k)==6); + BOOST_TEST(bind(sum_of_args_4, _1, _2, _3, 4)(i, j, k)==10); + BOOST_TEST(bind(sum_of_args_5, _1, _2, _3, 4, 5)(i, j, k)==15); + BOOST_TEST(bind(sum_of_args_6, _1, _2, _3, 4, 5, 6)(i, j, k)==21); + BOOST_TEST(bind(sum_of_args_7, _1, _2, _3, 4, 5, 6, 7)(i, j, k)==28); + BOOST_TEST(bind(sum_of_args_8, _1, _2, _3, 4, 5, 6, 7, 8)(i, j, k)==36); + BOOST_TEST(bind(sum_of_args_9, _1, _2, _3, 4, 5, 6, 7, 8, 9)(i, j, k)==45); + + // function compositions with bind + BOOST_TEST(bind(sum_of_args_3, bind(sum_of_args_2, _1, 2), 2, 3)(i)==8); + BOOST_TEST( + bind(sum_of_args_9, + bind(sum_of_args_0), // 0 + bind(sum_of_args_1, _1), // 1 + bind(sum_of_args_2, _1, _2), // 3 + bind(sum_of_args_3, _1, _2, _3), // 6 + bind(sum_of_args_4, _1, _2, _3, 4), // 10 + bind(sum_of_args_5, _1, _2, _3, 4, 5), // 15 + bind(sum_of_args_6, _1, _2, _3, 4, 5, 6), // 21 + bind(sum_of_args_7, _1, _2, _3, 4, 5, 6, 7), // 28 + bind(sum_of_args_8, _1, _2, _3, 4, 5, 6, 7, 8) // 36 + )(i, j, k) == 120); + + // deeper nesting + int result = + bind(sum_of_args_1, // 12 + bind(sum_of_args_4, // 12 + bind(sum_of_args_2, // 3 + bind(sum_of_args_1, // 1 + bind(sum_of_args_1, _1) // 1 + ), + _2), + _2, + _3, + 4) + )(i, j, k); + BOOST_TEST(result == 12); + return 0; +} diff --git a/test/cast_test.cpp b/test/cast_test.cpp new file mode 100644 index 0000000..83c5b1f --- /dev/null +++ b/test/cast_test.cpp @@ -0,0 +1,81 @@ +// constructor_tests.cpp -------------------------------- + +#define BOOST_INCLUDE_MAIN // for testing, include rather than link +#include // see "Header Implementation Option" + + +#include "boost/lambda/lambda.hpp" + +#include "boost/lambda/casts.hpp" + +#include + +using namespace boost::lambda; +using namespace std; + +class base { + int x; +public: + virtual std::string class_name() const { return "const base"; } + virtual std::string class_name() { return "base"; } + +}; + +class derived : public base { +public: + virtual std::string class_name() const { return "const derived"; } + virtual std::string class_name() { return "derived"; } +}; + + + + +int do_test() { + + derived *p_derived = new derived; + base *p_base = new base; + + base *b = 0; + derived *d = 0; + + (var(b) = ll_static_cast(p_derived))(); + (var(d) = ll_static_cast(b))(); + + BOOST_TEST(b->class_name() == "derived"); + BOOST_TEST(d->class_name() == "derived"); + + (var(b) = ll_dynamic_cast(b))(); + BOOST_TEST(b != 0); + BOOST_TEST(b->class_name() == "derived"); + + (var(d) = ll_dynamic_cast(p_base))(); + BOOST_TEST(d == 0); + + + + const derived* p_const_derived = p_derived; + + BOOST_TEST(p_const_derived->class_name() == "const derived"); + (var(d) = ll_const_cast(p_const_derived))(); + BOOST_TEST(d->class_name() == "derived"); + + int i = 10; + char* cp = reinterpret_cast(&i); + + int* ip; + (var(ip) = ll_reinterpret_cast(cp))(); + BOOST_TEST(*ip == 10); + + BOOST_TEST(string(ll_typeid(d)().name()) == string(typeid(d).name())); + + + delete p_derived; + delete p_base; + +} + +int test_main(int, char *[]) { + + do_test(); + return 0; +} diff --git a/test/constructor_tests.cpp b/test/constructor_tests.cpp new file mode 100644 index 0000000..53fac64 --- /dev/null +++ b/test/constructor_tests.cpp @@ -0,0 +1,244 @@ +// constructor_tests.cpp -------------------------------- + +#define BOOST_INCLUDE_MAIN // for testing, include rather than link +#include // see "Header Implementation Option" + + +#include "boost/lambda/lambda.hpp" +#include "boost/lambda/bind.hpp" + +#include "boost/lambda/construct.hpp" + +#include +#include + +using namespace boost::lambda; +using namespace std; + +template +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 >(), + 1)() + ); + BOOST_TEST(ok); + + ok = check_tuple( + 1, + bind(constructor >(), + 1, 2)() + ); + BOOST_TEST(ok); + + ok = check_tuple( + 1, + bind(constructor >(), + 1, 2, 3)() + ); + BOOST_TEST(ok); + + ok = check_tuple( + 1, + bind(constructor >(), + 1, 2, 3, 4)() + ); + BOOST_TEST(ok); + + ok = check_tuple( + 1, + bind(constructor >(), + 1, 2, 3, 4, 5)() + ); + BOOST_TEST(ok); + + ok = check_tuple( + 1, + bind(constructor >(), + 1, 2, 3, 4, 5, 6)() + ); + BOOST_TEST(ok); + + ok = check_tuple( + 1, + bind(constructor >(), + 1, 2, 3, 4, 5, 6, 7)() + ); + BOOST_TEST(ok); + + ok = check_tuple( + 1, + bind(constructor >(), + 1, 2, 3, 4, 5, 6, 7, 8)() + ); + BOOST_TEST(ok); + + ok = check_tuple( + 1, + bind(constructor >(), + 1, 2, 3, 4, 5, 6, 7, 8, 9)() + ); + BOOST_TEST(ok); + +} + +void new_ptr_all_lengths() +{ + bool ok; + ok = check_tuple( + 1, + *(bind(new_ptr >(), + 1))() + ); + BOOST_TEST(ok); + + ok = check_tuple( + 1, + *(bind(new_ptr >(), + 1, 2))() + ); + BOOST_TEST(ok); + + ok = check_tuple( + 1, + *(bind(new_ptr >(), + 1, 2, 3))() + ); + BOOST_TEST(ok); + + ok = check_tuple( + 1, + *(bind(new_ptr >(), + 1, 2, 3, 4))() + ); + BOOST_TEST(ok); + + ok = check_tuple( + 1, + *(bind(new_ptr >(), + 1, 2, 3, 4, 5))() + ); + BOOST_TEST(ok); + + ok = check_tuple( + 1, + *(bind(new_ptr >(), + 1, 2, 3, 4, 5, 6))() + ); + BOOST_TEST(ok); + + ok = check_tuple( + 1, + *(bind(new_ptr >(), + 1, 2, 3, 4, 5, 6, 7))() + ); + BOOST_TEST(ok); + + ok = check_tuple( + 1, + *(bind(new_ptr >(), + 1, 2, 3, 4, 5, 6, 7, 8))() + ); + BOOST_TEST(ok); + + ok = check_tuple( + 1, + *(bind(new_ptr >(), + 1, 2, 3, 4, 5, 6, 7, 8, 9))() + ); + BOOST_TEST(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; + + is_destructor_called* idc = new(space) is_destructor_called(flag); + BOOST_TEST(flag == false); + bind(destructor(), _1)(idc); + BOOST_TEST(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]; + for_each(i, i+10, _1 = bind(new_ptr(), 2)); + int count_errors = 0; + + for_each(i, i+10, (*_1 == 2) || ++var(count_errors)); + BOOST_TEST(count_errors == 0); + + + count_deletes* ct[10]; + for_each(ct, ct+10, _1 = bind(new_ptr())); + count_deletes::count = 0; + for_each(ct, ct+10, bind(delete_ptr(), _1)); + BOOST_TEST(count_deletes::count == 10); + +} + +void test_array_new_and_delete() +{ + count_deletes* c; + (_1 = bind(new_array(), 5))(c); + count_deletes::count = 0; + + bind(delete_array(), _1)(c); + BOOST_TEST(count_deletes::count == 5); +} + + +void delayed_construction() +{ + vector x(3); + vector y(3); + + fill(x.begin(), x.end(), 0); + fill(y.begin(), y.end(), 1); + + vector > v; + + transform(x.begin(), x.end(), y.begin(), back_inserter(v), + bind(constructor >(), _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; +} diff --git a/test/control_structures.cpp b/test/control_structures.cpp new file mode 100644 index 0000000..8144224 --- /dev/null +++ b/test/control_structures.cpp @@ -0,0 +1,99 @@ +#define BOOST_INCLUDE_MAIN // for testing, include rather than link +#include // see "Header Implementation Option" + +#include "boost/lambda/lambda.hpp" +#include "boost/lambda/control_structures.hpp" + +#include +#include +#include + +using namespace boost; +using namespace boost::lambda; + +// 2 container for_each +template +Function for_each(InputIter1 first, InputIter1 last, + InputIter2 first2, Function f) { + for ( ; first != last; ++first, ++first2) + f(*first, *first2); + return f; +} + +void simple_loops() { + + // for loops --------------------------------------------------------- + int i; + int arithmetic_series = 0; + for_loop(_1 = 0, _1 < 10, _1++, arithmetic_series += _1)(i); + BOOST_TEST(arithmetic_series == 45); + + // no body case + for_loop(var(i) = 0, var(i) < 100, ++var(i))(); + BOOST_TEST(i == 100); + + // while loops ------------------------------------------------------- + int a = 0, b = 0, c = 0; + + while_loop((_1 + _2) >= (_1 * _2), (++_1, ++_2, ++_3))(a, b, c); + BOOST_TEST(c == 3); + + int count; + count = 0; i = 0; + while_loop(_1++ < 10, ++var(count))(i); + BOOST_TEST(count == 10); + + // note that the first parameter of do_while_loop is the condition + count = 0; i = 0; + do_while_loop(_1++ < 10, ++var(count))(i); + BOOST_TEST(count == 11); + + a = 0; + do_while_loop(constant(false), _1++)(a); + BOOST_TEST(a == 1); + + // no body cases + a = 40; b = 30; + while_loop(--_1 > _2)(a, b); + BOOST_TEST(a == b); + + // (the no body case for do_while_loop is pretty redundant) + a = 40; b = 30; + do_while_loop(--_1 > _2)(a, b); + BOOST_TEST(a == b); + + +} + +void simple_ifs () { + + int value = 42; + if_then(_1 < 0, _1 = 0)(value); + BOOST_TEST(value == 42); + + value = -42; + if_then(_1 < 0, _1 = -_1)(value); + BOOST_TEST(value == 42); + + int min; + if_then_else(_1 < _2, var(min) = _1, var(min) = _2) + (make_const(1), make_const(2)); + BOOST_TEST(min == 1); + + if_then_else(_1 < _2, var(min) = _1, var(min) = _2) + (make_const(5), make_const(3)); + BOOST_TEST(min == 3); + + int x, y; + x = -1; y = 1; + BOOST_TEST(if_then_else_return(_1 < _2, _2, _1)(x, y) == std::max(x ,y)); + BOOST_TEST(if_then_else_return(_1 < _2, _2, _1)(y, x) == std::max(x ,y)); +} + + +int test_main(int, char *[]) +{ + simple_loops(); + simple_ifs(); + return 0; +} diff --git a/test/exception_test.cpp b/test/exception_test.cpp new file mode 100644 index 0000000..915032b --- /dev/null +++ b/test/exception_test.cpp @@ -0,0 +1,638 @@ +#define BOOST_INCLUDE_MAIN // for testing, include rather than link +#include // see "Header Implementation Option" + +#include "boost/lambda/lambda.hpp" + +#include "boost/lambda/exceptions.hpp" + +#include "boost/lambda/bind.hpp" + +#include +#include +#include + +#include + +using namespace boost::lambda; +using namespace std; + +// to prevent unused variables warnings +template void dummy(const T& t) {} + +void erroneous_exception_related_lambda_expressions() { + + int i = 0; + dummy(i); + + // Uncommenting any of the below code lines should result in a compile + // time error + + // this should fail (a rethrow binder outside of catch + // rethrow()(); + + // this should fail too for the same reason + // try_catch(rethrow(), catch_all(cout << constant("Howdy")))(); + + // this fails too (_E outside of catch_exception) + // (_1 + _2 + _E)(i, i, i); + + // and this (_E outside of catch_exception) + // try_catch( throw_exception(1), catch_all(cout << _E)); + + // and this (_3 in catch_exception + // try_catch( throw_exception(1), catch_exception(cout << _3)); +} + + +class A1 {}; +class A2 {}; +class A3 {}; +class A4 {}; +class A5 {}; +class A6 {}; +class A7 {}; +class A8 {}; +class A9 {}; + +void throw_AX(int i) { + switch(i) + { + case 1: throw A1(); + case 2: throw A2(); + case 3: throw A3(); + case 4: throw A4(); + case 5: throw A5(); + case 6: throw A6(); + case 7: throw A7(); + case 8: throw A8(); + case 9: throw A9(); + } +} + +void test_different_number_of_catch_blocks() { + + int ecount; + +// no catch(...) cases + + + ecount = 0; + for(int i=1; i<=1; i++) + { + try_catch( + bind(throw_AX, _1), + catch_exception( + var(ecount)++ + ) + )(i); + } + BOOST_TEST(ecount == 1); + + ecount = 0; + for(int i=1; i<=2; i++) + { + try_catch( + bind(throw_AX, _1), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ) + )(i); + } + BOOST_TEST(ecount == 2); + + ecount = 0; + for(int i=1; i<=3; i++) + { + try_catch( + bind(throw_AX, _1), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ) + )(i); + } + BOOST_TEST(ecount == 3); + + ecount = 0; + for(int i=1; i<=4; i++) + { + try_catch( + bind(throw_AX, _1), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ) + )(i); + } + BOOST_TEST(ecount == 4); + + ecount = 0; + for(int i=1; i<=5; i++) + { + try_catch( + bind(throw_AX, _1), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ) + )(i); + } + BOOST_TEST(ecount == 5); + + ecount = 0; + for(int i=1; i<=6; i++) + { + try_catch( + bind(throw_AX, _1), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ) + )(i); + } + BOOST_TEST(ecount == 6); + + ecount = 0; + for(int i=1; i<=7; i++) + { + try_catch( + bind(throw_AX, _1), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ) + )(i); + } + BOOST_TEST(ecount == 7); + + ecount = 0; + for(int i=1; i<=8; i++) + { + try_catch( + bind(throw_AX, _1), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ) + )(i); + } + BOOST_TEST(ecount == 8); + + ecount = 0; + for(int i=1; i<=9; i++) + { + try_catch( + bind(throw_AX, _1), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ) + )(i); + } + BOOST_TEST(ecount == 9); + + + // with catch(...) blocks + + ecount = 0; + for(int i=1; i<=1; i++) + { + try_catch( + bind(throw_AX, _1), + catch_all( + var(ecount)++ + ) + )(i); + } + BOOST_TEST(ecount == 1); + + ecount = 0; + for(int i=1; i<=2; i++) + { + try_catch( + bind(throw_AX, _1), + catch_exception( + var(ecount)++ + ), + catch_all( + var(ecount)++ + ) + )(i); + } + BOOST_TEST(ecount == 2); + + ecount = 0; + for(int i=1; i<=3; i++) + { + try_catch( + bind(throw_AX, _1), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_all( + var(ecount)++ + ) + )(i); + } + BOOST_TEST(ecount == 3); + + ecount = 0; + for(int i=1; i<=4; i++) + { + try_catch( + bind(throw_AX, _1), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_all( + var(ecount)++ + ) + )(i); + } + BOOST_TEST(ecount == 4); + + ecount = 0; + for(int i=1; i<=5; i++) + { + try_catch( + bind(throw_AX, _1), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_all( + var(ecount)++ + ) + )(i); + } + BOOST_TEST(ecount == 5); + + ecount = 0; + for(int i=1; i<=6; i++) + { + try_catch( + bind(throw_AX, _1), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_all( + var(ecount)++ + ) + )(i); + } + BOOST_TEST(ecount == 6); + + ecount = 0; + for(int i=1; i<=7; i++) + { + try_catch( + bind(throw_AX, _1), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_all( + var(ecount)++ + ) + )(i); + } + BOOST_TEST(ecount == 7); + + ecount = 0; + for(int i=1; i<=8; i++) + { + try_catch( + bind(throw_AX, _1), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_all( + var(ecount)++ + ) + )(i); + } + BOOST_TEST(ecount == 8); + + ecount = 0; + for(int i=1; i<=9; i++) + { + try_catch( + bind(throw_AX, _1), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_exception( + var(ecount)++ + ), + catch_all( + var(ecount)++ + ) + )(i); + } + BOOST_TEST(ecount == 9); +} + + +void return_type_matching() { + +// Rules for return types of the lambda functors in try and catch parts: +// 1. The try part dictates the return type of the whole +// try_catch lambda functor +// 2. If return type of try part is void, catch parts can return anything, +// but the return types are ignored +// 3. If the return type of the try part is A, then each catch return type +// must be implicitly convertible to A, or then it must throw for sure + + + int i = 1; + + BOOST_TEST( + + try_catch( + _1 + 1, + catch_exception((&_1, rethrow())), // no match, but ok since throws + catch_exception(_E) // ok, char convertible to int + )(i) + + == 2 + ); + + // note that while e.g. char is convertible to int, it is not convertible + // to int&, (some lambda functors return references) + + // try_catch( + // _1 += 1, + // catch_exception(_E) // NOT ok, char not convertible to int& + // )(i); + + // if you don't care about the return type, you can use make_void + try_catch( + make_void(_1 += 1), + catch_exception(_E) // since try is void, catch can return anything + )(i); + BOOST_TEST(i == 2); + + try_catch( + (_1 += 1, throw_exception('a')), + catch_exception(_E) // since try throws, it is void, + // so catch can return anything + )(i); + BOOST_TEST(i == 3); + + char a = 'a'; + try_catch( + try_catch( + throw_exception(1), + catch_exception(throw_exception('b')) + ), + catch_exception( _1 = _E ) + )(a); + BOOST_TEST(a == 'b'); +} + +int test_main(int, char *[]) { + + try + { + test_different_number_of_catch_blocks(); + return_type_matching(); + } + catch (int x) + { + BOOST_TEST(false); + } + catch(...) + { + BOOST_TEST(false); + } + + + return EXIT_SUCCESS; +} + + + + +// cout << "Before make void call. i ="<< i << "\n"; +// (make_void(free1 += 3))(i); +// cout << "After make void call, should be += 3 i = " << i << "\n"; + +// int j =0; +// var_type::type vj(var(j)); +// (make_void(for_loop(vj = 0, vj < free1, ++vj, cout << vj << "\n")))(i); + +// try_catch( make_void(free1 += 3 + free2), +// catch_exception( cout << constant("Should work: ") << free1 + free2 << "\n" ) +// ) +// (i, i); + +// try_catch( make_void(free1 += 3), +// catch_exception( cout << constant("Should work: ") << free1 + free2 << "\n" ) +// ) +// (i, i); + +// try_catch( throw_exception(1), +// catch_exception( +// throw_exception(2) ) +// ) +// (); + +// try_catch( throw_exception(1), +// catch_exception( +// ((cout << constant("caught int: ") << free1 + free2 << "\n") +// ,throw_exception(2) ) +// ), +// catch_all( +// ((cout << constant("catch all: ") << free1 + free2 << "\n") +// ,rethrow()) +// ) +// )(i,i); + +// // try_catch which returns (10 is added, so that the try return type is int +// cout << "\n -------------- \n" << +// try_catch( (throw_exception(5), 10), +// catch_exception( free1 + free2 + freeE ) // returns int +// ) +// (i, i) << "\n"; + + diff --git a/test/is_instance_of_test.cpp b/test/is_instance_of_test.cpp new file mode 100644 index 0000000..c45b099 --- /dev/null +++ b/test/is_instance_of_test.cpp @@ -0,0 +1,58 @@ +// is_convertible_to_template_test.cpp ---------------------------- + +#define BOOST_INCLUDE_MAIN // for testing, include rather than link +#include // see "Header Implementation Option" + +#include "boost/lambda/detail/is_instance_of.hpp" + +#include + +template struct A1 {}; +template struct A2 {}; +template struct A3 {}; +template struct A4 {}; + +class B1 : public A1 {}; +class B2 : public A2 {}; +class B3 : public A3 {}; +class B4 : public A4 {}; + +// classes that are convertible to classes that derive from A instances +// This is not enough to make the test succeed + +class C1 { public: operator A1() { return A1(); } }; +class C2 { public: operator B2() { return B2(); } }; +class C3 { public: operator B3() { return B3(); } }; +class C4 { public: operator B4() { return B4(); } }; + +int test_main(int, char *[]) { + +using boost::lambda::detail::is_instance_of_1; +using boost::lambda::detail::is_instance_of_2; +using boost::lambda::detail::is_instance_of_3; +using boost::lambda::detail::is_instance_of_4; + +BOOST_TEST((is_instance_of_1::value == true)); +BOOST_TEST((is_instance_of_1, A1>::value == true)); +BOOST_TEST((is_instance_of_1::value == false)); +BOOST_TEST((is_instance_of_1::value == false)); + +BOOST_TEST((is_instance_of_2::value == true)); +BOOST_TEST((is_instance_of_2, A2>::value == true)); +BOOST_TEST((is_instance_of_2::value == false)); +BOOST_TEST((is_instance_of_2::value == false)); + +BOOST_TEST((is_instance_of_3::value == true)); +BOOST_TEST((is_instance_of_3, A3>::value == true)); +BOOST_TEST((is_instance_of_3::value == false)); +BOOST_TEST((is_instance_of_3::value == false)); + +BOOST_TEST((is_instance_of_4::value == true)); +BOOST_TEST((is_instance_of_4, A4>::value == true)); +BOOST_TEST((is_instance_of_4::value == false)); +BOOST_TEST((is_instance_of_4::value == false)); + +return 0; + +}; + diff --git a/test/operator_tests_simple.cpp b/test/operator_tests_simple.cpp new file mode 100644 index 0000000..f2125df --- /dev/null +++ b/test/operator_tests_simple.cpp @@ -0,0 +1,319 @@ +// operator_tests_simple.cpp -------------------------------- + +#define BOOST_INCLUDE_MAIN // for testing, include rather than link +#include // see "Header Implementation Option" + +#include "boost/lambda/lambda.hpp" + +#include + + +class B {}; + +using namespace boost::lambda; + + +class unary_plus_tester {}; +unary_plus_tester operator+(const unary_plus_tester& a) { return a; } + +void arithmetic_operators() { + int i = 1; int j = 2; int k = 3; + + using namespace std; + using namespace boost::lambda; + + BOOST_TEST((_1 + 1)(i)==2); + BOOST_TEST(((_1 + 1) * _2)(i, j)==4); + BOOST_TEST((_1 - 1)(i)==0); + + BOOST_TEST((_1 * 2)(j)==4); + BOOST_TEST((_1 / 2)(j)==1); + + BOOST_TEST((_1 % 2)(k)==1); + + BOOST_TEST((-_1)(i) == -1); + BOOST_TEST((+_1)(i) == 1); + + // test that unary plus really does something + unary_plus_tester u; + unary_plus_tester up = (+_1)(u); +} + +void bitwise_operators() { + unsigned int ui = 2; + BOOST_TEST((_1 << 1)(ui)==(2 << 1)); + BOOST_TEST((_1 >> 1)(ui)==(2 >> 1)); + + BOOST_TEST((_1 & 1)(ui)==(2 & 1)); + BOOST_TEST((_1 | 1)(ui)==(2 | 1)); + BOOST_TEST((_1 ^ 1)(ui)==(2 ^ 1)); + BOOST_TEST((~_1)(ui)==~2); +} + +void comparison_operators() { + int i = 0, j = 1; + + BOOST_TEST((_1 < _2)(i, j) == true); + BOOST_TEST((_1 <= _2)(i, j) == true); + BOOST_TEST((_1 == _2)(i, j) == false); + BOOST_TEST((_1 != _2)(i, j) == true); + BOOST_TEST((_1 > _2)(i, j) == false); + BOOST_TEST((_1 >= _2)(i, j) == false); + + BOOST_TEST((!(_1 < _2))(i, j) == false); + BOOST_TEST((!(_1 <= _2))(i, j) == false); + BOOST_TEST((!(_1 == _2))(i, j) == true); + BOOST_TEST((!(_1 != _2))(i, j) == false); + BOOST_TEST((!(_1 > _2))(i, j) == true); + BOOST_TEST((!(_1 >= _2))(i, j) == true); +} + +void logical_operators() { + + bool t = true, f = false; + BOOST_TEST((_1 && _2)(t, t) == true); + BOOST_TEST((_1 && _2)(t, f) == false); + BOOST_TEST((_1 && _2)(f, t) == false); + BOOST_TEST((_1 && _2)(f, f) == false); + + BOOST_TEST((_1 || _2)(t, t) == true); + BOOST_TEST((_1 || _2)(t, f) == true); + BOOST_TEST((_1 || _2)(f, t) == true); + BOOST_TEST((_1 || _2)(f, f) == false); + + BOOST_TEST((!_1)(t) == false); + BOOST_TEST((!_1)(f) == true); + + // test short circuiting + int i=0; + + (false && ++_1)(i); + BOOST_TEST(i==0); + i = 0; + + (true && ++_1)(i); + BOOST_TEST(i==1); + i = 0; + + (false || ++_1)(i); + BOOST_TEST(i==1); + i = 0; + + (true || ++_1)(i); + BOOST_TEST(i==0); + i = 0; +} + +void unary_incs_and_decs() { + int i = 0; + + BOOST_TEST(_1++(i) == 0); + BOOST_TEST(i == 1); + i = 0; + + BOOST_TEST(_1--(i) == 0); + BOOST_TEST(i == -1); + i = 0; + + BOOST_TEST((++_1)(i) == 1); + BOOST_TEST(i == 1); + i = 0; + + BOOST_TEST((--_1)(i) == -1); + BOOST_TEST(i == -1); + i = 0; + + // the result of prefix -- and ++ are lvalues + (++_1)(i) = 10; + BOOST_TEST(i==10); + i = 0; + + (--_1)(i) = 10; + BOOST_TEST(i==10); + i = 0; +} + +void compound_operators() { + + int i = 1; + + // normal variable as the left operand + (i += _1)(make_const(1)); + BOOST_TEST(i == 2); + + (i -= _1)(make_const(1)); + BOOST_TEST(i == 1); + + (i *= _1)(make_const(10)); + BOOST_TEST(i == 10); + + (i /= _1)(make_const(2)); + BOOST_TEST(i == 5); + + (i %= _1)(make_const(2)); + BOOST_TEST(i == 1); + + // lambda expression as a left operand + (_1 += 1)(i); + BOOST_TEST(i == 2); + + (_1 -= 1)(i); + BOOST_TEST(i == 1); + + (_1 *= 10)(i); + BOOST_TEST(i == 10); + + (_1 /= 2)(i); + BOOST_TEST(i == 5); + + (_1 %= 2)(i); + BOOST_TEST(i == 1); + + // shifts + unsigned int ui = 2; + (_1 <<= 1)(ui); + BOOST_TEST(ui==(2 << 1)); + + ui = 2; + (_1 >>= 1)(ui); + BOOST_TEST(ui==(2 >> 1)); + + ui = 2; + (ui <<= _1)(make_const(1)); + BOOST_TEST(ui==(2 << 1)); + + ui = 2; + (ui >>= _1)(make_const(1)); + BOOST_TEST(ui==(2 >> 1)); + + // and, or, xor + ui = 2; + (_1 &= 1)(ui); + BOOST_TEST(ui==(2 & 1)); + + ui = 2; + (_1 |= 1)(ui); + BOOST_TEST(ui==(2 | 1)); + + ui = 2; + (_1 ^= 1)(ui); + BOOST_TEST(ui==(2 ^ 1)); + + ui = 2; + (ui &= _1)(make_const(1)); + BOOST_TEST(ui==(2 & 1)); + + ui = 2; + (ui |= _1)(make_const(1)); + BOOST_TEST(ui==(2 | 1)); + + ui = 2; + (ui ^= _1)(make_const(1)); + BOOST_TEST(ui==(2 ^ 1)); + +} + +void assignment_and_subscript() { + + // assignment and subscript need to be defined as member functions. + // Hence, if you wish to use a normal variable as the left hand argument, + // you must wrap it with var to turn it into a lambda expression + + using std::string; + string s; + + (_1 = "one")(s); + BOOST_TEST(s == string("one")); + + (var(s) = "two")(); + BOOST_TEST(s == string("two")); + + BOOST_TEST((var(s)[_1])(make_const(2)) == 'o'); + BOOST_TEST((_1[2])(s) == 'o'); + BOOST_TEST((_1[_2])(s, make_const(2)) == 'o'); + + // subscript returns lvalue + (var(s)[_1])(make_const(1)) = 'o'; + BOOST_TEST(s == "too"); + + (_1[1])(s) = 'a'; + BOOST_TEST(s == "tao"); + + (_1[_2])(s, make_const(0)) = 'm'; + BOOST_TEST(s == "mao"); +} + +class A {}; + +void address_of_and_dereference() { + + A a; int i = 42; + + BOOST_TEST((&_1)(a) == &a); + BOOST_TEST((*&_1)(i) == 42); +} + + + +void comma() { + + int i = 100; + BOOST_TEST((_1 = 10, 2 * _1)(i) == 20); + +} + +void pointer_arithmetic() { + + int ia[4] = { 1, 2, 3, 4 }; + int* ip = ia; + int* ia_last = &ia[3]; + + const int cia[4] = { 1, 2, 3, 4 }; + const int* cip = cia; + const int* cia_last = &cia[3]; + + + // non-const array + BOOST_TEST((*(_1 + 1))(ia) == 2); + + // non-const pointer + BOOST_TEST((*(_1 + 1))(ip) == 2); + + BOOST_TEST((*(_1 - 1))(ia_last) == 3); + + // const array + BOOST_TEST((*(_1 + 1))(cia) == 2); + // const pointer + BOOST_TEST((*(_1 + 1))(cip) == 2); + BOOST_TEST((*(_1 - 1))(cia_last) == 3); + + // pointer arithmetic should not make non-consts const + (*(_1 + 2))(ia) = 0; + (*(_1 + 3))(ip) = 0; + BOOST_TEST(ia[2] == 0); + BOOST_TEST(ia[3] == 0); + + // pointer - pointer + BOOST_TEST((_1 - _2)(ia_last, ia) == 3); + BOOST_TEST((_1 - _2)(cia_last, cia) == 3); + BOOST_TEST((ia_last - _1)(ia) == 3); + BOOST_TEST((cia_last - _1)(cia) == 3); + BOOST_TEST((cia_last - _1)(cip) == 3); + +}; + +int test_main(int, char *[]) { + + arithmetic_operators(); + bitwise_operators(); + comparison_operators(); + logical_operators(); + unary_incs_and_decs(); + compound_operators(); + assignment_and_subscript(); + address_of_and_dereference(); + comma(); + pointer_arithmetic(); + + return 0; +} diff --git a/test/switch_construct.cpp b/test/switch_construct.cpp new file mode 100644 index 0000000..b94b6e2 --- /dev/null +++ b/test/switch_construct.cpp @@ -0,0 +1,361 @@ +// switch_test.cpp -------------------------------- + +#define BOOST_INCLUDE_MAIN // for testing, include rather than link +#include // see "Header Implementation Option" + + +#include "boost/lambda/lambda.hpp" +#include "boost/lambda/control_structures.hpp" + +#include +#include +#include +#include + + + +// Check that elements 0 -- index are 1, and the rest are 0 +bool check(const std::vector& v, int index) { + using namespace boost::lambda; + int counter = 0; + std::vector::const_iterator + result = std::find_if(v.begin(), v.end(), + ! if_then_else_return( + var(counter)++ <= index, + _1 == 1, + _1 == 0) + ); + return result == v.end(); +} + + + +void do_switch_no_defaults_tests() { + + using namespace boost::lambda; + + int i = 0; + std::vector v,w; + + // elements from 0 to 9 + std::generate_n(std::back_inserter(v), + 10, + var(i)++); + std::fill_n(std::back_inserter(w), 10, 0); + + // --- + std::for_each(v.begin(), v.end(), + switch_statement( + _1, + case_statement<0>(++var(w[0])) + ) + ); + + BOOST_TEST(check(w, 0)); + std::fill_n(w.begin(), 10, 0); + + // --- + std::for_each(v.begin(), v.end(), + switch_statement( + _1, + case_statement<0>(++var(w[0])), + case_statement<1>(++var(w[1])) + ) + ); + + BOOST_TEST(check(w, 1)); + std::fill_n(w.begin(), 10, 0); + + // --- + std::for_each(v.begin(), v.end(), + switch_statement( + _1, + case_statement<0>(++var(w[0])), + case_statement<1>(++var(w[1])), + case_statement<2>(++var(w[2])) + ) + ); + + BOOST_TEST(check(w, 2)); + std::fill_n(w.begin(), 10, 0); + + // --- + std::for_each(v.begin(), v.end(), + switch_statement( + _1, + case_statement<0>(++var(w[0])), + case_statement<1>(++var(w[1])), + case_statement<2>(++var(w[2])), + case_statement<3>(++var(w[3])) + ) + ); + + BOOST_TEST(check(w, 3)); + std::fill_n(w.begin(), 10, 0); + + // --- + std::for_each(v.begin(), v.end(), + switch_statement( + _1, + case_statement<0>(++var(w[0])), + case_statement<1>(++var(w[1])), + case_statement<2>(++var(w[2])), + case_statement<3>(++var(w[3])), + case_statement<4>(++var(w[4])) + ) + ); + + BOOST_TEST(check(w, 4)); + std::fill_n(w.begin(), 10, 0); + + // --- + std::for_each(v.begin(), v.end(), + switch_statement( + _1, + case_statement<0>(++var(w[0])), + case_statement<1>(++var(w[1])), + case_statement<2>(++var(w[2])), + case_statement<3>(++var(w[3])), + case_statement<4>(++var(w[4])), + case_statement<5>(++var(w[5])) + ) + ); + + BOOST_TEST(check(w, 5)); + std::fill_n(w.begin(), 10, 0); + + // --- + std::for_each(v.begin(), v.end(), + switch_statement( + _1, + case_statement<0>(++var(w[0])), + case_statement<1>(++var(w[1])), + case_statement<2>(++var(w[2])), + case_statement<3>(++var(w[3])), + case_statement<4>(++var(w[4])), + case_statement<5>(++var(w[5])), + case_statement<6>(++var(w[6])) + ) + ); + + BOOST_TEST(check(w, 6)); + std::fill_n(w.begin(), 10, 0); + + // --- + std::for_each(v.begin(), v.end(), + switch_statement( + _1, + case_statement<0>(++var(w[0])), + case_statement<1>(++var(w[1])), + case_statement<2>(++var(w[2])), + case_statement<3>(++var(w[3])), + case_statement<4>(++var(w[4])), + case_statement<5>(++var(w[5])), + case_statement<6>(++var(w[6])), + case_statement<7>(++var(w[7])) + ) + ); + + BOOST_TEST(check(w, 7)); + std::fill_n(w.begin(), 10, 0); + + // --- + std::for_each(v.begin(), v.end(), + switch_statement( + _1, + case_statement<0>(++var(w[0])), + case_statement<1>(++var(w[1])), + case_statement<2>(++var(w[2])), + case_statement<3>(++var(w[3])), + case_statement<4>(++var(w[4])), + case_statement<5>(++var(w[5])), + case_statement<6>(++var(w[6])), + case_statement<7>(++var(w[7])), + case_statement<8>(++var(w[8])) + ) + ); + + BOOST_TEST(check(w, 8)); + std::fill_n(w.begin(), 10, 0); + +} + + +void do_switch_yes_defaults_tests() { + + using namespace boost::lambda; + + int i = 0; + std::vector v,w; + + // elements from 0 to 9 + std::generate_n(std::back_inserter(v), + 10, + var(i)++); + std::fill_n(std::back_inserter(w), 10, 0); + + int default_count; + // --- + default_count = 0; + std::for_each(v.begin(), v.end(), + switch_statement( + _1, + default_statement(++var(default_count)) + ) + ); + + BOOST_TEST(check(w, -1)); + BOOST_TEST(default_count == 10); + std::fill_n(w.begin(), 10, 0); + + // --- + default_count = 0; + std::for_each(v.begin(), v.end(), + switch_statement( + _1, + case_statement<0>(++var(w[0])), + default_statement(++var(default_count)) + ) + ); + + BOOST_TEST(check(w, 0)); + BOOST_TEST(default_count == 9); + std::fill_n(w.begin(), 10, 0); + + // --- + default_count = 0; + std::for_each(v.begin(), v.end(), + switch_statement( + _1, + case_statement<0>(++var(w[0])), + case_statement<1>(++var(w[1])), + default_statement(++var(default_count)) + ) + ); + + BOOST_TEST(check(w, 1)); + BOOST_TEST(default_count == 8); + std::fill_n(w.begin(), 10, 0); + + // --- + default_count = 0; + std::for_each(v.begin(), v.end(), + switch_statement( + _1, + case_statement<0>(++var(w[0])), + case_statement<1>(++var(w[1])), + case_statement<2>(++var(w[2])), + default_statement(++var(default_count)) + ) + ); + + BOOST_TEST(check(w, 2)); + BOOST_TEST(default_count == 7); + std::fill_n(w.begin(), 10, 0); + + // --- + default_count = 0; + std::for_each(v.begin(), v.end(), + switch_statement( + _1, + case_statement<0>(++var(w[0])), + case_statement<1>(++var(w[1])), + case_statement<2>(++var(w[2])), + case_statement<3>(++var(w[3])), + default_statement(++var(default_count)) + ) + ); + + BOOST_TEST(check(w, 3)); + BOOST_TEST(default_count == 6); + std::fill_n(w.begin(), 10, 0); + + // --- + default_count = 0; + std::for_each(v.begin(), v.end(), + switch_statement( + _1, + case_statement<0>(++var(w[0])), + case_statement<1>(++var(w[1])), + case_statement<2>(++var(w[2])), + case_statement<3>(++var(w[3])), + case_statement<4>(++var(w[4])), + default_statement(++var(default_count)) + ) + ); + + BOOST_TEST(check(w, 4)); + BOOST_TEST(default_count == 5); + std::fill_n(w.begin(), 10, 0); + + // --- + default_count = 0; + std::for_each(v.begin(), v.end(), + switch_statement( + _1, + case_statement<0>(++var(w[0])), + case_statement<1>(++var(w[1])), + case_statement<2>(++var(w[2])), + case_statement<3>(++var(w[3])), + case_statement<4>(++var(w[4])), + case_statement<5>(++var(w[5])), + default_statement(++var(default_count)) + ) + ); + + BOOST_TEST(check(w, 5)); + BOOST_TEST(default_count == 4); + std::fill_n(w.begin(), 10, 0); + + // --- + default_count = 0; + std::for_each(v.begin(), v.end(), + switch_statement( + _1, + case_statement<0>(++var(w[0])), + case_statement<1>(++var(w[1])), + case_statement<2>(++var(w[2])), + case_statement<3>(++var(w[3])), + case_statement<4>(++var(w[4])), + case_statement<5>(++var(w[5])), + case_statement<6>(++var(w[6])), + default_statement(++var(default_count)) + ) + ); + + BOOST_TEST(check(w, 6)); + BOOST_TEST(default_count == 3); + std::fill_n(w.begin(), 10, 0); + + // --- + default_count = 0; + std::for_each(v.begin(), v.end(), + switch_statement( + _1, + case_statement<0>(++var(w[0])), + case_statement<1>(++var(w[1])), + case_statement<2>(++var(w[2])), + case_statement<3>(++var(w[3])), + case_statement<4>(++var(w[4])), + case_statement<5>(++var(w[5])), + case_statement<6>(++var(w[6])), + case_statement<7>(++var(w[7])), + default_statement(++var(default_count)) + ) + ); + + BOOST_TEST(check(w, 7)); + BOOST_TEST(default_count == 2); + std::fill_n(w.begin(), 10, 0); + +} + +int test_main(int, char* []) { + + do_switch_no_defaults_tests(); + do_switch_yes_defaults_tests(); + + return EXIT_SUCCESS; + +} +