From 4403017952664934eb45ad4b7acb11e2532da181 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Mon, 26 Aug 2019 20:22:17 -0400 Subject: [PATCH] Rewrite factory and value_factory - Support r-value arguments - Use variadic templates for arbitrary arguments - Support allocators that are final - Support allocators that use fancy pointers - Support environments with disabled exceptions - Improve compilation times --- factory/doc/factory.qbk | 41 +- factory/test/Jamfile | 36 +- factory/test/factory.cpp | 102 ++-- factory/test/factory_allocator_throws.cpp | 85 +++ factory/test/factory_args.cpp | 42 ++ factory/test/factory_default_allocator.cpp | 55 ++ factory/test/factory_move.cpp | 55 ++ factory/test/factory_with_allocator.cpp | 139 ++--- factory/test/factory_with_none_t.cpp | 56 -- factory/test/factory_with_std_allocator.cpp | 59 +-- factory/test/value_factory.cpp | 91 +++- factory/test/value_factory_args.cpp | 40 ++ factory/test/value_factory_move.cpp | 54 ++ include/boost/functional/factory.hpp | 551 +++++++++++++------- include/boost/functional/value_factory.hpp | 153 +++--- meta/libraries.json | 1 + 16 files changed, 1072 insertions(+), 488 deletions(-) create mode 100644 factory/test/factory_allocator_throws.cpp create mode 100644 factory/test/factory_args.cpp create mode 100644 factory/test/factory_default_allocator.cpp create mode 100644 factory/test/factory_move.cpp delete mode 100644 factory/test/factory_with_none_t.cpp create mode 100644 factory/test/value_factory_args.cpp create mode 100644 factory/test/value_factory_move.cpp diff --git a/factory/doc/factory.qbk b/factory/doc/factory.qbk index ef1acf8..fe9d2f6 100644 --- a/factory/doc/factory.qbk +++ b/factory/doc/factory.qbk @@ -1,8 +1,9 @@ [library Boost.Functional/Factory [quickbook 1.3] [version 1.0] - [authors [Schwinger, Tobias]] + [authors [Schwinger, Tobias], [Fernandes, Glen]] [copyright 2007 2008 Tobias Schwinger] + [copyright 2019 Glen Joseph Fernandes] [license Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -54,9 +55,10 @@ invocation without `new`. __boost__value_factory__()(arg1,arg2,arg3) // same as T(arg1,arg2,arg3) -For technical reasons the arguments to the function objects have to be -LValues. A factory that also accepts RValues can be composed using the -__boost__forward_adapter__ or __boost__bind__. +Before C++11 the arguments to the function objects have to be LValues. A +factory that also accepts RValues can be composed using the +__boost__forward_adapter__ or __boost__bind__. In C++11 or higher the +arguments can be LValues or RValues. [endsect] @@ -259,7 +261,7 @@ Function object template that invokes the constructor of the type `T`. [variablelist Notation [[`T`] [an arbitrary type with at least one public constructor]] - [[`a0`...`aN`] [argument LValues to a constructor of `T`]] + [[`a0`...`aN`] [argument values to a constructor of `T`]] [[`F`] [the type `value_factory`]] [[`f`] [an instance object of `F`]] ] @@ -276,8 +278,8 @@ Function object template that invokes the constructor of the type `T`. [heading Limits] -The macro BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY can be defined to set the -maximum arity. It defaults to 10. +Before C++11, the maximum number of arguments supported is 10. Since C++11 an +arbitrary number of arguments is supported. [endsect] @@ -326,7 +328,7 @@ separately allocated reference counter). [variablelist Notation [[`T`] [an arbitrary type with at least one public constructor]] [[`P`] [pointer or smart pointer to `T`]] - [[`a0`...`aN`] [argument LValues to a constructor of `T`]] + [[`a0`...`aN`] [argument values to a constructor of `T`]] [[`F`] [the type `factory

`]] [[`f`] [an instance object of `F`]] ] @@ -344,8 +346,8 @@ separately allocated reference counter). [heading Limits] -The macro BOOST_FUNCTIONAL_FACTORY_MAX_ARITY can be defined to set the -maximum arity. It defaults to 10. +Before C++11, the maximum number of arguments supported is 10. Since C++11 an +arbitrary number of arguments is supported. [endsect] @@ -353,6 +355,25 @@ maximum arity. It defaults to 10. [section Changes] +[heading Boost 1.72.0] + +Glen Fernandes rewrote the implementations of `factory` and `value_factory` to +provide the following features: + +* Support r-value arguments when available +* Support arbitrary number of arguments via variadic templates when available +* Support allocators that are final +* Support allocators that use fancy pointers +* Support for disabled exceptions (`BOOST_NO_EXCEPTIONS`) +* Improved compilation times + +The following features have been removed: + +* Increasing limits for C++03 compilers through + `BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY` +* Using `boost::none_t` in place of `void` through + `BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T` + [heading Boost 1.58.0] In order to remove the dependency on Boost.Optional, the default parameter diff --git a/factory/test/Jamfile b/factory/test/Jamfile index c4a06af..7030e93 100644 --- a/factory/test/Jamfile +++ b/factory/test/Jamfile @@ -1,24 +1,20 @@ - -# (C) Copyright Tobias Schwinger +# Copyright 2007,2008 Tobias Schwinger # -# Use modification and distribution are subject to the boost Software License, -# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt). +# Copyright 2019 Glen Joseph Fernandes +# (glenjofe@gmail.com) +# +# Distributed under the Boost Software License, Version 1.0. +# (http://www.boost.org/LICENSE_1_0.txt) import testing ; -project factory-tests - ; - -test-suite functional/factory - : - [ run value_factory.cpp ] - [ run factory.cpp ] - [ run factory_with_allocator.cpp ] - [ run factory_with_std_allocator.cpp ] - [ compile-fail factory_with_none_t.cpp ] - [ run factory.cpp : : : BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T : none_t_factory ] - [ run factory_with_allocator.cpp : : : BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T : none_t_factory_with_allocator ] - [ run factory_with_std_allocator.cpp : : : BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T : none_t_factory_with_std_allocator ] - [ run factory_with_none_t.cpp : : : BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T : none_t_factory_with_none_t ] - ; - +run value_factory.cpp ; +run value_factory_args.cpp ; +run value_factory_move.cpp ; +run factory.cpp ; +run factory_args.cpp ; +run factory_move.cpp ; +run factory_with_allocator.cpp ; +run factory_with_std_allocator.cpp ; +run factory_allocator_throws.cpp ; +run factory_default_allocator.cpp : : : off ; diff --git a/factory/test/factory.cpp b/factory/test/factory.cpp index ef895cf..2da5cf4 100644 --- a/factory/test/factory.cpp +++ b/factory/test/factory.cpp @@ -1,53 +1,87 @@ -/*============================================================================= - Copyright (c) 2007 Tobias Schwinger +/* +Copyright 2007 Tobias Schwinger - Use modification and distribution are subject to the Boost Software - License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt). -==============================================================================*/ +Copyright 2019 Glen Joseph Fernandes +(glenjofe@gmail.com) +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ #include #include +#include -#include +class sum { +public: + explicit sum(int i0 = 0, int i1 = 0, int i2 = 0, int i3 = 0, + int i4 = 0, int i5 = 0, int i6 = 0, int i7 = 0, + int i8 = 0, int i9 = 0) + : value_(i0 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9) { } -class sum -{ - int val_sum; - public: - sum(int a, int b) : val_sum(a + b) { } + int get() const { + return value_; + } - operator int() const { return this->val_sum; } +private: + int value_; }; -// Suppress warnings about std::auto_ptr. -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif - int main() { - int one = 1, two = 2; + boost::factory x; + int a = 1; + int b = 2; + int c = 3; + int d = 4; + int e = 5; + int f = 6; + int g = 7; + int h = 8; + int i = 9; + int j = 10; { - sum* instance( boost::factory< sum* >()(one,two) ); - BOOST_TEST(*instance == 3); + boost::scoped_ptr s(x()); + BOOST_TEST(s->get() == 0); } -#if !defined(BOOST_NO_AUTO_PTR) { - std::auto_ptr instance( boost::factory< std::auto_ptr >()(one,two) ); - BOOST_TEST(*instance == 3); + boost::scoped_ptr s(x(a)); + BOOST_TEST(s->get() == 1); } -#endif -#if !defined(BOOST_NO_CXX11_SMART_PTR) { - std::unique_ptr instance( boost::factory< std::unique_ptr >()(one,two) ); - BOOST_TEST(*instance == 3); + boost::scoped_ptr s(x(a, b)); + BOOST_TEST(s->get() == 3); + } + { + boost::scoped_ptr s(x(a, b, c)); + BOOST_TEST(s->get() == 6); + } + { + boost::scoped_ptr s(x(a, b, c, d)); + BOOST_TEST(s->get() == 10); + } + { + boost::scoped_ptr s(x(a, b, c, d, e)); + BOOST_TEST(s->get() == 15); + } + { + boost::scoped_ptr s(x(a, b, c, d, e, f)); + BOOST_TEST(s->get() == 21); + } + { + boost::scoped_ptr s(x(a, b, c, d, e, f, g)); + BOOST_TEST(s->get() == 28); + } + { + boost::scoped_ptr s(x(a, b, c, d, e, f, g, h)); + BOOST_TEST(s->get() == 36); + } + { + boost::scoped_ptr s(x(a, b, c, d, e, f, g, h, i)); + BOOST_TEST(s->get() == 45); + } + { + boost::scoped_ptr s(x(a, b, c, d, e, f, g, h, i, j)); + BOOST_TEST(s->get() == 55); } -#endif return boost::report_errors(); } - -#if defined(__clang__) -#pragma clang diagnostic pop -#endif diff --git a/factory/test/factory_allocator_throws.cpp b/factory/test/factory_allocator_throws.cpp new file mode 100644 index 0000000..856e2dd --- /dev/null +++ b/factory/test/factory_allocator_throws.cpp @@ -0,0 +1,85 @@ +/* +Copyright 2019 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include + +struct type { + explicit type(bool b) { + if (b) { + throw true; + } + } +}; + +template +class creator { +public: + static int count; + + typedef T value_type; + typedef T* pointer; + + template + struct rebind { + typedef creator other; + }; + + creator() { } + + template + creator(const creator&) { } + + T* allocate(std::size_t size) { + ++count; + return static_cast(::operator new(sizeof(T) * size)); + } + + void deallocate(T* ptr, std::size_t) { + --count; + ::operator delete(ptr); + } +}; + +template +int creator::count = 0; + +template +inline bool +operator==(const creator&, const creator&) +{ + return true; +} + +template +inline bool +operator!=(const creator&, const creator&) +{ + return false; +} + +int main() +{ + bool b = true; + try { + boost::shared_ptr s(boost::factory, + creator, + boost::factory_alloc_for_pointee_and_deleter>()(b)); + } catch (...) { + BOOST_TEST(creator::count == 0); + } + try { + boost::shared_ptr s(boost::factory, + creator, + boost::factory_passes_alloc_to_smart_pointer>()(b)); + } catch (...) { + BOOST_TEST(creator::count == 0); + } + return boost::report_errors(); +} + diff --git a/factory/test/factory_args.cpp b/factory/test/factory_args.cpp new file mode 100644 index 0000000..bec677e --- /dev/null +++ b/factory/test/factory_args.cpp @@ -0,0 +1,42 @@ +/* +Copyright 2019 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#include +#include + +class sum { +public: + explicit sum(int a = 0, int b = 0, int c = 0, int d = 0, + int e = 0, int f = 0, int g = 0, int h = 0, + int i = 0, int j = 0, int k = 0, int l = 0) + : value_(a + b + c + d + e + f + g + h + i + j + k + l) { } + + int get() const { + return value_; + } + +private: + int value_; +}; + +int main() +{ + boost::scoped_ptr s(boost::factory()(1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12)); + BOOST_TEST(s->get() == 78); + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif diff --git a/factory/test/factory_default_allocator.cpp b/factory/test/factory_default_allocator.cpp new file mode 100644 index 0000000..4b8565f --- /dev/null +++ b/factory/test/factory_default_allocator.cpp @@ -0,0 +1,55 @@ +/* +Copyright 2019 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_EXCEPTIONS) +namespace boost { + +void throw_exception(const std::exception&) +{ + std::terminate(); +} + +} +#endif + +class sum { +public: + sum(int a, int b) + : value_(a + b) { } + + int get() const { + return value_; + } + +private: + int value_; +}; + +int main() +{ + int a = 1; + int b = 2; + { + boost::shared_ptr s(boost::factory, + boost::default_allocator, + boost::factory_alloc_for_pointee_and_deleter>()(a, b)); + BOOST_TEST(s->get() == 3); + } + { + boost::shared_ptr s(boost::factory, + boost::default_allocator, + boost::factory_passes_alloc_to_smart_pointer>()(a, b)); + BOOST_TEST(s->get() == 3); + } + return boost::report_errors(); +} diff --git a/factory/test/factory_move.cpp b/factory/test/factory_move.cpp new file mode 100644 index 0000000..5b6575b --- /dev/null +++ b/factory/test/factory_move.cpp @@ -0,0 +1,55 @@ +/* +Copyright 2019 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#include +#include + +class arg { +public: + explicit arg(int n) + : value_(n) { } + + arg(arg&& a) + : value_(a.value_) { } + + int get() const { + return value_; + } + +private: + int value_; +}; + +class sum { +public: + explicit sum(arg&& a1, arg&& a2) + : value_(a1.get() + a2.get()) { } + + int get() const { + return value_; + } + +private: + int value_; +}; + +int main() +{ + boost::scoped_ptr s(boost::factory()(arg(1), arg(2))); + BOOST_TEST(s->get() == 3); + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif diff --git a/factory/test/factory_with_allocator.cpp b/factory/test/factory_with_allocator.cpp index c1eef65..544fd59 100644 --- a/factory/test/factory_with_allocator.cpp +++ b/factory/test/factory_with_allocator.cpp @@ -1,84 +1,95 @@ -/*============================================================================= - Copyright (c) 2007 Tobias Schwinger - - Use modification and distribution are subject to the Boost Software - License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt). -==============================================================================*/ +/* +Copyright 2007 Tobias Schwinger +Copyright 2019 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ #include #include - -#include -#include #include -#ifdef BOOST_MSVC -// none of the deprecated members of std::allocate are used here -# pragma warning(disable:4996) // Various members of std::allocator are deprecated in C++17 -#endif +class sum { +public: + sum(int a, int b) + : value_(a + b) { } -using std::size_t; - -class sum -{ - int val_sum; - public: - sum(int a, int b) : val_sum(a + b) { } - - operator int() const { return this->val_sum; } -}; - -template< typename T > -class counting_allocator : public std::allocator -{ - public: - counting_allocator() - { } - - template< typename OtherT > - struct rebind { typedef counting_allocator other; }; - - template< typename OtherT > - counting_allocator(counting_allocator const& that) - { } - - static size_t n_allocated; - T* allocate(size_t n, void const* hint = 0l) - { - n_allocated += 1; - return std::allocator::allocate(n,hint); + int get() const { + return value_; } - static size_t n_deallocated; - void deallocate(T* ptr, size_t n) - { - n_deallocated += 1; - return std::allocator::deallocate(ptr,n); +private: + int value_; +}; + +template +class creator { +public: + static int count; + + typedef T value_type; + typedef T* pointer; + + template + struct rebind { + typedef creator other; + }; + + creator() { } + + template + creator(const creator&) { } + + T* allocate(std::size_t size) { + ++count; + return static_cast(::operator new(sizeof(T) * size)); + } + + void deallocate(T* ptr, std::size_t) { + --count; + ::operator delete(ptr); } }; -template< typename T > size_t counting_allocator::n_allocated = 0; -template< typename T > size_t counting_allocator::n_deallocated = 0; + +template +int creator::count = 0; + +template +inline bool +operator==(const creator&, const creator&) +{ + return true; +} + +template +inline bool +operator!=(const creator&, const creator&) +{ + return false; +} int main() { - int one = 1, two = 2; + int a = 1; + int b = 2; { - boost::shared_ptr instance( - boost::factory< boost::shared_ptr, counting_allocator, - boost::factory_alloc_for_pointee_and_deleter >()(one,two) ); - BOOST_TEST(*instance == 3); + boost::shared_ptr s(boost::factory, + creator, + boost::factory_alloc_for_pointee_and_deleter>()(a, b)); + BOOST_TEST(creator::count == 1); + BOOST_TEST(s->get() == 3); } - BOOST_TEST(counting_allocator::n_allocated == 1); - BOOST_TEST(counting_allocator::n_deallocated == 1); + BOOST_TEST(creator::count == 0); { - boost::shared_ptr instance( - boost::factory< boost::shared_ptr, counting_allocator, - boost::factory_passes_alloc_to_smart_pointer >()(one,two) ); - BOOST_TEST(*instance == 3); + boost::shared_ptr s(boost::factory, + creator, + boost::factory_passes_alloc_to_smart_pointer>()(a, b)); + BOOST_TEST(creator::count == 1); + BOOST_TEST(s->get() == 3); } - BOOST_TEST(counting_allocator::n_allocated == 2); - BOOST_TEST(counting_allocator::n_deallocated == 2); + BOOST_TEST(creator::count == 0); return boost::report_errors(); } diff --git a/factory/test/factory_with_none_t.cpp b/factory/test/factory_with_none_t.cpp deleted file mode 100644 index e8a515a..0000000 --- a/factory/test/factory_with_none_t.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/*============================================================================= - Copyright (c) 2007 Tobias Schwinger - - Use modification and distribution are subject to the Boost Software - License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt). -==============================================================================*/ - -#include -#include -#include - -#include - -class sum -{ - int val_sum; - public: - sum(int a, int b) : val_sum(a + b) { } - - operator int() const { return this->val_sum; } -}; - -// Suppress warnings about std::auto_ptr. -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif - -int main() -{ - int one = 1, two = 2; - { - sum* instance( boost::factory< sum*, boost::none_t >()(one,two) ); - BOOST_TEST(*instance == 3); - } -#if !defined(BOOST_NO_AUTO_PTR) - { - std::auto_ptr instance( - boost::factory< std::auto_ptr, boost::none_t >()(one,two) ); - BOOST_TEST(*instance == 3); - } -#endif -#if !defined(BOOST_NO_CXX11_SMART_PTR) - { - std::unique_ptr instance( - boost::factory< std::unique_ptr, boost::none_t >()(one,two) ); - BOOST_TEST(*instance == 3); - } -#endif - return boost::report_errors(); -} - -#if defined(__clang__) -#pragma clang diagnostic pop -#endif diff --git a/factory/test/factory_with_std_allocator.cpp b/factory/test/factory_with_std_allocator.cpp index 2a58a60..5f0af35 100644 --- a/factory/test/factory_with_std_allocator.cpp +++ b/factory/test/factory_with_std_allocator.cpp @@ -1,45 +1,46 @@ -/*============================================================================= - Copyright (c) 2007 Tobias Schwinger - Copyright (c) 2017 Daniel James +/* +Copyright 2007 Tobias Schwinger +Copyright 2017 Daniel James - Use modification and distribution are subject to the Boost Software - License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt). -==============================================================================*/ +Copyright 2019 Glen Joseph Fernandes +(glenjofe@gmail.com) +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ #include -#include - -#include -#include +#include #include +#include -class sum -{ - int val_sum; - public: - sum(int a, int b) : val_sum(a + b) { } +class sum { +public: + sum(int a, int b) + : value_(a + b) { } - operator int() const { return this->val_sum; } + int get() const { + return value_; + } + +private: + int value_; }; int main() { - int one = 1, two = 2; + int a = 1; + int b = 2; { - boost::shared_ptr instance( - boost::factory< boost::shared_ptr, std::allocator, - boost::factory_alloc_for_pointee_and_deleter >()(one,two) ); - BOOST_TEST(*instance == 3); + boost::shared_ptr s(boost::factory, + std::allocator, + boost::factory_alloc_for_pointee_and_deleter>()(a, b)); + BOOST_TEST(s->get() == 3); } - { - boost::shared_ptr instance( - boost::factory< boost::shared_ptr, std::allocator, - boost::factory_passes_alloc_to_smart_pointer >()(one,two) ); - BOOST_TEST(*instance == 3); + boost::shared_ptr s(boost::factory, + std::allocator, + boost::factory_passes_alloc_to_smart_pointer>()(a, b)); + BOOST_TEST(s->get() == 3); } - return boost::report_errors(); } - diff --git a/factory/test/value_factory.cpp b/factory/test/value_factory.cpp index 331757d..7af232c 100644 --- a/factory/test/value_factory.cpp +++ b/factory/test/value_factory.cpp @@ -1,29 +1,86 @@ -/*============================================================================= - Copyright (c) 2007 Tobias Schwinger - - Use modification and distribution are subject to the Boost Software - License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt). -==============================================================================*/ +/* +Copyright 2007 Tobias Schwinger +Copyright 2019 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ #include #include -class sum -{ - int val_sum; - public: - sum(int a, int b) : val_sum(a + b) { } - operator int() const { return this->val_sum; } +class sum { +public: + explicit sum(int i0 = 0, int i1 = 0, int i2 = 0, int i3 = 0, + int i4 = 0, int i5 = 0, int i6 = 0, int i7 = 0, + int i8 = 0, int i9 = 0) + : value_(i0 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9) { } + + int get() const { + return value_; + } + +private: + int value_; }; int main() { - int one = 1, two = 2; + boost::value_factory x; + int a = 1; + int b = 2; + int c = 3; + int d = 4; + int e = 5; + int f = 6; + int g = 7; + int h = 8; + int i = 9; + int j = 10; { - sum instance( boost::value_factory< sum >()(one,two) ); - BOOST_TEST(instance == 3); + sum s(x()); + BOOST_TEST(s.get() == 0); + } + { + sum s(x(a)); + BOOST_TEST(s.get() == 1); + } + { + sum s(x(a, b)); + BOOST_TEST(s.get() == 3); + } + { + sum s(x(a, b, c)); + BOOST_TEST(s.get() == 6); + } + { + sum s(x(a, b, c, d)); + BOOST_TEST(s.get() == 10); + } + { + sum s(x(a, b, c, d, e)); + BOOST_TEST(s.get() == 15); + } + { + sum s(x(a, b, c, d, e, f)); + BOOST_TEST(s.get() == 21); + } + { + sum s(x(a, b, c, d, e, f, g)); + BOOST_TEST(s.get() == 28); + } + { + sum s(x(a, b, c, d, e, f, g, h)); + BOOST_TEST(s.get() == 36); + } + { + sum s(x(a, b, c, d, e, f, g, h, i)); + BOOST_TEST(s.get() == 45); + } + { + sum s(x(a, b, c, d, e, f, g, h, i, j)); + BOOST_TEST(s.get() == 55); } return boost::report_errors(); } - diff --git a/factory/test/value_factory_args.cpp b/factory/test/value_factory_args.cpp new file mode 100644 index 0000000..0288fcd --- /dev/null +++ b/factory/test/value_factory_args.cpp @@ -0,0 +1,40 @@ +/* +Copyright 2019 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#include + +class sum { +public: + explicit sum(int a = 0, int b = 0, int c = 0, int d = 0, + int e = 0, int f = 0, int g = 0, int h = 0, + int i = 0, int j = 0, int k = 0, int l = 0) + : value_(a + b + c + d + e + f + g + h + i + j + k + l) { } + + int get() const { + return value_; + } + +private: + int value_; +}; + +int main() +{ + sum s(boost::value_factory()(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)); + BOOST_TEST(s.get() == 78); + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif diff --git a/factory/test/value_factory_move.cpp b/factory/test/value_factory_move.cpp new file mode 100644 index 0000000..c0dd37f --- /dev/null +++ b/factory/test/value_factory_move.cpp @@ -0,0 +1,54 @@ +/* +Copyright 2019 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#include + +class arg { +public: + explicit arg(int n) + : value_(n) { } + + arg(arg&& a) + : value_(a.value_) { } + + int get() const { + return value_; + } + +private: + int value_; +}; + +class sum { +public: + explicit sum(arg&& a1, arg&& a2) + : value_(a1.get() + a2.get()) { } + + int get() const { + return value_; + } + +private: + int value_; +}; + +int main() +{ + sum s(boost::value_factory()(arg(1), arg(2))); + BOOST_TEST(s.get() == 3); + return boost::report_errors(); +} +#else +int main() +{ + return 0; +} +#endif diff --git a/include/boost/functional/factory.hpp b/include/boost/functional/factory.hpp index 92f67d9..4e0e1ba 100644 --- a/include/boost/functional/factory.hpp +++ b/include/boost/functional/factory.hpp @@ -1,214 +1,365 @@ -/*============================================================================= - Copyright (c) 2007 Tobias Schwinger - - Use modification and distribution are subject to the Boost Software - License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt). -==============================================================================*/ +/* +Copyright 2007 Tobias Schwinger -#ifndef BOOST_FUNCTIONAL_FACTORY_HPP_INCLUDED -# ifndef BOOST_PP_IS_ITERATING +Copyright 2019 Glen Joseph Fernandes +(glenjofe@gmail.com) -# include -# include -# include -# include +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#ifndef BOOST_FUNCTIONAL_FACTORY_HPP +#define BOOST_FUNCTIONAL_FACTORY_HPP -# include -# include -# include -# include -# include +#include +#include +#include +#include +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +#include +#endif +#include +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif -# if defined(BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T) -# include -# endif +namespace boost { -# ifndef BOOST_FUNCTIONAL_FACTORY_MAX_ARITY -# define BOOST_FUNCTIONAL_FACTORY_MAX_ARITY 10 -# elif BOOST_FUNCTIONAL_FACTORY_MAX_ARITY < 3 -# undef BOOST_FUNCTIONAL_FACTORY_MAX_ARITY -# define BOOST_FUNCTIONAL_FACTORY_MAX_ARITY 3 -# endif +enum factory_alloc_propagation { + factory_alloc_for_pointee_and_deleter, + factory_passes_alloc_to_smart_pointer +}; -namespace boost +namespace detail { + +template +struct fc_tag { }; + +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +template +struct fc_rebind { + typedef typename std::allocator_traits::template rebind_alloc type; +}; + +template +struct fc_pointer { + typedef typename std::allocator_traits::pointer type; +}; +#else +template +struct fc_rebind { + typedef typename A::template rebind::other type; +}; + +template +struct fc_pointer { + typedef typename A::pointer type; +}; +#endif + +#if !defined(BOOST_NO_CXX11_ALLOCATOR) && \ + !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template +inline void +fc_destroy(A& a, T* p) { - enum factory_alloc_propagation - { - factory_alloc_for_pointee_and_deleter, - factory_passes_alloc_to_smart_pointer - }; - -#if defined(BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T) - template< typename Pointer, class Allocator = boost::none_t, - factory_alloc_propagation AP = factory_alloc_for_pointee_and_deleter > - class factory; -#else - template< typename Pointer, class Allocator = void, - factory_alloc_propagation AP = factory_alloc_for_pointee_and_deleter > - class factory; -#endif - - //----- ---- --- -- - - - - - - template< typename Pointer, factory_alloc_propagation AP > - class factory - { - public: - typedef typename boost::remove_cv::type result_type; - typedef typename boost::pointee::type value_type; - - factory() - { } - -# define BOOST_PP_FILENAME_1 -# define BOOST_PP_ITERATION_LIMITS (0,BOOST_FUNCTIONAL_FACTORY_MAX_ARITY) -# include BOOST_PP_ITERATE() - }; - -#if defined(BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T) - template< typename Pointer, factory_alloc_propagation AP > - class factory - : public factory - {}; -#endif - - template< class Pointer, class Allocator, factory_alloc_propagation AP > - class factory -#if defined(BOOST_NO_CXX11_ALLOCATOR) - : private Allocator::template rebind< typename boost::pointee< - typename boost::remove_cv::type >::type >::other -#else - : private std::allocator_traits::template rebind_alloc< - typename boost::pointee< typename boost::remove_cv::type >::type > -#endif - { - public: - typedef typename boost::remove_cv::type result_type; - typedef typename boost::pointee::type value_type; - -#if defined(BOOST_NO_CXX11_ALLOCATOR) - typedef typename Allocator::template rebind::other - allocator_type; -#else - typedef typename std::allocator_traits::template rebind_alloc - allocator_type; - typedef std::allocator_traits allocator_traits; -#endif - - explicit factory(allocator_type const & a = allocator_type()) - : allocator_type(a) - { } - - private: - - struct deleter - : allocator_type - { - inline deleter(allocator_type const& that) - : allocator_type(that) - { } - - allocator_type& get_allocator() const - { - return *const_cast( - static_cast(this)); - } - - void operator()(value_type* ptr) const - { - if (!! ptr) { -#if defined(BOOST_NO_CXX11_ALLOCATOR) - ptr->~value_type(); - const_cast(static_cast( - this))->deallocate(ptr,1); -#else - allocator_traits::destroy(this->get_allocator(), ptr); - allocator_traits::deallocate(this->get_allocator(),ptr,1); -#endif - } - } - }; - - inline allocator_type& get_allocator() const - { - return *const_cast( - static_cast(this)); - } - - inline result_type make_pointer(value_type* ptr, boost::non_type< - factory_alloc_propagation,factory_passes_alloc_to_smart_pointer>) - const - { - return result_type(ptr,deleter(this->get_allocator())); - } - inline result_type make_pointer(value_type* ptr, boost::non_type< - factory_alloc_propagation,factory_alloc_for_pointee_and_deleter>) - const - { - return result_type(ptr,deleter(this->get_allocator()), - this->get_allocator()); - } - - public: - -# define BOOST_TMP_MACRO -# define BOOST_PP_FILENAME_1 -# define BOOST_PP_ITERATION_LIMITS (0,BOOST_FUNCTIONAL_FACTORY_MAX_ARITY) -# include BOOST_PP_ITERATE() -# undef BOOST_TMP_MACRO - }; - - template< typename Pointer, class Allocator, factory_alloc_propagation AP > - class factory; - // forbidden, would create a dangling reference + std::allocator_traits::destroy(a, p); } +#else +template +inline void +fc_destroy(A&, T* p) +{ + p->~T(); +} +#endif -# define BOOST_FUNCTIONAL_FACTORY_HPP_INCLUDED -# else // defined(BOOST_PP_IS_ITERATING) -# define N BOOST_PP_ITERATION() -# if !defined(BOOST_TMP_MACRO) -# if N > 0 - template< BOOST_PP_ENUM_PARAMS(N, typename T) > -# endif - inline result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& a)) const - { - return result_type( new value_type(BOOST_PP_ENUM_PARAMS(N,a)) ); +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +template +inline void +fc_construct(A& a, T* p, Args&&... args) +{ + std::allocator_traits::construct(a, p, std::forward(args)...); +} +#else +template +inline void +fc_construct(A&, T* p, Args&&... args) +{ + ::new((void*)p) T(std::forward(args)...); +} +#endif +#endif + +template +class fc_delete + : boost::empty_value { + typedef boost::empty_value base; + +public: + explicit fc_delete(const A& a) BOOST_NOEXCEPT + : base(boost::empty_init_t(), a) { } + + void operator()(typename fc_pointer::type p) { + boost::detail::fc_destroy(base::get(), boost::to_address(p)); + base::get().deallocate(p, 1); } -# else // defined(BOOST_TMP_MACRO) -# if N > 0 - template< BOOST_PP_ENUM_PARAMS(N, typename T) > -# endif - inline result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& a)) const - { -#if defined(BOOST_NO_CXX11_ALLOCATOR) - value_type* memory = this->get_allocator().allocate(1); -#else - value_type* memory = allocator_traits::allocate(this->get_allocator(), 1); -#endif - try - { -#if defined(BOOST_NO_CXX11_ALLOCATOR) - new(memory) value_type(BOOST_PP_ENUM_PARAMS(N,a)); -#else - allocator_traits::construct(this->get_allocator(), memory - BOOST_PP_ENUM_TRAILING_PARAMS(N,a)); -#endif - } - catch (...) { -#if defined(BOOST_NO_CXX11_ALLOCATOR) - this->get_allocator().deallocate(memory,1); -#else - allocator_traits::deallocate(this->get_allocator(), memory, 1); -#endif - throw; - } +}; - return make_pointer(memory, boost::non_type()); +template +class fc_allocate { +public: + explicit fc_allocate(const A& a) + : a_(a) + , p_(a_.allocate(1)) { } + + ~fc_allocate() { + if (p_) { + a_.deallocate(p_, 1); + } } -# endif -# undef N -# endif // defined(BOOST_PP_IS_ITERATING) -#endif // include guard + A& state() BOOST_NOEXCEPT { + return a_; + } + typename A::value_type* get() const BOOST_NOEXCEPT { + return boost::to_address(p_); + } + + R release(fc_tag) { + return R(release(), fc_delete(a_), a_); + } + + R release(fc_tag) { + return R(release(), fc_delete(a_)); + } + +private: + typedef typename fc_pointer::type pointer; + + fc_allocate(const fc_allocate&); + fc_allocate& operator=(const fc_allocate&); + + pointer release() BOOST_NOEXCEPT { + pointer p = p_; + p_ = pointer(); + return p; + } + + A a_; + pointer p_; +}; + +} /* detail */ + +template +class factory; + +template +class factory { +public: + typedef typename remove_cv::type result_type; + +private: + typedef typename pointer_traits::element_type type; + +public: +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + result_type operator()(Args&&... args) const { + return result_type(new type(std::forward(args)...)); + } +#else + result_type operator()() const { + return result_type(new type()); + } + + template + result_type operator()(A0& a0) const { + return result_type(new type(a0)); + } + + template + result_type operator()(A0& a0, A1& a1) const { + return result_type(new type(a0, a1)); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2) const { + return result_type(new type(a0, a1, a2)); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3) const { + return result_type(new type(a0, a1, a2, a3)); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4) const { + return result_type(new type(a0, a1, a2, a3, a4)); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, + A5& a5) const { + return result_type(new type(a0, a1, a2, a3, a4, a5)); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, + A6& a6) const { + return result_type(new type(a0, a1, a2, a3, a4, a5, a6)); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, + A6& a6, A7& a7) const { + return result_type(new type(a0, a1, a2, a3, a4, a5, a6, a7)); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, + A6& a6, A7& a7, A8& a8) const { + return result_type(new type(a0, a1, a2, a3, a4, a5, a6, a7, a8)); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, + A6& a6, A7& a7, A8& a8, A9& a9) const { + return result_type(new type(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); + } +#endif +}; + +template +class factory + : empty_value::type>::element_type>::type> { +public: + typedef typename remove_cv::type result_type; + +private: + typedef typename pointer_traits::element_type type; + typedef typename detail::fc_rebind::type allocator; + typedef empty_value base; + +public: + factory() BOOST_NOEXCEPT + : base(empty_init_t()) { } + + explicit factory(const Allocator& a) BOOST_NOEXCEPT + : base(empty_init_t(), a) { } + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + result_type operator()(Args&&... args) const { + detail::fc_allocate s(base::get()); + detail::fc_construct(s.state(), s.get(), std::forward(args)...); + return s.release(detail::fc_tag()); + } +#else + result_type operator()() const { + detail::fc_allocate s(base::get()); + ::new((void*)s.get()) type(); + return s.release(detail::fc_tag()); + } + + template + result_type operator()(A0& a0) const { + detail::fc_allocate s(base::get()); + ::new((void*)s.get()) type(a0); + return s.release(detail::fc_tag()); + } + + template + result_type operator()(A0& a0, A1& a1) const { + detail::fc_allocate s(base::get()); + ::new((void*)s.get()) type(a0, a1); + return s.release(detail::fc_tag()); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2) const { + detail::fc_allocate s(base::get()); + ::new((void*)s.get()) type(a0, a1, a2); + return s.release(detail::fc_tag()); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3) const { + detail::fc_allocate s(base::get()); + ::new((void*)s.get()) type(a0, a1, a2, a3); + return s.release(detail::fc_tag()); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4) const { + detail::fc_allocate s(base::get()); + ::new((void*)s.get()) type(a0, a1, a2, a3, a4); + return s.release(detail::fc_tag()); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, + A5& a5) const { + detail::fc_allocate s(base::get()); + ::new((void*)s.get()) type(a0, a1, a2, a3, a4, a5); + return s.release(detail::fc_tag()); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, + A6& a6) const { + detail::fc_allocate s(base::get()); + ::new((void*)s.get()) type(a0, a1, a2, a3, a4, a5, a6); + return s.release(detail::fc_tag()); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, + A6& a6, A7& a7) const { + detail::fc_allocate s(base::get()); + ::new((void*)s.get()) type(a0, a1, a2, a3, a4, a5, a6, a7); + return s.release(detail::fc_tag()); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, + A6& a6, A7& a7, A8& a8) const { + detail::fc_allocate s(base::get()); + ::new((void*)s.get()) type(a0, a1, a2, a3, a4, a5, a6, a7, a8); + return s.release(detail::fc_tag()); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, + A6& a6, A7& a7, A8& a8, A9& a9) const { + detail::fc_allocate s(base::get()); + ::new((void*)s.get()) type(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); + return s.release(detail::fc_tag()); + } +#endif +}; + +template +class factory { }; + +} /* boost */ + +#endif diff --git a/include/boost/functional/value_factory.hpp b/include/boost/functional/value_factory.hpp index ba94c2a..dc716bb 100644 --- a/include/boost/functional/value_factory.hpp +++ b/include/boost/functional/value_factory.hpp @@ -1,69 +1,106 @@ -/*============================================================================= - Copyright (c) 2007 Tobias Schwinger - - Use modification and distribution are subject to the Boost Software - License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt). -==============================================================================*/ +/* +Copyright 2007 Tobias Schwinger -#ifndef BOOST_FUNCTIONAL_VALUE_FACTORY_HPP_INCLUDED -# ifndef BOOST_PP_IS_ITERATING +Copyright 2019 Glen Joseph Fernandes +(glenjofe@gmail.com) -# include -# include -# include +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#ifndef BOOST_FUNCTIONAL_VALUE_FACTORY_HPP +#define BOOST_FUNCTIONAL_VALUE_FACTORY_HPP -# include -# include -# include -# include -# include +#include +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif -# ifndef BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY -# define BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY 10 -# elif BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY < 3 -# undef BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY -# define BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY 3 -# endif +namespace boost { -namespace boost -{ - template< typename T > - class value_factory; +template +class value_factory; - //----- ---- --- -- - - - - +template +class value_factory { +public: + typedef T result_type; - template< typename T > - class value_factory - { - public: - typedef T result_type; - - value_factory() - { } - -# define BOOST_PP_FILENAME_1 -# define BOOST_PP_ITERATION_LIMITS (0,BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY) -# include BOOST_PP_ITERATE() - }; - - template< typename T > class value_factory; - // forbidden, would create a dangling reference -} -# define BOOST_FUNCTIONAL_VALUE_FACTORY_HPP_INCLUDED -# else // defined(BOOST_PP_IS_ITERATING) - -# define N BOOST_PP_ITERATION() -# if N > 0 - template< BOOST_PP_ENUM_PARAMS(N, typename T) > -# endif - inline result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& a)) const - { - return result_type(BOOST_PP_ENUM_PARAMS(N,a)); +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + result_type operator()(Args&&... args) const { + return result_type(std::forward(args)...); + } +#else + result_type operator()() const { + return result_type(); } -# undef N -# endif // defined(BOOST_PP_IS_ITERATING) + template + result_type operator()(A0& a0) const { + return result_type(a0); + } -#endif // include guard + template + result_type operator()(A0& a0, A1& a1) const { + return result_type(a0, a1); + } + template + result_type operator()(A0& a0, A1& a1, A2& a2) const { + return result_type(a0, a1, a2); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3) const { + return result_type(a0, a1, a2, a3); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4) const { + return result_type(a0, a1, a2, a3, a4); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, + A5& a5) const { + return result_type(a0, a1, a2, a3, a4, a5); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, + A6& a6) const { + return result_type(a0, a1, a2, a3, a4, a5, a6); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, + A6& a6, A7& a7) const { + return result_type(a0, a1, a2, a3, a4, a5, a6, a7); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, + A6& a6, A7& a7, A8& a8) const { + return result_type(a0, a1, a2, a3, a4, a5, a6, a7, a8); + } + + template + result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, + A6& a6, A7& a7, A8& a8, A9& a9) const { + return result_type(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); + } +#endif +}; + +template +class value_factory { }; + +} /* boost */ + +#endif diff --git a/meta/libraries.json b/meta/libraries.json index 23f64ff..c9d7a3b 100644 --- a/meta/libraries.json +++ b/meta/libraries.json @@ -16,6 +16,7 @@ "boost-version": "1.43.0", "name": "Functional/Factory", "authors": [ + "Glen Fernandes", "Tobias Schwinger" ], "maintainers": [