Make it possible to add optional methods to continuable_base depending on the annotation

This commit is contained in:
Denis Blank 2018-12-08 02:32:39 +01:00
parent f5dd02ef8b
commit b5f353222c
6 changed files with 53 additions and 39 deletions

View File

@ -90,7 +90,9 @@ using is_continuable = detail::base::is_continuable<T>;
/// ///
/// \since 1.0.0 /// \since 1.0.0
template <typename Data, typename Annotation> template <typename Data, typename Annotation>
class continuable_base { class continuable_base
: public detail::annotation_trait<Annotation>::template //
annotation_base<continuable_base<Data, Annotation>> {
/// \cond false /// \cond false
using ownership = detail::util::ownership; using ownership = detail::util::ownership;
@ -99,11 +101,6 @@ class continuable_base {
friend class continuable_base; friend class continuable_base;
friend struct detail::base::attorney; friend struct detail::base::attorney;
// The materializer which is used when this continuable_base is an
// expression template such that is_connection_strategy<Annotation>::value
// holds for the Annotation.
using materializer = detail::connection::materializer<continuable_base>;
// The continuation type or intermediate result // The continuation type or intermediate result
Data data_; Data data_;
// The transferable state which represents the validity of the object // The transferable state which represents the validity of the object
@ -565,6 +562,7 @@ public:
detail::base::finalize_continuation(std::move(*this)); detail::base::finalize_continuation(std::move(*this));
} }
#ifdef CONTINUABLE_HAS_DOXYGEN
/// Materializes the continuation expression template and finishes /// Materializes the continuation expression template and finishes
/// the current applied strategy. /// the current applied strategy.
/// ///
@ -588,9 +586,8 @@ public:
/// on conversion. /// on conversion.
/// ///
/// \since 4.0.0 /// \since 4.0.0
auto finish() && { unspecified finish() &&;
return materializer::apply(std::move(*this)); #endif // CONTINUABLE_HAS_DOXYGEN
}
#ifdef CONTINUABLE_HAS_DOXYGEN #ifdef CONTINUABLE_HAS_DOXYGEN
/// Returns true if the continuable_base will resolve its promise /// Returns true if the continuable_base will resolve its promise

View File

@ -40,8 +40,8 @@
#include <continuable/continuable-primitives.hpp> #include <continuable/continuable-primitives.hpp>
#include <continuable/detail/connection/connection-aggregated.hpp> #include <continuable/detail/connection/connection-aggregated.hpp>
#include <continuable/detail/connection/connection.hpp> #include <continuable/detail/connection/connection.hpp>
#include <continuable/detail/core/base.hpp>
#include <continuable/detail/core/annotation.hpp> #include <continuable/detail/core/annotation.hpp>
#include <continuable/detail/core/base.hpp>
#include <continuable/detail/core/types.hpp> #include <continuable/detail/core/types.hpp>
#include <continuable/detail/utility/traits.hpp> #include <continuable/detail/utility/traits.hpp>
@ -164,7 +164,6 @@ struct connection_finalizer<connection_strategy_all_tag> {
return base::attorney::create_from( return base::attorney::create_from(
[result = std::move(result)](auto&& callback) mutable { [result = std::move(result)](auto&& callback) mutable {
using submitter_t = using submitter_t =
all::result_submitter<std::decay_t<decltype(callback)>, all::result_submitter<std::decay_t<decltype(callback)>,
std::decay_t<decltype(result)>>; std::decay_t<decltype(result)>>;
@ -186,6 +185,12 @@ struct connection_finalizer<connection_strategy_all_tag> {
} }
}; };
} // namespace connection } // namespace connection
/// Specialization for a connection annotation
template <>
struct annotation_trait<connection::connection_strategy_all_tag>
: connection::connection_annotation_trait {};
} // namespace detail } // namespace detail
} // namespace cti } // namespace cti

View File

@ -40,8 +40,8 @@
#include <continuable/continuable-primitives.hpp> #include <continuable/continuable-primitives.hpp>
#include <continuable/continuable-promise-base.hpp> #include <continuable/continuable-promise-base.hpp>
#include <continuable/continuable-traverse.hpp> #include <continuable/continuable-traverse.hpp>
#include <continuable/detail/core/base.hpp>
#include <continuable/detail/core/annotation.hpp> #include <continuable/detail/core/annotation.hpp>
#include <continuable/detail/core/base.hpp>
#include <continuable/detail/core/types.hpp> #include <continuable/detail/core/types.hpp>
#include <continuable/detail/traversal/container-category.hpp> #include <continuable/detail/traversal/container-category.hpp>
#include <continuable/detail/utility/traits.hpp> #include <continuable/detail/utility/traits.hpp>
@ -177,7 +177,6 @@ struct connection_finalizer<connection_strategy_any_tag> {
return base::attorney::create_from( return base::attorney::create_from(
[connection = [connection =
std::forward<Connection>(connection)](auto&& callback) mutable { std::forward<Connection>(connection)](auto&& callback) mutable {
using submitter_t = using submitter_t =
any::any_result_submitter<std::decay_t<decltype(callback)>>; any::any_result_submitter<std::decay_t<decltype(callback)>>;
@ -193,6 +192,12 @@ struct connection_finalizer<connection_strategy_any_tag> {
} }
}; };
} // namespace connection } // namespace connection
/// Specialization for a connection annotation
template <>
struct annotation_trait<connection::connection_strategy_any_tag>
: connection::connection_annotation_trait {};
} // namespace detail } // namespace detail
} // namespace cti } // namespace cti

View File

@ -160,6 +160,12 @@ struct connection_finalizer<connection_strategy_seq_tag> {
} }
}; };
} // namespace connection } // namespace connection
/// Specialization for a connection annotation
template <>
struct annotation_trait<connection::connection_strategy_seq_tag>
: connection::connection_annotation_trait {};
} // namespace detail } // namespace detail
} // namespace cti } // namespace cti

View File

@ -124,9 +124,16 @@ auto connect(Strategy strategy, continuable_base<LData, LAnnotation>&& left,
template <typename Strategy> template <typename Strategy>
struct connection_finalizer; struct connection_finalizer;
/// Finalizes the connection logic of a given connection struct connection_annotation_trait {
template <typename Data, typename Strategy> template <typename Continuable>
auto finalize_connection(continuable_base<Data, Strategy>&& continuation) { struct annotation_base;
template <typename Data, typename Strategy>
struct annotation_base<continuable_base<Data, Strategy>> {
/// Finalizes the connection logic of a given connection
auto finish() && {
using continuable_t = continuable_base<Data, Strategy>;
auto&& continuation = std::move(*static_cast<continuable_t*>(this));
using finalizer = connection_finalizer<Strategy>; using finalizer = connection_finalizer<Strategy>;
util::ownership ownership = base::attorney::ownership_of(continuation); util::ownership ownership = base::attorney::ownership_of(continuation);
@ -134,23 +141,10 @@ auto finalize_connection(continuable_base<Data, Strategy>&& continuation) {
// Return a new continuable which // Return a new continuable which
return finalizer::finalize(std::move(connection), std::move(ownership)); return finalizer::finalize(std::move(connection), std::move(ownership));
}
/// A base class from which the continuable may inherit in order to
/// provide a materializer method which will finalize an oustanding strategy.
template <typename Continuable, typename = void>
struct materializer {
static constexpr auto&& apply(Continuable&& continuable) {
return std::move(continuable);
} }
}; };
template <typename Data, typename Strategy>
struct materializer<continuable_base<Data, Strategy>,
std::enable_if_t<is_connection_strategy<Strategy>::value>> {
static constexpr auto apply(continuable_base<Data, Strategy>&& continuable) { using is_concrete = std::false_type;
return finalize_connection(std::move(continuable));
}
}; };
class prepare_continuables { class prepare_continuables {

View File

@ -43,9 +43,16 @@ struct annotation_trait;
/// Specialization for a present signature hint /// Specialization for a present signature hint
template <typename... Args> template <typename... Args>
struct annotation_trait<traits::identity<Args...>> { struct annotation_trait<traits::identity<Args...>> {
using is_concrete_hint = std::true_type; template <typename Continuable>
using hint_t = traits::identity<Args...>; struct annotation_base {
using is_materialized = std::true_type; Continuable&& finish() {
return std::move(*static_cast<Continuable*>(this));
}
static constexpr bool is_concrete = true;
};
using is_concrete = std::true_type;
}; };
namespace hints { namespace hints {