123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- //
- // cancellation_state.hpp
- // ~~~~~~~~~~~~~~~~~~~~~~
- //
- // Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com)
- //
- // 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_ASIO_CANCELLATION_STATE_HPP
- #define BOOST_ASIO_CANCELLATION_STATE_HPP
- #if defined(_MSC_VER) && (_MSC_VER >= 1200)
- # pragma once
- #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
- #include <boost/asio/detail/config.hpp>
- #include <cassert>
- #include <new>
- #include <utility>
- #include <boost/asio/cancellation_signal.hpp>
- #include <boost/asio/detail/cstddef.hpp>
- #include <boost/asio/detail/push_options.hpp>
- namespace boost {
- namespace asio {
- /// A simple cancellation signal propagation filter.
- template <cancellation_type_t Mask>
- struct cancellation_filter
- {
- /// Returns <tt>type & Mask</tt>.
- cancellation_type_t operator()(
- cancellation_type_t type) const noexcept
- {
- return type & Mask;
- }
- };
- /// A cancellation filter that disables cancellation.
- typedef cancellation_filter<cancellation_type::none>
- disable_cancellation;
- /// A cancellation filter that enables terminal cancellation only.
- typedef cancellation_filter<cancellation_type::terminal>
- enable_terminal_cancellation;
- #if defined(GENERATING_DOCUMENTATION)
- /// A cancellation filter that enables terminal and partial cancellation.
- typedef cancellation_filter<
- cancellation_type::terminal | cancellation_type::partial>
- enable_partial_cancellation;
- /// A cancellation filter that enables terminal, partial and total cancellation.
- typedef cancellation_filter<cancellation_type::terminal
- | cancellation_type::partial | cancellation_type::total>
- enable_total_cancellation;
- #else // defined(GENERATING_DOCUMENTATION)
- typedef cancellation_filter<
- static_cast<cancellation_type_t>(
- static_cast<unsigned int>(cancellation_type::terminal)
- | static_cast<unsigned int>(cancellation_type::partial))>
- enable_partial_cancellation;
- typedef cancellation_filter<
- static_cast<cancellation_type_t>(
- static_cast<unsigned int>(cancellation_type::terminal)
- | static_cast<unsigned int>(cancellation_type::partial)
- | static_cast<unsigned int>(cancellation_type::total))>
- enable_total_cancellation;
- #endif // defined(GENERATING_DOCUMENTATION)
- /// A cancellation state is used for chaining signals and slots in compositions.
- class cancellation_state
- {
- public:
- /// Construct a disconnected cancellation state.
- constexpr cancellation_state() noexcept
- : impl_(0)
- {
- }
- /// Construct and attach to a parent slot to create a new child slot.
- /**
- * Initialises the cancellation state so that it allows terminal cancellation
- * only. Equivalent to <tt>cancellation_state(slot,
- * enable_terminal_cancellation())</tt>.
- *
- * @param slot The parent cancellation slot to which the state will be
- * attached.
- */
- template <typename CancellationSlot>
- constexpr explicit cancellation_state(CancellationSlot slot)
- : impl_(slot.is_connected() ? &slot.template emplace<impl<>>() : 0)
- {
- }
- /// Construct and attach to a parent slot to create a new child slot.
- /**
- * @param slot The parent cancellation slot to which the state will be
- * attached.
- *
- * @param filter A function object that is used to transform incoming
- * cancellation signals as they are received from the parent slot. This
- * function object must have the signature:
- * @code boost::asio::cancellation_type_t filter(
- * boost::asio::cancellation_type_t); @endcode
- *
- * The library provides the following pre-defined cancellation filters:
- *
- * @li boost::asio::disable_cancellation
- * @li boost::asio::enable_terminal_cancellation
- * @li boost::asio::enable_partial_cancellation
- * @li boost::asio::enable_total_cancellation
- */
- template <typename CancellationSlot, typename Filter>
- constexpr cancellation_state(CancellationSlot slot, Filter filter)
- : impl_(slot.is_connected()
- ? &slot.template emplace<impl<Filter, Filter>>(filter, filter)
- : 0)
- {
- }
- /// Construct and attach to a parent slot to create a new child slot.
- /**
- * @param slot The parent cancellation slot to which the state will be
- * attached.
- *
- * @param in_filter A function object that is used to transform incoming
- * cancellation signals as they are received from the parent slot. This
- * function object must have the signature:
- * @code boost::asio::cancellation_type_t in_filter(
- * boost::asio::cancellation_type_t); @endcode
- *
- * @param out_filter A function object that is used to transform outcoming
- * cancellation signals as they are relayed to the child slot. This function
- * object must have the signature:
- * @code boost::asio::cancellation_type_t out_filter(
- * boost::asio::cancellation_type_t); @endcode
- *
- * The library provides the following pre-defined cancellation filters:
- *
- * @li boost::asio::disable_cancellation
- * @li boost::asio::enable_terminal_cancellation
- * @li boost::asio::enable_partial_cancellation
- * @li boost::asio::enable_total_cancellation
- */
- template <typename CancellationSlot, typename InFilter, typename OutFilter>
- constexpr cancellation_state(CancellationSlot slot,
- InFilter in_filter, OutFilter out_filter)
- : impl_(slot.is_connected()
- ? &slot.template emplace<impl<InFilter, OutFilter>>(
- static_cast<InFilter&&>(in_filter),
- static_cast<OutFilter&&>(out_filter))
- : 0)
- {
- }
- /// Returns the single child slot associated with the state.
- /**
- * This sub-slot is used with the operations that are being composed.
- */
- constexpr cancellation_slot slot() const noexcept
- {
- return impl_ ? impl_->signal_.slot() : cancellation_slot();
- }
- /// Returns the cancellation types that have been triggered.
- cancellation_type_t cancelled() const noexcept
- {
- return impl_ ? impl_->cancelled_ : cancellation_type_t();
- }
- /// Clears the specified cancellation types, if they have been triggered.
- void clear(cancellation_type_t mask = cancellation_type::all)
- noexcept
- {
- if (impl_)
- impl_->cancelled_ &= ~mask;
- }
- private:
- struct impl_base
- {
- impl_base()
- : cancelled_()
- {
- }
- cancellation_signal signal_;
- cancellation_type_t cancelled_;
- };
- template <
- typename InFilter = enable_terminal_cancellation,
- typename OutFilter = InFilter>
- struct impl : impl_base
- {
- impl()
- : in_filter_(),
- out_filter_()
- {
- }
- impl(InFilter in_filter, OutFilter out_filter)
- : in_filter_(static_cast<InFilter&&>(in_filter)),
- out_filter_(static_cast<OutFilter&&>(out_filter))
- {
- }
- void operator()(cancellation_type_t in)
- {
- this->cancelled_ = in_filter_(in);
- cancellation_type_t out = out_filter_(this->cancelled_);
- if (out != cancellation_type::none)
- this->signal_.emit(out);
- }
- InFilter in_filter_;
- OutFilter out_filter_;
- };
- impl_base* impl_;
- };
- } // namespace asio
- } // namespace boost
- #include <boost/asio/detail/pop_options.hpp>
- #endif // BOOST_ASIO_CANCELLATION_STATE_HPP
|