[cfe-commits] [libcxx] r112388 - in /libcxx/trunk: include/ test/thread/futures/ test/thread/futures/futures.promise/

Howard Hinnant hhinnant at apple.com
Sat Aug 28 14:01:06 PDT 2010


Author: hhinnant
Date: Sat Aug 28 16:01:06 2010
New Revision: 112388

URL: http://llvm.org/viewvc/llvm-project?rev=112388&view=rev
Log:
[futures.promise].  Depends on rvalue-ref support to work 100%.

Added:
    libcxx/trunk/test/thread/futures/futures.promise/alloc_ctor.pass.cpp
    libcxx/trunk/test/thread/futures/futures.promise/copy_assign.fail.cpp
    libcxx/trunk/test/thread/futures/futures.promise/copy_ctor.fail.cpp
    libcxx/trunk/test/thread/futures/futures.promise/default.pass.cpp
    libcxx/trunk/test/thread/futures/futures.promise/dtor.pass.cpp
    libcxx/trunk/test/thread/futures/futures.promise/move_assign.pass.cpp
    libcxx/trunk/test/thread/futures/futures.promise/move_ctor.pass.cpp
    libcxx/trunk/test/thread/futures/futures.promise/set_exception.pass.cpp
    libcxx/trunk/test/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp
    libcxx/trunk/test/thread/futures/futures.promise/set_lvalue.pass.cpp
    libcxx/trunk/test/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp
    libcxx/trunk/test/thread/futures/futures.promise/set_rvalue.pass.cpp
    libcxx/trunk/test/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp
    libcxx/trunk/test/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp
    libcxx/trunk/test/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp
    libcxx/trunk/test/thread/futures/futures.promise/set_value_const.pass.cpp
    libcxx/trunk/test/thread/futures/futures.promise/set_value_void.pass.cpp
    libcxx/trunk/test/thread/futures/futures.promise/swap.pass.cpp
    libcxx/trunk/test/thread/futures/futures.promise/uses_allocator.pass.cpp
    libcxx/trunk/test/thread/futures/test_allocator.h
Modified:
    libcxx/trunk/include/future

Modified: libcxx/trunk/include/future
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/future?rev=112388&r1=112387&r2=112388&view=diff
==============================================================================
--- libcxx/trunk/include/future (original)
+++ libcxx/trunk/include/future Sat Aug 28 16:01:06 2010
@@ -576,6 +576,28 @@
         wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
 };
 
+template <class _Clock, class _Duration>
+future_status
+__assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const
+{
+    unique_lock<mutex> __lk(__mut_);
+    while (!(__state_ & (ready | deferred)) && _Clock::now() < __abs_time)
+        __cv_.wait_until(__lk, __abs_time);
+    if (__state_ & ready)
+        return future_status::ready;
+    if (__state_ & deferred)
+        return future_status::deferred;
+    return future_status::timeout;
+}
+
+template <class _Rep, class _Period>
+inline _LIBCPP_INLINE_VISIBILITY
+future_status
+__assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const
+{
+    return wait_until(chrono::monotonic_clock::now() + __rel_time);
+}
+
 template <class _R>
 class __assoc_state
     : public __assoc_sub_state
@@ -675,6 +697,69 @@
     return *reinterpret_cast<_R*>(&__value_);
 }
 
+template <class _R>
+class __assoc_state<_R&>
+    : public __assoc_sub_state
+{
+    typedef __assoc_sub_state base;
+    typedef _R* _U;
+protected:
+    _U __value_;
+
+    virtual void __on_zero_shared();
+public:
+
+    void set_value(_R& __arg);
+    void set_value_at_thread_exit(_R& __arg);
+
+    _R& copy();
+};
+
+template <class _R>
+void
+__assoc_state<_R&>::__on_zero_shared()
+{
+    delete this;
+}
+
+template <class _R>
+void
+__assoc_state<_R&>::set_value(_R& __arg)
+{
+    unique_lock<mutex> __lk(this->__mut_);
+    if (this->__has_value())
+        throw future_error(make_error_code(future_errc::promise_already_satisfied));
+    __value_ = &__arg;
+    this->__state_ |= base::__constructed | base::ready;
+    __lk.unlock();
+    __cv_.notify_all();
+}
+
+template <class _R>
+void
+__assoc_state<_R&>::set_value_at_thread_exit(_R& __arg)
+{
+    unique_lock<mutex> __lk(this->__mut_);
+    if (this->__has_value())
+        throw future_error(make_error_code(future_errc::promise_already_satisfied));
+    __value_ = &__arg;
+    this->__state_ |= base::__constructed;
+    __thread_local_data->__make_ready_at_thread_exit(this);
+    __lk.unlock();
+}
+
+template <class _R>
+_R&
+__assoc_state<_R&>::copy()
+{
+    unique_lock<mutex> __lk(this->__mut_);
+    while (!this->__is_ready())
+        this->__cv_.wait(__lk);
+    if (this->__exception_ != nullptr)
+        rethrow_exception(this->__exception_);
+    return *__value_;
+}
+
 template <class _R, class _Alloc>
 class __assoc_state_alloc
     : public __assoc_state<_R>
@@ -699,6 +784,28 @@
     __a.deallocate(this, 1);
 }
 
+template <class _R, class _Alloc>
+class __assoc_state_alloc<_R&, _Alloc>
+    : public __assoc_state<_R&>
+{
+    typedef __assoc_state<_R&> base;
+    _Alloc __alloc_;
+
+    virtual void __on_zero_shared();
+public:
+    explicit __assoc_state_alloc(const _Alloc& __a)
+        : __alloc_(__a) {}
+};
+
+template <class _R, class _Alloc>
+void
+__assoc_state_alloc<_R&, _Alloc>::__on_zero_shared()
+{
+    typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
+    this->~__assoc_state_alloc();
+    __a.deallocate(this, 1);
+}
+
 template <class _Alloc>
 class __assoc_sub_state_alloc
     : public __assoc_sub_state
@@ -717,7 +824,7 @@
 __assoc_sub_state_alloc<_Alloc>::__on_zero_shared()
 {
     this->~base();
-    typename _Alloc::template rebind<__assoc_state_alloc>::other __a(__alloc_);
+    typename _Alloc::template rebind<__assoc_sub_state_alloc>::other __a(__alloc_);
     this->~__assoc_sub_state_alloc();
     __a.deallocate(this, 1);
 }
@@ -865,7 +972,7 @@
 _R&
 future<_R&>::get()
 {
-    __assoc_state<_R>* __s = __state_;
+    __assoc_state<_R&>* __s = __state_;
     __state_ = nullptr;
     return __s->copy();
 }

Added: libcxx/trunk/test/thread/futures/futures.promise/alloc_ctor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/futures/futures.promise/alloc_ctor.pass.cpp?rev=112388&view=auto
==============================================================================
--- libcxx/trunk/test/thread/futures/futures.promise/alloc_ctor.pass.cpp (added)
+++ libcxx/trunk/test/thread/futures/futures.promise/alloc_ctor.pass.cpp Sat Aug 28 16:01:06 2010
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// template <class Allocator>
+//   promise(allocator_arg_t, const Allocator& a);
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+
+int main()
+{
+    assert(test_alloc_base::count == 0);
+    {
+        std::promise<int> p(std::allocator_arg, test_allocator<int>());
+        assert(test_alloc_base::count == 1);
+        std::future<int> f = p.get_future();
+        assert(test_alloc_base::count == 1);
+        assert(f.valid());
+    }
+    assert(test_alloc_base::count == 0);
+    {
+        std::promise<int&> p(std::allocator_arg, test_allocator<int>());
+        assert(test_alloc_base::count == 1);
+        std::future<int&> f = p.get_future();
+        assert(test_alloc_base::count == 1);
+        assert(f.valid());
+    }
+    assert(test_alloc_base::count == 0);
+    {
+        std::promise<void> p(std::allocator_arg, test_allocator<void>());
+        assert(test_alloc_base::count == 1);
+        std::future<void> f = p.get_future();
+        assert(test_alloc_base::count == 1);
+        assert(f.valid());
+    }
+    assert(test_alloc_base::count == 0);
+}

Added: libcxx/trunk/test/thread/futures/futures.promise/copy_assign.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/futures/futures.promise/copy_assign.fail.cpp?rev=112388&view=auto
==============================================================================
--- libcxx/trunk/test/thread/futures/futures.promise/copy_assign.fail.cpp (added)
+++ libcxx/trunk/test/thread/futures/futures.promise/copy_assign.fail.cpp Sat Aug 28 16:01:06 2010
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// promise& operator=(const promise& rhs) = delete;
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+
+int main()
+{
+    assert(test_alloc_base::count == 0);
+    {
+        std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+        std::promise<int> p(std::allocator_arg, test_allocator<int>());
+        assert(test_alloc_base::count == 2);
+        p = p0;
+        assert(test_alloc_base::count == 1);
+        std::future<int> f = p.get_future();
+        assert(test_alloc_base::count == 1);
+        assert(f.valid());
+        try
+        {
+            f = p0.get_future();
+            assert(false);
+        }
+        catch (const std::future_error& e)
+        {
+            assert(e.code() == make_error_code(std::future_errc::no_state));
+        }
+        assert(test_alloc_base::count == 1);
+    }
+    assert(test_alloc_base::count == 0);
+    {
+        std::promise<int&> p0(std::allocator_arg, test_allocator<int>());
+        std::promise<int&> p(std::allocator_arg, test_allocator<int>());
+        assert(test_alloc_base::count == 2);
+        p = p0;
+        assert(test_alloc_base::count == 1);
+        std::future<int&> f = p.get_future();
+        assert(test_alloc_base::count == 1);
+        assert(f.valid());
+        try
+        {
+            f = p0.get_future();
+            assert(false);
+        }
+        catch (const std::future_error& e)
+        {
+            assert(e.code() == make_error_code(std::future_errc::no_state));
+        }
+        assert(test_alloc_base::count == 1);
+    }
+    assert(test_alloc_base::count == 0);
+    {
+        std::promise<void> p0(std::allocator_arg, test_allocator<void>());
+        std::promise<void> p(std::allocator_arg, test_allocator<void>());
+        assert(test_alloc_base::count == 2);
+        p = p0;
+        assert(test_alloc_base::count == 1);
+        std::future<void> f = p.get_future();
+        assert(test_alloc_base::count == 1);
+        assert(f.valid());
+        try
+        {
+            f = p0.get_future();
+            assert(false);
+        }
+        catch (const std::future_error& e)
+        {
+            assert(e.code() == make_error_code(std::future_errc::no_state));
+        }
+        assert(test_alloc_base::count == 1);
+    }
+    assert(test_alloc_base::count == 0);
+}

Added: libcxx/trunk/test/thread/futures/futures.promise/copy_ctor.fail.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/futures/futures.promise/copy_ctor.fail.cpp?rev=112388&view=auto
==============================================================================
--- libcxx/trunk/test/thread/futures/futures.promise/copy_ctor.fail.cpp (added)
+++ libcxx/trunk/test/thread/futures/futures.promise/copy_ctor.fail.cpp Sat Aug 28 16:01:06 2010
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// promise(const promise&) = delete;
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+
+int main()
+{
+    assert(test_alloc_base::count == 0);
+    {
+        std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+        std::promise<int> p(p0);
+        assert(test_alloc_base::count == 1);
+        std::future<int> f = p.get_future();
+        assert(test_alloc_base::count == 1);
+        assert(f.valid());
+        try
+        {
+            f = p0.get_future();
+            assert(false);
+        }
+        catch (const std::future_error& e)
+        {
+            assert(e.code() == make_error_code(std::future_errc::no_state));
+        }
+        assert(test_alloc_base::count == 1);
+    }
+    assert(test_alloc_base::count == 0);
+    {
+        std::promise<int&> p0(std::allocator_arg, test_allocator<int>());
+        std::promise<int&> p(p0);
+        assert(test_alloc_base::count == 1);
+        std::future<int&> f = p.get_future();
+        assert(test_alloc_base::count == 1);
+        assert(f.valid());
+        try
+        {
+            f = p0.get_future();
+            assert(false);
+        }
+        catch (const std::future_error& e)
+        {
+            assert(e.code() == make_error_code(std::future_errc::no_state));
+        }
+        assert(test_alloc_base::count == 1);
+    }
+    assert(test_alloc_base::count == 0);
+    {
+        std::promise<void> p0(std::allocator_arg, test_allocator<void>());
+        std::promise<void> p(p0);
+        assert(test_alloc_base::count == 1);
+        std::future<void> f = p.get_future();
+        assert(test_alloc_base::count == 1);
+        assert(f.valid());
+        try
+        {
+            f = p0.get_future();
+            assert(false);
+        }
+        catch (const std::future_error& e)
+        {
+            assert(e.code() == make_error_code(std::future_errc::no_state));
+        }
+        assert(test_alloc_base::count == 1);
+    }
+    assert(test_alloc_base::count == 0);
+}

Added: libcxx/trunk/test/thread/futures/futures.promise/default.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/futures/futures.promise/default.pass.cpp?rev=112388&view=auto
==============================================================================
--- libcxx/trunk/test/thread/futures/futures.promise/default.pass.cpp (added)
+++ libcxx/trunk/test/thread/futures/futures.promise/default.pass.cpp Sat Aug 28 16:01:06 2010
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// promise();
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+    {
+        std::promise<int> p;
+        std::future<int> f = p.get_future();
+        assert(f.valid());
+    }
+    {
+        std::promise<int&> p;
+        std::future<int&> f = p.get_future();
+        assert(f.valid());
+    }
+    {
+        std::promise<void> p;
+        std::future<void> f = p.get_future();
+        assert(f.valid());
+    }
+}

Added: libcxx/trunk/test/thread/futures/futures.promise/dtor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/futures/futures.promise/dtor.pass.cpp?rev=112388&view=auto
==============================================================================
--- libcxx/trunk/test/thread/futures/futures.promise/dtor.pass.cpp (added)
+++ libcxx/trunk/test/thread/futures/futures.promise/dtor.pass.cpp Sat Aug 28 16:01:06 2010
@@ -0,0 +1,106 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// ~promise();
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+    {
+        typedef int T;
+        std::future<T> f;
+        {
+            std::promise<T> p;
+            f = p.get_future();
+            p.set_value(3);
+        }
+        assert(f.get() == 3);
+    }
+    {
+        typedef int T;
+        std::future<T> f;
+        {
+            std::promise<T> p;
+            f = p.get_future();
+        }
+        try
+        {
+            T i = f.get();
+            assert(false);
+        }
+        catch (const std::future_error& e)
+        {
+            assert(e.code() == make_error_code(std::future_errc::broken_promise));
+        }
+    }
+
+    {
+        typedef int& T;
+        int i = 4;
+        std::future<T> f;
+        {
+            std::promise<T> p;
+            f = p.get_future();
+            p.set_value(i);
+        }
+        assert(&f.get() == &i);
+    }
+    {
+        typedef int& T;
+        std::future<T> f;
+        {
+            std::promise<T> p;
+            f = p.get_future();
+        }
+        try
+        {
+            T i = f.get();
+            assert(false);
+        }
+        catch (const std::future_error& e)
+        {
+            assert(e.code() == make_error_code(std::future_errc::broken_promise));
+        }
+    }
+
+    {
+        typedef void T;
+        std::future<T> f;
+        {
+            std::promise<T> p;
+            f = p.get_future();
+            p.set_value();
+        }
+        f.get();
+        assert(true);
+    }
+    {
+        typedef void T;
+        std::future<T> f;
+        {
+            std::promise<T> p;
+            f = p.get_future();
+        }
+        try
+        {
+            f.get();
+            assert(false);
+        }
+        catch (const std::future_error& e)
+        {
+            assert(e.code() == make_error_code(std::future_errc::broken_promise));
+        }
+    }
+}

Added: libcxx/trunk/test/thread/futures/futures.promise/move_assign.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/futures/futures.promise/move_assign.pass.cpp?rev=112388&view=auto
==============================================================================
--- libcxx/trunk/test/thread/futures/futures.promise/move_assign.pass.cpp (added)
+++ libcxx/trunk/test/thread/futures/futures.promise/move_assign.pass.cpp Sat Aug 28 16:01:06 2010
@@ -0,0 +1,89 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// promise& operator=(promise&& rhs);
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+    assert(test_alloc_base::count == 0);
+    {
+        std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+        std::promise<int> p(std::allocator_arg, test_allocator<int>());
+        assert(test_alloc_base::count == 2);
+        p = std::move(p0);
+        assert(test_alloc_base::count == 1);
+        std::future<int> f = p.get_future();
+        assert(test_alloc_base::count == 1);
+        assert(f.valid());
+        try
+        {
+            f = p0.get_future();
+            assert(false);
+        }
+        catch (const std::future_error& e)
+        {
+            assert(e.code() == make_error_code(std::future_errc::no_state));
+        }
+        assert(test_alloc_base::count == 1);
+    }
+    assert(test_alloc_base::count == 0);
+    {
+        std::promise<int&> p0(std::allocator_arg, test_allocator<int>());
+        std::promise<int&> p(std::allocator_arg, test_allocator<int>());
+        assert(test_alloc_base::count == 2);
+        p = std::move(p0);
+        assert(test_alloc_base::count == 1);
+        std::future<int&> f = p.get_future();
+        assert(test_alloc_base::count == 1);
+        assert(f.valid());
+        try
+        {
+            f = p0.get_future();
+            assert(false);
+        }
+        catch (const std::future_error& e)
+        {
+            assert(e.code() == make_error_code(std::future_errc::no_state));
+        }
+        assert(test_alloc_base::count == 1);
+    }
+    assert(test_alloc_base::count == 0);
+    {
+        std::promise<void> p0(std::allocator_arg, test_allocator<void>());
+        std::promise<void> p(std::allocator_arg, test_allocator<void>());
+        assert(test_alloc_base::count == 2);
+        p = std::move(p0);
+        assert(test_alloc_base::count == 1);
+        std::future<void> f = p.get_future();
+        assert(test_alloc_base::count == 1);
+        assert(f.valid());
+        try
+        {
+            f = p0.get_future();
+            assert(false);
+        }
+        catch (const std::future_error& e)
+        {
+            assert(e.code() == make_error_code(std::future_errc::no_state));
+        }
+        assert(test_alloc_base::count == 1);
+    }
+    assert(test_alloc_base::count == 0);
+#endif  // _LIBCPP_MOVE
+}

Added: libcxx/trunk/test/thread/futures/futures.promise/move_ctor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/futures/futures.promise/move_ctor.pass.cpp?rev=112388&view=auto
==============================================================================
--- libcxx/trunk/test/thread/futures/futures.promise/move_ctor.pass.cpp (added)
+++ libcxx/trunk/test/thread/futures/futures.promise/move_ctor.pass.cpp Sat Aug 28 16:01:06 2010
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// promise(promise&& rhs);
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+    assert(test_alloc_base::count == 0);
+    {
+        std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+        std::promise<int> p(std::move(p0));
+        assert(test_alloc_base::count == 1);
+        std::future<int> f = p.get_future();
+        assert(test_alloc_base::count == 1);
+        assert(f.valid());
+        try
+        {
+            f = p0.get_future();
+            assert(false);
+        }
+        catch (const std::future_error& e)
+        {
+            assert(e.code() == make_error_code(std::future_errc::no_state));
+        }
+        assert(test_alloc_base::count == 1);
+    }
+    assert(test_alloc_base::count == 0);
+    {
+        std::promise<int&> p0(std::allocator_arg, test_allocator<int>());
+        std::promise<int&> p(std::move(p0));
+        assert(test_alloc_base::count == 1);
+        std::future<int&> f = p.get_future();
+        assert(test_alloc_base::count == 1);
+        assert(f.valid());
+        try
+        {
+            f = p0.get_future();
+            assert(false);
+        }
+        catch (const std::future_error& e)
+        {
+            assert(e.code() == make_error_code(std::future_errc::no_state));
+        }
+        assert(test_alloc_base::count == 1);
+    }
+    assert(test_alloc_base::count == 0);
+    {
+        std::promise<void> p0(std::allocator_arg, test_allocator<void>());
+        std::promise<void> p(std::move(p0));
+        assert(test_alloc_base::count == 1);
+        std::future<void> f = p.get_future();
+        assert(test_alloc_base::count == 1);
+        assert(f.valid());
+        try
+        {
+            f = p0.get_future();
+            assert(false);
+        }
+        catch (const std::future_error& e)
+        {
+            assert(e.code() == make_error_code(std::future_errc::no_state));
+        }
+        assert(test_alloc_base::count == 1);
+    }
+    assert(test_alloc_base::count == 0);
+#endif  // _LIBCPP_MOVE
+}

Added: libcxx/trunk/test/thread/futures/futures.promise/set_exception.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/futures/futures.promise/set_exception.pass.cpp?rev=112388&view=auto
==============================================================================
--- libcxx/trunk/test/thread/futures/futures.promise/set_exception.pass.cpp (added)
+++ libcxx/trunk/test/thread/futures/futures.promise/set_exception.pass.cpp Sat Aug 28 16:01:06 2010
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// void set_exception(exception_ptr p);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+    {
+        typedef int T;
+        std::promise<T> p;
+        std::future<T> f = p.get_future();
+        p.set_exception(std::make_exception_ptr(3));
+        try
+        {
+            f.get();
+            assert(false);
+        }
+        catch (int i)
+        {
+            assert(i == 3);
+        }
+        try
+        {
+            p.set_exception(std::make_exception_ptr(3));
+            assert(false);
+        }
+        catch (const std::future_error& e)
+        {
+            assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied));
+        }
+    }
+}

Added: libcxx/trunk/test/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp?rev=112388&view=auto
==============================================================================
--- libcxx/trunk/test/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp (added)
+++ libcxx/trunk/test/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp Sat Aug 28 16:01:06 2010
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// void promise::set_exception_at_thread_exit(exception_ptr p);
+
+#include <future>
+#include <cassert>
+
+void func(std::promise<int>& p)
+{
+    const int i = 5;
+    p.set_exception_at_thread_exit(std::make_exception_ptr(3));
+}
+
+int main()
+{
+    {
+        typedef int T;
+        std::promise<T> p;
+        std::future<T> f = p.get_future();
+        std::thread(func, std::move(p)).detach();
+        try
+        {
+            f.get();
+            assert(false);
+        }
+        catch (int i)
+        {
+            assert(i == 3);
+        }
+    }
+}

Added: libcxx/trunk/test/thread/futures/futures.promise/set_lvalue.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/futures/futures.promise/set_lvalue.pass.cpp?rev=112388&view=auto
==============================================================================
--- libcxx/trunk/test/thread/futures/futures.promise/set_lvalue.pass.cpp (added)
+++ libcxx/trunk/test/thread/futures/futures.promise/set_lvalue.pass.cpp Sat Aug 28 16:01:06 2010
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// void promise<R&>::set_value(R& r);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+    {
+        typedef int& T;
+        int i = 3;
+        std::promise<T> p;
+        std::future<T> f = p.get_future();
+        p.set_value(i);
+        assert(f.get() == 3);
+        ++i;
+        f = p.get_future();
+        assert(f.get() == 4);
+        try
+        {
+            p.set_value(i);
+            assert(false);
+        }
+        catch (const std::future_error& e)
+        {
+            assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied));
+        }
+    }
+}

Added: libcxx/trunk/test/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp?rev=112388&view=auto
==============================================================================
--- libcxx/trunk/test/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp (added)
+++ libcxx/trunk/test/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp Sat Aug 28 16:01:06 2010
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// void promise<R&>::set_value_at_thread_exit(R& r);
+
+#include <future>
+#include <memory>
+#include <cassert>
+
+int i = 0;
+
+void func(std::promise<int&>& p)
+{
+    p.set_value_at_thread_exit(i);
+    i = 4;
+}
+
+int main()
+{
+    {
+        std::promise<int&> p;
+        std::future<int&> f = p.get_future();
+        std::thread(func, std::move(p)).detach();
+        assert(f.get() == 4);
+    }
+}

Added: libcxx/trunk/test/thread/futures/futures.promise/set_rvalue.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/futures/futures.promise/set_rvalue.pass.cpp?rev=112388&view=auto
==============================================================================
--- libcxx/trunk/test/thread/futures/futures.promise/set_rvalue.pass.cpp (added)
+++ libcxx/trunk/test/thread/futures/futures.promise/set_rvalue.pass.cpp Sat Aug 28 16:01:06 2010
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// void promise::set_value(R&& r);
+
+#include <future>
+#include <memory>
+#include <cassert>
+
+#ifdef _LIBCPP_MOVE
+
+struct A
+{
+    A() {}
+    A(const A&) = delete;
+    A(A&&) {throw 9;}
+};
+
+#endif  // _LIBCPP_MOVE
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+    {
+        typedef std::unique_ptr<int> T;
+        T i(new int(3));
+        std::promise<T> p;
+        std::future<T> f = p.get_future();
+        p.set_value(std::move(i));
+        assert(*f.get() == 3);
+        try
+        {
+            p.set_value(std::move(i));
+            assert(false);
+        }
+        catch (const std::future_error& e)
+        {
+            assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied));
+        }
+    }
+    {
+        typedef A T;
+        T i;
+        std::promise<T> p;
+        std::future<T> f = p.get_future();
+        try
+        {
+            p.set_value(std::move(i));
+            assert(false);
+        }
+        catch (int j)
+        {
+            assert(j == 9);
+        }
+    }
+#endif  // _LIBCPP_MOVE
+}

Added: libcxx/trunk/test/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp?rev=112388&view=auto
==============================================================================
--- libcxx/trunk/test/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp (added)
+++ libcxx/trunk/test/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp Sat Aug 28 16:01:06 2010
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// void promise::set_value_at_thread_exit(R&& r);
+
+#include <future>
+#include <memory>
+#include <cassert>
+
+#ifdef _LIBCPP_MOVE
+
+void func(std::promise<std::unique_ptr<int>>& p)
+{
+    p.set_value_at_thread_exit(std::unique_ptr<int>(new int(5)));
+}
+
+#endif  // _LIBCPP_MOVE
+
+int main()
+{
+#ifdef _LIBCPP_MOVE
+    {
+        std::promise<std::unique_ptr<int>> p;
+        std::future<std::unique_ptr<int>> f = p.get_future();
+        std::thread(func, std::move(p)).detach();
+        assert(*f.get() == 5);
+    }
+#endif  // _LIBCPP_MOVE
+}

Added: libcxx/trunk/test/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp?rev=112388&view=auto
==============================================================================
--- libcxx/trunk/test/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp (added)
+++ libcxx/trunk/test/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp Sat Aug 28 16:01:06 2010
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// void promise::set_value_at_thread_exit(const R& r);
+
+#include <future>
+#include <cassert>
+
+void func(std::promise<int>& p)
+{
+    const int i = 5;
+    p.set_value_at_thread_exit(i);
+}
+
+int main()
+{
+    {
+        std::promise<int> p;
+        std::future<int> f = p.get_future();
+        std::thread(func, std::move(p)).detach();
+        assert(f.get() == 5);
+    }
+}

Added: libcxx/trunk/test/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp?rev=112388&view=auto
==============================================================================
--- libcxx/trunk/test/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp (added)
+++ libcxx/trunk/test/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp Sat Aug 28 16:01:06 2010
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// void promise<void>::set_value_at_thread_exit();
+
+#include <future>
+#include <memory>
+#include <cassert>
+
+int i = 0;
+
+void func(std::promise<void>& p)
+{
+    p.set_value_at_thread_exit();
+    i = 1;
+}
+
+int main()
+{
+    {
+        std::promise<void> p;
+        std::future<void> f = p.get_future();
+        std::thread(func, std::move(p)).detach();
+        f.get();
+        assert(i == 1);
+    }
+}

Added: libcxx/trunk/test/thread/futures/futures.promise/set_value_const.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/futures/futures.promise/set_value_const.pass.cpp?rev=112388&view=auto
==============================================================================
--- libcxx/trunk/test/thread/futures/futures.promise/set_value_const.pass.cpp (added)
+++ libcxx/trunk/test/thread/futures/futures.promise/set_value_const.pass.cpp Sat Aug 28 16:01:06 2010
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// void promise::set_value(const R& r);
+
+#include <future>
+#include <cassert>
+
+struct A
+{
+    A() {}
+    A(const A&) {throw 10;}
+};
+
+int main()
+{
+    {
+        typedef int T;
+        T i = 3;
+        std::promise<T> p;
+        std::future<T> f = p.get_future();
+        p.set_value(i);
+        ++i;
+        assert(f.get() == 3);
+        --i;
+        try
+        {
+            p.set_value(i);
+            assert(false);
+        }
+        catch (const std::future_error& e)
+        {
+            assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied));
+        }
+    }
+    {
+        typedef A T;
+        T i;
+        std::promise<T> p;
+        std::future<T> f = p.get_future();
+        try
+        {
+            p.set_value(i);
+            assert(false);
+        }
+        catch (int j)
+        {
+            assert(j == 10);
+        }
+    }
+}

Added: libcxx/trunk/test/thread/futures/futures.promise/set_value_void.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/futures/futures.promise/set_value_void.pass.cpp?rev=112388&view=auto
==============================================================================
--- libcxx/trunk/test/thread/futures/futures.promise/set_value_void.pass.cpp (added)
+++ libcxx/trunk/test/thread/futures/futures.promise/set_value_void.pass.cpp Sat Aug 28 16:01:06 2010
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// void promise<void>::set_value();
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+    {
+        typedef void T;
+        std::promise<T> p;
+        std::future<T> f = p.get_future();
+        p.set_value();
+        f.get();
+        try
+        {
+            p.set_value();
+            assert(false);
+        }
+        catch (const std::future_error& e)
+        {
+            assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied));
+        }
+    }
+}

Added: libcxx/trunk/test/thread/futures/futures.promise/swap.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/futures/futures.promise/swap.pass.cpp?rev=112388&view=auto
==============================================================================
--- libcxx/trunk/test/thread/futures/futures.promise/swap.pass.cpp (added)
+++ libcxx/trunk/test/thread/futures/futures.promise/swap.pass.cpp Sat Aug 28 16:01:06 2010
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// void swap(promise& other);
+
+// template <class R> void swap(promise<R>& x, promise<R>& y);
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+
+int main()
+{
+    assert(test_alloc_base::count == 0);
+    {
+        std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+        std::promise<int> p(std::allocator_arg, test_allocator<int>());
+        assert(test_alloc_base::count == 2);
+        p.swap(p0);
+        assert(test_alloc_base::count == 2);
+        std::future<int> f = p.get_future();
+        assert(test_alloc_base::count == 2);
+        assert(f.valid());
+        f = p0.get_future();
+        assert(f.valid());
+        assert(test_alloc_base::count == 2);
+    }
+    assert(test_alloc_base::count == 0);
+    {
+        std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+        std::promise<int> p(std::allocator_arg, test_allocator<int>());
+        assert(test_alloc_base::count == 2);
+        swap(p, p0);
+        assert(test_alloc_base::count == 2);
+        std::future<int> f = p.get_future();
+        assert(test_alloc_base::count == 2);
+        assert(f.valid());
+        f = p0.get_future();
+        assert(f.valid());
+        assert(test_alloc_base::count == 2);
+    }
+    assert(test_alloc_base::count == 0);
+    {
+        std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+        std::promise<int> p;
+        assert(test_alloc_base::count == 1);
+        p.swap(p0);
+        assert(test_alloc_base::count == 1);
+        std::future<int> f = p.get_future();
+        assert(test_alloc_base::count == 1);
+        assert(f.valid());
+        f = p0.get_future();
+        assert(f.valid());
+        assert(test_alloc_base::count == 1);
+    }
+    assert(test_alloc_base::count == 0);
+    {
+        std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+        std::promise<int> p;
+        assert(test_alloc_base::count == 1);
+        swap(p, p0);
+        assert(test_alloc_base::count == 1);
+        std::future<int> f = p.get_future();
+        assert(test_alloc_base::count == 1);
+        assert(f.valid());
+        f = p0.get_future();
+        assert(f.valid());
+        assert(test_alloc_base::count == 1);
+    }
+    assert(test_alloc_base::count == 0);
+}

Added: libcxx/trunk/test/thread/futures/futures.promise/uses_allocator.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/futures/futures.promise/uses_allocator.pass.cpp?rev=112388&view=auto
==============================================================================
--- libcxx/trunk/test/thread/futures/futures.promise/uses_allocator.pass.cpp (added)
+++ libcxx/trunk/test/thread/futures/futures.promise/uses_allocator.pass.cpp Sat Aug 28 16:01:06 2010
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// template <class R, class Alloc>
+//   struct uses_allocator<promise<R>, Alloc>
+//      : true_type { };
+
+#include <future>
+#include "../test_allocator.h"
+
+int main()
+{
+    static_assert((std::uses_allocator<std::promise<int>, test_allocator<int> >::value), "");
+    static_assert((std::uses_allocator<std::promise<int&>, test_allocator<int> >::value), "");
+    static_assert((std::uses_allocator<std::promise<void>, test_allocator<void> >::value), "");
+}

Added: libcxx/trunk/test/thread/futures/test_allocator.h
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/futures/test_allocator.h?rev=112388&view=auto
==============================================================================
--- libcxx/trunk/test/thread/futures/test_allocator.h (added)
+++ libcxx/trunk/test/thread/futures/test_allocator.h Sat Aug 28 16:01:06 2010
@@ -0,0 +1,143 @@
+#ifndef TEST_ALLOCATOR_H
+#define TEST_ALLOCATOR_H
+
+#include <cstddef>
+#include <type_traits>
+#include <cstdlib>
+#include <new>
+#include <climits>
+
+class test_alloc_base
+{
+public:
+    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)
+        {--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);}
+#ifdef _LIBCPP_MOVE
+    void construct(pointer p, T&& val)
+        {::new(p) T(std::move(val));}
+#endif  // _LIBCPP_MOVE
+    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 test_allocator<void>
+    : public test_alloc_base
+{
+    int data_;
+
+    template <class U> friend class test_allocator;
+public:
+
+    typedef unsigned                                                   size_type;
+    typedef int                                                        difference_type;
+    typedef void                                                       value_type;
+    typedef value_type*                                                pointer;
+    typedef const value_type*                                          const_pointer;
+
+    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;}
+
+    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  // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+
+};
+
+#endif  // TEST_ALLOCATOR_H





More information about the cfe-commits mailing list