mirror of
https://github.com/boostorg/functional.git
synced 2025-07-29 20:17:19 +02:00
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:
@ -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__<T>()(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>`]]
|
||||
[[`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<P>`]]
|
||||
[[`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
|
||||
|
@ -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 : : : <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 ]
|
||||
;
|
||||
|
||||
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 : : : <exception-handling>off ;
|
||||
|
@ -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 <boost/functional/factory.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 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<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_TEST(*instance == 3);
|
||||
boost::scoped_ptr<sum> s(x());
|
||||
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_TEST(*instance == 3);
|
||||
boost::scoped_ptr<sum> s(x(a));
|
||||
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_TEST(*instance == 3);
|
||||
boost::scoped_ptr<sum> s(x(a, b));
|
||||
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();
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
85
factory/test/factory_allocator_throws.cpp
Normal file
85
factory/test/factory_allocator_throws.cpp
Normal 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();
|
||||
}
|
||||
|
42
factory/test/factory_args.cpp
Normal file
42
factory/test/factory_args.cpp
Normal 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
|
55
factory/test/factory_default_allocator.cpp
Normal file
55
factory/test/factory_default_allocator.cpp
Normal 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();
|
||||
}
|
55
factory/test/factory_move.cpp
Normal file
55
factory/test/factory_move.cpp
Normal 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
|
@ -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 <boost/functional/factory.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#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<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);
|
||||
int get() const {
|
||||
return value_;
|
||||
}
|
||||
|
||||
static size_t n_deallocated;
|
||||
void deallocate(T* ptr, size_t n)
|
||||
{
|
||||
n_deallocated += 1;
|
||||
return std::allocator<T>::deallocate(ptr,n);
|
||||
private:
|
||||
int value_;
|
||||
};
|
||||
|
||||
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 one = 1, two = 2;
|
||||
int a = 1;
|
||||
int b = 2;
|
||||
{
|
||||
boost::shared_ptr<sum> instance(
|
||||
boost::factory< boost::shared_ptr<sum>, counting_allocator<void>,
|
||||
boost::factory_alloc_for_pointee_and_deleter >()(one,two) );
|
||||
BOOST_TEST(*instance == 3);
|
||||
boost::shared_ptr<sum> s(boost::factory<boost::shared_ptr<sum>,
|
||||
creator<void>,
|
||||
boost::factory_alloc_for_pointee_and_deleter>()(a, b));
|
||||
BOOST_TEST(creator<sum>::count == 1);
|
||||
BOOST_TEST(s->get() == 3);
|
||||
}
|
||||
BOOST_TEST(counting_allocator<sum>::n_allocated == 1);
|
||||
BOOST_TEST(counting_allocator<sum>::n_deallocated == 1);
|
||||
BOOST_TEST(creator<sum>::count == 0);
|
||||
{
|
||||
boost::shared_ptr<sum> instance(
|
||||
boost::factory< boost::shared_ptr<sum>, counting_allocator<void>,
|
||||
boost::factory_passes_alloc_to_smart_pointer >()(one,two) );
|
||||
BOOST_TEST(*instance == 3);
|
||||
boost::shared_ptr<sum> s(boost::factory<boost::shared_ptr<sum>,
|
||||
creator<void>,
|
||||
boost::factory_passes_alloc_to_smart_pointer>()(a, b));
|
||||
BOOST_TEST(creator<sum>::count == 1);
|
||||
BOOST_TEST(s->get() == 3);
|
||||
}
|
||||
BOOST_TEST(counting_allocator<sum>::n_allocated == 2);
|
||||
BOOST_TEST(counting_allocator<sum>::n_deallocated == 2);
|
||||
BOOST_TEST(creator<sum>::count == 0);
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
@ -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
|
@ -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 <boost/functional/factory.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <memory>
|
||||
|
||||
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<sum> instance(
|
||||
boost::factory< boost::shared_ptr<sum>, std::allocator<int>,
|
||||
boost::factory_alloc_for_pointee_and_deleter >()(one,two) );
|
||||
BOOST_TEST(*instance == 3);
|
||||
boost::shared_ptr<sum> s(boost::factory<boost::shared_ptr<sum>,
|
||||
std::allocator<char>,
|
||||
boost::factory_alloc_for_pointee_and_deleter>()(a, b));
|
||||
BOOST_TEST(s->get() == 3);
|
||||
}
|
||||
|
||||
{
|
||||
boost::shared_ptr<sum> instance(
|
||||
boost::factory< boost::shared_ptr<sum>, std::allocator<int>,
|
||||
boost::factory_passes_alloc_to_smart_pointer >()(one,two) );
|
||||
BOOST_TEST(*instance == 3);
|
||||
boost::shared_ptr<sum> s(boost::factory<boost::shared_ptr<sum>,
|
||||
std::allocator<char>,
|
||||
boost::factory_passes_alloc_to_smart_pointer>()(a, b));
|
||||
BOOST_TEST(s->get() == 3);
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
@ -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 <boost/functional/value_factory.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
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<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) );
|
||||
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();
|
||||
}
|
||||
|
||||
|
40
factory/test/value_factory_args.cpp
Normal file
40
factory/test/value_factory_args.cpp
Normal 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
|
54
factory/test/value_factory_move.cpp
Normal file
54
factory/test/value_factory_move.cpp
Normal 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
|
@ -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 <boost/preprocessor/iteration/iterate.hpp>
|
||||
# include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
# include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
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 <new>
|
||||
# include <boost/pointee.hpp>
|
||||
# include <boost/get_pointer.hpp>
|
||||
# include <boost/non_type.hpp>
|
||||
# include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/core/empty_value.hpp>
|
||||
#include <boost/core/pointer_traits.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/config.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)
|
||||
# include <boost/none_t.hpp>
|
||||
# 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<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
|
||||
{
|
||||
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
|
||||
std::allocator_traits<A>::destroy(a, p);
|
||||
}
|
||||
#else
|
||||
template<class A, class T>
|
||||
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<class A, class T, class... Args>
|
||||
inline void
|
||||
fc_construct(A& a, T* p, Args&&... args)
|
||||
{
|
||||
std::allocator_traits<A>::construct(a, p, std::forward<Args>(args)...);
|
||||
}
|
||||
#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
|
||||
|
@ -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 <boost/preprocessor/iteration/iterate.hpp>
|
||||
# include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
# include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
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 <new>
|
||||
# include <boost/pointee.hpp>
|
||||
# include <boost/get_pointer.hpp>
|
||||
# include <boost/non_type.hpp>
|
||||
# include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
|
||||
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#include <utility>
|
||||
#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 T>
|
||||
class value_factory;
|
||||
|
||||
//----- ---- --- -- - - - -
|
||||
template<class T>
|
||||
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 <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));
|
||||
#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(std::forward<Args>(args)...);
|
||||
}
|
||||
#else
|
||||
result_type operator()() const {
|
||||
return result_type();
|
||||
}
|
||||
# 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
|
||||
|
@ -16,6 +16,7 @@
|
||||
"boost-version": "1.43.0",
|
||||
"name": "Functional/Factory",
|
||||
"authors": [
|
||||
"Glen Fernandes",
|
||||
"Tobias Schwinger"
|
||||
],
|
||||
"maintainers": [
|
||||
|
Reference in New Issue
Block a user