Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:35:35

0001 
0002 //          Copyright Oliver Kowalke 2013.
0003 // Distributed under the Boost Software License, Version 1.0.
0004 //    (See accompanying file LICENSE_1_0.txt or copy at
0005 //          http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 #ifndef BOOST_FIBERS_FUTURE_HPP
0008 #define BOOST_FIBERS_FUTURE_HPP
0009 
0010 #include <algorithm>
0011 #include <chrono>
0012 #include <exception>
0013 #include <utility>
0014 
0015 #include <boost/config.hpp>
0016 
0017 #include <boost/fiber/detail/config.hpp>
0018 #include <boost/fiber/exceptions.hpp>
0019 #include <boost/fiber/future/detail/shared_state.hpp>
0020 #include <boost/fiber/future/future_status.hpp>
0021 
0022 namespace boost {
0023 namespace fibers {
0024 namespace detail {
0025 
0026 template< typename R >
0027 struct future_base {
0028     typedef typename shared_state< R >::ptr_type   ptr_type;
0029 
0030     ptr_type           state_{};
0031 
0032     future_base() = default;
0033 
0034     explicit future_base( ptr_type  p) noexcept :
0035         state_{std::move( p )} {
0036     }
0037 
0038     ~future_base() = default;
0039 
0040     future_base( future_base const& other) :
0041         state_{ other.state_ } {
0042     }
0043 
0044     future_base( future_base && other) noexcept :
0045         state_{ other.state_ } {
0046         other.state_.reset();
0047     }
0048 
0049     future_base & operator=( future_base const& other) noexcept {
0050         if ( BOOST_LIKELY( this != & other) ) {
0051             state_ = other.state_;
0052         }
0053         return * this;
0054     }
0055 
0056     future_base & operator=( future_base && other) noexcept {
0057         if ( BOOST_LIKELY( this != & other) ) {
0058             state_ = other.state_;
0059             other.state_.reset();
0060         }
0061         return * this;
0062     }
0063 
0064     bool valid() const noexcept {
0065         return nullptr != state_.get();
0066     }
0067 
0068     std::exception_ptr get_exception_ptr() {
0069         if ( BOOST_UNLIKELY( ! valid() ) ) {
0070             throw future_uninitialized{};
0071         }
0072         return state_->get_exception_ptr();
0073     }
0074 
0075     void wait() const {
0076         if ( BOOST_UNLIKELY( ! valid() ) ) {
0077             throw future_uninitialized{};
0078         }
0079         state_->wait();
0080     }
0081 
0082     template< typename Rep, typename Period >
0083     future_status wait_for( std::chrono::duration< Rep, Period > const& timeout_duration) const {
0084         if ( BOOST_UNLIKELY( ! valid() ) ) {
0085             throw future_uninitialized{};
0086         }
0087         return state_->wait_for( timeout_duration);
0088     }
0089 
0090     template< typename Clock, typename Duration >
0091     future_status wait_until( std::chrono::time_point< Clock, Duration > const& timeout_time) const {
0092         if ( BOOST_UNLIKELY( ! valid() ) ) {
0093             throw future_uninitialized{};
0094         }
0095         return state_->wait_until( timeout_time);
0096     }
0097 };
0098 
0099 template< typename R >
0100 struct promise_base;
0101 
0102 }
0103 
0104 template< typename R >
0105 class shared_future;
0106 
0107 template< typename Signature >
0108 class packaged_task;
0109 
0110 template< typename R >
0111 class future : private detail::future_base< R > {
0112 private:
0113     typedef detail::future_base< R >  base_type;
0114 
0115     friend struct detail::promise_base< R >;
0116     friend class shared_future< R >;
0117     template< typename Signature >
0118     friend class packaged_task;
0119 
0120     explicit future( typename base_type::ptr_type const& p) noexcept :
0121         base_type{ p } {
0122     }
0123 
0124 public:
0125     future() = default;
0126 
0127     future( future const&) = delete;
0128     future & operator=( future const&) = delete;
0129 
0130     future( future && other) noexcept :
0131         base_type{ std::move( other) } {
0132     }
0133 
0134     future & operator=( future && other) noexcept {
0135         if ( BOOST_LIKELY( this != & other) ) {
0136             base_type::operator=( std::move( other) );
0137         }
0138         return * this;
0139     }
0140 
0141     shared_future< R > share();
0142 
0143     R get() {
0144         if ( BOOST_UNLIKELY( ! base_type::valid() ) ) {
0145             throw future_uninitialized{};
0146         }
0147         typename base_type::ptr_type tmp{};
0148         tmp.swap( base_type::state_);
0149         return std::move( tmp->get() );
0150     }
0151 
0152     using base_type::valid;
0153     using base_type::get_exception_ptr;
0154     using base_type::wait;
0155     using base_type::wait_for;
0156     using base_type::wait_until;
0157 };
0158 
0159 template< typename R >
0160 class future< R & > : private detail::future_base< R & > {
0161 private:
0162     typedef detail::future_base< R & >  base_type;
0163 
0164     friend struct detail::promise_base< R & >;
0165     friend class shared_future< R & >;
0166     template< typename Signature >
0167     friend class packaged_task;
0168 
0169     explicit future( typename base_type::ptr_type const& p) noexcept :
0170         base_type{ p  } {
0171     }
0172 
0173 public:
0174     future() = default;
0175 
0176     future( future const&) = delete;
0177     future & operator=( future const&) = delete;
0178 
0179     future( future && other) noexcept :
0180         base_type{ std::move( other) } {
0181     }
0182 
0183     future & operator=( future && other) noexcept {
0184         if ( BOOST_LIKELY( this != & other) ) {
0185             base_type::operator=( std::move( other) );
0186         }
0187         return * this;
0188     }
0189 
0190     shared_future< R & > share();
0191 
0192     R & get() {
0193         if ( BOOST_UNLIKELY( ! base_type::valid() ) ) {
0194             throw future_uninitialized{};
0195         }
0196         typename base_type::ptr_type tmp{};
0197         tmp.swap( base_type::state_);
0198         return tmp->get();
0199     }
0200 
0201     using base_type::valid;
0202     using base_type::get_exception_ptr;
0203     using base_type::wait;
0204     using base_type::wait_for;
0205     using base_type::wait_until;
0206 };
0207 
0208 template<>
0209 class future< void > : private detail::future_base< void > {
0210 private:
0211     typedef detail::future_base< void >  base_type;
0212 
0213     friend struct detail::promise_base< void >;
0214     friend class shared_future< void >;
0215     template< typename Signature >
0216     friend class packaged_task;
0217 
0218     explicit future( base_type::ptr_type const& p) noexcept :
0219         base_type{ p } {
0220     }
0221 
0222 public:
0223     future() = default;
0224 
0225     future( future const&) = delete;
0226     future & operator=( future const&) = delete;
0227 
0228     inline
0229     future( future && other) noexcept :
0230         base_type{ std::move( other) } {
0231     }
0232 
0233     inline
0234     future & operator=( future && other) noexcept {
0235         if ( BOOST_LIKELY( this != & other) ) {
0236             base_type::operator=( std::move( other) );
0237         }
0238         return * this;
0239     }
0240 
0241     shared_future< void > share();
0242 
0243     inline
0244     void get() {
0245         if ( BOOST_UNLIKELY( ! base_type::valid() ) ) {
0246             throw future_uninitialized{};
0247         }
0248         base_type::ptr_type tmp{};
0249         tmp.swap( base_type::state_);
0250         tmp->get();
0251     }
0252 
0253     using base_type::valid;
0254     using base_type::get_exception_ptr;
0255     using base_type::wait;
0256     using base_type::wait_for;
0257     using base_type::wait_until;
0258 };
0259 
0260 
0261 template< typename R >
0262 class shared_future : private detail::future_base< R > {
0263 private:
0264     typedef detail::future_base< R >   base_type;
0265 
0266     explicit shared_future( typename base_type::ptr_type const& p) noexcept :
0267         base_type{ p } {
0268     }
0269 
0270 public:
0271     shared_future() = default;
0272 
0273     ~shared_future() = default;
0274 
0275     shared_future( shared_future const& other) :
0276         base_type{ other } {
0277     }
0278 
0279     shared_future( shared_future && other) noexcept :
0280         base_type{ std::move( other) } {
0281     }
0282 
0283     shared_future( future< R > && other) noexcept :
0284         base_type{ std::move( other) } {
0285     }
0286 
0287     shared_future & operator=( shared_future const& other) noexcept {
0288         if ( BOOST_LIKELY( this != & other) ) {
0289             base_type::operator=( other); 
0290         }
0291         return * this;
0292     }
0293 
0294     shared_future & operator=( shared_future && other) noexcept {
0295         if ( BOOST_LIKELY( this != & other) ) {
0296             base_type::operator=( std::move( other) ); 
0297         }
0298         return * this;
0299     }
0300 
0301     shared_future & operator=( future< R > && other) noexcept {
0302         base_type::operator=( std::move( other) ); 
0303         return * this;
0304     }
0305 
0306     R const& get() const {
0307         if ( BOOST_UNLIKELY( ! valid() ) ) {
0308             throw future_uninitialized{};
0309         }
0310         return base_type::state_->get();
0311     }
0312 
0313     using base_type::valid;
0314     using base_type::get_exception_ptr;
0315     using base_type::wait;
0316     using base_type::wait_for;
0317     using base_type::wait_until;
0318 };
0319 
0320 template< typename R >
0321 class shared_future< R & > : private detail::future_base< R & > {
0322 private:
0323     typedef detail::future_base< R & >  base_type;
0324 
0325     explicit shared_future( typename base_type::ptr_type const& p) noexcept :
0326         base_type{ p } {
0327     }
0328 
0329 public:
0330     shared_future() = default;
0331 
0332     ~shared_future() = default;
0333 
0334     shared_future( shared_future const& other) :
0335         base_type{ other } {
0336     }
0337 
0338     shared_future( shared_future && other) noexcept :
0339         base_type{ std::move( other) } {
0340     }
0341 
0342     shared_future( future< R & > && other) noexcept :
0343         base_type{ std::move( other) } {
0344     }
0345 
0346     shared_future & operator=( shared_future const& other) noexcept {
0347         if ( BOOST_LIKELY( this != & other) ) {
0348             base_type::operator=( other);
0349         }
0350         return * this;
0351     }
0352 
0353     shared_future & operator=( shared_future && other) noexcept {
0354         if ( BOOST_LIKELY( this != & other) ) {
0355             base_type::operator=( std::move( other) );
0356         }
0357         return * this;
0358     }
0359 
0360     shared_future & operator=( future< R & > && other) noexcept {
0361         base_type::operator=( std::move( other) );
0362         return * this;
0363     }
0364 
0365     R & get() const {
0366         if ( BOOST_UNLIKELY( ! valid() ) ) {
0367             throw future_uninitialized{};
0368         }
0369         return base_type::state_->get();
0370     }
0371 
0372     using base_type::valid;
0373     using base_type::get_exception_ptr;
0374     using base_type::wait;
0375     using base_type::wait_for;
0376     using base_type::wait_until;
0377 };
0378 
0379 template<>
0380 class shared_future< void > : private detail::future_base< void > {
0381 private:
0382     typedef detail::future_base< void > base_type;
0383 
0384     explicit shared_future( base_type::ptr_type const& p) noexcept :
0385         base_type{ p } {
0386     }
0387 
0388 public:
0389     shared_future() = default;
0390 
0391     ~shared_future() = default;
0392 
0393     inline
0394     shared_future( shared_future const& other) :
0395         base_type{ other } {
0396     }
0397 
0398     inline
0399     shared_future( shared_future && other) noexcept :
0400         base_type{ std::move( other) } {
0401     }
0402 
0403     inline
0404     shared_future( future< void > && other) noexcept :
0405         base_type{ std::move( other) } {
0406     }
0407 
0408     inline
0409     shared_future & operator=( shared_future const& other) noexcept {
0410         if ( BOOST_LIKELY( this != & other) ) {
0411             base_type::operator=( other);
0412         }
0413         return * this;
0414     }
0415 
0416     inline
0417     shared_future & operator=( shared_future && other) noexcept {
0418         if ( BOOST_LIKELY( this != & other) ) {
0419             base_type::operator=( std::move( other) );
0420         }
0421         return * this;
0422     }
0423 
0424     inline
0425     shared_future & operator=( future< void > && other) noexcept {
0426         base_type::operator=( std::move( other) );
0427         return * this;
0428     }
0429 
0430     inline
0431     void get() const {
0432         if ( BOOST_UNLIKELY( ! valid() ) ) {
0433             throw future_uninitialized{};
0434         }
0435         base_type::state_->get();
0436     }
0437 
0438     using base_type::valid;
0439     using base_type::get_exception_ptr;
0440     using base_type::wait;
0441     using base_type::wait_for;
0442     using base_type::wait_until;
0443 };
0444 
0445 
0446 template< typename R >
0447 shared_future< R >
0448 future< R >::share() {
0449     if ( BOOST_UNLIKELY( ! base_type::valid() ) ) {
0450         throw future_uninitialized{};
0451     }
0452     return shared_future< R >{ std::move( * this) };
0453 }
0454 
0455 template< typename R >
0456 shared_future< R & >
0457 future< R & >::share() {
0458     if ( BOOST_UNLIKELY( ! base_type::valid() ) ) {
0459         throw future_uninitialized{};
0460     }
0461     return shared_future< R & >{ std::move( * this) };
0462 }
0463 
0464 inline
0465 shared_future< void >
0466 future< void >::share() {
0467     if ( BOOST_UNLIKELY( ! base_type::valid() ) ) {
0468         throw future_uninitialized{};
0469     }
0470     return shared_future< void >{ std::move( * this) };
0471 }
0472 
0473 }}
0474 
0475 #endif