diff options
Diffstat (limited to 'libcxx/test/utilities/function.objects')
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 |