From 19fcec84d8d7d21e796c7624e521b60d28ee21ed Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:45:59 +0200 Subject: Adding upstream version 16.2.11+ds. Signed-off-by: Daniel Baumann --- src/boost/libs/local_function/example/Jamfile.v2 | 77 ++++++++++++ .../local_function/example/add_cxx11_lambda.cpp | 34 ++++++ .../local_function/example/add_global_functor.cpp | 38 ++++++ .../local_function/example/add_local_functor.cpp | 35 ++++++ .../libs/local_function/example/add_phoenix.cpp | 34 ++++++ src/boost/libs/local_function/example/chrono.py | 25 ++++ .../libs/local_function/example/const_block.cpp | 18 +++ .../libs/local_function/example/const_block.hpp | 58 +++++++++ .../local_function/example/const_block_error.cpp | 20 ++++ .../example/const_block_error_cxx11_lambda.cpp | 28 +++++ .../example/expensive_copy_cxx11_lambda.cpp | 39 +++++++ .../example/expensive_copy_local_function.cpp | 35 ++++++ .../libs/local_function/example/gcc_access.cpp | 23 ++++ .../local_function/example/gcc_cxx11_lambda.cpp | 35 ++++++ .../libs/local_function/example/gcc_lambda.cpp | 36 ++++++ .../libs/local_function/example/gcc_lambda.hpp | 129 +++++++++++++++++++++ .../libs/local_function/example/gcc_square.cpp | 23 ++++ .../libs/local_function/example/gcc_store.cpp | 33 ++++++ .../local_function/example/impl_pp_keyword.cpp | 28 +++++ .../local_function/example/impl_tparam_tricks.cpp | 71 ++++++++++++ .../libs/local_function/example/n2529_this.cpp | 47 ++++++++ .../libs/local_function/example/n2550_find_if.cpp | 44 +++++++ .../example/noncopyable_cxx11_lambda_error.cpp | 36 ++++++ .../example/noncopyable_local_function.cpp | 32 +++++ .../local_function/example/phoenix_factorial.cpp | 40 +++++++ .../example/phoenix_factorial_local.cpp | 31 +++++ src/boost/libs/local_function/example/profile.xls | Bin 0 -> 181248 bytes .../example/profile_cxx11_lambda.cpp | 44 +++++++ .../example/profile_gcc_cxx11_debug.png | Bin 0 -> 52012 bytes .../example/profile_gcc_cxx11_release.png | Bin 0 -> 54872 bytes .../local_function/example/profile_gcc_debug.png | Bin 0 -> 44726 bytes .../local_function/example/profile_gcc_release.png | Bin 0 -> 48328 bytes .../example/profile_global_functor.cpp | 51 ++++++++ .../local_function/example/profile_helpers.hpp | 54 +++++++++ .../example/profile_legend_cxx11_lambda.png | Bin 0 -> 207 bytes .../example/profile_legend_global_functor.png | Bin 0 -> 205 bytes .../example/profile_legend_local_function.png | Bin 0 -> 206 bytes .../profile_legend_local_function_inline.png | Bin 0 -> 206 bytes .../example/profile_legend_local_functor.png | Bin 0 -> 205 bytes .../example/profile_legend_phoenix.png | Bin 0 -> 207 bytes .../example/profile_local_function.cpp | 45 +++++++ .../example/profile_local_function_inline.cpp | 45 +++++++ .../example/profile_local_functor.cpp | 50 ++++++++ .../local_function/example/profile_msvc_debug.png | Bin 0 -> 43851 bytes .../example/profile_msvc_release.png | Bin 0 -> 50420 bytes .../local_function/example/profile_phoenix.cpp | 45 +++++++ .../libs/local_function/example/scope_exit.cpp | 110 ++++++++++++++++++ .../libs/local_function/example/scope_exit.hpp | 51 ++++++++ 48 files changed, 1544 insertions(+) create mode 100644 src/boost/libs/local_function/example/Jamfile.v2 create mode 100644 src/boost/libs/local_function/example/add_cxx11_lambda.cpp create mode 100644 src/boost/libs/local_function/example/add_global_functor.cpp create mode 100644 src/boost/libs/local_function/example/add_local_functor.cpp create mode 100644 src/boost/libs/local_function/example/add_phoenix.cpp create mode 100755 src/boost/libs/local_function/example/chrono.py create mode 100644 src/boost/libs/local_function/example/const_block.cpp create mode 100644 src/boost/libs/local_function/example/const_block.hpp create mode 100644 src/boost/libs/local_function/example/const_block_error.cpp create mode 100644 src/boost/libs/local_function/example/const_block_error_cxx11_lambda.cpp create mode 100644 src/boost/libs/local_function/example/expensive_copy_cxx11_lambda.cpp create mode 100644 src/boost/libs/local_function/example/expensive_copy_local_function.cpp create mode 100644 src/boost/libs/local_function/example/gcc_access.cpp create mode 100644 src/boost/libs/local_function/example/gcc_cxx11_lambda.cpp create mode 100644 src/boost/libs/local_function/example/gcc_lambda.cpp create mode 100644 src/boost/libs/local_function/example/gcc_lambda.hpp create mode 100644 src/boost/libs/local_function/example/gcc_square.cpp create mode 100644 src/boost/libs/local_function/example/gcc_store.cpp create mode 100644 src/boost/libs/local_function/example/impl_pp_keyword.cpp create mode 100644 src/boost/libs/local_function/example/impl_tparam_tricks.cpp create mode 100644 src/boost/libs/local_function/example/n2529_this.cpp create mode 100644 src/boost/libs/local_function/example/n2550_find_if.cpp create mode 100644 src/boost/libs/local_function/example/noncopyable_cxx11_lambda_error.cpp create mode 100644 src/boost/libs/local_function/example/noncopyable_local_function.cpp create mode 100644 src/boost/libs/local_function/example/phoenix_factorial.cpp create mode 100644 src/boost/libs/local_function/example/phoenix_factorial_local.cpp create mode 100644 src/boost/libs/local_function/example/profile.xls create mode 100644 src/boost/libs/local_function/example/profile_cxx11_lambda.cpp create mode 100644 src/boost/libs/local_function/example/profile_gcc_cxx11_debug.png create mode 100644 src/boost/libs/local_function/example/profile_gcc_cxx11_release.png create mode 100644 src/boost/libs/local_function/example/profile_gcc_debug.png create mode 100644 src/boost/libs/local_function/example/profile_gcc_release.png create mode 100644 src/boost/libs/local_function/example/profile_global_functor.cpp create mode 100644 src/boost/libs/local_function/example/profile_helpers.hpp create mode 100644 src/boost/libs/local_function/example/profile_legend_cxx11_lambda.png create mode 100644 src/boost/libs/local_function/example/profile_legend_global_functor.png create mode 100644 src/boost/libs/local_function/example/profile_legend_local_function.png create mode 100644 src/boost/libs/local_function/example/profile_legend_local_function_inline.png create mode 100644 src/boost/libs/local_function/example/profile_legend_local_functor.png create mode 100644 src/boost/libs/local_function/example/profile_legend_phoenix.png create mode 100644 src/boost/libs/local_function/example/profile_local_function.cpp create mode 100644 src/boost/libs/local_function/example/profile_local_function_inline.cpp create mode 100644 src/boost/libs/local_function/example/profile_local_functor.cpp create mode 100644 src/boost/libs/local_function/example/profile_msvc_debug.png create mode 100644 src/boost/libs/local_function/example/profile_msvc_release.png create mode 100644 src/boost/libs/local_function/example/profile_phoenix.cpp create mode 100644 src/boost/libs/local_function/example/scope_exit.cpp create mode 100644 src/boost/libs/local_function/example/scope_exit.hpp (limited to 'src/boost/libs/local_function/example') 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 sun: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 : debug : ; +run const_block_error.cpp : 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 + : /boost/chrono//boost_chrono + /boost/system//boost_system + static + ; +exe profile_cxx11_lambda : profile_cxx11_lambda.cpp + : /boost/chrono//boost_chrono + /boost/system//boost_system + static + ; +exe profile_local_function : profile_local_function.cpp + : /boost/chrono//boost_chrono + /boost/system//boost_system + static + ; +exe profile_local_function_inline : profile_local_function_inline.cpp + : /boost/chrono//boost_chrono + /boost/system//boost_system + static + ; +exe profile_local_functor : profile_local_functor.cpp + : /boost/chrono//boost_chrono + /boost/system//boost_system + static + ; +exe profile_phoenix : profile_phoenix.cpp + : /boost/chrono//boost_chrono + /boost/system//boost_system + 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 +#ifdef BOOST_NO_CXX11_LAMBDAS +# error "lambda functions required" +#else + +#include +#include + +//[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 +#include + +//[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 + +//[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 +#include +#include +#include + +//[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 + +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 +#include +#include +#include +#include +#include +#include +#include +#include + +// 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 + +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 +#ifdef BOOST_NO_CXX11_LAMBDAS +# error "requires lambda functions" +#else + +#include + +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 +#ifdef BOOST_NO_CXX11_LAMBDAS +# error "lambda functions required" +#else + +#include +#include + +//[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 +#include +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include +#include + +//[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 +#include + +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 +#ifdef BOOST_NO_CXX11_LAMBDAS +# error "lambda functions required" +#else + +#include +#include + +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 +#ifndef __GNUC__ +# error "GCC required (using non-standard GCC statement expressions)" +#else + +#include "gcc_lambda.hpp" +#include +#include + +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// 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 +#include + +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 +#include +#include + +void intermediate(boost::function 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 +#include +#include +#include + +// 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 +#include +#include + +// 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(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 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 +#include +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include +#include +#include + +struct v; +BOOST_TYPEOF_REGISTER_TYPE(v) // Register before `bind this_` below. + +struct v { + std::vector nums; + + v(const std::vector& numbers): nums(numbers) {} + + void change_sign_all(const std::vector& 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 n(3); + n[0] = 1; n[1] = 2; n[2] = 3; + + std::vector 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 +#include +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include +#include +#include + +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 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::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 +#ifdef BOOST_NO_CXX11_LAMBDAS +# error "lambda functions required" +#else + +#include +#include + +//[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 +#include +#include +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include + +//[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 +#include +#include + +//[phoenix_factorial +struct factorial_impl { // Phoenix function from global functor. + template + struct result; + + template + struct result : result {}; + + template + struct result { typedef Arg type; }; + + template // 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; + + 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 +#include +#include +#include +#include + +//[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 > + 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 new file mode 100644 index 000000000..9087ed174 Binary files /dev/null and b/src/boost/libs/local_function/example/profile.xls differ 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 +#ifdef BOOST_NO_CXX11_LAMBDAS +# error "lambda functions required" +#else + +#include +#include +#include +#include +#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 v(size); + std::fill(v.begin(), v.end(), 1.0); + + boost::chrono::duration 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 new file mode 100644 index 000000000..431f2bb37 Binary files /dev/null and b/src/boost/libs/local_function/example/profile_gcc_cxx11_debug.png differ 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 new file mode 100644 index 000000000..eeb371a4a Binary files /dev/null and b/src/boost/libs/local_function/example/profile_gcc_cxx11_release.png differ diff --git a/src/boost/libs/local_function/example/profile_gcc_debug.png b/src/boost/libs/local_function/example/profile_gcc_debug.png new file mode 100644 index 000000000..f907ca139 Binary files /dev/null and b/src/boost/libs/local_function/example/profile_gcc_debug.png differ diff --git a/src/boost/libs/local_function/example/profile_gcc_release.png b/src/boost/libs/local_function/example/profile_gcc_release.png new file mode 100644 index 000000000..1a23e56b1 Binary files /dev/null and b/src/boost/libs/local_function/example/profile_gcc_release.png differ 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 +#include +#include +#include +#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 decl_sec = + boost::chrono::system_clock::now() - start; + + std::vector v(size); + std::fill(v.begin(), v.end(), 1.0); + + boost::chrono::duration 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 +#include + +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 new file mode 100644 index 000000000..58770b195 Binary files /dev/null and b/src/boost/libs/local_function/example/profile_legend_cxx11_lambda.png differ 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 new file mode 100644 index 000000000..d7f5b70fd Binary files /dev/null and b/src/boost/libs/local_function/example/profile_legend_global_functor.png differ 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 new file mode 100644 index 000000000..5b9b51766 Binary files /dev/null and b/src/boost/libs/local_function/example/profile_legend_local_function.png differ 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 new file mode 100644 index 000000000..809de56d9 Binary files /dev/null and b/src/boost/libs/local_function/example/profile_legend_local_function_inline.png differ 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 new file mode 100644 index 000000000..6038c5776 Binary files /dev/null and b/src/boost/libs/local_function/example/profile_legend_local_functor.png differ diff --git a/src/boost/libs/local_function/example/profile_legend_phoenix.png b/src/boost/libs/local_function/example/profile_legend_phoenix.png new file mode 100644 index 000000000..249962540 Binary files /dev/null and b/src/boost/libs/local_function/example/profile_legend_phoenix.png differ 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 +#include +#include +#include +#include +#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 decl_sec = + boost::chrono::system_clock::now() - start; + + std::vector v(size); + std::fill(v.begin(), v.end(), 1.0); + + boost::chrono::duration 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 +#include +#include +#include +#include +#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 decl_sec = + boost::chrono::system_clock::now() - start; + + std::vector v(size); + std::fill(v.begin(), v.end(), 1.0); + + boost::chrono::duration 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 +#include +#include +#include +#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 decl_sec = + boost::chrono::system_clock::now() - start; + + std::vector v(size); + std::fill(v.begin(), v.end(), 1.0); + + boost::chrono::duration 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 new file mode 100644 index 000000000..859744b73 Binary files /dev/null and b/src/boost/libs/local_function/example/profile_msvc_debug.png differ diff --git a/src/boost/libs/local_function/example/profile_msvc_release.png b/src/boost/libs/local_function/example/profile_msvc_release.png new file mode 100644 index 000000000..ea14d44a1 Binary files /dev/null and b/src/boost/libs/local_function/example/profile_msvc_release.png differ 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 +#include +#include +#include +#include +#include +#include +#include +#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 v(size); + std::fill(v.begin(), v.end(), 1.0); + + boost::chrono::duration 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 +#include +#include +#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() +#include +#include +#include +#include + +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 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 +#include +#include +#include +#include + +//[scope_exit_class +struct scope_exit { + scope_exit(boost::function f): f_(f) {} + ~scope_exit(void) { f_(); } +private: + boost::function 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 + -- cgit v1.2.3