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
This commit is contained in:
Glen Fernandes
2019-08-26 20:22:17 -04:00
parent 03a3376483
commit 4403017952
16 changed files with 1072 additions and 488 deletions

View File

@ -1,8 +1,9 @@
[library Boost.Functional/Factory [library Boost.Functional/Factory
[quickbook 1.3] [quickbook 1.3]
[version 1.0] [version 1.0]
[authors [Schwinger, Tobias]] [authors [Schwinger, Tobias], [Fernandes, Glen]]
[copyright 2007 2008 Tobias Schwinger] [copyright 2007 2008 Tobias Schwinger]
[copyright 2019 Glen Joseph Fernandes]
[license [license
Distributed under the Boost Software License, Version 1.0. Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at (See accompanying file LICENSE_1_0.txt or copy at
@ -54,9 +55,10 @@ invocation without `new`.
__boost__value_factory__<T>()(arg1,arg2,arg3) __boost__value_factory__<T>()(arg1,arg2,arg3)
// same as T(arg1,arg2,arg3) // same as T(arg1,arg2,arg3)
For technical reasons the arguments to the function objects have to be Before C++11 the arguments to the function objects have to be LValues. A
LValues. A factory that also accepts RValues can be composed using the factory that also accepts RValues can be composed using the
__boost__forward_adapter__ or __boost__bind__. __boost__forward_adapter__ or __boost__bind__. In C++11 or higher the
arguments can be LValues or RValues.
[endsect] [endsect]
@ -259,7 +261,7 @@ Function object template that invokes the constructor of the type `T`.
[variablelist Notation [variablelist Notation
[[`T`] [an arbitrary type with at least one public constructor]] [[`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>`]] [[`F`] [the type `value_factory<F>`]]
[[`f`] [an instance object of `F`]] [[`f`] [an instance object of `F`]]
] ]
@ -276,8 +278,8 @@ Function object template that invokes the constructor of the type `T`.
[heading Limits] [heading Limits]
The macro BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY can be defined to set the Before C++11, the maximum number of arguments supported is 10. Since C++11 an
maximum arity. It defaults to 10. arbitrary number of arguments is supported.
[endsect] [endsect]
@ -326,7 +328,7 @@ separately allocated reference counter).
[variablelist Notation [variablelist Notation
[[`T`] [an arbitrary type with at least one public constructor]] [[`T`] [an arbitrary type with at least one public constructor]]
[[`P`] [pointer or smart pointer to `T`]] [[`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<P>`]] [[`F`] [the type `factory<P>`]]
[[`f`] [an instance object of `F`]] [[`f`] [an instance object of `F`]]
] ]
@ -344,8 +346,8 @@ separately allocated reference counter).
[heading Limits] [heading Limits]
The macro BOOST_FUNCTIONAL_FACTORY_MAX_ARITY can be defined to set the Before C++11, the maximum number of arguments supported is 10. Since C++11 an
maximum arity. It defaults to 10. arbitrary number of arguments is supported.
[endsect] [endsect]
@ -353,6 +355,25 @@ maximum arity. It defaults to 10.
[section Changes] [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] [heading Boost 1.58.0]
In order to remove the dependency on Boost.Optional, the default parameter In order to remove the dependency on Boost.Optional, the default parameter

View File

@ -1,24 +1,20 @@
# Copyright 2007,2008 Tobias Schwinger
# (C) Copyright Tobias Schwinger
# #
# Use modification and distribution are subject to the boost Software License, # Copyright 2019 Glen Joseph Fernandes
# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt). # (glenjofe@gmail.com)
#
# Distributed under the Boost Software License, Version 1.0.
# (http://www.boost.org/LICENSE_1_0.txt)
import testing ; import testing ;
project factory-tests run value_factory.cpp ;
; run value_factory_args.cpp ;
run value_factory_move.cpp ;
test-suite functional/factory run factory.cpp ;
: run factory_args.cpp ;
[ run value_factory.cpp ] run factory_move.cpp ;
[ run factory.cpp ] run factory_with_allocator.cpp ;
[ run factory_with_allocator.cpp ] run factory_with_std_allocator.cpp ;
[ run factory_with_std_allocator.cpp ] run factory_allocator_throws.cpp ;
[ compile-fail factory_with_none_t.cpp ] run factory_default_allocator.cpp : : : <exception-handling>off ;
[ run factory.cpp : : : <define>BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T : none_t_factory ]
[ run factory_with_allocator.cpp : : : <define>BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T : none_t_factory_with_allocator ]
[ run factory_with_std_allocator.cpp : : : <define>BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T : none_t_factory_with_std_allocator ]
[ run factory_with_none_t.cpp : : : <define>BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T : none_t_factory_with_none_t ]
;

View File

@ -1,53 +1,87 @@
/*============================================================================= /*
Copyright (c) 2007 Tobias Schwinger Copyright 2007 Tobias Schwinger
Use modification and distribution are subject to the Boost Software Copyright 2019 Glen Joseph Fernandes
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at (glenjofe@gmail.com)
http://www.boost.org/LICENSE_1_0.txt).
==============================================================================*/
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/functional/factory.hpp> #include <boost/functional/factory.hpp>
#include <boost/core/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#include <boost/smart_ptr/scoped_ptr.hpp>
#include <memory> 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 get() const {
{ return value_;
int val_sum; }
public:
sum(int a, int b) : val_sum(a + b) { }
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 main()
{ {
int one = 1, two = 2; boost::factory<sum*> 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::scoped_ptr<sum> s(x());
BOOST_TEST(*instance == 3); BOOST_TEST(s->get() == 0);
} }
#if !defined(BOOST_NO_AUTO_PTR)
{ {
std::auto_ptr<sum> instance( boost::factory< std::auto_ptr<sum> >()(one,two) ); boost::scoped_ptr<sum> s(x(a));
BOOST_TEST(*instance == 3); BOOST_TEST(s->get() == 1);
} }
#endif
#if !defined(BOOST_NO_CXX11_SMART_PTR)
{ {
std::unique_ptr<sum> instance( boost::factory< std::unique_ptr<sum> >()(one,two) ); boost::scoped_ptr<sum> s(x(a, b));
BOOST_TEST(*instance == 3); BOOST_TEST(s->get() == 3);
}
{
boost::scoped_ptr<sum> s(x(a, b, c));
BOOST_TEST(s->get() == 6);
}
{
boost::scoped_ptr<sum> s(x(a, b, c, d));
BOOST_TEST(s->get() == 10);
}
{
boost::scoped_ptr<sum> s(x(a, b, c, d, e));
BOOST_TEST(s->get() == 15);
}
{
boost::scoped_ptr<sum> s(x(a, b, c, d, e, f));
BOOST_TEST(s->get() == 21);
}
{
boost::scoped_ptr<sum> s(x(a, b, c, d, e, f, g));
BOOST_TEST(s->get() == 28);
}
{
boost::scoped_ptr<sum> s(x(a, b, c, d, e, f, g, h));
BOOST_TEST(s->get() == 36);
}
{
boost::scoped_ptr<sum> s(x(a, b, c, d, e, f, g, h, i));
BOOST_TEST(s->get() == 45);
}
{
boost::scoped_ptr<sum> s(x(a, b, c, d, e, f, g, h, i, j));
BOOST_TEST(s->get() == 55);
} }
#endif
return boost::report_errors(); return boost::report_errors();
} }
#if defined(__clang__)
#pragma clang diagnostic pop
#endif

View File

@ -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 <boost/functional/factory.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/shared_ptr.hpp>
struct type {
explicit type(bool b) {
if (b) {
throw true;
}
}
};
template<class T>
class creator {
public:
static int count;
typedef T value_type;
typedef T* pointer;
template<class U>
struct rebind {
typedef creator<U> other;
};
creator() { }
template<class U>
creator(const creator<U>&) { }
T* allocate(std::size_t size) {
++count;
return static_cast<T*>(::operator new(sizeof(T) * size));
}
void deallocate(T* ptr, std::size_t) {
--count;
::operator delete(ptr);
}
};
template<class T>
int creator<T>::count = 0;
template<class T, class U>
inline bool
operator==(const creator<T>&, const creator<U>&)
{
return true;
}
template<class T, class U>
inline bool
operator!=(const creator<T>&, const creator<U>&)
{
return false;
}
int main()
{
bool b = true;
try {
boost::shared_ptr<type> s(boost::factory<boost::shared_ptr<type>,
creator<void>,
boost::factory_alloc_for_pointee_and_deleter>()(b));
} catch (...) {
BOOST_TEST(creator<type>::count == 0);
}
try {
boost::shared_ptr<type> s(boost::factory<boost::shared_ptr<type>,
creator<void>,
boost::factory_passes_alloc_to_smart_pointer>()(b));
} catch (...) {
BOOST_TEST(creator<type>::count == 0);
}
return boost::report_errors();
}

View File

@ -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 <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/functional/factory.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/smart_ptr/scoped_ptr.hpp>
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<sum> s(boost::factory<sum*>()(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

View File

@ -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 <boost/functional/factory.hpp>
#include <boost/core/default_allocator.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/shared_ptr.hpp>
#include <exception>
#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<sum> s(boost::factory<boost::shared_ptr<sum>,
boost::default_allocator<void>,
boost::factory_alloc_for_pointee_and_deleter>()(a, b));
BOOST_TEST(s->get() == 3);
}
{
boost::shared_ptr<sum> s(boost::factory<boost::shared_ptr<sum>,
boost::default_allocator<void>,
boost::factory_passes_alloc_to_smart_pointer>()(a, b));
BOOST_TEST(s->get() == 3);
}
return boost::report_errors();
}

View File

@ -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 <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/functional/factory.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/smart_ptr/scoped_ptr.hpp>
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<sum> s(boost::factory<sum*>()(arg(1), arg(2)));
BOOST_TEST(s->get() == 3);
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@ -1,84 +1,95 @@
/*============================================================================= /*
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 <boost/functional/factory.hpp> #include <boost/functional/factory.hpp>
#include <boost/core/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#include <cstddef>
#include <memory>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#ifdef BOOST_MSVC class sum {
// none of the deprecated members of std::allocate are used here public:
# pragma warning(disable:4996) // Various members of std::allocator are deprecated in C++17 sum(int a, int b)
#endif : value_(a + b) { }
using std::size_t; int get() const {
return value_;
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<T>
{
public:
counting_allocator()
{ }
template< typename OtherT >
struct rebind { typedef counting_allocator<OtherT> other; };
template< typename OtherT >
counting_allocator(counting_allocator<OtherT> const& that)
{ }
static size_t n_allocated;
T* allocate(size_t n, void const* hint = 0l)
{
n_allocated += 1;
return std::allocator<T>::allocate(n,hint);
} }
static size_t n_deallocated; private:
void deallocate(T* ptr, size_t n) int value_;
{ };
n_deallocated += 1;
return std::allocator<T>::deallocate(ptr,n); template<class T>
class creator {
public:
static int count;
typedef T value_type;
typedef T* pointer;
template<class U>
struct rebind {
typedef creator<U> other;
};
creator() { }
template<class U>
creator(const creator<U>&) { }
T* allocate(std::size_t size) {
++count;
return static_cast<T*>(::operator new(sizeof(T) * size));
}
void deallocate(T* ptr, std::size_t) {
--count;
::operator delete(ptr);
} }
}; };
template< typename T > size_t counting_allocator<T>::n_allocated = 0;
template< typename T > size_t counting_allocator<T>::n_deallocated = 0; template<class T>
int creator<T>::count = 0;
template<class T, class U>
inline bool
operator==(const creator<T>&, const creator<U>&)
{
return true;
}
template<class T, class U>
inline bool
operator!=(const creator<T>&, const creator<U>&)
{
return false;
}
int main() int main()
{ {
int one = 1, two = 2; int a = 1;
int b = 2;
{ {
boost::shared_ptr<sum> instance( boost::shared_ptr<sum> s(boost::factory<boost::shared_ptr<sum>,
boost::factory< boost::shared_ptr<sum>, counting_allocator<void>, creator<void>,
boost::factory_alloc_for_pointee_and_deleter >()(one,two) ); boost::factory_alloc_for_pointee_and_deleter>()(a, b));
BOOST_TEST(*instance == 3); BOOST_TEST(creator<sum>::count == 1);
BOOST_TEST(s->get() == 3);
} }
BOOST_TEST(counting_allocator<sum>::n_allocated == 1); BOOST_TEST(creator<sum>::count == 0);
BOOST_TEST(counting_allocator<sum>::n_deallocated == 1);
{ {
boost::shared_ptr<sum> instance( boost::shared_ptr<sum> s(boost::factory<boost::shared_ptr<sum>,
boost::factory< boost::shared_ptr<sum>, counting_allocator<void>, creator<void>,
boost::factory_passes_alloc_to_smart_pointer >()(one,two) ); boost::factory_passes_alloc_to_smart_pointer>()(a, b));
BOOST_TEST(*instance == 3); BOOST_TEST(creator<sum>::count == 1);
BOOST_TEST(s->get() == 3);
} }
BOOST_TEST(counting_allocator<sum>::n_allocated == 2); BOOST_TEST(creator<sum>::count == 0);
BOOST_TEST(counting_allocator<sum>::n_deallocated == 2);
return boost::report_errors(); return boost::report_errors();
} }

View File

@ -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 <boost/functional/factory.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/none_t.hpp>
#include <memory>
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<sum> instance(
boost::factory< std::auto_ptr<sum>, boost::none_t >()(one,two) );
BOOST_TEST(*instance == 3);
}
#endif
#if !defined(BOOST_NO_CXX11_SMART_PTR)
{
std::unique_ptr<sum> instance(
boost::factory< std::unique_ptr<sum>, boost::none_t >()(one,two) );
BOOST_TEST(*instance == 3);
}
#endif
return boost::report_errors();
}
#if defined(__clang__)
#pragma clang diagnostic pop
#endif

View File

@ -1,45 +1,46 @@
/*============================================================================= /*
Copyright (c) 2007 Tobias Schwinger Copyright 2007 Tobias Schwinger
Copyright (c) 2017 Daniel James Copyright 2017 Daniel James
Use modification and distribution are subject to the Boost Software Copyright 2019 Glen Joseph Fernandes
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at (glenjofe@gmail.com)
http://www.boost.org/LICENSE_1_0.txt).
==============================================================================*/
Distributed under the Boost Software License, Version 1.0.
(http://www.boost.org/LICENSE_1_0.txt)
*/
#include <boost/functional/factory.hpp> #include <boost/functional/factory.hpp>
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#include <cstddef>
#include <memory>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <memory>
class sum class sum {
{ public:
int val_sum; sum(int a, int b)
public: : value_(a + b) { }
sum(int a, int b) : val_sum(a + b) { }
operator int() const { return this->val_sum; } int get() const {
return value_;
}
private:
int value_;
}; };
int main() int main()
{ {
int one = 1, two = 2; int a = 1;
int b = 2;
{ {
boost::shared_ptr<sum> instance( boost::shared_ptr<sum> s(boost::factory<boost::shared_ptr<sum>,
boost::factory< boost::shared_ptr<sum>, std::allocator<int>, std::allocator<char>,
boost::factory_alloc_for_pointee_and_deleter >()(one,two) ); boost::factory_alloc_for_pointee_and_deleter>()(a, b));
BOOST_TEST(*instance == 3); BOOST_TEST(s->get() == 3);
} }
{ {
boost::shared_ptr<sum> instance( boost::shared_ptr<sum> s(boost::factory<boost::shared_ptr<sum>,
boost::factory< boost::shared_ptr<sum>, std::allocator<int>, std::allocator<char>,
boost::factory_passes_alloc_to_smart_pointer >()(one,two) ); boost::factory_passes_alloc_to_smart_pointer>()(a, b));
BOOST_TEST(*instance == 3); BOOST_TEST(s->get() == 3);
} }
return boost::report_errors(); return boost::report_errors();
} }

View File

@ -1,29 +1,86 @@
/*============================================================================= /*
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 <boost/functional/value_factory.hpp> #include <boost/functional/value_factory.hpp>
#include <boost/core/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
class sum class sum {
{ public:
int val_sum; explicit sum(int i0 = 0, int i1 = 0, int i2 = 0, int i3 = 0,
public: int i4 = 0, int i5 = 0, int i6 = 0, int i7 = 0,
sum(int a, int b) : val_sum(a + b) { } int i8 = 0, int i9 = 0)
operator int() const { return this->val_sum; } : value_(i0 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9) { }
int get() const {
return value_;
}
private:
int value_;
}; };
int main() int main()
{ {
int one = 1, two = 2; boost::value_factory<sum> 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) ); sum s(x());
BOOST_TEST(instance == 3); 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(); return boost::report_errors();
} }

View File

@ -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 <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/functional/value_factory.hpp>
#include <boost/core/lightweight_test.hpp>
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<sum>()(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

View File

@ -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 <boost/config.hpp>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/functional/value_factory.hpp>
#include <boost/core/lightweight_test.hpp>
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<sum>()(arg(1), arg(2)));
BOOST_TEST(s.get() == 3);
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@ -1,214 +1,365 @@
/*============================================================================= /*
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).
==============================================================================*/
#ifndef BOOST_FUNCTIONAL_FACTORY_HPP_INCLUDED Copyright 2019 Glen Joseph Fernandes
# ifndef BOOST_PP_IS_ITERATING (glenjofe@gmail.com)
# include <boost/preprocessor/iteration/iterate.hpp> Distributed under the Boost Software License, Version 1.0.
# include <boost/preprocessor/repetition/enum_params.hpp> (http://www.boost.org/LICENSE_1_0.txt)
# include <boost/preprocessor/repetition/enum_binary_params.hpp> */
# include <boost/preprocessor/repetition/enum_trailing_params.hpp> #ifndef BOOST_FUNCTIONAL_FACTORY_HPP
#define BOOST_FUNCTIONAL_FACTORY_HPP
# include <new> #include <boost/core/empty_value.hpp>
# include <boost/pointee.hpp> #include <boost/core/pointer_traits.hpp>
# include <boost/get_pointer.hpp> #include <boost/type_traits/remove_cv.hpp>
# include <boost/non_type.hpp> #include <boost/config.hpp>
# include <boost/type_traits/remove_cv.hpp> #if !defined(BOOST_NO_CXX11_ALLOCATOR)
#include <memory>
#endif
#include <new>
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <utility>
#endif
# if defined(BOOST_FUNCTIONAL_FACTORY_SUPPORT_NONE_T) namespace boost {
# include <boost/none_t.hpp>
# endif
# ifndef BOOST_FUNCTIONAL_FACTORY_MAX_ARITY enum factory_alloc_propagation {
# define BOOST_FUNCTIONAL_FACTORY_MAX_ARITY 10 factory_alloc_for_pointee_and_deleter,
# elif BOOST_FUNCTIONAL_FACTORY_MAX_ARITY < 3 factory_passes_alloc_to_smart_pointer
# undef BOOST_FUNCTIONAL_FACTORY_MAX_ARITY };
# define BOOST_FUNCTIONAL_FACTORY_MAX_ARITY 3
# endif
namespace boost namespace detail {
template<factory_alloc_propagation>
struct fc_tag { };
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
template<class A, class T>
struct fc_rebind {
typedef typename std::allocator_traits<A>::template rebind_alloc<T> type;
};
template<class A>
struct fc_pointer {
typedef typename std::allocator_traits<A>::pointer type;
};
#else
template<class A, class T>
struct fc_rebind {
typedef typename A::template rebind<T>::other type;
};
template<class A>
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<class A, class T>
inline void
fc_destroy(A& a, T* p)
{ {
enum factory_alloc_propagation std::allocator_traits<A>::destroy(a, p);
{
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<Pointer, void, AP>
{
public:
typedef typename boost::remove_cv<Pointer>::type result_type;
typedef typename boost::pointee<result_type>::type value_type;
factory()
{ }
# define BOOST_PP_FILENAME_1 <boost/functional/factory.hpp>
# 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<Pointer, boost::none_t, AP>
: public factory<Pointer, void, AP>
{};
#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<Pointer>::type >::type >::other
#else
: private std::allocator_traits<Allocator>::template rebind_alloc<
typename boost::pointee< typename boost::remove_cv<Pointer>::type >::type >
#endif
{
public:
typedef typename boost::remove_cv<Pointer>::type result_type;
typedef typename boost::pointee<result_type>::type value_type;
#if defined(BOOST_NO_CXX11_ALLOCATOR)
typedef typename Allocator::template rebind<value_type>::other
allocator_type;
#else
typedef typename std::allocator_traits<Allocator>::template rebind_alloc<value_type>
allocator_type;
typedef std::allocator_traits<allocator_type> 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<allocator_type*>(
static_cast<allocator_type const*>(this));
}
void operator()(value_type* ptr) const
{
if (!! ptr) {
#if defined(BOOST_NO_CXX11_ALLOCATOR)
ptr->~value_type();
const_cast<allocator_type*>(static_cast<allocator_type const*>(
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<allocator_type*>(
static_cast<allocator_type const*>(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 <boost/functional/factory.hpp>
# 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<Pointer&, Allocator, AP>;
// forbidden, would create a dangling reference
} }
#else
template<class A, class T>
inline void
fc_destroy(A&, T* p)
{
p->~T();
}
#endif
# define BOOST_FUNCTIONAL_FACTORY_HPP_INCLUDED #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
# else // defined(BOOST_PP_IS_ITERATING) !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
# define N BOOST_PP_ITERATION() #if !defined(BOOST_NO_CXX11_ALLOCATOR)
# if !defined(BOOST_TMP_MACRO) template<class A, class T, class... Args>
# if N > 0 inline void
template< BOOST_PP_ENUM_PARAMS(N, typename T) > fc_construct(A& a, T* p, Args&&... args)
# endif {
inline result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& a)) const std::allocator_traits<A>::construct(a, p, std::forward<Args>(args)...);
{ }
return result_type( new value_type(BOOST_PP_ENUM_PARAMS(N,a)) ); #else
template<class A, class T, class... Args>
inline void
fc_construct(A&, T* p, Args&&... args)
{
::new((void*)p) T(std::forward<Args>(args)...);
}
#endif
#endif
template<class A>
class fc_delete
: boost::empty_value<A> {
typedef boost::empty_value<A> base;
public:
explicit fc_delete(const A& a) BOOST_NOEXCEPT
: base(boost::empty_init_t(), a) { }
void operator()(typename fc_pointer<A>::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<factory_alloc_propagation,AP>()); template<class R, class A>
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<factory_alloc_for_pointee_and_deleter>) {
return R(release(), fc_delete<A>(a_), a_);
}
R release(fc_tag<factory_passes_alloc_to_smart_pointer>) {
return R(release(), fc_delete<A>(a_));
}
private:
typedef typename fc_pointer<A>::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 Pointer, class Allocator = void,
factory_alloc_propagation Policy = factory_alloc_for_pointee_and_deleter>
class factory;
template<class Pointer, factory_alloc_propagation Policy>
class factory<Pointer, void, Policy> {
public:
typedef typename remove_cv<Pointer>::type result_type;
private:
typedef typename pointer_traits<result_type>::element_type type;
public:
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class... Args>
result_type operator()(Args&&... args) const {
return result_type(new type(std::forward<Args>(args)...));
}
#else
result_type operator()() const {
return result_type(new type());
}
template<class A0>
result_type operator()(A0& a0) const {
return result_type(new type(a0));
}
template<class A0, class A1>
result_type operator()(A0& a0, A1& a1) const {
return result_type(new type(a0, a1));
}
template<class A0, class A1, class A2>
result_type operator()(A0& a0, A1& a1, A2& a2) const {
return result_type(new type(a0, a1, a2));
}
template<class A0, class A1, class A2, class A3>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3) const {
return result_type(new type(a0, a1, a2, a3));
}
template<class A0, class A1, class A2, class A3, class A4>
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<class A0, class A1, class A2, class A3, class A4, class A5>
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<class A0, class A1, class A2, class A3, class A4, class A5,
class A6>
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<class A0, class A1, class A2, class A3, class A4, class A5,
class A6, class A7>
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<class A0, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8>
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<class A0, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8, class A9>
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 Pointer, class Allocator, factory_alloc_propagation Policy>
class factory
: empty_value<typename detail::fc_rebind<Allocator,
typename pointer_traits<typename
remove_cv<Pointer>::type>::element_type>::type> {
public:
typedef typename remove_cv<Pointer>::type result_type;
private:
typedef typename pointer_traits<result_type>::element_type type;
typedef typename detail::fc_rebind<Allocator, type>::type allocator;
typedef empty_value<allocator> 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<class... Args>
result_type operator()(Args&&... args) const {
detail::fc_allocate<result_type, allocator> s(base::get());
detail::fc_construct(s.state(), s.get(), std::forward<Args>(args)...);
return s.release(detail::fc_tag<Policy>());
}
#else
result_type operator()() const {
detail::fc_allocate<result_type, allocator> s(base::get());
::new((void*)s.get()) type();
return s.release(detail::fc_tag<Policy>());
}
template<class A0>
result_type operator()(A0& a0) const {
detail::fc_allocate<result_type, allocator> s(base::get());
::new((void*)s.get()) type(a0);
return s.release(detail::fc_tag<Policy>());
}
template<class A0, class A1>
result_type operator()(A0& a0, A1& a1) const {
detail::fc_allocate<result_type, allocator> s(base::get());
::new((void*)s.get()) type(a0, a1);
return s.release(detail::fc_tag<Policy>());
}
template<class A0, class A1, class A2>
result_type operator()(A0& a0, A1& a1, A2& a2) const {
detail::fc_allocate<result_type, allocator> s(base::get());
::new((void*)s.get()) type(a0, a1, a2);
return s.release(detail::fc_tag<Policy>());
}
template<class A0, class A1, class A2, class A3>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3) const {
detail::fc_allocate<result_type, allocator> s(base::get());
::new((void*)s.get()) type(a0, a1, a2, a3);
return s.release(detail::fc_tag<Policy>());
}
template<class A0, class A1, class A2, class A3, class A4>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4) const {
detail::fc_allocate<result_type, allocator> s(base::get());
::new((void*)s.get()) type(a0, a1, a2, a3, a4);
return s.release(detail::fc_tag<Policy>());
}
template<class A0, class A1, class A2, class A3, class A4, class A5>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4,
A5& a5) const {
detail::fc_allocate<result_type, allocator> s(base::get());
::new((void*)s.get()) type(a0, a1, a2, a3, a4, a5);
return s.release(detail::fc_tag<Policy>());
}
template<class A0, class A1, class A2, class A3, class A4, class A5,
class A6>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
A6& a6) const {
detail::fc_allocate<result_type, allocator> s(base::get());
::new((void*)s.get()) type(a0, a1, a2, a3, a4, a5, a6);
return s.release(detail::fc_tag<Policy>());
}
template<class A0, class A1, class A2, class A3, class A4, class A5,
class A6, class A7>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
A6& a6, A7& a7) const {
detail::fc_allocate<result_type, allocator> s(base::get());
::new((void*)s.get()) type(a0, a1, a2, a3, a4, a5, a6, a7);
return s.release(detail::fc_tag<Policy>());
}
template<class A0, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8>
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<result_type, allocator> s(base::get());
::new((void*)s.get()) type(a0, a1, a2, a3, a4, a5, a6, a7, a8);
return s.release(detail::fc_tag<Policy>());
}
template<class A0, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8, class A9>
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<result_type, allocator> s(base::get());
::new((void*)s.get()) type(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
return s.release(detail::fc_tag<Policy>());
}
#endif
};
template<class Pointer, class Allocator, factory_alloc_propagation Policy>
class factory<Pointer&, Allocator, Policy> { };
} /* boost */
#endif

View File

@ -1,69 +1,106 @@
/*============================================================================= /*
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).
==============================================================================*/
#ifndef BOOST_FUNCTIONAL_VALUE_FACTORY_HPP_INCLUDED Copyright 2019 Glen Joseph Fernandes
# ifndef BOOST_PP_IS_ITERATING (glenjofe@gmail.com)
# include <boost/preprocessor/iteration/iterate.hpp> Distributed under the Boost Software License, Version 1.0.
# include <boost/preprocessor/repetition/enum_params.hpp> (http://www.boost.org/LICENSE_1_0.txt)
# include <boost/preprocessor/repetition/enum_binary_params.hpp> */
#ifndef BOOST_FUNCTIONAL_VALUE_FACTORY_HPP
#define BOOST_FUNCTIONAL_VALUE_FACTORY_HPP
# include <new> #include <boost/config.hpp>
# include <boost/pointee.hpp> #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
# include <boost/get_pointer.hpp> !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
# include <boost/non_type.hpp> #include <utility>
# include <boost/type_traits/remove_cv.hpp> #endif
# ifndef BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY namespace boost {
# 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 template<class T>
{ class value_factory;
template< typename T >
class value_factory;
//----- ---- --- -- - - - - template<class T>
class value_factory {
public:
typedef T result_type;
template< typename T > #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
class value_factory !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
{ template<class... Args>
public: result_type operator()(Args&&... args) const {
typedef T result_type; return result_type(std::forward<Args>(args)...);
}
value_factory() #else
{ } result_type operator()() const {
return result_type();
# define BOOST_PP_FILENAME_1 <boost/functional/value_factory.hpp>
# define BOOST_PP_ITERATION_LIMITS (0,BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY)
# include BOOST_PP_ITERATE()
};
template< typename T > class value_factory<T&>;
// 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));
} }
# undef N
# endif // defined(BOOST_PP_IS_ITERATING) template<class A0>
result_type operator()(A0& a0) const {
return result_type(a0);
}
#endif // include guard template<class A0, class A1>
result_type operator()(A0& a0, A1& a1) const {
return result_type(a0, a1);
}
template<class A0, class A1, class A2>
result_type operator()(A0& a0, A1& a1, A2& a2) const {
return result_type(a0, a1, a2);
}
template<class A0, class A1, class A2, class A3>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3) const {
return result_type(a0, a1, a2, a3);
}
template<class A0, class A1, class A2, class A3, class A4>
result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4) const {
return result_type(a0, a1, a2, a3, a4);
}
template<class A0, class A1, class A2, class A3, class A4, class A5>
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<class A0, class A1, class A2, class A3, class A4, class A5,
class A6>
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<class A0, class A1, class A2, class A3, class A4, class A5,
class A6, class A7>
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<class A0, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8>
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<class A0, class A1, class A2, class A3, class A4, class A5,
class A6, class A7, class A8, class A9>
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 T>
class value_factory<T&> { };
} /* boost */
#endif

View File

@ -16,6 +16,7 @@
"boost-version": "1.43.0", "boost-version": "1.43.0",
"name": "Functional/Factory", "name": "Functional/Factory",
"authors": [ "authors": [
"Glen Fernandes",
"Tobias Schwinger" "Tobias Schwinger"
], ],
"maintainers": [ "maintainers": [