stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -0,0 +1,220 @@
|
||||
|
||||
// Copyright Oliver Kowalke 2013.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_FIBERS_PROMISE_HPP
|
||||
#define BOOST_FIBERS_PROMISE_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/fiber/detail/convert.hpp>
|
||||
#include <boost/fiber/exceptions.hpp>
|
||||
#include <boost/fiber/future/detail/shared_state.hpp>
|
||||
#include <boost/fiber/future/detail/shared_state_object.hpp>
|
||||
#include <boost/fiber/future/future.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace fibers {
|
||||
namespace detail {
|
||||
|
||||
template< typename R >
|
||||
struct promise_base {
|
||||
typedef typename shared_state< R >::ptr_type ptr_type;
|
||||
|
||||
bool obtained_{ false };
|
||||
ptr_type future_{};
|
||||
|
||||
promise_base() :
|
||||
promise_base{ std::allocator_arg, std::allocator< promise_base >{} } {
|
||||
}
|
||||
|
||||
template< typename Allocator >
|
||||
promise_base( std::allocator_arg_t, Allocator alloc) {
|
||||
typedef detail::shared_state_object< R, Allocator > object_type;
|
||||
typedef std::allocator_traits< typename object_type::allocator_type > traits_type;
|
||||
typename object_type::allocator_type a{ alloc };
|
||||
typename traits_type::pointer ptr{ traits_type::allocate( a, 1) };
|
||||
|
||||
try {
|
||||
traits_type::construct( a, ptr, a);
|
||||
} catch (...) {
|
||||
traits_type::deallocate( a, ptr, 1);
|
||||
throw;
|
||||
}
|
||||
future_.reset( convert( ptr) );
|
||||
}
|
||||
|
||||
~promise_base() {
|
||||
if ( future_) {
|
||||
future_->owner_destroyed();
|
||||
}
|
||||
}
|
||||
|
||||
promise_base( promise_base const&) = delete;
|
||||
promise_base & operator=( promise_base const&) = delete;
|
||||
|
||||
promise_base( promise_base && other) noexcept :
|
||||
obtained_{ other.obtained_ },
|
||||
future_{ std::move( other.future_) } {
|
||||
other.obtained_ = false;
|
||||
}
|
||||
|
||||
promise_base & operator=( promise_base && other) noexcept {
|
||||
if ( this != & other) {
|
||||
promise_base tmp{ std::move( other) };
|
||||
swap( tmp);
|
||||
}
|
||||
return * this;
|
||||
}
|
||||
|
||||
future< R > get_future() {
|
||||
if ( obtained_) {
|
||||
throw future_already_retrieved{};
|
||||
}
|
||||
if ( ! future_) {
|
||||
throw promise_uninitialized{};
|
||||
}
|
||||
obtained_ = true;
|
||||
return future< R >{ future_ };
|
||||
}
|
||||
|
||||
void swap( promise_base & other) noexcept {
|
||||
std::swap( obtained_, other.obtained_);
|
||||
future_.swap( other.future_);
|
||||
}
|
||||
|
||||
void set_exception( std::exception_ptr p) {
|
||||
if ( ! future_) {
|
||||
throw promise_uninitialized{};
|
||||
}
|
||||
future_->set_exception( p);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template< typename R >
|
||||
class promise : private detail::promise_base< R > {
|
||||
private:
|
||||
typedef detail::promise_base< R > base_type;
|
||||
|
||||
public:
|
||||
promise() = default;
|
||||
|
||||
template< typename Allocator >
|
||||
promise( std::allocator_arg_t, Allocator alloc) :
|
||||
base_type{ std::allocator_arg, alloc } {
|
||||
}
|
||||
|
||||
promise( promise const&) = delete;
|
||||
promise & operator=( promise const&) = delete;
|
||||
|
||||
promise( promise && other) noexcept = default;
|
||||
promise & operator=( promise && other) = default;
|
||||
|
||||
void set_value( R const& value) {
|
||||
if ( ! base_type::future_) {
|
||||
throw promise_uninitialized{};
|
||||
}
|
||||
base_type::future_->set_value( value);
|
||||
}
|
||||
|
||||
void set_value( R && value) {
|
||||
if ( ! base_type::future_) {
|
||||
throw promise_uninitialized{};
|
||||
}
|
||||
base_type::future_->set_value( std::move( value) );
|
||||
}
|
||||
|
||||
void swap( promise & other) noexcept {
|
||||
base_type::swap( other);
|
||||
}
|
||||
|
||||
using base_type::get_future;
|
||||
using base_type::set_exception;
|
||||
};
|
||||
|
||||
template< typename R >
|
||||
class promise< R & > : private detail::promise_base< R & > {
|
||||
private:
|
||||
typedef detail::promise_base< R & > base_type;
|
||||
|
||||
public:
|
||||
promise() = default;
|
||||
|
||||
template< typename Allocator >
|
||||
promise( std::allocator_arg_t, Allocator alloc) :
|
||||
base_type{ std::allocator_arg, alloc } {
|
||||
}
|
||||
|
||||
promise( promise const&) = delete;
|
||||
promise & operator=( promise const&) = delete;
|
||||
|
||||
promise( promise && other) noexcept = default;
|
||||
promise & operator=( promise && other) noexcept = default;
|
||||
|
||||
void set_value( R & value) {
|
||||
if ( ! base_type::future_) {
|
||||
throw promise_uninitialized{};
|
||||
}
|
||||
base_type::future_->set_value( value);
|
||||
}
|
||||
|
||||
void swap( promise & other) noexcept {
|
||||
base_type::swap( other);
|
||||
}
|
||||
|
||||
using base_type::get_future;
|
||||
using base_type::set_exception;
|
||||
};
|
||||
|
||||
template<>
|
||||
class promise< void > : private detail::promise_base< void > {
|
||||
private:
|
||||
typedef detail::promise_base< void > base_type;
|
||||
|
||||
public:
|
||||
promise() = default;
|
||||
|
||||
template< typename Allocator >
|
||||
promise( std::allocator_arg_t, Allocator alloc) :
|
||||
base_type{ std::allocator_arg, alloc } {
|
||||
}
|
||||
|
||||
promise( promise const&) = delete;
|
||||
promise & operator=( promise const&) = delete;
|
||||
|
||||
promise( promise && other) noexcept = default;
|
||||
promise & operator=( promise && other) noexcept = default;
|
||||
|
||||
inline
|
||||
void set_value() {
|
||||
if ( ! base_type::future_) {
|
||||
throw promise_uninitialized{};
|
||||
}
|
||||
base_type::future_->set_value();
|
||||
}
|
||||
|
||||
inline
|
||||
void swap( promise & other) noexcept {
|
||||
base_type::swap( other);
|
||||
}
|
||||
|
||||
using base_type::get_future;
|
||||
using base_type::set_exception;
|
||||
};
|
||||
|
||||
template< typename R >
|
||||
void swap( promise< R > & l, promise< R > & r) noexcept {
|
||||
l.swap( r);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_FIBERS_PROMISE_HPP
|
||||
Reference in New Issue
Block a user