diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/local_function | |
parent | Initial commit. (diff) | |
download | ceph-upstream/16.2.11+ds.tar.xz ceph-upstream/16.2.11+ds.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
139 files changed, 4335 insertions, 0 deletions
diff --git a/src/boost/libs/local_function/example/Jamfile.v2 b/src/boost/libs/local_function/example/Jamfile.v2 new file mode 100644 index 000000000..198027163 --- /dev/null +++ b/src/boost/libs/local_function/example/Jamfile.v2 @@ -0,0 +1,77 @@ + +# Copyright (C) 2009-2012 Lorenzo Caminiti +# Distributed under the Boost Software License, Version 1.0 +# (see accompanying file LICENSE_1_0.txt or a copy at +# http://www.boost.org/LICENSE_1_0.txt) +# Home at http://www.boost.org/libs/local_function + +import testing ; + +# Sun does not automatically detect type-of emulation mode (force it). +project : requirements <toolset>sun:<define>BOOST_TYPEOF_EMULATION ; + +run add_cxx11_lambda.cpp ; +run add_global_functor.cpp ; +run add_local_functor.cpp ; +run add_phoenix.cpp ; + +run const_block.cpp ; +compile-fail const_block_error.cpp : <variant>debug : ; +run const_block_error.cpp : <variant>release : ; +compile-fail const_block_error_cxx11_lambda.cpp ; + +run expensive_copy_cxx11_lambda.cpp ; +run expensive_copy_local_function.cpp ; + +run gcc_access.cpp ; +run gcc_lambda.cpp ; +run gcc_cxx11_lambda.cpp ; +run gcc_square.cpp ; +run gcc_store.cpp ; + +run impl_pp_keyword.cpp ; +run impl_tparam_tricks.cpp ; + +run n2529_this.cpp ; +run n2550_find_if.cpp ; + +compile-fail noncopyable_cxx11_lambda_error.cpp ; +run noncopyable_local_function.cpp ; + +run phoenix_factorial.cpp ; +run phoenix_factorial_local.cpp ; + +# Only compile but do not run profiling programs (they take a long time to run). +exe profile_global_functor : profile_global_functor.cpp + : <library>/boost/chrono//boost_chrono + <library>/boost/system//boost_system + <link>static + ; +exe profile_cxx11_lambda : profile_cxx11_lambda.cpp + : <library>/boost/chrono//boost_chrono + <library>/boost/system//boost_system + <link>static + ; +exe profile_local_function : profile_local_function.cpp + : <library>/boost/chrono//boost_chrono + <library>/boost/system//boost_system + <link>static + ; +exe profile_local_function_inline : profile_local_function_inline.cpp + : <library>/boost/chrono//boost_chrono + <library>/boost/system//boost_system + <link>static + ; +exe profile_local_functor : profile_local_functor.cpp + : <library>/boost/chrono//boost_chrono + <library>/boost/system//boost_system + <link>static + ; +exe profile_phoenix : profile_phoenix.cpp + : <library>/boost/chrono//boost_chrono + <library>/boost/system//boost_system + <link>static + ; + +run scope_exit.cpp ; + diff --git a/src/boost/libs/local_function/example/add_cxx11_lambda.cpp b/src/boost/libs/local_function/example/add_cxx11_lambda.cpp new file mode 100644 index 000000000..4a34cb5f0 --- /dev/null +++ b/src/boost/libs/local_function/example/add_cxx11_lambda.cpp @@ -0,0 +1,34 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_LAMBDAS +# error "lambda functions required" +#else + +#include <boost/detail/lightweight_test.hpp> +#include <algorithm> + +//[add_cxx11_lambda +int main(void) { // Some local scope. + int sum = 0, factor = 10; // Variables in scope to bind. + + auto add = [factor, &sum](int num) { // C++11 only. + sum += factor * num; + }; + + add(1); // Call the lambda. + int nums[] = {2, 3}; + std::for_each(nums, nums + 2, add); // Pass it to an algorithm. + + BOOST_TEST(sum == 60); // Assert final summation value. + return boost::report_errors(); +} +//] + +#endif + diff --git a/src/boost/libs/local_function/example/add_global_functor.cpp b/src/boost/libs/local_function/example/add_global_functor.cpp new file mode 100644 index 000000000..229b31525 --- /dev/null +++ b/src/boost/libs/local_function/example/add_global_functor.cpp @@ -0,0 +1,38 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/detail/lightweight_test.hpp> +#include <algorithm> + +//[add_global_functor +// Unfortunately, cannot be defined locally (so not a real alternative). +struct global_add { // Unfortunately, boilerplate code to program the class. + global_add(int& _sum, int _factor): sum(_sum), factor(_factor) {} + + inline void operator()(int num) { // Body uses C++ statement syntax. + sum += factor * num; + } + +private: // Unfortunately, cannot bind so repeat variable types. + int& sum; // Access `sum` by reference. + const int factor; // Make `factor` constant. +}; + +int main(void) { + int sum = 0, factor = 10; + + global_add add(sum, factor); + + add(1); + int nums[] = {2, 3}; + std::for_each(nums, nums + 2, add); // Passed as template parameter. + + BOOST_TEST(sum == 60); + return boost::report_errors(); +} +//] + diff --git a/src/boost/libs/local_function/example/add_local_functor.cpp b/src/boost/libs/local_function/example/add_local_functor.cpp new file mode 100644 index 000000000..e75f83f76 --- /dev/null +++ b/src/boost/libs/local_function/example/add_local_functor.cpp @@ -0,0 +1,35 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/detail/lightweight_test.hpp> + +//[add_local_functor +int main(void) { + int sum = 0, factor = 10; + + struct local_add { // Unfortunately, boilerplate code to program the class. + local_add(int& _sum, int _factor): sum(_sum), factor(_factor) {} + + inline void operator()(int num) { // Body uses C++ statement syntax. + sum += factor * num; + } + + private: // Unfortunately, cannot bind so repeat variable types. + int& sum; // Access `sum` by reference. + const int factor; // Make `factor` constant. + } add(sum, factor); + + add(1); + int nums[] = {2, 3}; + // Unfortunately, cannot pass as template parameter to `std::for_each`. + for(size_t i = 0; i < 2; ++i) add(nums[i]); + + BOOST_TEST(sum == 60); + return boost::report_errors(); +} +//] + diff --git a/src/boost/libs/local_function/example/add_phoenix.cpp b/src/boost/libs/local_function/example/add_phoenix.cpp new file mode 100644 index 000000000..10b534265 --- /dev/null +++ b/src/boost/libs/local_function/example/add_phoenix.cpp @@ -0,0 +1,34 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/spirit/include/phoenix.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <algorithm> +#include <iostream> + +//[add_phoenix +int main(void) { + using boost::phoenix::let; + using boost::phoenix::local_names::_f; + using boost::phoenix::cref; + using boost::phoenix::ref; + using boost::phoenix::arg_names::_1; + + int sum = 0, factor = 10; + int nums[] = {1, 2, 3}; + + // Passed to template, `factor` by constant, and defined in expression. + std::for_each(nums, nums + 3, let(_f = cref(factor))[ + // Unfortunately, body cannot use C++ statement syntax. + ref(sum) += _f * _1, _1 // Access `sum` by reference. + ]); + + BOOST_TEST(sum == 60); + return boost::report_errors(); +} +//] + diff --git a/src/boost/libs/local_function/example/chrono.py b/src/boost/libs/local_function/example/chrono.py new file mode 100755 index 000000000..84d6dfb3a --- /dev/null +++ b/src/boost/libs/local_function/example/chrono.py @@ -0,0 +1,25 @@ + +# Copyright (C) 2009-2012 Lorenzo Caminiti +# Distributed under the Boost Software License, Version 1.0 +# (see accompanying file LICENSE_1_0.txt or a copy at +# http://www.boost.org/LICENSE_1_0.txt) +# Home at http://www.boost.org/libs/local_function + +import sys +import time +import os + +if len(sys.argv) < 2: + print "Usage: python " + sys.argv[0] + " COMMAND [COMMAND_OPTIONS]" + print "Measure run-time of executing the specified command." + exit(1) + +cmd = "" +for arg in sys.argv[1:]: cmd += str(arg) + " " + +start = time.time() +ret = os.system(cmd) +sec = time.time() - start + +if (ret == 0): print "\n" + str(sec) + "s" + diff --git a/src/boost/libs/local_function/example/const_block.cpp b/src/boost/libs/local_function/example/const_block.cpp new file mode 100644 index 000000000..55fb5ec17 --- /dev/null +++ b/src/boost/libs/local_function/example/const_block.cpp @@ -0,0 +1,18 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "const_block.hpp" +#include <cassert> + +int main(void) { + int x = 0, y = 0; + CONST_BLOCK(x, y) { + assert(x == y); + } CONST_BLOCK_END + return 0; +} + diff --git a/src/boost/libs/local_function/example/const_block.hpp b/src/boost/libs/local_function/example/const_block.hpp new file mode 100644 index 000000000..904273410 --- /dev/null +++ b/src/boost/libs/local_function/example/const_block.hpp @@ -0,0 +1,58 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#ifndef CONST_BLOCK_HPP_ +#define CONST_BLOCK_HPP_ + +#include <boost/local_function.hpp> +#include <boost/local_function/detail/preprocessor/void_list.hpp> +#include <boost/local_function/detail/preprocessor/line_counter.hpp> +#include <boost/preprocessor/list/for_each_i.hpp> +#include <boost/preprocessor/list/adt.hpp> +#include <boost/preprocessor/tuple/eat.hpp> +#include <boost/preprocessor/punctuation/comma_if.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/preprocessor/cat.hpp> + +// PRIVATE // + +#define CONST_BLOCK_BIND_(r, unused, i, var) \ + BOOST_PP_COMMA_IF(i) const bind& var + +//[const_block_macro +#define CONST_BLOCK_(variables) \ + void BOOST_LOCAL_FUNCTION( \ + BOOST_PP_IIF(BOOST_PP_LIST_IS_NIL(variables), \ + void BOOST_PP_TUPLE_EAT(3) \ + , \ + BOOST_PP_LIST_FOR_EACH_I \ + )(CONST_BLOCK_BIND_, ~, variables) \ + ) +//] + +//[const_block_end_macro +#define CONST_BLOCK_END_(id) \ + BOOST_LOCAL_FUNCTION_NAME(BOOST_PP_CAT(const_block_, id)) \ + BOOST_PP_CAT(const_block_, id)(); /* call local function immediately */ +//] + +// PUBLIC // + +// Arguments `void | var1, var2, ... | (var1) (var2) ...`. +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# define CONST_BLOCK(void_or_seq) \ + CONST_BLOCK_(BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST(void_or_seq)) +#else +# define CONST_BLOCK(...) \ + CONST_BLOCK_(BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST(__VA_ARGS__)) +#endif + +#define CONST_BLOCK_END \ + CONST_BLOCK_END_(BOOST_LOCAL_FUNCTION_DETAIL_PP_LINE_COUNTER) + +#endif // #include guard + diff --git a/src/boost/libs/local_function/example/const_block_error.cpp b/src/boost/libs/local_function/example/const_block_error.cpp new file mode 100644 index 000000000..3e70c5037 --- /dev/null +++ b/src/boost/libs/local_function/example/const_block_error.cpp @@ -0,0 +1,20 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "const_block.hpp" +#include <cassert> + +int main(void) { + //[const_block + int x = 1, y = 2; + CONST_BLOCK(x, y) { // Constant block. + assert(x = y); // Compiler error. + } CONST_BLOCK_END + //] + return 0; +} + diff --git a/src/boost/libs/local_function/example/const_block_error_cxx11_lambda.cpp b/src/boost/libs/local_function/example/const_block_error_cxx11_lambda.cpp new file mode 100644 index 000000000..d555cc876 --- /dev/null +++ b/src/boost/libs/local_function/example/const_block_error_cxx11_lambda.cpp @@ -0,0 +1,28 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_LAMBDAS +# error "requires lambda functions" +#else + +#include <cassert> + +int main(void) { + //[const_block_cxx11_lambda + int x = 1, y = 2; + const decltype(x)& const_x = x; // Constant so cannot be modified + const decltype(y)& const_y = y; // and reference so no copy. + [&const_x, &const_y]() { // Lambda functions (C++11 only). + assert(const_x = const_y); // Unfortunately, `const_` names. + }(); + //] + return 0; +} + +#endif // LAMBDAS + diff --git a/src/boost/libs/local_function/example/expensive_copy_cxx11_lambda.cpp b/src/boost/libs/local_function/example/expensive_copy_cxx11_lambda.cpp new file mode 100644 index 000000000..e1b40136e --- /dev/null +++ b/src/boost/libs/local_function/example/expensive_copy_cxx11_lambda.cpp @@ -0,0 +1,39 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_LAMBDAS +# error "lambda functions required" +#else + +#include <iostream> +#include <cassert> + +//[expensive_copy_cxx11_lambda +struct n { + int i; + n(int _i): i(_i) {} + n(n const& x): i(x.i) { // Some time consuming copy operation. + for (unsigned i = 0; i < 10000; ++i) std::cout << '.'; + } +}; + + +int main(void) { + n x(-1); + + auto f = [x]() { // Problem: Expensive copy, but if bind + assert(x.i == -1); // by `&x` then `x` is not constant. + }; + f(); + + return 0; +} +//] + +#endif // NO_LAMBDAS + diff --git a/src/boost/libs/local_function/example/expensive_copy_local_function.cpp b/src/boost/libs/local_function/example/expensive_copy_local_function.cpp new file mode 100644 index 000000000..ed67fec9f --- /dev/null +++ b/src/boost/libs/local_function/example/expensive_copy_local_function.cpp @@ -0,0 +1,35 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/typeof/typeof.hpp> +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include <iostream> +#include <cassert> + +//[expensive_copy_local_function +struct n { + int i; + n(int _i): i(_i) {} + n(n const& x): i(x.i) { // Some time consuming copy operation. + for (unsigned i = 0; i < 10000; ++i) std::cout << '.'; + } +}; +BOOST_TYPEOF_REGISTER_TYPE(n) // Register for `bind& x` below. + +int main(void) { + n x(-1); + + void BOOST_LOCAL_FUNCTION(const bind& x) { // OK: No copy expensive + assert(x.i == -1); // copy but constant. + } BOOST_LOCAL_FUNCTION_NAME(f) + f(); + + return 0; +} +//] + diff --git a/src/boost/libs/local_function/example/gcc_access.cpp b/src/boost/libs/local_function/example/gcc_access.cpp new file mode 100644 index 000000000..0b0e171e2 --- /dev/null +++ b/src/boost/libs/local_function/example/gcc_access.cpp @@ -0,0 +1,23 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main(void) { + int nums[] = {1, 2, 3}; + int offset = -1; + int BOOST_LOCAL_FUNCTION(const bind offset, int* array, int index) { + return array[index + offset]; + } BOOST_LOCAL_FUNCTION_NAME(access) + + BOOST_TEST(access(nums, 1) == 1); + BOOST_TEST(access(nums, 2) == 2); + BOOST_TEST(access(nums, 3) == 3); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/example/gcc_cxx11_lambda.cpp b/src/boost/libs/local_function/example/gcc_cxx11_lambda.cpp new file mode 100644 index 000000000..c6299b66f --- /dev/null +++ b/src/boost/libs/local_function/example/gcc_cxx11_lambda.cpp @@ -0,0 +1,35 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_LAMBDAS +# error "lambda functions required" +#else + +#include <boost/detail/lightweight_test.hpp> +#include <algorithm> + +int main(void) { + //[gcc_cxx11_lambda + int val = 2; + int nums[] = {1, 2, 3}; + int* end = nums + 3; + + int* iter = std::find_if(nums, end, + [val](int num) -> bool { + return num == val; + } + ); + //] + + BOOST_TEST(iter != end); + BOOST_TEST(*iter == val); + return boost::report_errors(); +} + +#endif // LAMBDAS + diff --git a/src/boost/libs/local_function/example/gcc_lambda.cpp b/src/boost/libs/local_function/example/gcc_lambda.cpp new file mode 100644 index 000000000..602ad8172 --- /dev/null +++ b/src/boost/libs/local_function/example/gcc_lambda.cpp @@ -0,0 +1,36 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifndef __GNUC__ +# error "GCC required (using non-standard GCC statement expressions)" +#else + +#include "gcc_lambda.hpp" +#include <boost/detail/lightweight_test.hpp> +#include <algorithm> + +int main(void) { + //[gcc_lambda + int val = 2; + int nums[] = {1, 2, 3}; + int* end = nums + 3; + + int* iter = std::find_if(nums, end, + GCC_LAMBDA(const bind val, int num, return bool) { + return num == val; + } GCC_LAMBDA_END + ); + //] + + BOOST_TEST(iter != end); + BOOST_TEST(*iter == val); + return boost::report_errors(); +} + +#endif // GCC + diff --git a/src/boost/libs/local_function/example/gcc_lambda.hpp b/src/boost/libs/local_function/example/gcc_lambda.hpp new file mode 100644 index 000000000..665febc82 --- /dev/null +++ b/src/boost/libs/local_function/example/gcc_lambda.hpp @@ -0,0 +1,129 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#ifndef GCC_LAMBDA_HPP_ +#define GCC_LAMBDA_HPP_ + +#include <boost/local_function.hpp> +#include <boost/local_function/detail/preprocessor/void_list.hpp> +#include <boost/local_function/detail/preprocessor/line_counter.hpp> +#include <boost/local_function/detail/preprocessor/keyword/return.hpp> +#include <boost/local_function/detail/preprocessor/keyword/const_bind.hpp> +#include <boost/local_function/detail/preprocessor/keyword/bind.hpp> +#include <boost/preprocessor/list/for_each_i.hpp> +#include <boost/preprocessor/list/fold_left.hpp> +#include <boost/preprocessor/list/append.hpp> +#include <boost/preprocessor/list/enum.hpp> +#include <boost/preprocessor/list/adt.hpp> +#include <boost/preprocessor/tuple/elem.hpp> +#include <boost/preprocessor/tuple/eat.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/preprocessor/punctuation/comma_if.hpp> +#include <boost/preprocessor/facilities/expand.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/config.hpp> + +// PRIVATE // + +#define GCC_LAMBDA_SPLIT_BIND_(elem, binds, params, results) \ + (BOOST_PP_LIST_APPEND(binds, (elem, BOOST_PP_NIL)), params, results) + +#define GCC_LAMBDA_SPLIT_PARAM_(elem, binds, params, results) \ + (binds, BOOST_PP_LIST_APPEND(params, (elem, BOOST_PP_NIL)), results) + +#define GCC_LAMBDA_SPLIT_RESULT_(elem, binds, params, results) \ + (binds, params, BOOST_PP_LIST_APPEND(results, (elem, BOOT_PP_NIL))) + +#define GCC_LAMBDA_SPLIT_DISPATCH_(d, binds_params_results, elem) \ + BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_RETURN_FRONT(elem), \ + GCC_LAMBDA_SPLIT_RESULT_ \ + , BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_BIND_FRONT(elem), \ + GCC_LAMBDA_SPLIT_BIND_ \ + , BOOST_PP_IIF(BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_CONST_BIND_FRONT( \ + elem), \ + GCC_LAMBDA_SPLIT_BIND_ \ + , /* no result, no bind, and no const bind so it's param */ \ + GCC_LAMBDA_SPLIT_PARAM_ \ + )))(elem, BOOST_PP_TUPLE_ELEM(3, 0, binds_params_results), \ + BOOST_PP_TUPLE_ELEM(3, 1, binds_params_results), \ + BOOST_PP_TUPLE_ELEM(3, 2, binds_params_results)) + +#define GCC_LAMBDA_SPLIT_(list) \ + BOOST_PP_LIST_FOLD_LEFT(GCC_LAMBDA_SPLIT_DISPATCH_, \ + (BOOST_PP_NIL, BOOST_PP_NIL, BOOST_PP_NIL), list) + +#define GCC_LAMBDA_REMOVE_CONST_BIND_(r, unused, i, elem) \ + BOOST_PP_COMMA_IF(i) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_BIND_REMOVE_FRONT(elem) + +#define GCC_LAMBDA_RESULT_TYPE_(results) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_RETURN_REMOVE_FRONT( \ + BOOST_PP_LIST_FIRST(results)) + +#ifdef BOOST_NO_CXX11_LAMBDAS +//[gcc_lambda_macro +# define GCC_LAMBDA_(binds, params, results) \ + ({ /* open statement expression (GCC extension only) */ \ + BOOST_LOCAL_FUNCTION( \ + BOOST_PP_LIST_ENUM(BOOST_PP_LIST_APPEND(binds, \ + BOOST_PP_LIST_APPEND(params, \ + BOOST_PP_IIF(BOOST_PP_LIST_IS_NIL(results), \ + (return void, BOOST_PP_NIL) /* default for lambdas */ \ + , \ + results \ + )\ + ) \ + )) \ + ) +//] +#else +# define GCC_LAMBDA_(binds, params, results) \ + /* ignore const binding because not supported by C++11 lambdas */ \ + [ BOOST_PP_LIST_FOR_EACH_I(GCC_LAMBDA_REMOVE_CONST_BIND_, ~, binds) ] \ + ( BOOST_PP_LIST_ENUM(params) ) \ + BOOST_PP_IIF(BOOST_PP_LIST_IS_NIL(results), \ + BOOST_PP_TUPLE_EAT(1) /* void result type (default) */ \ + , \ + -> GCC_LAMBDA_RESULT_TYPE_ \ + )(results) +#endif + +#define GCC_LAMBDA_TUPLE_(binds_params_results) \ + GCC_LAMBDA_(BOOST_PP_TUPLE_ELEM(3, 0, binds_params_results), \ + BOOST_PP_TUPLE_ELEM(3, 1, binds_params_results), \ + BOOST_PP_TUPLE_ELEM(3, 2, binds_params_results)) + +//[gcc_lambda_end_macro +#define GCC_LAMBDA_END_(id) \ + BOOST_LOCAL_FUNCTION_NAME(BOOST_PP_CAT(gcc_lambda_, id)) \ + BOOST_PP_CAT(gcc_lambda_, id); \ + }) /* close statement expression (GCC extension only) */ +//] + +// PUBLIC // + +// Same arguments as for local functions but respect to C++11 lambdas: +// const bind v is =v, bind& v is &v, void if no return specified, no = or &. +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# define GCC_LAMBDA(void_or_seq) \ + GCC_LAMBDA_TUPLE_(GCC_LAMBDA_SPLIT_( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST(void_or_seq))) +#else +# define GCC_LAMBDA(...) \ + GCC_LAMBDA_TUPLE_(GCC_LAMBDA_SPLIT_( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_VOID_LIST(__VA_ARGS__))) +#endif + +#ifdef BOOST_NO_CXX11_LAMBDAS +# define GCC_LAMBDA_END \ + GCC_LAMBDA_END_(BOOST_LOCAL_FUNCTION_DETAIL_PP_LINE_COUNTER) +#else +# define GCC_LAMBDA_END /* nothing */ +#endif + +#endif // #include guard + diff --git a/src/boost/libs/local_function/example/gcc_square.cpp b/src/boost/libs/local_function/example/gcc_square.cpp new file mode 100644 index 000000000..6bd16e88d --- /dev/null +++ b/src/boost/libs/local_function/example/gcc_square.cpp @@ -0,0 +1,23 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> + +int add_square(int a, int b) { + int BOOST_LOCAL_FUNCTION(int z) { + return z * z; + } BOOST_LOCAL_FUNCTION_NAME(square) + + return square(a) + square(b); +} + +int main(void) { + BOOST_TEST(add_square(2, 4) == 20); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/example/gcc_store.cpp b/src/boost/libs/local_function/example/gcc_store.cpp new file mode 100644 index 000000000..57b68ad2e --- /dev/null +++ b/src/boost/libs/local_function/example/gcc_store.cpp @@ -0,0 +1,33 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/function.hpp> +#include <boost/detail/lightweight_test.hpp> + +void intermediate(boost::function<void (int, int)> store_func, int size) { + store_func(size - 1, -1); +} + +void hack(int* array, int size) { + void BOOST_LOCAL_FUNCTION(bind array, int index, int value) { + array[index] = value; + } BOOST_LOCAL_FUNCTION_NAME(store) + + intermediate(store, size); +} + +int main(void) { + int nums[] = {1, 2, 3}; + hack(nums, 3); + + BOOST_TEST(nums[0] == 1); + BOOST_TEST(nums[1] == 2); + BOOST_TEST(nums[2] == -1); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/example/impl_pp_keyword.cpp b/src/boost/libs/local_function/example/impl_pp_keyword.cpp new file mode 100644 index 000000000..7a03ae77b --- /dev/null +++ b/src/boost/libs/local_function/example/impl_pp_keyword.cpp @@ -0,0 +1,28 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +//[impl_pp_keyword +#include <boost/local_function/detail/preprocessor/keyword/thisunderscore.hpp> +#include <boost/local_function/detail/preprocessor/keyword/const.hpp> +#include <boost/local_function/detail/preprocessor/keyword/bind.hpp> +#include <boost/detail/lightweight_test.hpp> + +// Expand to 1 if space-separated tokens end with `this_`, 0 otherwise. +#define IS_THIS_BACK(tokens) \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_IS_THISUNDERSCORE_BACK( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_BIND_REMOVE_FRONT( \ + BOOST_LOCAL_FUNCTION_DETAIL_PP_KEYWORD_CONST_REMOVE_FRONT( \ + tokens \ + ))) + +int main(void) { + BOOST_TEST(IS_THIS_BACK(const bind this_) == 1); + BOOST_TEST(IS_THIS_BACK(const bind& x) == 0); + return boost::report_errors(); +} +//] + diff --git a/src/boost/libs/local_function/example/impl_tparam_tricks.cpp b/src/boost/libs/local_function/example/impl_tparam_tricks.cpp new file mode 100644 index 000000000..aa394df2d --- /dev/null +++ b/src/boost/libs/local_function/example/impl_tparam_tricks.cpp @@ -0,0 +1,71 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +//[impl_tparam_tricks +#include <boost/detail/lightweight_test.hpp> +#include <vector> +#include <algorithm> + +// Casting functor trick. +struct casting_func { + explicit casting_func(void* obj, void (*call)(void*, const int&)) + : obj_(obj), call_(call) {} + // Unfortunately, function pointer call is not inlined. + inline void operator()(const int& num) { call_(obj_, num); } +private: + void* obj_; + void (*call_)(void*, const int&); +}; + +// Virtual functor trick. +struct virtual_func { + struct interface { + // Unfortunately, virtual function call is not inlined. + inline virtual void operator()(const int&) {} + }; + explicit virtual_func(interface& func): func_(&func) {} + inline void operator()(const int& num) { (*func_)(num); } +private: + interface* func_; +}; + +int main(void) { + int sum = 0, factor = 10; + + // Local class for local function. + struct local_add : virtual_func::interface { + explicit local_add(int& _sum, const int& _factor) + : sum_(_sum), factor_(_factor) {} + inline void operator()(const int& num) { + body(sum_, factor_, num); + } + inline static void call(void* obj, const int& num) { + local_add* self = static_cast<local_add*>(obj); + self->body(self->sum_, self->factor_, num); + } + private: + int& sum_; + const int& factor_; + inline void body(int& sum, const int& factor, const int& num) { + sum += factor * num; + } + } add_local(sum, factor); + casting_func add_casting(&add_local, &local_add::call); + virtual_func add_virtual(add_local); + + std::vector<int> v(10); + std::fill(v.begin(), v.end(), 1); + + // std::for_each(v.begin(), v.end(), add_local); // Error but OK on C++11. + std::for_each(v.begin(), v.end(), add_casting); // OK. + std::for_each(v.begin(), v.end(), add_virtual); // OK. + + BOOST_TEST(sum == 200); + return boost::report_errors(); +} +//] + diff --git a/src/boost/libs/local_function/example/n2529_this.cpp b/src/boost/libs/local_function/example/n2529_this.cpp new file mode 100644 index 000000000..1a954ad3e --- /dev/null +++ b/src/boost/libs/local_function/example/n2529_this.cpp @@ -0,0 +1,47 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/typeof/typeof.hpp> +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include <boost/detail/lightweight_test.hpp> +#include <vector> +#include <algorithm> + +struct v; +BOOST_TYPEOF_REGISTER_TYPE(v) // Register before `bind this_` below. + +struct v { + std::vector<int> nums; + + v(const std::vector<int>& numbers): nums(numbers) {} + + void change_sign_all(const std::vector<int>& indices) { + void BOOST_LOCAL_FUNCTION(bind this_, int i) { // Bind object `this`. + this_->nums.at(i) = -this_->nums.at(i); + } BOOST_LOCAL_FUNCTION_NAME(complement) + + std::for_each(indices.begin(), indices.end(), complement); + } +}; + +int main(void) { + std::vector<int> n(3); + n[0] = 1; n[1] = 2; n[2] = 3; + + std::vector<int> i(2); + i[0] = 0; i[1] = 2; // Will change n[0] and n[2] but not n[1]. + + v vn(n); + vn.change_sign_all(i); + + BOOST_TEST(vn.nums.at(0) == -1); + BOOST_TEST(vn.nums.at(1) == 2); + BOOST_TEST(vn.nums.at(2) == -3); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/example/n2550_find_if.cpp b/src/boost/libs/local_function/example/n2550_find_if.cpp new file mode 100644 index 000000000..f372707a3 --- /dev/null +++ b/src/boost/libs/local_function/example/n2550_find_if.cpp @@ -0,0 +1,44 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/typeof/typeof.hpp> +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include <boost/detail/lightweight_test.hpp> +#include <vector> +#include <algorithm> + +struct employee { + int salary; + explicit employee(const int& a_salary): salary(a_salary) {} +}; +BOOST_TYPEOF_REGISTER_TYPE(employee) // Register for `NAME` below. + +int main(void) { + std::vector<employee> employees; + employees.push_back(employee(85000)); + employees.push_back(employee(100000)); + employees.push_back(employee(120000)); + + int min_salary = 100000; + int u_limit = min_salary + 1; + + bool BOOST_LOCAL_FUNCTION(const bind& min_salary, const bind& u_limit, + const employee& e) { + return e.salary >= min_salary && e.salary < u_limit; + } BOOST_LOCAL_FUNCTION_NAME(between) + + // Pass local function to an STL algorithm as a template paramter (this + // cannot be done with plain member functions of local classes). + std::vector<employee>::iterator i = std::find_if( + employees.begin(), employees.end(), between); + + BOOST_TEST(i != employees.end()); + BOOST_TEST(i->salary >= min_salary && i->salary < u_limit); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/example/noncopyable_cxx11_lambda_error.cpp b/src/boost/libs/local_function/example/noncopyable_cxx11_lambda_error.cpp new file mode 100644 index 000000000..706079ebc --- /dev/null +++ b/src/boost/libs/local_function/example/noncopyable_cxx11_lambda_error.cpp @@ -0,0 +1,36 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_LAMBDAS +# error "lambda functions required" +#else + +#include <boost/noncopyable.hpp> +#include <cassert> + +//[noncopyable_cxx11_lambda_error +struct n: boost::noncopyable { + int i; + n(int _i): i(_i) {} +}; + + +int main(void) { + n x(-1); + + auto f = [x](void) { // Error: x is non-copyable, but if + assert(x.i == -1); // bind `&x` then `x` is not constant. + }; + f(); + + return 0; +} +//] + +#endif // LAMBDAS + diff --git a/src/boost/libs/local_function/example/noncopyable_local_function.cpp b/src/boost/libs/local_function/example/noncopyable_local_function.cpp new file mode 100644 index 000000000..b4ef9ad5a --- /dev/null +++ b/src/boost/libs/local_function/example/noncopyable_local_function.cpp @@ -0,0 +1,32 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/noncopyable.hpp> +#include <boost/typeof/typeof.hpp> +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include <cassert> + +//[noncopyable_local_function +struct n: boost::noncopyable { + int i; + n(int _i): i(_i) {} +}; +BOOST_TYPEOF_REGISTER_TYPE(n) // Register for `bind& x` below. + +int main(void) { + n x(-1); + + void BOOST_LOCAL_FUNCTION(const bind& x) { // OK: No copy + assert(x.i == -1); // and constant. + } BOOST_LOCAL_FUNCTION_NAME(f) + f(); + + return 0; +} +//] + diff --git a/src/boost/libs/local_function/example/phoenix_factorial.cpp b/src/boost/libs/local_function/example/phoenix_factorial.cpp new file mode 100644 index 000000000..bdc8306f6 --- /dev/null +++ b/src/boost/libs/local_function/example/phoenix_factorial.cpp @@ -0,0 +1,40 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/phoenix/core.hpp> +#include <boost/phoenix/function.hpp> +#include <boost/detail/lightweight_test.hpp> + +//[phoenix_factorial +struct factorial_impl { // Phoenix function from global functor. + template<typename Sig> + struct result; + + template<typename This, typename Arg> + struct result<This (Arg)> : result<This (Arg const&)> {}; + + template<typename This, typename Arg> + struct result<This (Arg&)> { typedef Arg type; }; + + template<typename Arg> // Polymorphic. + Arg operator()(Arg n) const { + return (n <= 0) ? 1 : n * (*this)(n - 1); + } +}; + +int main(void) { + using boost::phoenix::arg_names::arg1; + + boost::phoenix::function<factorial_impl> factorial; + + int i = 4; + BOOST_TEST(factorial(i)() == 24); // Call. + BOOST_TEST(factorial(arg1)(i) == 24); // Lazy call. + return boost::report_errors(); +} +//] + diff --git a/src/boost/libs/local_function/example/phoenix_factorial_local.cpp b/src/boost/libs/local_function/example/phoenix_factorial_local.cpp new file mode 100644 index 000000000..c52c094b5 --- /dev/null +++ b/src/boost/libs/local_function/example/phoenix_factorial_local.cpp @@ -0,0 +1,31 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/function.hpp> +#include <boost/phoenix/core.hpp> +#include <boost/phoenix/function.hpp> +#include <boost/detail/lightweight_test.hpp> + +//[phoenix_factorial_local +int main(void) { + using boost::phoenix::arg_names::arg1; + + int BOOST_LOCAL_FUNCTION(int n) { // Unfortunately, monomorphic. + return (n <= 0) ? 1 : n * factorial_impl(n - 1); + } BOOST_LOCAL_FUNCTION_NAME(recursive factorial_impl) + + boost::phoenix::function< boost::function<int (int)> > + factorial(factorial_impl); // Phoenix function from local function. + + int i = 4; + BOOST_TEST(factorial(i)() == 24); // Call. + BOOST_TEST(factorial(arg1)(i) == 24); // Lazy call. + return boost::report_errors(); +} +//] + diff --git a/src/boost/libs/local_function/example/profile.xls b/src/boost/libs/local_function/example/profile.xls Binary files differnew file mode 100644 index 000000000..9087ed174 --- /dev/null +++ b/src/boost/libs/local_function/example/profile.xls diff --git a/src/boost/libs/local_function/example/profile_cxx11_lambda.cpp b/src/boost/libs/local_function/example/profile_cxx11_lambda.cpp new file mode 100644 index 000000000..f2c1c26e5 --- /dev/null +++ b/src/boost/libs/local_function/example/profile_cxx11_lambda.cpp @@ -0,0 +1,44 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_LAMBDAS +# error "lambda functions required" +#else + +#include <boost/chrono.hpp> +#include <vector> +#include <algorithm> +#include <iostream> +#include "profile_helpers.hpp" + +int main(int argc, char* argv[]) { + unsigned long size = 0, trials = 0; + profile::args(argc, argv, size, trials); + + double sum = 0.0; + int factor = 1; + + std::vector<double> v(size); + std::fill(v.begin(), v.end(), 1.0); + + boost::chrono::duration<double> trials_sec; + for(unsigned long i = 0; i < trials; ++i) { + boost::chrono::system_clock::time_point start = + boost::chrono::system_clock::now(); + std::for_each(v.begin(), v.end(), [&sum, factor](const double& num) { + sum += factor * num; + }); + trials_sec += boost::chrono::system_clock::now() - start; + } + + profile::display(size, trials, sum, trials_sec.count()); + return 0; +} + +#endif // LAMBDAS + diff --git a/src/boost/libs/local_function/example/profile_gcc_cxx11_debug.png b/src/boost/libs/local_function/example/profile_gcc_cxx11_debug.png Binary files differnew file mode 100644 index 000000000..431f2bb37 --- /dev/null +++ b/src/boost/libs/local_function/example/profile_gcc_cxx11_debug.png diff --git a/src/boost/libs/local_function/example/profile_gcc_cxx11_release.png b/src/boost/libs/local_function/example/profile_gcc_cxx11_release.png Binary files differnew file mode 100644 index 000000000..eeb371a4a --- /dev/null +++ b/src/boost/libs/local_function/example/profile_gcc_cxx11_release.png diff --git a/src/boost/libs/local_function/example/profile_gcc_debug.png b/src/boost/libs/local_function/example/profile_gcc_debug.png Binary files differnew file mode 100644 index 000000000..f907ca139 --- /dev/null +++ b/src/boost/libs/local_function/example/profile_gcc_debug.png diff --git a/src/boost/libs/local_function/example/profile_gcc_release.png b/src/boost/libs/local_function/example/profile_gcc_release.png Binary files differnew file mode 100644 index 000000000..1a23e56b1 --- /dev/null +++ b/src/boost/libs/local_function/example/profile_gcc_release.png diff --git a/src/boost/libs/local_function/example/profile_global_functor.cpp b/src/boost/libs/local_function/example/profile_global_functor.cpp new file mode 100644 index 000000000..6e104e4b4 --- /dev/null +++ b/src/boost/libs/local_function/example/profile_global_functor.cpp @@ -0,0 +1,51 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/chrono.hpp> +#include <vector> +#include <algorithm> +#include <iostream> +#include "profile_helpers.hpp" + +struct global_add { + global_add(double& _sum, const int& _factor): sum(_sum), factor(_factor) {} + inline void operator()(const double& num) { + sum += factor * num; + } +private: + double& sum; + const int& factor; +}; + +int main(int argc, char* argv[]) { + unsigned long size = 0, trials =0; + profile::args(argc, argv, size, trials); + + double sum = 0.0; + int factor = 1; + + boost::chrono::system_clock::time_point start = + boost::chrono::system_clock::now(); + global_add add(sum, factor); + boost::chrono::duration<double> decl_sec = + boost::chrono::system_clock::now() - start; + + std::vector<double> v(size); + std::fill(v.begin(), v.end(), 1.0); + + boost::chrono::duration<double> trials_sec; + for(unsigned long i = 0; i < trials; ++i) { + boost::chrono::system_clock::time_point start = + boost::chrono::system_clock::now(); + std::for_each(v.begin(), v.end(), add); + trials_sec += boost::chrono::system_clock::now() - start; + } + + profile::display(size, trials, sum, trials_sec.count(), decl_sec.count()); + return 0; +} + diff --git a/src/boost/libs/local_function/example/profile_helpers.hpp b/src/boost/libs/local_function/example/profile_helpers.hpp new file mode 100644 index 000000000..fe7969de5 --- /dev/null +++ b/src/boost/libs/local_function/example/profile_helpers.hpp @@ -0,0 +1,54 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#ifndef PROFILE_HELPERS_HPP_ +#define PROFILE_HELPERS_HPP_ + +#include <iostream> +#include <cassert> + +namespace profile { + +void args(int argc, char* argv[], unsigned long& size, unsigned long& trials) { + size = 100000000; // Defaults. + trials = 10; // Default. + if (argc != 1 && argc != 2 && argc != 3) { + std::cerr << "ERROR: Incorrect argument(s)" << std::endl; + std::cerr << "Usage: " << argv[0] << " [SIZE] [TRIALS]" << + std::endl; + std::cerr << "Defaults: SIZE = " << double(size) << ", TRIALS = " << + double(trials) << std::endl; + exit(1); + } + if (argc >= 2) size = atol(argv[1]); + if (argc >= 3) trials = atol(argv[2]); + + std::clog << "vector size = " << double(size) << std::endl; + std::clog << "number of trials = " << double(trials) << std::endl; + std::clog << "number of calls = " << double(size) * double(trials) << + std::endl; +} + +void display(const unsigned long& size, const unsigned long& trials, + const double& sum, const double& trials_sec, + const double& decl_sec = 0.0) { + std::clog << "sum = " << sum << std::endl; + std::clog << "declaration run-time [s] = " << decl_sec << std::endl; + std::clog << "trials run-time [s] = " << trials_sec << std::endl; + + double avg_sec = decl_sec + trials_sec / trials; + std::clog << "average run-time [s] = declaration run-time + trials " << + "run-time / number of trials = " << std::endl; + std::cout << avg_sec << std::endl; // To cout so it can be parsed easily. + + assert(sum == double(size) * double(trials)); +} + +} // namespace + +#endif // #include guard + diff --git a/src/boost/libs/local_function/example/profile_legend_cxx11_lambda.png b/src/boost/libs/local_function/example/profile_legend_cxx11_lambda.png Binary files differnew file mode 100644 index 000000000..58770b195 --- /dev/null +++ b/src/boost/libs/local_function/example/profile_legend_cxx11_lambda.png diff --git a/src/boost/libs/local_function/example/profile_legend_global_functor.png b/src/boost/libs/local_function/example/profile_legend_global_functor.png Binary files differnew file mode 100644 index 000000000..d7f5b70fd --- /dev/null +++ b/src/boost/libs/local_function/example/profile_legend_global_functor.png diff --git a/src/boost/libs/local_function/example/profile_legend_local_function.png b/src/boost/libs/local_function/example/profile_legend_local_function.png Binary files differnew file mode 100644 index 000000000..5b9b51766 --- /dev/null +++ b/src/boost/libs/local_function/example/profile_legend_local_function.png diff --git a/src/boost/libs/local_function/example/profile_legend_local_function_inline.png b/src/boost/libs/local_function/example/profile_legend_local_function_inline.png Binary files differnew file mode 100644 index 000000000..809de56d9 --- /dev/null +++ b/src/boost/libs/local_function/example/profile_legend_local_function_inline.png diff --git a/src/boost/libs/local_function/example/profile_legend_local_functor.png b/src/boost/libs/local_function/example/profile_legend_local_functor.png Binary files differnew file mode 100644 index 000000000..6038c5776 --- /dev/null +++ b/src/boost/libs/local_function/example/profile_legend_local_functor.png diff --git a/src/boost/libs/local_function/example/profile_legend_phoenix.png b/src/boost/libs/local_function/example/profile_legend_phoenix.png Binary files differnew file mode 100644 index 000000000..249962540 --- /dev/null +++ b/src/boost/libs/local_function/example/profile_legend_phoenix.png diff --git a/src/boost/libs/local_function/example/profile_local_function.cpp b/src/boost/libs/local_function/example/profile_local_function.cpp new file mode 100644 index 000000000..1e2029a54 --- /dev/null +++ b/src/boost/libs/local_function/example/profile_local_function.cpp @@ -0,0 +1,45 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/chrono.hpp> +#include <vector> +#include <algorithm> +#include <iostream> +#include "profile_helpers.hpp" + +int main(int argc, char* argv[]) { + unsigned long size = 0, trials = 0; + profile::args(argc, argv, size, trials); + + double sum = 0.0; + int factor = 1; + + boost::chrono::system_clock::time_point start = + boost::chrono::system_clock::now(); + void BOOST_LOCAL_FUNCTION( + const double& num, bind& sum, const bind& factor) { + sum += factor * num; + } BOOST_LOCAL_FUNCTION_NAME(add) + boost::chrono::duration<double> decl_sec = + boost::chrono::system_clock::now() - start; + + std::vector<double> v(size); + std::fill(v.begin(), v.end(), 1.0); + + boost::chrono::duration<double> trials_sec; + for(unsigned long i = 0; i < trials; ++i) { + boost::chrono::system_clock::time_point start = + boost::chrono::system_clock::now(); + std::for_each(v.begin(), v.end(), add); + trials_sec += boost::chrono::system_clock::now() - start; + } + + profile::display(size, trials, sum, trials_sec.count(), decl_sec.count()); + return 0; +} + diff --git a/src/boost/libs/local_function/example/profile_local_function_inline.cpp b/src/boost/libs/local_function/example/profile_local_function_inline.cpp new file mode 100644 index 000000000..8b113ac7a --- /dev/null +++ b/src/boost/libs/local_function/example/profile_local_function_inline.cpp @@ -0,0 +1,45 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/chrono.hpp> +#include <vector> +#include <algorithm> +#include <iostream> +#include "profile_helpers.hpp" + +int main(int argc, char* argv[]) { + unsigned long size = 0, trials = 0; + profile::args(argc, argv, size, trials); + + double sum = 0.0; + int factor = 1; + + boost::chrono::system_clock::time_point start = + boost::chrono::system_clock::now(); + void BOOST_LOCAL_FUNCTION( + const double& num, bind& sum, const bind& factor) { + sum += factor * num; + } BOOST_LOCAL_FUNCTION_NAME(inline add) // Inlined. + boost::chrono::duration<double> decl_sec = + boost::chrono::system_clock::now() - start; + + std::vector<double> v(size); + std::fill(v.begin(), v.end(), 1.0); + + boost::chrono::duration<double> trials_sec; + for(unsigned long i = 0; i < trials; ++i) { + boost::chrono::system_clock::time_point start = + boost::chrono::system_clock::now(); + for(unsigned long j = 0; j < v.size(); ++j) add(v[j]); // No for_each. + trials_sec += boost::chrono::system_clock::now() - start; + } + + profile::display(size, trials, sum, trials_sec.count(), decl_sec.count()); + return 0; +} + diff --git a/src/boost/libs/local_function/example/profile_local_functor.cpp b/src/boost/libs/local_function/example/profile_local_functor.cpp new file mode 100644 index 000000000..abdef0bb7 --- /dev/null +++ b/src/boost/libs/local_function/example/profile_local_functor.cpp @@ -0,0 +1,50 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/chrono.hpp> +#include <vector> +#include <algorithm> +#include <iostream> +#include "profile_helpers.hpp" + +int main(int argc, char* argv[]) { + unsigned long size = 0, trials = 0; + profile::args(argc, argv, size, trials); + + double sum = 0.0; + int factor = 1; + + boost::chrono::system_clock::time_point start = + boost::chrono::system_clock::now(); + struct local_add { + local_add(double& _sum, const int& _factor): + sum(_sum), factor(_factor) {} + inline void operator()(const double& num) { + sum += factor * num; + } + private: + double& sum; + const int& factor; + } add(sum, factor); + boost::chrono::duration<double> decl_sec = + boost::chrono::system_clock::now() - start; + + std::vector<double> v(size); + std::fill(v.begin(), v.end(), 1.0); + + boost::chrono::duration<double> trials_sec; + for(unsigned long i = 0; i < trials; ++i) { + boost::chrono::system_clock::time_point start = + boost::chrono::system_clock::now(); + for(unsigned long j = 0; j < v.size(); ++j) add(v[j]); // No for_each. + trials_sec += boost::chrono::system_clock::now() - start; + } + + profile::display(size, trials, sum, trials_sec.count(), decl_sec.count()); + return 0; +} + diff --git a/src/boost/libs/local_function/example/profile_msvc_debug.png b/src/boost/libs/local_function/example/profile_msvc_debug.png Binary files differnew file mode 100644 index 000000000..859744b73 --- /dev/null +++ b/src/boost/libs/local_function/example/profile_msvc_debug.png diff --git a/src/boost/libs/local_function/example/profile_msvc_release.png b/src/boost/libs/local_function/example/profile_msvc_release.png Binary files differnew file mode 100644 index 000000000..ea14d44a1 --- /dev/null +++ b/src/boost/libs/local_function/example/profile_msvc_release.png diff --git a/src/boost/libs/local_function/example/profile_phoenix.cpp b/src/boost/libs/local_function/example/profile_phoenix.cpp new file mode 100644 index 000000000..7bd2088a6 --- /dev/null +++ b/src/boost/libs/local_function/example/profile_phoenix.cpp @@ -0,0 +1,45 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/spirit/home/phoenix/statement/sequence.hpp> +#include <boost/spirit/home/phoenix/core/reference.hpp> +#include <boost/spirit/home/phoenix/core/argument.hpp> +#include <boost/spirit/home/phoenix/operator/arithmetic.hpp> +#include <boost/chrono.hpp> +#include <iostream> +#include <vector> +#include <algorithm> +#include "profile_helpers.hpp" + +int main(int argc, char* argv[]) { + unsigned long size = 0, trials = 0; + profile::args(argc, argv, size, trials); + + double sum = 0.0; + int factor = 1; + + std::vector<double> v(size); + std::fill(v.begin(), v.end(), 1.0); + + boost::chrono::duration<double> trials_sec; + for(unsigned long i = 0; i < trials; ++i) { + boost::chrono::system_clock::time_point start = + boost::chrono::system_clock::now(); + + using boost::phoenix::ref; + using boost::phoenix::arg_names::_1; + std::for_each(v.begin(), v.end(), ( + ref(sum) += factor * _1 + )); + + trials_sec += boost::chrono::system_clock::now() - start; + } + + profile::display(size, trials, sum, trials_sec.count()); + return 0; +} + diff --git a/src/boost/libs/local_function/example/scope_exit.cpp b/src/boost/libs/local_function/example/scope_exit.cpp new file mode 100644 index 000000000..607bf6be0 --- /dev/null +++ b/src/boost/libs/local_function/example/scope_exit.cpp @@ -0,0 +1,110 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "scope_exit.hpp" +#include <boost/foreach.hpp> +#include <boost/typeof/typeof.hpp> +#include <boost/typeof/std/vector.hpp> +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include <boost/detail/lightweight_test.hpp> +#include <vector> +#include <iostream> +#include <sstream> + +class person { + friend class world; +public: + typedef unsigned int id_t; + typedef unsigned int evolution_t; + + person(void): id_(0), evolution_(0) {} + + friend std::ostream& operator<<(std::ostream& o, person const& p) { + return o << "person(" << p.id_ << ", " << p.evolution_ << ")"; + } +private: + id_t id_; + evolution_t evolution_; +}; +BOOST_TYPEOF_REGISTER_TYPE(person) + +class world { +public: + typedef unsigned int id_t; + + world(void): next_id_(1) {} + + void add_person(person const& a_person); + + friend std::ostream& operator<<(std::ostream& o, world const& w) { + o << "world(" << w.next_id_ << ", {"; + BOOST_FOREACH(person const& p, w.persons_) { + o << " " << p << ", "; + } + return o << "})"; + } +private: + id_t next_id_; + std::vector<person> persons_; +}; +BOOST_TYPEOF_REGISTER_TYPE(world) + +void world::add_person(person const& a_person) { + persons_.push_back(a_person); + + // This block must be no-throw. + //[scope_exit + person& p = persons_.back(); + person::evolution_t checkpoint = p.evolution_; + + SCOPE_EXIT(const bind checkpoint, const bind& p, bind this_) { + if (checkpoint == p.evolution_) this_->persons_.pop_back(); + } SCOPE_EXIT_END + //] + + // ... + + checkpoint = ++p.evolution_; + + // Assign new id to the person. + world::id_t const prev_id = p.id_; + p.id_ = next_id_++; + SCOPE_EXIT(const bind checkpoint, const bind prev_id, bind& p, + bind& next_id_) { + if (checkpoint == p.evolution_) { + next_id_ = p.id_; + p.id_ = prev_id; + } + } SCOPE_EXIT_END + + // ... + + checkpoint = ++p.evolution_; +} + +int main(void) { + person adam, eva; + std::ostringstream oss; + oss << adam; + std::cout << oss.str() << std::endl; + BOOST_TEST(oss.str() == "person(0, 0)"); + + oss.str(""); + oss << eva; + std::cout << oss.str() << std::endl; + BOOST_TEST(oss.str() == "person(0, 0)"); + + world w; + w.add_person(adam); + w.add_person(eva); + oss.str(""); + oss << w; + std::cout << oss.str() << std::endl; + BOOST_TEST(oss.str() == "world(3, { person(1, 2), person(2, 2), })"); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/example/scope_exit.hpp b/src/boost/libs/local_function/example/scope_exit.hpp new file mode 100644 index 000000000..5876b1406 --- /dev/null +++ b/src/boost/libs/local_function/example/scope_exit.hpp @@ -0,0 +1,51 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#ifndef SCOPE_EXIT_HPP_ +#define SCOPE_EXIT_HPP_ + +#include <boost/local_function.hpp> +#include <boost/local_function/detail/preprocessor/line_counter.hpp> +#include <boost/function.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/config.hpp> + +//[scope_exit_class +struct scope_exit { + scope_exit(boost::function<void (void)> f): f_(f) {} + ~scope_exit(void) { f_(); } +private: + boost::function<void (void)> f_; +}; +//] + +// PRIVATE // + +//[scope_exit_end_macro +#define SCOPE_EXIT_END_(id) \ + BOOST_LOCAL_FUNCTION_NAME(BOOST_PP_CAT(scope_exit_func_, id)) \ + scope_exit BOOST_PP_CAT(scope_exit_, id)( \ + BOOST_PP_CAT(scope_exit_func_, id)); +//] + +// PUBLIC // + +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# define SCOPE_EXIT(void_or_seq) \ + void BOOST_LOCAL_FUNCTION(void_or_seq) +#else +//[scope_exit_macro +# define SCOPE_EXIT(...) \ + void BOOST_LOCAL_FUNCTION(__VA_ARGS__) +//] +#endif + +#define SCOPE_EXIT_END \ + SCOPE_EXIT_END_(BOOST_LOCAL_FUNCTION_DETAIL_PP_LINE_COUNTER) + +#endif // #include guard + diff --git a/src/boost/libs/local_function/index.html b/src/boost/libs/local_function/index.html new file mode 100644 index 000000000..e55456a36 --- /dev/null +++ b/src/boost/libs/local_function/index.html @@ -0,0 +1,15 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> + <head> + <meta http-equiv="refresh" content="0; URL=doc/html/index.html"> + </head> + <body> + Automatic redirection failed, click this + <a href="doc/html/index.html">link</a> <hr> + <p>© Copyright Lorenzo Caminiti, 2009-2012</p> + <p>Distributed under the Boost Software License, Version 1.0 (see + accompanying file <a href="../../LICENSE_1_0.txt"> + LICENSE_1_0.txt</a> or a copy at + <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p> + </body> +</html> diff --git a/src/boost/libs/local_function/meta/libraries.json b/src/boost/libs/local_function/meta/libraries.json new file mode 100644 index 000000000..8d5f72f13 --- /dev/null +++ b/src/boost/libs/local_function/meta/libraries.json @@ -0,0 +1,14 @@ +{ + "key": "local_function", + "name": "Local Function", + "authors": [ + "Lorenzo Caminiti" + ], + "description": "Program functions locally, within other functions, directly within the scope where they are needed.", + "category": [ + "Function-objects" + ], + "maintainers": [ + "Lorenzo Caminiti <lorcaminiti -at- gmail.com>" + ] +} diff --git a/src/boost/libs/local_function/test/Jamfile.v2 b/src/boost/libs/local_function/test/Jamfile.v2 new file mode 100644 index 000000000..a12f5c340 --- /dev/null +++ b/src/boost/libs/local_function/test/Jamfile.v2 @@ -0,0 +1,51 @@ + +# Copyright (C) 2009-2012 Lorenzo Caminiti +# Distributed under the Boost Software License, Version 1.0 +# (see accompanying file LICENSE_1_0.txt or a copy at +# http://www.boost.org/LICENSE_1_0.txt) +# Home at http://www.boost.org/libs/local_function + +import testing ; + +# Sun does not automatically detect type-of emulation mode (force it). +project : requirements <toolset>sun:<define>BOOST_TYPEOF_EMULATION ; + +rule vaseq ( command target ) +{ + $(command) $(target).cpp ; + $(command) $(target)_seq.cpp ; + $(command) $(target)_seq_nova.cpp ; +} + +vaseq run add ; +vaseq run add_classifiers ; +vaseq run add_default ; +vaseq run add_except ; +vaseq run add_inline ; +vaseq run add_params_only ; +vaseq run add_template ; +vaseq run add_this ; +vaseq run add_typed ; +vaseq run add_with_default ; +vaseq run all_decl ; +vaseq run factorial ; +vaseq run goto ; +vaseq compile-fail goto_error ; +vaseq run macro_commas ; +vaseq run nesting ; +vaseq run operator ; +vaseq compile-fail operator_error ; +vaseq run overload ; +vaseq run return_assign ; +vaseq run return_derivative ; +vaseq run return_inc ; +vaseq run return_setget ; +vaseq run return_this ; +vaseq run same_line ; +vaseq run transform ; +vaseq run typeof ; +vaseq run typeof_template ; + +run ten_void.cpp ; +run ten_void_nova.cpp ; + diff --git a/src/boost/libs/local_function/test/add.cpp b/src/boost/libs/local_function/test/add.cpp new file mode 100644 index 000000000..4b8ca3f1b --- /dev/null +++ b/src/boost/libs/local_function/test/add.cpp @@ -0,0 +1,35 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <algorithm> + +//[add +int main(void) { // Some local scope. + int sum = 0, factor = 10; // Variables in scope to bind. + + void BOOST_LOCAL_FUNCTION(const bind factor, bind& sum, int num) { + sum += factor * num; + } BOOST_LOCAL_FUNCTION_NAME(add) + + add(1); // Call the local function. + int nums[] = {2, 3}; + std::for_each(nums, nums + 2, add); // Pass it to an algorithm. + + BOOST_TEST(sum == 60); // Assert final summation value. + return boost::report_errors(); +} +//] + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/add_classifiers.cpp b/src/boost/libs/local_function/test/add_classifiers.cpp new file mode 100644 index 000000000..7dcf2dc04 --- /dev/null +++ b/src/boost/libs/local_function/test/add_classifiers.cpp @@ -0,0 +1,30 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#if !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) +# error "auto-declarations not allowed (using `auto` as storage classifier)" +#elif defined(BOOST_NO_CXX11_VARIADIC_MACROS) +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main(void) { + //[add_classifiers + int BOOST_LOCAL_FUNCTION(auto int x, register int y) { // Classifiers. + return x + y; + } BOOST_LOCAL_FUNCTION_NAME(add) + //] + + BOOST_TEST(add(1, 2) == 3); + return boost::report_errors(); +} + +#endif // AUTO_DECLARATIONS && VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/add_classifiers_seq.cpp b/src/boost/libs/local_function/test/add_classifiers_seq.cpp new file mode 100644 index 000000000..0499f875c --- /dev/null +++ b/src/boost/libs/local_function/test/add_classifiers_seq.cpp @@ -0,0 +1,26 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifndef BOOST_NO_CXX11_AUTO_DECLARATIONS +# error "auto-declarations not allowed (using `auto` as storage classifier)" +#else + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main(void) { + int BOOST_LOCAL_FUNCTION( (auto int x) (register int y) ) { + return x + y; + } BOOST_LOCAL_FUNCTION_NAME(add) + + BOOST_TEST(add(1, 2) == 3); + return boost::report_errors(); +} + +#endif // AUTO_DECLARATIONS + diff --git a/src/boost/libs/local_function/test/add_classifiers_seq_nova.cpp b/src/boost/libs/local_function/test/add_classifiers_seq_nova.cpp new file mode 100644 index 000000000..346258468 --- /dev/null +++ b/src/boost/libs/local_function/test/add_classifiers_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "add_classifiers_seq.cpp" + diff --git a/src/boost/libs/local_function/test/add_default.cpp b/src/boost/libs/local_function/test/add_default.cpp new file mode 100644 index 000000000..86c4e115a --- /dev/null +++ b/src/boost/libs/local_function/test/add_default.cpp @@ -0,0 +1,28 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main(void) { + //[add_default + int BOOST_LOCAL_FUNCTION(int x, int y, default 2) { // Default parameter. + return x + y; + } BOOST_LOCAL_FUNCTION_NAME(add) + + BOOST_TEST(add(1) == 3); + //] + return boost::report_errors(); +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/add_default_seq.cpp b/src/boost/libs/local_function/test/add_default_seq.cpp new file mode 100644 index 000000000..8130a90d5 --- /dev/null +++ b/src/boost/libs/local_function/test/add_default_seq.cpp @@ -0,0 +1,19 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main(void) { + int BOOST_LOCAL_FUNCTION( (int x) (int y)(default 2) ) { + return x + y; + } BOOST_LOCAL_FUNCTION_NAME(add) + + BOOST_TEST(add(1) == 3); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/add_default_seq_nova.cpp b/src/boost/libs/local_function/test/add_default_seq_nova.cpp new file mode 100644 index 000000000..92e4ea776 --- /dev/null +++ b/src/boost/libs/local_function/test/add_default_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "add_default_seq.cpp" + diff --git a/src/boost/libs/local_function/test/add_except.cpp b/src/boost/libs/local_function/test/add_except.cpp new file mode 100644 index 000000000..c3a148851 --- /dev/null +++ b/src/boost/libs/local_function/test/add_except.cpp @@ -0,0 +1,34 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main(void) { + //[add_except + double sum = 0.0; + int factor = 10; + + void BOOST_LOCAL_FUNCTION(const bind factor, bind& sum, + double num) throw() { // Throw nothing. + sum += factor * num; + } BOOST_LOCAL_FUNCTION_NAME(add) + + add(100); + //] + + BOOST_TEST(sum == 1000); + return boost::report_errors(); +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/add_except_seq.cpp b/src/boost/libs/local_function/test/add_except_seq.cpp new file mode 100644 index 000000000..be1d18605 --- /dev/null +++ b/src/boost/libs/local_function/test/add_except_seq.cpp @@ -0,0 +1,25 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main(void) { + double sum = 0.0; + int factor = 10; + + void BOOST_LOCAL_FUNCTION( (const bind factor) (bind& sum) + (double num) ) throw() { + sum += factor * num; + } BOOST_LOCAL_FUNCTION_NAME(add) + + add(100); + + BOOST_TEST(sum == 1000); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/add_except_seq_nova.cpp b/src/boost/libs/local_function/test/add_except_seq_nova.cpp new file mode 100644 index 000000000..44f53a29b --- /dev/null +++ b/src/boost/libs/local_function/test/add_except_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "add_except_seq.cpp" + diff --git a/src/boost/libs/local_function/test/add_inline.cpp b/src/boost/libs/local_function/test/add_inline.cpp new file mode 100644 index 000000000..4d3afe5c7 --- /dev/null +++ b/src/boost/libs/local_function/test/add_inline.cpp @@ -0,0 +1,37 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <vector> +#include <algorithm> + +int main(void) { + //[add_inline + int sum = 0, factor = 10; + + void BOOST_LOCAL_FUNCTION(const bind factor, bind& sum, int num) { + sum += factor * num; + } BOOST_LOCAL_FUNCTION_NAME(inline add) // Inlining. + + std::vector<int> v(100); + std::fill(v.begin(), v.end(), 1); + + for(size_t i = 0; i < v.size(); ++i) add(v[i]); // Cannot use for_each. + //] + + BOOST_TEST(sum == 1000); + return boost::report_errors(); +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/add_inline_seq.cpp b/src/boost/libs/local_function/test/add_inline_seq.cpp new file mode 100644 index 000000000..780262152 --- /dev/null +++ b/src/boost/libs/local_function/test/add_inline_seq.cpp @@ -0,0 +1,28 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <vector> +#include <algorithm> + +int main(void) { + int sum = 0, factor = 10; + + void BOOST_LOCAL_FUNCTION( (const bind factor) (bind& sum) (int num) ) { + sum += factor * num; + } BOOST_LOCAL_FUNCTION_NAME(inline add) + + std::vector<int> v(100); + std::fill(v.begin(), v.end(), 1); + + for(size_t i = 0; i < v.size(); ++i) add(v[i]); + + BOOST_TEST(sum == 1000); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/add_inline_seq_nova.cpp b/src/boost/libs/local_function/test/add_inline_seq_nova.cpp new file mode 100644 index 000000000..e040ad6d1 --- /dev/null +++ b/src/boost/libs/local_function/test/add_inline_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "add_inline_seq.cpp" + diff --git a/src/boost/libs/local_function/test/add_params_only.cpp b/src/boost/libs/local_function/test/add_params_only.cpp new file mode 100644 index 000000000..3b9b93d99 --- /dev/null +++ b/src/boost/libs/local_function/test/add_params_only.cpp @@ -0,0 +1,28 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main(void) { + //[add_params_only + int BOOST_LOCAL_FUNCTION(int x, int y) { // Local function. + return x + y; + } BOOST_LOCAL_FUNCTION_NAME(add) + + BOOST_TEST(add(1, 2) == 3); // Local function call. + //] + return boost::report_errors(); +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/add_params_only_seq.cpp b/src/boost/libs/local_function/test/add_params_only_seq.cpp new file mode 100644 index 000000000..565d5ff90 --- /dev/null +++ b/src/boost/libs/local_function/test/add_params_only_seq.cpp @@ -0,0 +1,19 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main(void) { + int BOOST_LOCAL_FUNCTION( (int x) (int y) ) { + return x + y; + } BOOST_LOCAL_FUNCTION_NAME(add) + + BOOST_TEST(add(1, 2) == 3); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/add_params_only_seq_nova.cpp b/src/boost/libs/local_function/test/add_params_only_seq_nova.cpp new file mode 100644 index 000000000..7123aae8a --- /dev/null +++ b/src/boost/libs/local_function/test/add_params_only_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "add_params_only_seq.cpp" + diff --git a/src/boost/libs/local_function/test/add_seq.cpp b/src/boost/libs/local_function/test/add_seq.cpp new file mode 100644 index 000000000..d04819b2c --- /dev/null +++ b/src/boost/libs/local_function/test/add_seq.cpp @@ -0,0 +1,28 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <algorithm> + +//[add_seq +int main(void) { + int sum = 0, factor = 10; + + void BOOST_LOCAL_FUNCTION( (const bind factor) (bind& sum) (int num) ) { + sum += factor * num; + } BOOST_LOCAL_FUNCTION_NAME(add) + + add(1); + int nums[] = {2, 3}; + std::for_each(nums, nums + 2, add); + + BOOST_TEST(sum == 60); + return boost::report_errors(); +} +//] + diff --git a/src/boost/libs/local_function/test/add_seq_nova.cpp b/src/boost/libs/local_function/test/add_seq_nova.cpp new file mode 100644 index 000000000..ce0c279f5 --- /dev/null +++ b/src/boost/libs/local_function/test/add_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "add_seq.cpp" + diff --git a/src/boost/libs/local_function/test/add_template.cpp b/src/boost/libs/local_function/test/add_template.cpp new file mode 100644 index 000000000..aa382673b --- /dev/null +++ b/src/boost/libs/local_function/test/add_template.cpp @@ -0,0 +1,41 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <algorithm> + +//[add_template +template<typename T> +T total(const T& x, const T& y, const T& z) { + T sum = T(), factor = 10; + + // Must use the `..._TPL` macros within templates. + T BOOST_LOCAL_FUNCTION_TPL(const bind factor, bind& sum, T num) { + return sum += factor * num; + } BOOST_LOCAL_FUNCTION_NAME_TPL(add) + + add(x); + T nums[2]; nums[0] = y; nums[1] = z; + std::for_each(nums, nums + 2, add); + + return sum; +} +//] + +int main(void) { + BOOST_TEST(total(1, 2, 3) == 60); + return boost::report_errors(); +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/add_template_seq.cpp b/src/boost/libs/local_function/test/add_template_seq.cpp new file mode 100644 index 000000000..3c0ea7155 --- /dev/null +++ b/src/boost/libs/local_function/test/add_template_seq.cpp @@ -0,0 +1,31 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <algorithm> + +template<typename T> +T total(const T& x, const T& y, const T& z) { + T sum = T(), factor = 10; + + T BOOST_LOCAL_FUNCTION_TPL( (const bind factor) (bind& sum) (T num) ) { + return sum += factor * num; + } BOOST_LOCAL_FUNCTION_NAME_TPL(add) + + add(x); + T nums[2]; nums[0] = y; nums[1] = z; + std::for_each(nums, nums + 2, add); + + return sum; +} + +int main(void) { + BOOST_TEST(total(1, 2, 3) == 60); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/add_template_seq_nova.cpp b/src/boost/libs/local_function/test/add_template_seq_nova.cpp new file mode 100644 index 000000000..9c02384b1 --- /dev/null +++ b/src/boost/libs/local_function/test/add_template_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "add_template_seq.cpp" + diff --git a/src/boost/libs/local_function/test/add_this.cpp b/src/boost/libs/local_function/test/add_this.cpp new file mode 100644 index 000000000..f42404367 --- /dev/null +++ b/src/boost/libs/local_function/test/add_this.cpp @@ -0,0 +1,51 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/typeof/typeof.hpp> +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include <boost/detail/lightweight_test.hpp> +#include <vector> +#include <algorithm> + +struct adder; +BOOST_TYPEOF_REGISTER_TYPE(adder) // Register before `bind this_` below. + +//[add_this +struct adder { + adder() : sum_(0) {} + + int sum(const std::vector<int>& nums, const int factor = 10) { + + void BOOST_LOCAL_FUNCTION(const bind factor, bind this_, int num) { + this_->sum_ += factor * num; // Use `this_` instead of `this`. + } BOOST_LOCAL_FUNCTION_NAME(add) + + std::for_each(nums.begin(), nums.end(), add); + return sum_; + } + +private: + int sum_; +}; +//] + +int main(void) { + std::vector<int> v(3); + v[0] = 1; v[1] = 2; v[2] = 3; + + BOOST_TEST(adder().sum(v) == 60); + return boost::report_errors(); +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/add_this_seq.cpp b/src/boost/libs/local_function/test/add_this_seq.cpp new file mode 100644 index 000000000..9957122e7 --- /dev/null +++ b/src/boost/libs/local_function/test/add_this_seq.cpp @@ -0,0 +1,43 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/typeof/typeof.hpp> +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include <boost/detail/lightweight_test.hpp> +#include <vector> +#include <algorithm> + +struct adder; +BOOST_TYPEOF_REGISTER_TYPE(adder) // Register before `bind this_` below. + +struct adder { + adder() : sum_(0) {} + + int sum(const std::vector<int>& nums, const int factor = 10) { + + void BOOST_LOCAL_FUNCTION( (const bind factor) (bind this_) + (int num) ) { + this_->sum_ += factor * num; + } BOOST_LOCAL_FUNCTION_NAME(add) + + std::for_each(nums.begin(), nums.end(), add); + return sum_; + } + +private: + int sum_; +}; + +int main(void) { + std::vector<int> v(3); + v[0] = 1; v[1] = 2; v[2] = 3; + + BOOST_TEST(adder().sum(v) == 60); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/add_this_seq_nova.cpp b/src/boost/libs/local_function/test/add_this_seq_nova.cpp new file mode 100644 index 000000000..e01573908 --- /dev/null +++ b/src/boost/libs/local_function/test/add_this_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "add_this_seq.cpp" + diff --git a/src/boost/libs/local_function/test/add_typed.cpp b/src/boost/libs/local_function/test/add_typed.cpp new file mode 100644 index 000000000..6912a334b --- /dev/null +++ b/src/boost/libs/local_function/test/add_typed.cpp @@ -0,0 +1,47 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <vector> +#include <algorithm> + +//[add_typed +struct adder { + adder(void) : sum_(0) {} + + int sum(const std::vector<int>& nums, const int& factor = 10) { + // Explicitly specify bound variable and return types (no type-of). + BOOST_LOCAL_FUNCTION(const bind(const int&) factor, + bind(adder*) this_, int num, return int) { + return this_->sum_ += factor * num; + } BOOST_LOCAL_FUNCTION_NAME(add) + + std::for_each(nums.begin(), nums.end(), add); + return sum_; + } + +private: + int sum_; +}; +//] + +int main(void) { + std::vector<int> v(3); + v[0] = 1; v[1] = 2; v[2] = 3; + + BOOST_TEST(adder().sum(v) == 60); + return boost::report_errors(); +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/add_typed_seq.cpp b/src/boost/libs/local_function/test/add_typed_seq.cpp new file mode 100644 index 000000000..e62ff505c --- /dev/null +++ b/src/boost/libs/local_function/test/add_typed_seq.cpp @@ -0,0 +1,37 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <vector> +#include <algorithm> + +struct adder { + adder(void) : sum_(0) {} + + int sum(const std::vector<int>& nums, const int& factor = 10) { + BOOST_LOCAL_FUNCTION( (const bind(const int&) factor) + (bind(adder*) this_) (int num) (return int) ) { + return this_->sum_ += factor * num; + } BOOST_LOCAL_FUNCTION_NAME(add) + + std::for_each(nums.begin(), nums.end(), add); + return sum_; + } + +private: + int sum_; +}; + +int main(void) { + std::vector<int> v(3); + v[0] = 1; v[1] = 2; v[2] = 3; + + BOOST_TEST(adder().sum(v) == 60); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/add_typed_seq_nova.cpp b/src/boost/libs/local_function/test/add_typed_seq_nova.cpp new file mode 100644 index 000000000..0cdb35615 --- /dev/null +++ b/src/boost/libs/local_function/test/add_typed_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "add_typed_seq.cpp" + diff --git a/src/boost/libs/local_function/test/add_with_default.cpp b/src/boost/libs/local_function/test/add_with_default.cpp new file mode 100644 index 000000000..f31cb1c63 --- /dev/null +++ b/src/boost/libs/local_function/test/add_with_default.cpp @@ -0,0 +1,32 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> + +//[add_with_default_macro +#define WITH_DEFAULT , default +//] + +int main(void) { + //[add_with_default + int BOOST_LOCAL_FUNCTION(int x, int y WITH_DEFAULT 2) { // Default. + return x + y; + } BOOST_LOCAL_FUNCTION_NAME(add) + + BOOST_TEST(add(1) == 3); + //] + return boost::report_errors(); +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/add_with_default_seq.cpp b/src/boost/libs/local_function/test/add_with_default_seq.cpp new file mode 100644 index 000000000..1513af021 --- /dev/null +++ b/src/boost/libs/local_function/test/add_with_default_seq.cpp @@ -0,0 +1,21 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> + +#define WITH_DEFAULT )(default + +int main(void) { + int BOOST_LOCAL_FUNCTION( (int x) (int y WITH_DEFAULT 2) ) { + return x + y; + } BOOST_LOCAL_FUNCTION_NAME(add) + + BOOST_TEST(add(1) == 3); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/add_with_default_seq_nova.cpp b/src/boost/libs/local_function/test/add_with_default_seq_nova.cpp new file mode 100644 index 000000000..d7149cc78 --- /dev/null +++ b/src/boost/libs/local_function/test/add_with_default_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "add_with_default_seq.cpp" + diff --git a/src/boost/libs/local_function/test/addable.hpp b/src/boost/libs/local_function/test/addable.hpp new file mode 100644 index 000000000..3b13ab288 --- /dev/null +++ b/src/boost/libs/local_function/test/addable.hpp @@ -0,0 +1,26 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#ifndef ADDABLE_HPP_ +#define ADDABLE_HPP_ + +#include <boost/concept_check.hpp> + +template<typename T> +struct Addable { // User-defined concept. + BOOST_CONCEPT_USAGE(Addable) { + return_type(x + y); // Check addition `T operator+(T x, T y)`. + } + +private: + void return_type(T) {} // Implementation (required for some linkers). + static T const& x; + static T const& y; +}; + +#endif // #include guard + diff --git a/src/boost/libs/local_function/test/all_decl.cpp b/src/boost/libs/local_function/test/all_decl.cpp new file mode 100644 index 000000000..a9a63db1c --- /dev/null +++ b/src/boost/libs/local_function/test/all_decl.cpp @@ -0,0 +1,177 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/typeof/typeof.hpp> +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() + +struct s; +BOOST_TYPEOF_REGISTER_TYPE(s) // Register before binding `this_` below. + +// Compile all local function declaration combinations. +struct s { + void f(double p = 1.23, double q = -1.23) { + { // Only params. + void BOOST_LOCAL_FUNCTION(int x, int y, default 0) { + } BOOST_LOCAL_FUNCTION_NAME(l) + l(1); + } + { // Only const binds. + int a, b; + + const int& BOOST_LOCAL_FUNCTION(const bind a, + const bind& b, const bind& p, const bind q) { + return b; + } BOOST_LOCAL_FUNCTION_NAME(l) + l(); + + const s& BOOST_LOCAL_FUNCTION(const bind this_) { + return *this_; + } BOOST_LOCAL_FUNCTION_NAME(t) + t(); + + const int BOOST_LOCAL_FUNCTION(const bind a, + const bind& b, const bind& p, const bind q, + const bind this_) { + return a; + } BOOST_LOCAL_FUNCTION_NAME(lt) + lt(); + } + { // Only plain binds. + int c, d; + + int& BOOST_LOCAL_FUNCTION(bind c, bind& d, + bind& p, bind& q) { + return d; + } BOOST_LOCAL_FUNCTION_NAME(l) + l(); + + s& BOOST_LOCAL_FUNCTION(bind this_) { + return *this_; + } BOOST_LOCAL_FUNCTION_NAME(t) + t(); + + int BOOST_LOCAL_FUNCTION(bind c, bind& d, + bind& p, bind& q, bind this_) { + return c; + } BOOST_LOCAL_FUNCTION_NAME(lt) + lt(); + } + + { // Both params and const binds. + int a, b; + + void BOOST_LOCAL_FUNCTION(const bind a, const bind& b, + const bind& p, const bind q, + int x, int y, default 0) { + } BOOST_LOCAL_FUNCTION_NAME(l) + l(1); + + void BOOST_LOCAL_FUNCTION(const bind this_, + int x, int y, default 0) { + } BOOST_LOCAL_FUNCTION_NAME(t) + t(1); + + void BOOST_LOCAL_FUNCTION(const bind a, const bind this_, + const bind& b, const bind& p, const bind q, + int x, int y, default 0) { + } BOOST_LOCAL_FUNCTION_NAME(lt) + lt(1); + } + { // Both params and plain binds. + int c, d; + + void BOOST_LOCAL_FUNCTION(bind c, bind& d, bind& p, bind q, + int x, int y, default 0) { + } BOOST_LOCAL_FUNCTION_NAME(l) + l(1); + + void BOOST_LOCAL_FUNCTION(bind this_, + int x, int y, default 0) { + } BOOST_LOCAL_FUNCTION_NAME(t) + t(1); + + void BOOST_LOCAL_FUNCTION(bind c, bind& d, + bind& p, bind this_, bind q, + int x, int y, default 0) { + } BOOST_LOCAL_FUNCTION_NAME(lt) + lt(1); + } + { // Both const and plain binds. + int a, b, c, d; + + void BOOST_LOCAL_FUNCTION(const bind a, const bind& b, + const bind p, bind c, bind& d, bind q) { + } BOOST_LOCAL_FUNCTION_NAME(l) + l(); + + void BOOST_LOCAL_FUNCTION(const bind this_, + bind c, bind& d, bind q) { + } BOOST_LOCAL_FUNCTION_NAME(ct) + ct(); + void BOOST_LOCAL_FUNCTION(const bind this_, + const bind a, const bind& b, const bind p, + bind c, bind& d, bind q) { + } BOOST_LOCAL_FUNCTION_NAME(lct) + lct(); + + void BOOST_LOCAL_FUNCTION(const bind a, const bind& b, + const bind p, bind this_) { + } BOOST_LOCAL_FUNCTION_NAME(pt) + pt(); + void BOOST_LOCAL_FUNCTION(const bind a, const bind& b, + const bind p, bind c, bind this_, bind& d, bind q) { + } BOOST_LOCAL_FUNCTION_NAME(lpt) + lpt(); + } + + { // All params, const binds, and plain binds. + int a, b, c, d; + + void BOOST_LOCAL_FUNCTION( + const bind a, const bind& b, const bind& p, + bind c, bind& d, bind& q, int x, int y, default 0) { + } BOOST_LOCAL_FUNCTION_NAME(l) + l(1); + + void BOOST_LOCAL_FUNCTION(const bind this_, + bind c, bind& d, bind& q, + int x, int y, default 0) { + } BOOST_LOCAL_FUNCTION_NAME(ct) + ct(1); + void BOOST_LOCAL_FUNCTION( + const bind a, const bind& b, const bind& p, + bind this_, int x, int y, default 0) { + } BOOST_LOCAL_FUNCTION_NAME(pt) + pt(1); + + void BOOST_LOCAL_FUNCTION(const bind a, const bind this_, + const bind& b, const bind& p, bind c, bind& d, + bind& q, int x, int y, default 0) { + } BOOST_LOCAL_FUNCTION_NAME(lct) + lct(1); + void BOOST_LOCAL_FUNCTION(const bind a, const bind& b, + const bind& p, bind c, bind& d, bind this_, bind& q, + int x, int y, default 0) { + } BOOST_LOCAL_FUNCTION_NAME(lpt) + lpt(1); + } + } +}; + +int main(void) { + s().f(); + return 0; +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/all_decl_seq.cpp b/src/boost/libs/local_function/test/all_decl_seq.cpp new file mode 100644 index 000000000..95fb75ede --- /dev/null +++ b/src/boost/libs/local_function/test/all_decl_seq.cpp @@ -0,0 +1,170 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/typeof/typeof.hpp> +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() + +struct s; +BOOST_TYPEOF_REGISTER_TYPE(s); // Register before bind `this_` below. + +// Compile all local function declaration combinations. +struct s { + void f(double p = 1.23, double q = -1.23) { + { // Only params. + void BOOST_LOCAL_FUNCTION( (int x) (int y)(default 0) ) { + } BOOST_LOCAL_FUNCTION_NAME(l) + l(1); + } + { // Only const binds. + int a, b; + + const int& BOOST_LOCAL_FUNCTION( (const bind a) + (const bind& b) (const bind& p) (const bind q) ) { + return b; + } BOOST_LOCAL_FUNCTION_NAME(l) + l(); + + const s& BOOST_LOCAL_FUNCTION( (const bind this_) ) { + return *this_; + } BOOST_LOCAL_FUNCTION_NAME(t) + t(); + + const int BOOST_LOCAL_FUNCTION( (const bind a) + (const bind& b) (const bind& p) (const bind q) + (const bind this_) ) { + return a; + } BOOST_LOCAL_FUNCTION_NAME(lt) + lt(); + } + { // Only plain binds. + int c, d; + + int& BOOST_LOCAL_FUNCTION( (bind c) (bind& d) + (bind& p) (bind& q) ) { + return d; + } BOOST_LOCAL_FUNCTION_NAME(l) + l(); + + s& BOOST_LOCAL_FUNCTION( (bind this_) ) { + return *this_; + } BOOST_LOCAL_FUNCTION_NAME(t) + t(); + + int BOOST_LOCAL_FUNCTION( (bind c) (bind& d) + (bind& p) (bind& q) (bind this_) ) { + return c; + } BOOST_LOCAL_FUNCTION_NAME(lt) + lt(); + } + + { // Both params and const binds. + int a, b; + + void BOOST_LOCAL_FUNCTION( (const bind a) (const bind& b) + (const bind& p) (const bind q) + (int x) (int y)(default 0) ) { + } BOOST_LOCAL_FUNCTION_NAME(l) + l(1); + + void BOOST_LOCAL_FUNCTION( (const bind this_) + (int x) (int y)(default 0) ) { + } BOOST_LOCAL_FUNCTION_NAME(t) + t(1); + + void BOOST_LOCAL_FUNCTION( (const bind a) (const bind this_) + (const bind& b) (const bind& p) (const bind q) + (int x) (int y)(default 0) ) { + } BOOST_LOCAL_FUNCTION_NAME(lt) + lt(1); + } + { // Both params and plain binds. + int c, d; + + void BOOST_LOCAL_FUNCTION( (bind c) (bind& d) (bind& p) (bind q) + (int x) (int y)(default 0) ) { + } BOOST_LOCAL_FUNCTION_NAME(l) + l(1); + + void BOOST_LOCAL_FUNCTION( (bind this_) + (int x) (int y)(default 0) ) { + } BOOST_LOCAL_FUNCTION_NAME(t) + t(1); + + void BOOST_LOCAL_FUNCTION( (bind c) (bind& d) + (bind& p) (bind this_) (bind q) + (int x) (int y)(default 0) ) { + } BOOST_LOCAL_FUNCTION_NAME(lt) + lt(1); + } + { // Both const and plain binds. + int a, b, c, d; + + void BOOST_LOCAL_FUNCTION( (const bind a) (const bind& b) + (const bind p) (bind c) (bind& d) (bind q) ) { + } BOOST_LOCAL_FUNCTION_NAME(l) + l(); + + void BOOST_LOCAL_FUNCTION( (const bind this_) + (bind c) (bind& d) (bind q) ) { + } BOOST_LOCAL_FUNCTION_NAME(ct) + ct(); + void BOOST_LOCAL_FUNCTION( (const bind this_) + (const bind a) (const bind& b) (const bind p) + (bind c) (bind& d) (bind q) ) { + } BOOST_LOCAL_FUNCTION_NAME(lct) + lct(); + + void BOOST_LOCAL_FUNCTION( (const bind a) (const bind& b) + (const bind p) (bind this_) ) { + } BOOST_LOCAL_FUNCTION_NAME(pt) + pt(); + void BOOST_LOCAL_FUNCTION( (const bind a) (const bind& b) + (const bind p) (bind c) (bind this_) (bind& d) (bind q) ) { + } BOOST_LOCAL_FUNCTION_NAME(lpt) + lpt(); + } + + { // All params, const binds, and plain binds. + int a, b, c, d; + + void BOOST_LOCAL_FUNCTION( + (const bind a) (const bind& b) (const bind& p) + (bind c) (bind& d) (bind& q) (int x) (int y)(default 0) ) { + } BOOST_LOCAL_FUNCTION_NAME(l) + l(1); + + void BOOST_LOCAL_FUNCTION( (const bind this_) + (bind c) (bind& d) (bind& q) + (int x) (int y)(default 0) ) { + } BOOST_LOCAL_FUNCTION_NAME(ct) + ct(1); + void BOOST_LOCAL_FUNCTION( + (const bind a) (const bind& b) (const bind& p) + (bind this_) (int x) (int y)(default 0) ) { + } BOOST_LOCAL_FUNCTION_NAME(pt) + pt(1); + + void BOOST_LOCAL_FUNCTION( (const bind a) (const bind this_) + (const bind& b) (const bind& p) (bind c) (bind& d) + (bind& q) (int x) (int y)(default 0) ) { + } BOOST_LOCAL_FUNCTION_NAME(lct) + lct(1); + void BOOST_LOCAL_FUNCTION( (const bind a) (const bind& b) + (const bind& p) (bind c) (bind& d) (bind this_) (bind& q) + (int x) (int y)(default 0) ) { + } BOOST_LOCAL_FUNCTION_NAME(lpt) + lpt(1); + } + } +}; + +int main(void) { + s().f(); + return 0; +} + diff --git a/src/boost/libs/local_function/test/all_decl_seq_nova.cpp b/src/boost/libs/local_function/test/all_decl_seq_nova.cpp new file mode 100644 index 000000000..8333b2857 --- /dev/null +++ b/src/boost/libs/local_function/test/all_decl_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "all_decl_seq.cpp" + diff --git a/src/boost/libs/local_function/test/factorial.cpp b/src/boost/libs/local_function/test/factorial.cpp new file mode 100644 index 000000000..7260de23a --- /dev/null +++ b/src/boost/libs/local_function/test/factorial.cpp @@ -0,0 +1,57 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/typeof/typeof.hpp> +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include <boost/detail/lightweight_test.hpp> +#include <algorithm> +#include <vector> + +struct calculator; +BOOST_TYPEOF_REGISTER_TYPE(calculator) // Register before `bind this_` below. + +//[factorial +struct calculator { + std::vector<int> results; + + void factorials(const std::vector<int>& nums) { + int BOOST_LOCAL_FUNCTION(bind this_, int num, + bool recursion, default false) { + int result = 0; + + if(num <= 0) result = 1; + else result = num * factorial(num - 1, true); // Recursive call. + + if(!recursion) this_->results.push_back(result); + return result; + } BOOST_LOCAL_FUNCTION_NAME(recursive factorial) // Recursive. + + std::for_each(nums.begin(), nums.end(), factorial); + } +}; +//] + +int main(void) { + std::vector<int> v(3); + v[0] = 1; v[1] = 3; v[2] = 4; + + calculator calc; + calc.factorials(v); + BOOST_TEST(calc.results[0] == 1); + BOOST_TEST(calc.results[1] == 6); + BOOST_TEST(calc.results[2] == 24); + return boost::report_errors(); +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/factorial_seq.cpp b/src/boost/libs/local_function/test/factorial_seq.cpp new file mode 100644 index 000000000..e7c242c27 --- /dev/null +++ b/src/boost/libs/local_function/test/factorial_seq.cpp @@ -0,0 +1,48 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/typeof/typeof.hpp> +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include <boost/detail/lightweight_test.hpp> +#include <algorithm> +#include <vector> + +struct calculator; +BOOST_TYPEOF_REGISTER_TYPE(calculator) // Register before `bind this_` below. + +struct calculator { + std::vector<int> results; + + void factorials(const std::vector<int>& nums) { + int BOOST_LOCAL_FUNCTION( (bind this_) (int num) + (bool recursion)(default false) ) { + int result = 0; + + if(num <= 0) result = 1; + else result = num * factorial(num - 1, true); + + if(!recursion) this_->results.push_back(result); + return result; + } BOOST_LOCAL_FUNCTION_NAME(recursive factorial) + + std::for_each(nums.begin(), nums.end(), factorial); + } +}; + +int main(void) { + std::vector<int> v(3); + v[0] = 1; v[1] = 3; v[2] = 4; + + calculator calc; + calc.factorials(v); + BOOST_TEST(calc.results[0] == 1); + BOOST_TEST(calc.results[1] == 6); + BOOST_TEST(calc.results[2] == 24); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/factorial_seq_nova.cpp b/src/boost/libs/local_function/test/factorial_seq_nova.cpp new file mode 100644 index 000000000..b9376125a --- /dev/null +++ b/src/boost/libs/local_function/test/factorial_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "factorial_seq.cpp" + diff --git a/src/boost/libs/local_function/test/goto.cpp b/src/boost/libs/local_function/test/goto.cpp new file mode 100644 index 000000000..a6dda7512 --- /dev/null +++ b/src/boost/libs/local_function/test/goto.cpp @@ -0,0 +1,34 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> + +//[goto +int error(int x, int y) { + int BOOST_LOCAL_FUNCTION(int z) { + if(z > 0) goto success; // OK: Can jump within local function. + return -1; + success: + return 0; + } BOOST_LOCAL_FUNCTION_NAME(validate) + + return validate(x + y); +} +//] + +int main(void) { + error(1, 2); + return 0; +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/goto_error.cpp b/src/boost/libs/local_function/test/goto_error.cpp new file mode 100644 index 000000000..3ed397194 --- /dev/null +++ b/src/boost/libs/local_function/test/goto_error.cpp @@ -0,0 +1,36 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> + +//[goto_error +int error(int x, int y) { + int BOOST_LOCAL_FUNCTION(int z) { + if(z <= 0) goto failure; // Error: Cannot jump to enclosing scope. + else goto success; // OK: Can jump within local function. + success: + return 0; + } BOOST_LOCAL_FUNCTION_NAME(validate) + + return validate(x + y); +failure: + return -1; +} +//] + +int main(void) { + error(1, 2); + return 0; +} + +#endif + diff --git a/src/boost/libs/local_function/test/goto_error_seq.cpp b/src/boost/libs/local_function/test/goto_error_seq.cpp new file mode 100644 index 000000000..178ac4372 --- /dev/null +++ b/src/boost/libs/local_function/test/goto_error_seq.cpp @@ -0,0 +1,27 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> + +int error(int x, int y) { + int BOOST_LOCAL_FUNCTION( (int z) ) { + if(z <= 0) goto failure; + else goto success; + success: + return 0; + } BOOST_LOCAL_FUNCTION_NAME(validate) + + return validate(x + y); +failure: + return -1; +} + +int main(void) { + error(1, 2); + return 0; +} + diff --git a/src/boost/libs/local_function/test/goto_error_seq_nova.cpp b/src/boost/libs/local_function/test/goto_error_seq_nova.cpp new file mode 100644 index 000000000..6433add5c --- /dev/null +++ b/src/boost/libs/local_function/test/goto_error_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "goto_error_seq.cpp" + diff --git a/src/boost/libs/local_function/test/goto_seq.cpp b/src/boost/libs/local_function/test/goto_seq.cpp new file mode 100644 index 000000000..5acb5b46d --- /dev/null +++ b/src/boost/libs/local_function/test/goto_seq.cpp @@ -0,0 +1,25 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> + +int error(int x, int y) { + int BOOST_LOCAL_FUNCTION( (int z) ) { + if(z > 0) goto success; + return -1; + success: + return 0; + } BOOST_LOCAL_FUNCTION_NAME(validate) + + return validate(x + y); +} + +int main(void) { + error(1, 2); + return 0; +} + diff --git a/src/boost/libs/local_function/test/goto_seq_nova.cpp b/src/boost/libs/local_function/test/goto_seq_nova.cpp new file mode 100644 index 000000000..edec9f283 --- /dev/null +++ b/src/boost/libs/local_function/test/goto_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "goto_seq.cpp" + diff --git a/src/boost/libs/local_function/test/macro_commas.cpp b/src/boost/libs/local_function/test/macro_commas.cpp new file mode 100644 index 000000000..3905782f6 --- /dev/null +++ b/src/boost/libs/local_function/test/macro_commas.cpp @@ -0,0 +1,52 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/utility/identity_type.hpp> +#include <boost/typeof/std/string.hpp> // Type-of registrations +#include <boost/typeof/std/map.hpp> // needed for `NAME` macro. +#include <map> +#include <string> + +std::string cat(const std::string& x, const std::string& y) { return x + y; } + +template<typename V, typename K> +struct key_sizeof { + static int const value; +}; + +template<typename V, typename K> +int const key_sizeof<V, K>::value = sizeof(K); + +typedef int sign_t; + +int main(void) { + //[macro_commas + void BOOST_LOCAL_FUNCTION( + BOOST_IDENTITY_TYPE((const std::map<std::string, size_t>&)) m, + BOOST_IDENTITY_TYPE((::sign_t)) sign, + const size_t& factor, + default (key_sizeof<std::string, size_t>::value), + const std::string& separator, default cat(":", " ") + ) { + // Do something... + } BOOST_LOCAL_FUNCTION_NAME(f) + //] + + std::map<std::string, size_t> m; + ::sign_t sign = -1; + f(m, sign); + return 0; +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/macro_commas_seq.cpp b/src/boost/libs/local_function/test/macro_commas_seq.cpp new file mode 100644 index 000000000..f2e0f49af --- /dev/null +++ b/src/boost/libs/local_function/test/macro_commas_seq.cpp @@ -0,0 +1,44 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/utility/identity_type.hpp> +#include <boost/typeof/std/string.hpp> // Type-of registrations +#include <boost/typeof/std/map.hpp> // needed for `NAME` macro. +#include <boost/config.hpp> +#include <map> +#include <string> + +std::string cat(const std::string& x, const std::string& y) { return x + y; } + +template<typename V, typename K> +struct key_sizeof { + static int const value; +}; + +template<typename V, typename K> +int const key_sizeof<V, K>::value = sizeof(K); + +typedef int sign_t; + +int main(void) { + void BOOST_LOCAL_FUNCTION( + (BOOST_IDENTITY_TYPE((const std::map<std::string, size_t>&)) m) + (BOOST_IDENTITY_TYPE((::sign_t)) sign) + (const size_t& factor) + (default (key_sizeof<std::string, size_t>::value)) + (const std::string& separator)(default cat(":", " ")) + ) { + // Do something... + } BOOST_LOCAL_FUNCTION_NAME(f) + + std::map<std::string, size_t> m; + ::sign_t sign = -1; + f(m, sign); + return 0; +} + diff --git a/src/boost/libs/local_function/test/macro_commas_seq_nova.cpp b/src/boost/libs/local_function/test/macro_commas_seq_nova.cpp new file mode 100644 index 000000000..4252379d6 --- /dev/null +++ b/src/boost/libs/local_function/test/macro_commas_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "macro_commas_seq.cpp" + diff --git a/src/boost/libs/local_function/test/nesting.cpp b/src/boost/libs/local_function/test/nesting.cpp new file mode 100644 index 000000000..e13ac2692 --- /dev/null +++ b/src/boost/libs/local_function/test/nesting.cpp @@ -0,0 +1,37 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main(void) { + //[nesting + int x = 0; + + void BOOST_LOCAL_FUNCTION(bind& x) { + void BOOST_LOCAL_FUNCTION(bind& x) { // Nested. + x++; + } BOOST_LOCAL_FUNCTION_NAME(g) + + x--; + g(); // Nested local function call. + } BOOST_LOCAL_FUNCTION_NAME(f) + + f(); + //] + + BOOST_TEST(x == 0); + return boost::report_errors(); +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/nesting_seq.cpp b/src/boost/libs/local_function/test/nesting_seq.cpp new file mode 100644 index 000000000..6e18558bf --- /dev/null +++ b/src/boost/libs/local_function/test/nesting_seq.cpp @@ -0,0 +1,28 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main(void) { + int x = 0; + + void BOOST_LOCAL_FUNCTION( (bind& x) ) { + void BOOST_LOCAL_FUNCTION( (bind& x) ) { + x++; + } BOOST_LOCAL_FUNCTION_NAME(g) + + x--; + g(); + } BOOST_LOCAL_FUNCTION_NAME(f) + + f(); + + BOOST_TEST(x == 0); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/nesting_seq_nova.cpp b/src/boost/libs/local_function/test/nesting_seq_nova.cpp new file mode 100644 index 000000000..caeb0720c --- /dev/null +++ b/src/boost/libs/local_function/test/nesting_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "nesting_seq.cpp" + diff --git a/src/boost/libs/local_function/test/nova.hpp b/src/boost/libs/local_function/test/nova.hpp new file mode 100644 index 000000000..ceef87eed --- /dev/null +++ b/src/boost/libs/local_function/test/nova.hpp @@ -0,0 +1,21 @@ + +// Copyright (C) 2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/scope_exit + +#ifndef NOVA_HPP_ +#define NOVA_HPP_ + +#include <boost/config.hpp> + +// WARNING: This file must be included first in each compilation unit. + +// Force no variadic macros but avoiding macro redefinition warning/error. +#ifndef BOOST_NO_CXX11_VARIADIC_MACROS +# define BOOST_NO_CXX11_VARIADIC_MACROS +#endif + +#endif // #include guard + diff --git a/src/boost/libs/local_function/test/operator.cpp b/src/boost/libs/local_function/test/operator.cpp new file mode 100644 index 000000000..c8911c3e4 --- /dev/null +++ b/src/boost/libs/local_function/test/operator.cpp @@ -0,0 +1,38 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/typeof/typeof.hpp> +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include <boost/detail/lightweight_test.hpp> + +//[operator +struct point { + int x; + int y; +}; +BOOST_TYPEOF_REGISTER_TYPE(point) // Register for `NAME` below. + +int main(void) { + bool BOOST_LOCAL_FUNCTION(const point& p, const point& q) { + return p.x == q.x && p.y == q.y; + } BOOST_LOCAL_FUNCTION_NAME(equal) // OK: not using `operator==`. + + point a; a.x = 1; a.y = 2; + point b = a; + BOOST_TEST(equal(a, b)); + return boost::report_errors(); +} +//] + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/operator_error.cpp b/src/boost/libs/local_function/test/operator_error.cpp new file mode 100644 index 000000000..9fd81f622 --- /dev/null +++ b/src/boost/libs/local_function/test/operator_error.cpp @@ -0,0 +1,38 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/typeof/typeof.hpp> +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include <boost/detail/lightweight_test.hpp> + +struct point { + int x; + int y; +}; +BOOST_TYPEOF_REGISTER_TYPE(point) // Register for `NAME` below. + +int main(void) { + //[operator_error + bool BOOST_LOCAL_FUNCTION(const point& p, const point& q) { + return p.x == q.x && p.y == q.y; + } BOOST_LOCAL_FUNCTION_NAME(operator==) // Error: Cannot use `operator...`. + //] + + point a; a.x = 1; a.y = 2; + point b = a; + BOOST_TEST(a == b); + return boost::report_errors(); +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/operator_error_seq.cpp b/src/boost/libs/local_function/test/operator_error_seq.cpp new file mode 100644 index 000000000..08c21f2a1 --- /dev/null +++ b/src/boost/libs/local_function/test/operator_error_seq.cpp @@ -0,0 +1,29 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/typeof/typeof.hpp> +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include <boost/detail/lightweight_test.hpp> + +struct point { + int x; + int y; +}; +BOOST_TYPEOF_REGISTER_TYPE(point) // Register for `NAME` below. + +int main(void) { + bool BOOST_LOCAL_FUNCTION( (const point& p) (const point& q) ) { + return p.x == q.x && p.y == q.y; + } BOOST_LOCAL_FUNCTION_NAME(operator==) + + point a; a.x = 1; a.y = 2; + point b = a; + BOOST_TEST(a == b); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/operator_error_seq_nova.cpp b/src/boost/libs/local_function/test/operator_error_seq_nova.cpp new file mode 100644 index 000000000..6df7178ab --- /dev/null +++ b/src/boost/libs/local_function/test/operator_error_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "operator_error_seq.cpp" + diff --git a/src/boost/libs/local_function/test/operator_seq.cpp b/src/boost/libs/local_function/test/operator_seq.cpp new file mode 100644 index 000000000..d4f70f450 --- /dev/null +++ b/src/boost/libs/local_function/test/operator_seq.cpp @@ -0,0 +1,29 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/typeof/typeof.hpp> +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include <boost/detail/lightweight_test.hpp> + +struct point { + int x; + int y; +}; +BOOST_TYPEOF_REGISTER_TYPE(point) // Register for `NAME` below. + +int main(void) { + bool BOOST_LOCAL_FUNCTION( (const point& p) (const point& q) ) { + return p.x == q.x && p.y == q.y; + } BOOST_LOCAL_FUNCTION_NAME(equal) + + point a; a.x = 1; a.y = 2; + point b = a; + BOOST_TEST(equal(a, b)); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/operator_seq_nova.cpp b/src/boost/libs/local_function/test/operator_seq_nova.cpp new file mode 100644 index 000000000..e6f624682 --- /dev/null +++ b/src/boost/libs/local_function/test/operator_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "operator_seq.cpp" + diff --git a/src/boost/libs/local_function/test/overload.cpp b/src/boost/libs/local_function/test/overload.cpp new file mode 100644 index 000000000..6a2c1eede --- /dev/null +++ b/src/boost/libs/local_function/test/overload.cpp @@ -0,0 +1,52 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/functional/overloaded_function.hpp> // For overloading. +#include <boost/typeof/std/string.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <string> + +//[overload_decl +int add_i(int x, int y) { return x + y; } +//] + +int main(void) { + //[overload + std::string s = "abc"; + std::string BOOST_LOCAL_FUNCTION( + const bind& s, const std::string& x) { + return s + x; + } BOOST_LOCAL_FUNCTION_NAME(add_s) + + double d = 1.23; + double BOOST_LOCAL_FUNCTION(const bind d, double x, double y, default 0) { + return d + x + y; + } BOOST_LOCAL_FUNCTION_NAME(add_d) + + boost::overloaded_function< + std::string (const std::string&) + , double (double) + , double (double, double) // Overload giving default param. + , int (int, int) + > add(add_s, add_d, add_d, add_i); // Overloaded function object. + + BOOST_TEST(add("xyz") == "abcxyz"); // Call `add_s`. + BOOST_TEST((4.44 - add(3.21)) <= 0.001); // Call `add_d` (no default). + BOOST_TEST((44.44 - add(3.21, 40.0)) <= 0.001); // Call `add_d`. + BOOST_TEST(add(1, 2) == 3); // Call `add_i`. + //] + return boost::report_errors(); +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/overload_seq.cpp b/src/boost/libs/local_function/test/overload_seq.cpp new file mode 100644 index 000000000..5bb0dab7d --- /dev/null +++ b/src/boost/libs/local_function/test/overload_seq.cpp @@ -0,0 +1,42 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/functional/overloaded_function.hpp> +#include <boost/typeof/std/string.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <string> + +int add_i(int x, int y) { return x + y; } + +int main(void) { + std::string s = "abc"; + std::string BOOST_LOCAL_FUNCTION( + (const bind& s) (const std::string& x) ) { + return s + x; + } BOOST_LOCAL_FUNCTION_NAME(add_s) + + double d = 1.23; + double BOOST_LOCAL_FUNCTION( (const bind d) (double x) + (double y)(default 0) ) { + return d + x + y; + } BOOST_LOCAL_FUNCTION_NAME(add_d) + + boost::overloaded_function< + std::string (const std::string&) + , double (double) + , double (double, double) + , int (int, int) + > add(add_s, add_d, add_d, add_i); + + BOOST_TEST(add("xyz") == "abcxyz"); + BOOST_TEST((4.44 - add(3.21)) <= 0.001); // Equal within precision. + BOOST_TEST((44.44 - add(3.21, 40.0)) <= 0.001); // Equal within precision. + BOOST_TEST(add(1, 2) == 3); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/overload_seq_nova.cpp b/src/boost/libs/local_function/test/overload_seq_nova.cpp new file mode 100644 index 000000000..e72b63bde --- /dev/null +++ b/src/boost/libs/local_function/test/overload_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "overload_seq.cpp" + diff --git a/src/boost/libs/local_function/test/return_assign.cpp b/src/boost/libs/local_function/test/return_assign.cpp new file mode 100644 index 000000000..6637ffa92 --- /dev/null +++ b/src/boost/libs/local_function/test/return_assign.cpp @@ -0,0 +1,49 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/function.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <iostream> + +//[return_assign +void call1(boost::function<int (int) > f) { BOOST_TEST(f(1) == 5); } +void call0(boost::function<int (void)> f) { BOOST_TEST(f() == 5); } + +boost::function<int (int, int)> linear(const int& slope) { + int BOOST_LOCAL_FUNCTION(const bind& slope, + int x, default 1, int y, default 2) { + return x + slope * y; + } BOOST_LOCAL_FUNCTION_NAME(lin) + + boost::function<int (int, int)> f = lin; // Assign to local variable. + BOOST_TEST(f(1, 2) == 5); + + call1(lin); // Pass to other functions. + call0(lin); + + return lin; // Return. +} + +void call(void) { + boost::function<int (int, int)> f = linear(2); + BOOST_TEST(f(1, 2) == 5); +} +//] + +int main(void) { + call(); + return boost::report_errors(); +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/return_assign_seq.cpp b/src/boost/libs/local_function/test/return_assign_seq.cpp new file mode 100644 index 000000000..95c6bf15e --- /dev/null +++ b/src/boost/libs/local_function/test/return_assign_seq.cpp @@ -0,0 +1,40 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/function.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <iostream> + +void call1(boost::function<int (int) > f) { BOOST_TEST(f(1) == 5); } +void call0(boost::function<int (void)> f) { BOOST_TEST(f() == 5); } + +boost::function<int (int, int)> linear(const int& slope) { + int BOOST_LOCAL_FUNCTION( (const bind& slope) + (int x)(default 1) (int y)(default 2) ) { + return x + slope * y; + } BOOST_LOCAL_FUNCTION_NAME(lin) + + boost::function<int (int, int)> f = lin; + BOOST_TEST(f(1, 2) == 5); + + call1(lin); + call0(lin); + + return lin; +} + +void call(void) { + boost::function<int (int, int)> f = linear(2); + BOOST_TEST(f(1, 2) == 5); +} + +int main(void) { + call(); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/return_assign_seq_nova.cpp b/src/boost/libs/local_function/test/return_assign_seq_nova.cpp new file mode 100644 index 000000000..12de8da2d --- /dev/null +++ b/src/boost/libs/local_function/test/return_assign_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "return_assign_seq.cpp" + diff --git a/src/boost/libs/local_function/test/return_derivative.cpp b/src/boost/libs/local_function/test/return_derivative.cpp new file mode 100644 index 000000000..746199132 --- /dev/null +++ b/src/boost/libs/local_function/test/return_derivative.cpp @@ -0,0 +1,41 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/function.hpp> +#include <boost/typeof/typeof.hpp> +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include <boost/detail/lightweight_test.hpp> + +BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function, 1) + +boost::function<int (int)> derivative(boost::function<int (int)>& f, int dx) { + int BOOST_LOCAL_FUNCTION(bind& f, const bind dx, int x) { + return (f(x + dx) - f(x)) / dx; + } BOOST_LOCAL_FUNCTION_NAME(deriv) + + return deriv; +} + +int main(void) { + int BOOST_LOCAL_FUNCTION(int x) { + return x + 4; + } BOOST_LOCAL_FUNCTION_NAME(add2) + + boost::function<int (int)> a2 = add2; // Reference valid where closure used. + boost::function<int (int)> d2 = derivative(a2, 2); + BOOST_TEST(d2(6) == 1); + return boost::report_errors(); +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/return_derivative_seq.cpp b/src/boost/libs/local_function/test/return_derivative_seq.cpp new file mode 100644 index 000000000..72c207425 --- /dev/null +++ b/src/boost/libs/local_function/test/return_derivative_seq.cpp @@ -0,0 +1,34 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/function.hpp> +#include <boost/typeof/typeof.hpp> +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include <boost/detail/lightweight_test.hpp> + +BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function, 1) + +boost::function<int (int)> derivative(boost::function<int (int)>& f, int dx) { + int BOOST_LOCAL_FUNCTION( (bind& f) (const bind dx) (int x) ) { + return (f(x + dx) - f(x)) / dx; + } BOOST_LOCAL_FUNCTION_NAME(deriv) + + return deriv; +} + +int main(void) { + int BOOST_LOCAL_FUNCTION( (int x) ) { + return x + 4; + } BOOST_LOCAL_FUNCTION_NAME(add2) + + boost::function<int (int)> a2 = add2; + boost::function<int (int)> d2 = derivative(a2, 2); + BOOST_TEST(d2(6) == 1); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/return_derivative_seq_nova.cpp b/src/boost/libs/local_function/test/return_derivative_seq_nova.cpp new file mode 100644 index 000000000..49bccdda3 --- /dev/null +++ b/src/boost/libs/local_function/test/return_derivative_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "return_derivative_seq.cpp" + diff --git a/src/boost/libs/local_function/test/return_inc.cpp b/src/boost/libs/local_function/test/return_inc.cpp new file mode 100644 index 000000000..7d3e4248c --- /dev/null +++ b/src/boost/libs/local_function/test/return_inc.cpp @@ -0,0 +1,38 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/function.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::function<int (void)> inc(int& value) { + int BOOST_LOCAL_FUNCTION(bind& value) { + return ++value; + } BOOST_LOCAL_FUNCTION_NAME(i) + return i; +} + +int main(void) { + int value1 = 0; // Reference valid in scope where closure is used. + boost::function<int (void)> inc1 = inc(value1); + int value2 = 0; + boost::function<int (void)> inc2 = inc(value2); + + BOOST_TEST(inc1() == 1); + BOOST_TEST(inc1() == 2); + BOOST_TEST(inc2() == 1); + BOOST_TEST(inc1() == 3); + return boost::report_errors(); +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/return_inc_seq.cpp b/src/boost/libs/local_function/test/return_inc_seq.cpp new file mode 100644 index 000000000..6116ea990 --- /dev/null +++ b/src/boost/libs/local_function/test/return_inc_seq.cpp @@ -0,0 +1,31 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/function.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::function<int (void)> inc(int& value) { + int BOOST_LOCAL_FUNCTION( (bind& value) ) { + return ++value; + } BOOST_LOCAL_FUNCTION_NAME(i) + return i; +} + +int main(void) { + int value1 = 0; + boost::function<int (void)> inc1 = inc(value1); + int value2 = 0; + boost::function<int (void)> inc2 = inc(value2); + + BOOST_TEST(inc1() == 1); + BOOST_TEST(inc1() == 2); + BOOST_TEST(inc2() == 1); + BOOST_TEST(inc1() == 3); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/return_inc_seq_nova.cpp b/src/boost/libs/local_function/test/return_inc_seq_nova.cpp new file mode 100644 index 000000000..c55ade6df --- /dev/null +++ b/src/boost/libs/local_function/test/return_inc_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "return_inc_seq.cpp" + diff --git a/src/boost/libs/local_function/test/return_setget.cpp b/src/boost/libs/local_function/test/return_setget.cpp new file mode 100644 index 000000000..1eb904c54 --- /dev/null +++ b/src/boost/libs/local_function/test/return_setget.cpp @@ -0,0 +1,47 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/function.hpp> +#include <boost/typeof/std/string.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <string> + +boost::function<void (const std::string&)> set; +boost::function<const std::string& (void)> get; + +void action(void) { + // State `message` hidden behind access functions from here. + BOOST_TEST(get() == "abc"); + set("xyz"); + BOOST_TEST(get() == "xyz"); +} + +int main(void) { + std::string message = "abc"; // Reference valid where closure used. + + void BOOST_LOCAL_FUNCTION(bind& message, const std::string& text) { + message = text; + } BOOST_LOCAL_FUNCTION_NAME(s) + set = s; + + const std::string& BOOST_LOCAL_FUNCTION(const bind& message) { + return message; + } BOOST_LOCAL_FUNCTION_NAME(g) + get = g; + + action(); + return boost::report_errors(); +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/return_setget_seq.cpp b/src/boost/libs/local_function/test/return_setget_seq.cpp new file mode 100644 index 000000000..33b1c35dd --- /dev/null +++ b/src/boost/libs/local_function/test/return_setget_seq.cpp @@ -0,0 +1,39 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/function.hpp> +#include <boost/typeof/std/string.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <string> + +boost::function<void (const std::string&)> set; +boost::function<const std::string& (void)> get; + +void action(void) { + BOOST_TEST(get() == "abc"); + set("xyz"); + BOOST_TEST(get() == "xyz"); +} + +int main(void) { + std::string message = "abc"; + + void BOOST_LOCAL_FUNCTION( (bind& message) (const std::string& text) ) { + message = text; + } BOOST_LOCAL_FUNCTION_NAME(s) + set = s; + + const std::string& BOOST_LOCAL_FUNCTION( (const bind& message) ) { + return message; + } BOOST_LOCAL_FUNCTION_NAME(g) + get = g; + + action(); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/return_setget_seq_nova.cpp b/src/boost/libs/local_function/test/return_setget_seq_nova.cpp new file mode 100644 index 000000000..87e2bde4c --- /dev/null +++ b/src/boost/libs/local_function/test/return_setget_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "return_setget_seq.cpp" + diff --git a/src/boost/libs/local_function/test/return_this.cpp b/src/boost/libs/local_function/test/return_this.cpp new file mode 100644 index 000000000..ea3debc86 --- /dev/null +++ b/src/boost/libs/local_function/test/return_this.cpp @@ -0,0 +1,50 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/function.hpp> +#include <boost/typeof/typeof.hpp> +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include <boost/detail/lightweight_test.hpp> + +struct number; +BOOST_TYPEOF_REGISTER_TYPE(number) // Register before `bind this_` below. + +struct number { + number(int value) : value_(value) {} + + boost::function<int (void)> inc(void) { + int BOOST_LOCAL_FUNCTION(bind this_) { + return ++this_->value_; + } BOOST_LOCAL_FUNCTION_NAME(i) + return i; + } + +private: + int value_; +}; + +int main(void) { + number n1 = 0; // Object valid in scope where closure is used. + boost::function<int (void)> inc1 = n1.inc(); + number n2 = 0; + boost::function<int (void)> inc2 = n2.inc(); + + BOOST_TEST(inc1() == 1); + BOOST_TEST(inc1() == 2); + BOOST_TEST(inc2() == 1); + BOOST_TEST(inc1() == 3); + return boost::report_errors(); +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/return_this_seq.cpp b/src/boost/libs/local_function/test/return_this_seq.cpp new file mode 100644 index 000000000..551d3e1b1 --- /dev/null +++ b/src/boost/libs/local_function/test/return_this_seq.cpp @@ -0,0 +1,43 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/function.hpp> +#include <boost/typeof/typeof.hpp> +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include <boost/detail/lightweight_test.hpp> + +struct number; +BOOST_TYPEOF_REGISTER_TYPE(number) // Register before `bind this_` below. + +struct number { + number(int value) : value_(value) {} + + boost::function<int (void)> inc(void) { + int BOOST_LOCAL_FUNCTION( (bind this_) ) { + return ++this_->value_; + } BOOST_LOCAL_FUNCTION_NAME(i) + return i; + } + +private: + int value_; +}; + +int main(void) { + number n1 = 0; // Object valid in scope where closure is used. + boost::function<int (void)> inc1 = n1.inc(); + number n2 = 0; + boost::function<int (void)> inc2 = n2.inc(); + + BOOST_TEST(inc1() == 1); + BOOST_TEST(inc1() == 2); + BOOST_TEST(inc2() == 1); + BOOST_TEST(inc1() == 3); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/return_this_seq_nova.cpp b/src/boost/libs/local_function/test/return_this_seq_nova.cpp new file mode 100644 index 000000000..1f0cfc258 --- /dev/null +++ b/src/boost/libs/local_function/test/return_this_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "return_this_seq.cpp" + diff --git a/src/boost/libs/local_function/test/same_line.cpp b/src/boost/libs/local_function/test/same_line.cpp new file mode 100644 index 000000000..0809e024f --- /dev/null +++ b/src/boost/libs/local_function/test/same_line.cpp @@ -0,0 +1,57 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <iostream> + +//[same_line +#define LOCAL_INC_DEC(offset) \ + int BOOST_LOCAL_FUNCTION_ID(BOOST_PP_CAT(inc, __LINE__), /* unique ID */ \ + const bind offset, const int x) { \ + return x + offset; \ + } BOOST_LOCAL_FUNCTION_NAME(inc) \ + \ + int BOOST_LOCAL_FUNCTION_ID(BOOST_PP_CAT(dec, __LINE__), \ + const bind offset, const int x) { \ + return x - offset; \ + } BOOST_LOCAL_FUNCTION_NAME(dec) + +#define LOCAL_INC_DEC_TPL(offset) \ + T BOOST_LOCAL_FUNCTION_ID_TPL(BOOST_PP_CAT(inc, __LINE__), \ + const bind offset, const T x) { \ + return x + offset; \ + } BOOST_LOCAL_FUNCTION_NAME_TPL(inc) \ + \ + T BOOST_LOCAL_FUNCTION_ID_TPL(BOOST_PP_CAT(dec, __LINE__), \ + const bind offset, const T x) { \ + return x - offset; \ + } BOOST_LOCAL_FUNCTION_NAME_TPL(dec) + +template<typename T> +void f(T& delta) { + LOCAL_INC_DEC_TPL(delta) // Multiple local functions on same line. + BOOST_TEST(dec(inc(123)) == 123); +} + +int main(void) { + int delta = 10; + LOCAL_INC_DEC(delta) // Multiple local functions on same line. + BOOST_TEST(dec(inc(123)) == 123); + f(delta); + return boost::report_errors(); +} +//] + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/same_line_seq.cpp b/src/boost/libs/local_function/test/same_line_seq.cpp new file mode 100644 index 000000000..2113f4752 --- /dev/null +++ b/src/boost/libs/local_function/test/same_line_seq.cpp @@ -0,0 +1,48 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <iostream> + +#define LOCAL_INC_DEC(offset) \ + int BOOST_LOCAL_FUNCTION_ID(BOOST_PP_CAT(inc, __LINE__), /* unique ID */ \ + (const bind offset) (const int x) ) { \ + return x + offset; \ + } BOOST_LOCAL_FUNCTION_NAME(inc) \ + \ + int BOOST_LOCAL_FUNCTION_ID(BOOST_PP_CAT(dec, __LINE__), \ + (const bind offset) (const int x) ) { \ + return x - offset; \ + } BOOST_LOCAL_FUNCTION_NAME(dec) + +#define LOCAL_INC_DEC_TPL(offset) \ + T BOOST_LOCAL_FUNCTION_ID_TPL(BOOST_PP_CAT(inc, __LINE__), \ + (const bind offset) (const T x) ) { \ + return x + offset; \ + } BOOST_LOCAL_FUNCTION_NAME_TPL(inc) \ + \ + T BOOST_LOCAL_FUNCTION_ID_TPL(BOOST_PP_CAT(dec, __LINE__), \ + (const bind offset) (const T x) ) { \ + return x - offset; \ + } BOOST_LOCAL_FUNCTION_NAME_TPL(dec) + +template<typename T> +void f(T& delta) { + LOCAL_INC_DEC_TPL(delta) // Multiple local functions on same line. + BOOST_TEST(dec(inc(123)) == 123); +} + +int main(void) { + int delta = 10; + LOCAL_INC_DEC(delta) // Declare local functions on same line using `_ID`. + BOOST_TEST(dec(inc(123)) == 123); + f(delta); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/same_line_seq_nova.cpp b/src/boost/libs/local_function/test/same_line_seq_nova.cpp new file mode 100644 index 000000000..fb5cc174f --- /dev/null +++ b/src/boost/libs/local_function/test/same_line_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "same_line_seq.cpp" + diff --git a/src/boost/libs/local_function/test/ten_void.cpp b/src/boost/libs/local_function/test/ten_void.cpp new file mode 100644 index 000000000..99bf1bfdb --- /dev/null +++ b/src/boost/libs/local_function/test/ten_void.cpp @@ -0,0 +1,21 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main(void) { + //[ten_void + int BOOST_LOCAL_FUNCTION(void) { // No parameter. + return 10; + } BOOST_LOCAL_FUNCTION_NAME(ten) + + BOOST_TEST(ten() == 10); + //] + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/ten_void_nova.cpp b/src/boost/libs/local_function/test/ten_void_nova.cpp new file mode 100644 index 000000000..64b01c56d --- /dev/null +++ b/src/boost/libs/local_function/test/ten_void_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "ten_void.cpp" + diff --git a/src/boost/libs/local_function/test/transform.cpp b/src/boost/libs/local_function/test/transform.cpp new file mode 100644 index 000000000..0cdbe76bc --- /dev/null +++ b/src/boost/libs/local_function/test/transform.cpp @@ -0,0 +1,47 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <algorithm> +#include <vector> + +int main(void) { + //[transform + int offset = 5; + std::vector<int> v; + std::vector<int> w; + + for(int i = 1; i <= 2; ++i) v.push_back(i * 10); + BOOST_TEST(v[0] == 10); BOOST_TEST(v[1] == 20); + w.resize(v.size()); + + int BOOST_LOCAL_FUNCTION(const bind& offset, int i) { + return ++i + offset; + } BOOST_LOCAL_FUNCTION_NAME(inc) + + std::transform(v.begin(), v.end(), w.begin(), inc); + BOOST_TEST(w[0] == 16); BOOST_TEST(w[1] == 26); + + int BOOST_LOCAL_FUNCTION(bind& inc, int i, int j) { + return inc(i + j); // Call the other bound local function. + } BOOST_LOCAL_FUNCTION_NAME(inc_sum) + + offset = 0; + std::transform(v.begin(), v.end(), w.begin(), v.begin(), inc_sum); + BOOST_TEST(v[0] == 27); BOOST_TEST(v[1] == 47); + //] + return boost::report_errors(); +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/transform_seq.cpp b/src/boost/libs/local_function/test/transform_seq.cpp new file mode 100644 index 000000000..b29514c45 --- /dev/null +++ b/src/boost/libs/local_function/test/transform_seq.cpp @@ -0,0 +1,39 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/local_function.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <algorithm> +#include <vector> + +int main(void) { + int offset = 5; + std::vector<int> v; + std::vector<int> w; + + for(int i = 1; i <= 2; ++i) v.push_back(i * 10); + BOOST_TEST(v[0] == 10); BOOST_TEST(v[1] == 20); + w.resize(v.size()); + + int BOOST_LOCAL_FUNCTION( (const bind& offset) (int i) ) { + return ++i + offset; + } BOOST_LOCAL_FUNCTION_NAME(inc) + + std::transform(v.begin(), v.end(), w.begin(), inc); + BOOST_TEST(w[0] == 16); BOOST_TEST(w[1] == 26); + + int BOOST_LOCAL_FUNCTION( (bind& inc) (int i) (int j) ) { + return inc(i + j); + } BOOST_LOCAL_FUNCTION_NAME(inc_sum) + + offset = 0; + std::transform(v.begin(), v.end(), w.begin(), v.begin(), inc_sum); + BOOST_TEST(v[0] == 27); BOOST_TEST(v[1] == 47); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/transform_seq_nova.cpp b/src/boost/libs/local_function/test/transform_seq_nova.cpp new file mode 100644 index 000000000..9f06e4fb1 --- /dev/null +++ b/src/boost/libs/local_function/test/transform_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "transform_seq.cpp" + diff --git a/src/boost/libs/local_function/test/typeof.cpp b/src/boost/libs/local_function/test/typeof.cpp new file mode 100644 index 000000000..aa347354a --- /dev/null +++ b/src/boost/libs/local_function/test/typeof.cpp @@ -0,0 +1,41 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include "addable.hpp" +#include <boost/local_function.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/concept_check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <algorithm> + +int main(void) { + //[typeof + int sum = 0, factor = 10; + + void BOOST_LOCAL_FUNCTION(const bind factor, bind& sum, int num) { + // Type-of for concept checking. + BOOST_CONCEPT_ASSERT((Addable<boost::remove_reference< + BOOST_LOCAL_FUNCTION_TYPEOF(sum)>::type>)); + // Type-of for declarations. + boost::remove_reference<BOOST_LOCAL_FUNCTION_TYPEOF( + factor)>::type mult = factor * num; + sum += mult; + } BOOST_LOCAL_FUNCTION_NAME(add) + + add(6); + //] + BOOST_TEST(sum == 60); + return boost::report_errors(); +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/typeof_seq.cpp b/src/boost/libs/local_function/test/typeof_seq.cpp new file mode 100644 index 000000000..01dd4633e --- /dev/null +++ b/src/boost/libs/local_function/test/typeof_seq.cpp @@ -0,0 +1,30 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "addable.hpp" +#include <boost/local_function.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/concept_check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <algorithm> + +int main(void) { + int sum = 0, factor = 10; + + void BOOST_LOCAL_FUNCTION( (const bind factor) (bind& sum) (int num) ) { + BOOST_CONCEPT_ASSERT((Addable<boost::remove_reference< + BOOST_LOCAL_FUNCTION_TYPEOF(sum)>::type>)); + boost::remove_reference<BOOST_LOCAL_FUNCTION_TYPEOF( + factor)>::type mult = factor * num; + sum += mult; + } BOOST_LOCAL_FUNCTION_NAME(add) + + add(6); + BOOST_TEST(sum == 60); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/typeof_seq_nova.cpp b/src/boost/libs/local_function/test/typeof_seq_nova.cpp new file mode 100644 index 000000000..bf8b982be --- /dev/null +++ b/src/boost/libs/local_function/test/typeof_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "typeof_seq.cpp" + diff --git a/src/boost/libs/local_function/test/typeof_template.cpp b/src/boost/libs/local_function/test/typeof_template.cpp new file mode 100644 index 000000000..f74e49fcd --- /dev/null +++ b/src/boost/libs/local_function/test/typeof_template.cpp @@ -0,0 +1,43 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include <boost/config.hpp> +#ifdef BOOST_NO_CXX11_VARIADIC_MACROS +# error "variadic macros required" +#else + +#include "addable.hpp" +#include <boost/local_function.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/concept_check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <algorithm> + +//[typeof_template +template<typename T> +T calculate(const T& factor) { + T sum = 0; + + void BOOST_LOCAL_FUNCTION_TPL(const bind factor, bind& sum, T num) { + // Local function `TYPEOF` does not need `typename`. + BOOST_CONCEPT_ASSERT((Addable<typename boost::remove_reference< + BOOST_LOCAL_FUNCTION_TYPEOF(sum)>::type>)); + sum += factor * num; + } BOOST_LOCAL_FUNCTION_NAME_TPL(add) + + add(6); + return sum; +} +//] + +int main(void) { + BOOST_TEST(calculate(10) == 60); + return boost::report_errors(); +} + +#endif // VARIADIC_MACROS + diff --git a/src/boost/libs/local_function/test/typeof_template_seq.cpp b/src/boost/libs/local_function/test/typeof_template_seq.cpp new file mode 100644 index 000000000..60028e958 --- /dev/null +++ b/src/boost/libs/local_function/test/typeof_template_seq.cpp @@ -0,0 +1,33 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "addable.hpp" +#include <boost/local_function.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/concept_check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <algorithm> + +template<typename T> +T calculate(const T& factor) { + T sum = 0; + + void BOOST_LOCAL_FUNCTION_TPL( (const bind factor) (bind& sum) (T num) ) { + BOOST_CONCEPT_ASSERT((Addable<typename boost::remove_reference< + BOOST_LOCAL_FUNCTION_TYPEOF(sum)>::type>)); + sum += factor * num; + } BOOST_LOCAL_FUNCTION_NAME_TPL(add) + + add(6); + return sum; +} + +int main(void) { + BOOST_TEST(calculate(10) == 60); + return boost::report_errors(); +} + diff --git a/src/boost/libs/local_function/test/typeof_template_seq_nova.cpp b/src/boost/libs/local_function/test/typeof_template_seq_nova.cpp new file mode 100644 index 000000000..48df4d431 --- /dev/null +++ b/src/boost/libs/local_function/test/typeof_template_seq_nova.cpp @@ -0,0 +1,10 @@ + +// Copyright (C) 2009-2012 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 +// (see accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt) +// Home at http://www.boost.org/libs/local_function + +#include "nova.hpp" +#include "typeof_template_seq.cpp" + |