summaryrefslogtreecommitdiffstats
path: root/libcxx/test/support
diff options
context:
space:
mode:
authorMarshall Clow <mclow.lists@gmail.com>2014-04-18 17:23:36 +0000
committerMarshall Clow <mclow.lists@gmail.com>2014-04-18 17:23:36 +0000
commit5f7c2db2ceae312498634bd521ef64a69a6e2545 (patch)
treead324e2e2c4bead2bdbe92d0b5c171c5611f090c /libcxx/test/support
parentf8361d127a92b81126a5370b50944bef169fbcff (diff)
downloadbcm5719-llvm-5f7c2db2ceae312498634bd521ef64a69a6e2545.tar.gz
bcm5719-llvm-5f7c2db2ceae312498634bd521ef64a69a6e2545.zip
Bug #19473. If you pass an allocator to std::function, we should use that allocator, not construct one from scratch. Add a test to make sure
llvm-svn: 206623
Diffstat (limited to 'libcxx/test/support')
-rw-r--r--libcxx/test/support/test_allocator.h60
1 files changed, 60 insertions, 0 deletions
diff --git a/libcxx/test/support/test_allocator.h b/libcxx/test/support/test_allocator.h
index 99f72a053c3..683fac239f2 100644
--- a/libcxx/test/support/test_allocator.h
+++ b/libcxx/test/support/test_allocator.h
@@ -92,6 +92,66 @@ public:
{return !(x == y);}
};
+template <class T>
+class non_default_test_allocator
+ : public test_alloc_base
+{
+ int data_;
+
+ template <class U> friend class non_default_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 non_default_test_allocator<U> other;};
+
+// non_default_test_allocator() throw() : data_(0) {++count;}
+ explicit non_default_test_allocator(int i) throw() : data_(i) {++count;}
+ non_default_test_allocator(const non_default_test_allocator& a) throw()
+ : data_(a.data_) {++count;}
+ template <class U> non_default_test_allocator(const non_default_test_allocator<U>& a) throw()
+ : data_(a.data_) {++count;}
+ ~non_default_test_allocator() throw() {assert(data_ >= 0); --count; data_ = -1;}
+ pointer address(reference x) const {return &x;}
+ const_pointer address(const_reference x) const {return &x;}
+ pointer allocate(size_type n, const void* = 0)
+ {
+ assert(data_ >= 0);
+ if (time_to_throw >= throw_after) {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ throw std::bad_alloc();
+#else
+ std::terminate();
+#endif
+ }
+ ++time_to_throw;
+ ++alloc_count;
+ return (pointer)std::malloc(n * sizeof(T));
+ }
+ void deallocate(pointer p, size_type n)
+ {assert(data_ >= 0); --alloc_count; 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);}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ void construct(pointer p, T&& val)
+ {::new(p) T(std::move(val));}
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ void destroy(pointer p) {p->~T();}
+
+ friend bool operator==(const non_default_test_allocator& x, const non_default_test_allocator& y)
+ {return x.data_ == y.data_;}
+ friend bool operator!=(const non_default_test_allocator& x, const non_default_test_allocator& y)
+ {return !(x == y);}
+};
+
template <>
class test_allocator<void>
: public test_alloc_base
OpenPOWER on IntegriCloud