[futures.promise]. Depends on rvalue-ref support to work 100%.
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@112388 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
47499b162a
commit
f39daa8e5a
include
test/thread/futures
futures.promise
alloc_ctor.pass.cppcopy_assign.fail.cppcopy_ctor.fail.cppdefault.pass.cppdtor.pass.cppmove_assign.pass.cppmove_ctor.pass.cppset_exception.pass.cppset_exception_at_thread_exit.pass.cppset_lvalue.pass.cppset_lvalue_at_thread_exit.pass.cppset_rvalue.pass.cppset_rvalue_at_thread_exit.pass.cppset_value_at_thread_exit_const.pass.cppset_value_at_thread_exit_void.pass.cppset_value_const.pass.cppset_value_void.pass.cppswap.pass.cppuses_allocator.pass.cpp
test_allocator.h
111
include/future
111
include/future
@ -576,6 +576,28 @@ public:
|
||||
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 @@ __assoc_state<_R>::copy()
|
||||
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 @@ __assoc_state_alloc<_R, _Alloc>::__on_zero_shared()
|
||||
__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 @@ void
|
||||
__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 @@ template <class _R>
|
||||
_R&
|
||||
future<_R&>::get()
|
||||
{
|
||||
__assoc_state<_R>* __s = __state_;
|
||||
__assoc_state<_R&>* __s = __state_;
|
||||
__state_ = nullptr;
|
||||
return __s->copy();
|
||||
}
|
||||
|
49
test/thread/futures/futures.promise/alloc_ctor.pass.cpp
Normal file
49
test/thread/futures/futures.promise/alloc_ctor.pass.cpp
Normal file
@ -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);
|
||||
}
|
87
test/thread/futures/futures.promise/copy_assign.fail.cpp
Normal file
87
test/thread/futures/futures.promise/copy_assign.fail.cpp
Normal file
@ -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);
|
||||
}
|
81
test/thread/futures/futures.promise/copy_ctor.fail.cpp
Normal file
81
test/thread/futures/futures.promise/copy_ctor.fail.cpp
Normal file
@ -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);
|
||||
}
|
36
test/thread/futures/futures.promise/default.pass.cpp
Normal file
36
test/thread/futures/futures.promise/default.pass.cpp
Normal file
@ -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());
|
||||
}
|
||||
}
|
106
test/thread/futures/futures.promise/dtor.pass.cpp
Normal file
106
test/thread/futures/futures.promise/dtor.pass.cpp
Normal file
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
89
test/thread/futures/futures.promise/move_assign.pass.cpp
Normal file
89
test/thread/futures/futures.promise/move_assign.pass.cpp
Normal file
@ -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
|
||||
}
|
83
test/thread/futures/futures.promise/move_ctor.pass.cpp
Normal file
83
test/thread/futures/futures.promise/move_ctor.pass.cpp
Normal file
@ -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
|
||||
}
|
45
test/thread/futures/futures.promise/set_exception.pass.cpp
Normal file
45
test/thread/futures/futures.promise/set_exception.pass.cpp
Normal file
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
41
test/thread/futures/futures.promise/set_lvalue.pass.cpp
Normal file
41
test/thread/futures/futures.promise/set_lvalue.pass.cpp
Normal file
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
67
test/thread/futures/futures.promise/set_rvalue.pass.cpp
Normal file
67
test/thread/futures/futures.promise/set_rvalue.pass.cpp
Normal file
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
61
test/thread/futures/futures.promise/set_value_const.pass.cpp
Normal file
61
test/thread/futures/futures.promise/set_value_const.pass.cpp
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
37
test/thread/futures/futures.promise/set_value_void.pass.cpp
Normal file
37
test/thread/futures/futures.promise/set_value_void.pass.cpp
Normal file
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
82
test/thread/futures/futures.promise/swap.pass.cpp
Normal file
82
test/thread/futures/futures.promise/swap.pass.cpp
Normal file
@ -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);
|
||||
}
|
26
test/thread/futures/futures.promise/uses_allocator.pass.cpp
Normal file
26
test/thread/futures/futures.promise/uses_allocator.pass.cpp
Normal file
@ -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), "");
|
||||
}
|
143
test/thread/futures/test_allocator.h
Normal file
143
test/thread/futures/test_allocator.h
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user