__base<_Rp()>*
__func<_Fp, _Alloc, _Rp()>::__clone() const
{
- typedef typename _Alloc::template rebind<__func>::other _Ap;
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
_Ap __a(__f_.second());
typedef __allocator_destructor<_Ap> _Dp;
unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
void
__func<_Fp, _Alloc, _Rp()>::destroy_deallocate()
{
- typedef typename _Alloc::template rebind<__func>::other _Ap;
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
_Ap __a(__f_.second());
__f_.~__compressed_pair<_Fp, _Alloc>();
__a.deallocate(this, 1);
__base<_Rp(_A0)>*
__func<_Fp, _Alloc, _Rp(_A0)>::__clone() const
{
- typedef typename _Alloc::template rebind<__func>::other _Ap;
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
_Ap __a(__f_.second());
typedef __allocator_destructor<_Ap> _Dp;
unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
void
__func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate()
{
- typedef typename _Alloc::template rebind<__func>::other _Ap;
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
_Ap __a(__f_.second());
__f_.~__compressed_pair<_Fp, _Alloc>();
__a.deallocate(this, 1);
__base<_Rp(_A0, _A1)>*
__func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const
{
- typedef typename _Alloc::template rebind<__func>::other _Ap;
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
_Ap __a(__f_.second());
typedef __allocator_destructor<_Ap> _Dp;
unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
void
__func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate()
{
- typedef typename _Alloc::template rebind<__func>::other _Ap;
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
_Ap __a(__f_.second());
__f_.~__compressed_pair<_Fp, _Alloc>();
__a.deallocate(this, 1);
__base<_Rp(_A0, _A1, _A2)>*
__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const
{
- typedef typename _Alloc::template rebind<__func>::other _Ap;
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
_Ap __a(__f_.second());
typedef __allocator_destructor<_Ap> _Dp;
unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
void
__func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate()
{
- typedef typename _Alloc::template rebind<__func>::other _Ap;
+ typedef allocator_traits<_Alloc> __alloc_traits;
+ typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
_Ap __a(__f_.second());
__f_.~__compressed_pair<_Fp, _Alloc>();
__a.deallocate(this, 1);
if (sizeof(_FF) <= sizeof(__buf_))
{
__f_ = (__base*)&__buf_;
- ::new (__f_) _FF(__f);
+ ::new (__f_) _FF(__f, __a0);
}
else
{
if (sizeof(_FF) <= sizeof(__buf_))
{
__f_ = (__base*)&__buf_;
- ::new (__f_) _FF(__f);
+ ::new (__f_) _FF(__f, __a0);
}
else
{
if (sizeof(_FF) <= sizeof(__buf_))
{
__f_ = (__base*)&__buf_;
- ::new (__f_) _FF(__f);
+ ::new (__f_) _FF(__f, __a0);
}
else
{
if (sizeof(_FF) <= sizeof(__buf_))
{
__f_ = (__base*)&__buf_;
- ::new (__f_) _FF(__f);
+ ::new (__f_) _FF(__f, __a0);
}
else
{
#include <cassert>
#include "min_allocator.h"
+#include "test_allocator.h"
+#include "count_new.hpp"
+#include "../function_types.h"
-class A
-{
- int data_[10];
-public:
- static int count;
+class DummyClass {};
- A()
+template <class FuncType, class AllocType>
+void test_FunctionObject(AllocType& alloc)
+{
+ assert(globalMemCounter.checkOutstandingNewEq(0));
{
- ++count;
- for (int i = 0; i < 10; ++i)
- data_[i] = i;
+ FunctionObject target;
+ assert(FunctionObject::count == 1);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ std::function<FuncType> f2(std::allocator_arg, alloc, target);
+ assert(FunctionObject::count == 2);
+ assert(globalMemCounter.checkOutstandingNewEq(1));
+ assert(f2.template target<FunctionObject>());
+ assert(f2.template target<FuncType>() == 0);
+ assert(f2.template target<FuncType*>() == 0);
}
+ assert(FunctionObject::count == 0);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+}
- A(const A&) {++count;}
-
- ~A() {--count;}
- int operator()(int i) const
+template <class FuncType, class AllocType>
+void test_FreeFunction(AllocType& alloc)
+{
+ assert(globalMemCounter.checkOutstandingNewEq(0));
{
- for (int j = 0; j < 10; ++j)
- i += data_[j];
- return i;
+ FuncType* target = &FreeFunction;
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ std::function<FuncType> f2(std::allocator_arg, alloc, target);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ assert(f2.template target<FuncType*>());
+ assert(*f2.template target<FuncType*>() == target);
+ assert(f2.template target<FuncType>() == 0);
+ assert(f2.template target<DummyClass>() == 0);
}
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+}
- int foo(int) const {return 1;}
-};
+template <class TargetType, class FuncType, class AllocType>
+void test_MemFunClass(AllocType& alloc)
+{
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ {
+ TargetType target = &MemFunClass::foo;
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ std::function<FuncType> f2(std::allocator_arg, alloc, target);
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+ assert(f2.template target<TargetType>());
+ assert(*f2.template target<TargetType>() == target);
+ assert(f2.template target<FuncType*>() == 0);
+ }
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+}
-int A::count = 0;
+template <class Alloc>
+void test_for_alloc(Alloc& alloc) {
+ test_FunctionObject<int()>(alloc);
+ test_FunctionObject<int(int)>(alloc);
+ test_FunctionObject<int(int, int)>(alloc);
+ test_FunctionObject<int(int, int, int)>(alloc);
-int g(int) {return 0;}
+ test_FreeFunction<int()>(alloc);
+ test_FreeFunction<int(int)>(alloc);
+ test_FreeFunction<int(int, int)>(alloc);
+ test_FreeFunction<int(int, int, int)>(alloc);
-class Foo {
-public:
- void bar(int k) { }
-};
+ test_MemFunClass<int(MemFunClass::*)() const, int(MemFunClass&)>(alloc);
+ test_MemFunClass<int(MemFunClass::*)(int) const, int(MemFunClass&, int)>(alloc);
+ test_MemFunClass<int(MemFunClass::*)(int, int) const, int(MemFunClass&, int, int)>(alloc);
+}
int main()
{
{
- std::function<int(int)> f(std::allocator_arg, bare_allocator<A>(), A());
- assert(A::count == 1);
- assert(f.target<A>());
- assert(f.target<int(*)(int)>() == 0);
- }
- assert(A::count == 0);
- {
- std::function<int(int)> f(std::allocator_arg, bare_allocator<int(*)(int)>(), g);
- assert(f.target<int(*)(int)>());
- assert(f.target<A>() == 0);
- }
- {
- std::function<int(int)> f(std::allocator_arg, bare_allocator<int(*)(int)>(),
- (int (*)(int))0);
- assert(!f);
- assert(f.target<int(*)(int)>() == 0);
- assert(f.target<A>() == 0);
- }
- {
- std::function<int(const A*, int)> f(std::allocator_arg,
- bare_allocator<int(A::*)(int)const>(),
- &A::foo);
- assert(f);
- assert(f.target<int (A::*)(int) const>() != 0);
- }
-#if __cplusplus >= 201103L
- {
- Foo f;
- std::function<void(int)> fun = std::bind(&Foo::bar, &f, std::placeholders::_1);
- fun(10);
+ bare_allocator<DummyClass> bare_alloc;
+ test_for_alloc(bare_alloc);
}
-#endif
{
- std::function<void(int)> fun(std::allocator_arg,
- bare_allocator<int(*)(int)>(),
- &g);
- assert(fun);
- assert(fun.target<int(*)(int)>() != 0);
- fun(10);
+ non_default_test_allocator<DummyClass> non_default_alloc(42);
+ test_for_alloc(non_default_alloc);
}
}
#include "min_allocator.h"
#include "test_allocator.h"
#include "count_new.hpp"
+#include "../function_types.h"
-class A
-{
- int data_[10];
-public:
- static int count;
-
- A()
- {
- ++count;
- for (int i = 0; i < 10; ++i)
- data_[i] = i;
- }
-
- A(const A&) {++count;}
-
- ~A() {--count;}
-
- int operator()(int i) const
- {
- for (int j = 0; j < 10; ++j)
- i += data_[j];
- return i;
- }
-};
-
-int A::count = 0;
+class DummyClass {};
-int g(int) {return 0;}
-
-int main()
+template <class FuncType, class AllocType>
+void test_FunctionObject(AllocType& alloc)
{
assert(globalMemCounter.checkOutstandingNewEq(0));
{
- std::function<int(int)> f = A();
- assert(A::count == 1);
+ // Construct function from FunctionObject.
+ std::function<FuncType> f = FunctionObject();
+ assert(FunctionObject::count == 1);
assert(globalMemCounter.checkOutstandingNewEq(1));
- assert(f.target<A>());
- assert(f.target<int(*)(int)>() == 0);
- std::function<int(int)> f2(std::allocator_arg, bare_allocator<A>(), f);
- assert(A::count == 2);
+ assert(f.template target<FunctionObject>());
+ assert(f.template target<FuncType>() == 0);
+ assert(f.template target<FuncType*>() == 0);
+ // Copy function with allocator
+ std::function<FuncType> f2(std::allocator_arg, alloc, f);
+ assert(FunctionObject::count == 2);
assert(globalMemCounter.checkOutstandingNewEq(2));
- assert(f2.target<A>());
- assert(f2.target<int(*)(int)>() == 0);
+ assert(f2.template target<FunctionObject>());
+ assert(f2.template target<FuncType>() == 0);
+ assert(f2.template target<FuncType*>() == 0);
}
- assert(A::count == 0);
+ assert(FunctionObject::count == 0);
assert(globalMemCounter.checkOutstandingNewEq(0));
- {
- std::function<int(int)> f = g;
- assert(globalMemCounter.checkOutstandingNewEq(0));
- assert(f.target<int(*)(int)>());
- assert(f.target<A>() == 0);
- std::function<int(int)> f2(std::allocator_arg, bare_allocator<int(*)(int)>(), f);
- assert(globalMemCounter.checkOutstandingNewEq(0));
- assert(f2.target<int(*)(int)>());
- assert(f2.target<A>() == 0);
- }
+}
+
+template <class FuncType, class AllocType>
+void test_FreeFunction(AllocType& alloc)
+{
assert(globalMemCounter.checkOutstandingNewEq(0));
{
+ // Construct function from function pointer.
+ FuncType* target = &FreeFunction;
+ std::function<FuncType> f = target;
assert(globalMemCounter.checkOutstandingNewEq(0));
- non_default_test_allocator<std::function<int(int)> > al(1);
- std::function<int(int)> f2(std::allocator_arg, al, g);
+ assert(f.template target<FuncType*>());
+ assert(*f.template target<FuncType*>() == target);
+ assert(f.template target<FuncType>() == 0);
+ // Copy function with allocator
+ std::function<FuncType> f2(std::allocator_arg, alloc, f);
assert(globalMemCounter.checkOutstandingNewEq(0));
- assert(f2.target<int(*)(int)>());
- assert(f2.target<A>() == 0);
+ assert(f2.template target<FuncType*>());
+ assert(*f2.template target<FuncType*>() == target);
+ assert(f2.template target<FuncType>() == 0);
}
assert(globalMemCounter.checkOutstandingNewEq(0));
+}
+
+template <class TargetType, class FuncType, class AllocType>
+void test_MemFunClass(AllocType& alloc)
+{
+ assert(globalMemCounter.checkOutstandingNewEq(0));
{
- std::function<int(int)> f;
+ // Construct function from function pointer.
+ TargetType target = &MemFunClass::foo;
+ std::function<FuncType> f = target;
assert(globalMemCounter.checkOutstandingNewEq(0));
- assert(f.target<int(*)(int)>() == 0);
- assert(f.target<A>() == 0);
- std::function<int(int)> f2(std::allocator_arg, bare_allocator<int>(), f);
+ assert(f.template target<TargetType>());
+ assert(*f.template target<TargetType>() == target);
+ assert(f.template target<FuncType*>() == 0);
+ // Copy function with allocator
+ std::function<FuncType> f2(std::allocator_arg, alloc, f);
assert(globalMemCounter.checkOutstandingNewEq(0));
- assert(f2.target<int(*)(int)>() == 0);
- assert(f2.target<A>() == 0);
+ assert(f2.template target<TargetType>());
+ assert(*f2.template target<TargetType>() == target);
+ assert(f2.template target<FuncType*>() == 0);
}
+ assert(globalMemCounter.checkOutstandingNewEq(0));
+}
+
+template <class Alloc>
+void test_for_alloc(Alloc& alloc)
+{
+ // Large FunctionObject -- Allocation should occur
+ test_FunctionObject<int()>(alloc);
+ test_FunctionObject<int(int)>(alloc);
+ test_FunctionObject<int(int, int)>(alloc);
+ test_FunctionObject<int(int, int, int)>(alloc);
+ // Free function -- No allocation should occur
+ test_FreeFunction<int()>(alloc);
+ test_FreeFunction<int(int)>(alloc);
+ test_FreeFunction<int(int, int)>(alloc);
+ test_FreeFunction<int(int, int, int)>(alloc);
+ // Member function -- No allocation should occur.
+ test_MemFunClass<int(MemFunClass::*)() const, int(MemFunClass&)>(alloc);
+ test_MemFunClass<int(MemFunClass::*)(int) const, int(MemFunClass&, int)>(alloc);
+ test_MemFunClass<int(MemFunClass::*)(int, int) const, int(MemFunClass&, int, int)>(alloc);
+}
+
+int main()
+{
+ {
+ bare_allocator<DummyClass> alloc;
+ test_for_alloc(alloc);
+ }
+ {
+ non_default_test_allocator<DummyClass> alloc(42);
+ test_for_alloc(alloc);
+ }
}
--- /dev/null
+#ifndef FUNCTION_TYPES_H
+#define FUNCTION_TYPES_H
+
+
+class FunctionObject
+{
+ int data_[10]; // dummy variable to prevent small object optimization in
+ // std::function
+public:
+ static int count;
+
+ FunctionObject() {
+ ++count;
+ for (int i = 0; i < 10; ++i) data_[i] = i;
+ }
+
+ FunctionObject(const FunctionObject&) {++count;}
+ ~FunctionObject() {--count; ((void)data_); }
+
+ int operator()() const { return 42; }
+ int operator()(int i) const { return i; }
+ int operator()(int i, int) const { return i; }
+ int operator()(int i, int, int) const { return i; }
+};
+
+int FunctionObject::count = 0;
+
+class MemFunClass
+{
+ int data_[10]; // dummy variable to prevent small object optimization in
+ // std::function
+public:
+ static int count;
+
+ MemFunClass() {
+ ++count;
+ for (int i = 0; i < 10; ++i) data_[i] = 0;
+ }
+
+ MemFunClass(const MemFunClass&) {++count; ((void)data_); }
+
+ ~MemFunClass() {--count;}
+
+ int foo() const { return 42; }
+ int foo(int i) const { return i; }
+ int foo(int i, int) const { return i; }
+ int foo(int i, int, int) const { return i; }
+};
+
+int MemFunClass::count = 0;
+
+int FreeFunction() { return 42; }
+int FreeFunction(int i) {return i;}
+int FreeFunction(int i, int) { return i; }
+int FreeFunction(int i, int, int) { return i; }
+
+#endif // FUNCTION_TYPES_H
}
++time_to_throw;
++alloc_count;
- return (pointer)std::malloc(n * sizeof(T));
+ return (pointer)::operator new(n * sizeof(T));
}
void deallocate(pointer p, size_type n)
- {assert(data_ >= 0); --alloc_count; std::free(p);}
+ {assert(data_ >= 0); --alloc_count; ::operator delete((void*)p);}
size_type max_size() const throw()
{return UINT_MAX / sizeof(T);}
void construct(pointer p, const T& val)
}
++time_to_throw;
++alloc_count;
- return (pointer)std::malloc(n * sizeof(T));
+ return (pointer)::operator new (n * sizeof(T));
}
void deallocate(pointer p, size_type n)
- {assert(data_ >= 0); --alloc_count; std::free(p);}
+ {assert(data_ >= 0); --alloc_count; ::operator delete((void*)p); }
size_type max_size() const throw()
{return UINT_MAX / sizeof(T);}
void construct(pointer p, const T& val)
template <class U> other_allocator(const other_allocator<U>& a)
: data_(a.data_) {}
T* allocate(std::size_t n)
- {return (T*)std::malloc(n * sizeof(T));}
+ {return (T*)::operator new(n * sizeof(T));}
void deallocate(T* p, std::size_t n)
- {std::free(p);}
+ {::operator delete((void*)p);}
other_allocator select_on_container_copy_construction() const
{return other_allocator(-2);}