summaryrefslogtreecommitdiffstats
path: root/libcxx/test/utilities/function.objects
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/test/utilities/function.objects')
-rw-r--r--libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp5
-rw-r--r--libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp60
-rw-r--r--libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp84
-rw-r--r--libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp5
-rw-r--r--libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp61
-rw-r--r--libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/assign_F_alloc.pass.cpp40
-rw-r--r--libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/test_allocator.h112
7 files changed, 361 insertions, 6 deletions
diff --git a/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp b/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp
index c6628718576..fa65aae85cd 100644
--- a/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp
+++ b/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc.pass.cpp
@@ -16,7 +16,10 @@
#include <functional>
#include <cassert>
+#include "../test_allocator.h"
+
int main()
{
-#error template<class A> function(allocator_arg_t, const A&); not implemented
+ std::function<int(int)> f(std::allocator_arg, test_allocator<int>());
+ assert(!f);
}
diff --git a/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp b/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp
index 01ffad74de8..43868e390ed 100644
--- a/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp
+++ b/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp
@@ -16,7 +16,65 @@
#include <functional>
#include <cassert>
+#include "../test_allocator.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 foo(int) const {return 1;}
+};
+
+int A::count = 0;
+
+int g(int) {return 0;}
+
int main()
{
-#error template<class F, class A> function(allocator_arg_t, const A&, F); not implemented
+ {
+ std::function<int(int)> f(std::allocator_arg, test_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, test_allocator<int(*)(int)>(), g);
+ assert(f.target<int(*)(int)>());
+ assert(f.target<A>() == 0);
+ }
+ {
+ std::function<int(int)> f(std::allocator_arg, test_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,
+ test_allocator<int(A::*)(int)const>(),
+ &A::foo);
+ assert(f);
+ assert(f.target<int (A::*)(int) const>() != 0);
+ }
}
diff --git a/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp b/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp
index 893949cc655..561dd68336b 100644
--- a/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp
+++ b/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_function.pass.cpp
@@ -14,9 +14,91 @@
// template<class A> function(allocator_arg_t, const A&, const function&);
#include <functional>
+#include <new>
+#include <cstdlib>
#include <cassert>
+#include "../test_allocator.h"
+
+int new_called = 0;
+
+void* operator new(std::size_t s) throw(std::bad_alloc)
+{
+ ++new_called;
+ return std::malloc(s);
+}
+
+void operator delete(void* p) throw()
+{
+ --new_called;
+ std::free(p);
+}
+
+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;
+
+int g(int) {return 0;}
+
int main()
{
-#error template<class A> function(allocator_arg_t, const A&, const function&); not implemented
+ assert(new_called == 0);
+ {
+ std::function<int(int)> f = A();
+ assert(A::count == 1);
+ assert(new_called == 1);
+ assert(f.target<A>());
+ assert(f.target<int(*)(int)>() == 0);
+ std::function<int(int)> f2(std::allocator_arg, test_allocator<A>(), f);
+ assert(A::count == 2);
+ assert(new_called == 2);
+ assert(f2.target<A>());
+ assert(f2.target<int(*)(int)>() == 0);
+ }
+ assert(A::count == 0);
+ assert(new_called == 0);
+ {
+ std::function<int(int)> f = g;
+ assert(new_called == 0);
+ assert(f.target<int(*)(int)>());
+ assert(f.target<A>() == 0);
+ std::function<int(int)> f2(std::allocator_arg, test_allocator<int(*)(int)>(), f);
+ assert(new_called == 0);
+ assert(f2.target<int(*)(int)>());
+ assert(f2.target<A>() == 0);
+ }
+ assert(new_called == 0);
+ {
+ std::function<int(int)> f;
+ assert(new_called == 0);
+ assert(f.target<int(*)(int)>() == 0);
+ assert(f.target<A>() == 0);
+ std::function<int(int)> f2(std::allocator_arg, test_allocator<int>(), f);
+ assert(new_called == 0);
+ assert(f2.target<int(*)(int)>() == 0);
+ assert(f2.target<A>() == 0);
+ }
}
diff --git a/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp b/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp
index 048b7f6bd5c..f69a9c615e1 100644
--- a/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp
+++ b/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_nullptr.pass.cpp
@@ -16,7 +16,10 @@
#include <functional>
#include <cassert>
+#include "../test_allocator.h"
+
int main()
{
-#error template<class A> function(allocator_arg_t, const A&, nullptr_t); not implemented
+ std::function<int(int)> f(std::allocator_arg, test_allocator<int>(), nullptr);
+ assert(!f);
}
diff --git a/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp b/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp
index 15e4dad2323..263cd81aee1 100644
--- a/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp
+++ b/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_rfunction.pass.cpp
@@ -16,7 +16,66 @@
#include <functional>
#include <cassert>
+#include "../test_allocator.h"
+
+int new_called = 0;
+
+void* operator new(std::size_t s) throw(std::bad_alloc)
+{
+ ++new_called;
+ return std::malloc(s);
+}
+
+void operator delete(void* p) throw()
+{
+ --new_called;
+ std::free(p);
+}
+
+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;
+
int main()
{
-#error template<class A> function(allocator_arg_t, const A&, function&&); not implemented
+#ifdef _LIBCPP_MOVE
+ assert(new_called == 0);
+ {
+ std::function<int(int)> f = A();
+ assert(A::count == 1);
+ assert(new_called == 1);
+ assert(f.target<A>());
+ assert(f.target<int(*)(int)>() == 0);
+ std::function<int(int)> f2(std::allocator_arg, test_allocator<A>(), std::move(f));
+ assert(A::count == 1);
+ assert(new_called == 1);
+ assert(f2.target<A>());
+ assert(f2.target<int(*)(int)>() == 0);
+ assert(f.target<A>() == 0);
+ assert(f.target<int(*)(int)>() == 0);
+ }
+#endif
}
diff --git a/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/assign_F_alloc.pass.cpp b/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/assign_F_alloc.pass.cpp
index eeb6956012a..8727f60df42 100644
--- a/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/assign_F_alloc.pass.cpp
+++ b/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/assign_F_alloc.pass.cpp
@@ -16,7 +16,45 @@
#include <functional>
#include <cassert>
+#include "../test_allocator.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 foo(int) const {return 1;}
+};
+
+int A::count = 0;
+
int main()
{
-#error template<class F, class A> void assign(F&&, const A&); not implemented
+ {
+ std::function<int(int)> f;
+ f.assign(A(), test_allocator<A>());
+ assert(A::count == 1);
+ assert(f.target<A>());
+ assert(f.target<int(*)(int)>() == 0);
+ }
+ assert(A::count == 0);
}
diff --git a/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/test_allocator.h b/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/test_allocator.h
new file mode 100644
index 00000000000..898c0900d4e
--- /dev/null
+++ b/libcxx/test/utilities/function.objects/func.wrap/func.wrap.func/test_allocator.h
@@ -0,0 +1,112 @@
+#ifndef TEST_ALLOCATOR_H
+#define TEST_ALLOCATOR_H
+
+#include <cstddef>
+#include <type_traits>
+#include <cstdlib>
+#include <new>
+#include <climits>
+
+class test_alloc_base
+{
+protected:
+ static int count;
+public:
+ static int throw_after;
+};
+
+int test_alloc_base::count = 0;
+int test_alloc_base::throw_after = INT_MAX;
+
+template <class T>
+class test_allocator
+ : public test_alloc_base
+{
+ int data_;
+
+ template <class U> friend class test_allocator;
+public:
+
+ typedef unsigned size_type;
+ typedef int difference_type;
+ typedef T value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef typename std::add_lvalue_reference<value_type>::type reference;
+ typedef typename std::add_lvalue_reference<const value_type>::type const_reference;
+
+ template <class U> struct rebind {typedef test_allocator<U> other;};
+
+ test_allocator() throw() : data_(-1) {}
+ explicit test_allocator(int i) throw() : data_(i) {}
+ test_allocator(const test_allocator& a) throw()
+ : data_(a.data_) {}
+ template <class U> test_allocator(const test_allocator<U>& a) throw()
+ : data_(a.data_) {}
+ ~test_allocator() throw() {data_ = 0;}
+ pointer address(reference x) const {return &x;}
+ const_pointer address(const_reference x) const {return &x;}
+ pointer allocate(size_type n, const void* = 0)
+ {
+ if (count >= throw_after)
+ throw std::bad_alloc();
+ ++count;
+ return (pointer)std::malloc(n * sizeof(T));
+ }
+ void deallocate(pointer p, size_type n)
+ {std::free(p);}
+ size_type max_size() const throw()
+ {return UINT_MAX / sizeof(T);}
+ void construct(pointer p, const T& val)
+ {::new(p) T(val);}
+#ifdef _LIBCPP_MOVE
+ void construct(pointer p, T&& val)
+ {::new(p) T(std::move(val));}
+#endif
+ void destroy(pointer p) {p->~T();}
+
+ friend bool operator==(const test_allocator& x, const test_allocator& y)
+ {return x.data_ == y.data_;}
+ friend bool operator!=(const test_allocator& x, const test_allocator& y)
+ {return !(x == y);}
+};
+
+template <class T>
+class other_allocator
+{
+ int data_;
+
+ template <class U> friend class other_allocator;
+
+public:
+ typedef T value_type;
+
+ other_allocator() : data_(-1) {}
+ explicit other_allocator(int i) : data_(i) {}
+ 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));}
+ void deallocate(T* p, std::size_t n)
+ {std::free(p);}
+
+ other_allocator select_on_container_copy_construction() const
+ {return other_allocator(-2);}
+
+ friend bool operator==(const other_allocator& x, const other_allocator& y)
+ {return x.data_ == y.data_;}
+ friend bool operator!=(const other_allocator& x, const other_allocator& y)
+ {return !(x == y);}
+
+ typedef std::true_type propagate_on_container_copy_assignment;
+ typedef std::true_type propagate_on_container_move_assignment;
+ typedef std::true_type propagate_on_container_swap;
+
+#ifdef _LIBCPP_HAS_NO_ADVANCED_SFINAE
+ std::size_t max_size() const
+ {return UINT_MAX / sizeof(T);}
+#endif
+
+};
+
+#endif
OpenPOWER on IntegriCloud