Add execution::executor_of concept and execution::is_executor trait.

This commit is contained in:
Christopher Kohlhoff 2020-06-28 23:16:57 +10:00
parent afff66d73e
commit a2e718da65
5 changed files with 191 additions and 12 deletions

View File

@ -33,6 +33,31 @@
namespace asio {
namespace execution {
namespace detail {
template <typename T, typename F>
struct is_executor_of_impl :
integral_constant<bool,
conditional<true, true_type,
typename result_of<typename decay<F>::type&()>::type
>::type::value
&& is_constructible<typename decay<F>::type, F>::value
&& is_move_constructible<typename decay<F>::type>::value
&& can_execute<T, F>::value
#if defined(ASIO_HAS_NOEXCEPT)
&& is_nothrow_copy_constructible<T>::value
&& is_nothrow_destructible<T>::value
#else // defined(ASIO_HAS_NOEXCEPT)
&& is_copy_constructible<T>::value
&& is_destructible<T>::value
#endif // defined(ASIO_HAS_NOEXCEPT)
&& traits::equality_comparable<T>::is_valid
&& traits::equality_comparable<T>::is_noexcept
>
{
};
} // namespace detail
/// The is_executor trait detects whether a type T satisfies the
/// execution::executor concept.
@ -46,18 +71,7 @@ struct is_executor :
#if defined(GENERATING_DOCUMENTATION)
integral_constant<bool, automatically_determined>
#else // defined(GENERATING_DOCUMENTATION)
integral_constant<bool,
can_execute<const T, invocable_archetype>::value
#if defined(ASIO_HAS_NOEXCEPT)
&& is_nothrow_copy_constructible<T>::value
&& is_nothrow_destructible<T>::value
#else // defined(ASIO_HAS_NOEXCEPT)
&& is_copy_constructible<T>::value
&& is_destructible<T>::value
#endif // defined(ASIO_HAS_NOEXCEPT)
&& traits::equality_comparable<typename decay<T>::type>::is_valid
&& traits::equality_comparable<typename decay<T>::type>::is_noexcept
>
detail::is_executor_of_impl<T, invocable_archetype>
#endif // defined(GENERATING_DOCUMENTATION)
{
};
@ -82,6 +96,47 @@ ASIO_CONCEPT executor = is_executor<T>::value;
#endif // defined(ASIO_HAS_CONCEPTS)
/// The is_executor_of trait detects whether a type T satisfies the
/// execution::executor_of concept for some set of value arguments.
/**
* Class template @c is_executor_of is a type trait that is derived from @c
* true_type if the type @c T meets the concept definition for a executor for
* value arguments @c Vs, otherwise @c false_type.
*/
template <typename T, typename F>
struct is_executor_of :
#if defined(GENERATING_DOCUMENTATION)
integral_constant<bool, automatically_determined>
#else // defined(GENERATING_DOCUMENTATION)
integral_constant<bool,
is_executor<T>::value && detail::is_executor_of_impl<T, F>::value
>
#endif // defined(GENERATING_DOCUMENTATION)
{
};
#if defined(ASIO_HAS_VARIABLE_TEMPLATES)
template <typename T, typename F>
ASIO_CONSTEXPR const bool is_executor_of_v =
is_executor_of<T, F>::value;
#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
#if defined(ASIO_HAS_CONCEPTS)
template <typename T, typename F>
ASIO_CONCEPT executor_of = is_executor_of<T, F>::value;
#define ASIO_EXECUTION_EXECUTOR_OF(f) \
::asio::execution::executor_of<f>
#else // defined(ASIO_HAS_CONCEPTS)
#define ASIO_EXECUTION_EXECUTOR_OF typename
#endif // defined(ASIO_HAS_CONCEPTS)
} // namespace execution
} // namespace asio

View File

@ -153,6 +153,7 @@ UNIT_TEST_EXES = \
tests\unit\execution\bulk_guarantee.exe \
tests\unit\execution\context_as.exe \
tests\unit\execution\execute.exe \
tests\unit\execution\executor.exe \
tests\unit\execution\invocable_archetype.exe \
tests\unit\execution\mapping.exe \
tests\unit\execution\outstanding_work.exe \

View File

@ -49,6 +49,7 @@ check_PROGRAMS = \
unit/execution/bulk_guarantee \
unit/execution/context_as \
unit/execution/execute \
unit/execution/executor \
unit/execution/invocable_archetype \
unit/execution/mapping \
unit/execution/outstanding_work \
@ -206,6 +207,7 @@ TESTS = \
unit/execution/bulk_guarantee \
unit/execution/context_as \
unit/execution/execute \
unit/execution/executor \
unit/execution/invocable_archetype \
unit/execution/mapping \
unit/execution/outstanding_work \
@ -363,6 +365,7 @@ unit_execution_blocking_adaptation_SOURCES = unit/execution/blocking_adaptation.
unit_execution_bulk_guarantee_SOURCES = unit/execution/bulk_guarantee.cpp
unit_execution_context_as_SOURCES = unit/execution/context_as.cpp
unit_execution_execute_SOURCES = unit/execution/execute.cpp
unit_execution_executor_SOURCES = unit/execution/executor.cpp
unit_execution_invocable_archetype_SOURCES = unit/execution/invocable_archetype.cpp
unit_execution_mapping_SOURCES = unit/execution/mapping.cpp
unit_execution_outstanding_work_SOURCES = unit/execution/outstanding_work.cpp

View File

@ -13,6 +13,7 @@ blocking_adaptation
bulk_guarantee
context_as
execute
executor
invocable_archetype
mapping
outstanding_work

View File

@ -0,0 +1,119 @@
//
// executor.cpp
// ~~~~~~~~~~~~
//
// Copyright (c) 2003-2020 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)
//
// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)
// Test that header file is self-contained.
#include "asio/execution/executor.hpp"
#include "../unit_test.hpp"
struct not_an_executor
{
};
struct executor
{
executor()
{
}
executor(const executor&) ASIO_NOEXCEPT
{
}
#if defined(ASIO_HAS_MOVE)
executor(executor&&) ASIO_NOEXCEPT
{
}
#endif // defined(ASIO_HAS_MOVE)
template <typename F>
void execute(ASIO_MOVE_ARG(F) f) const ASIO_NOEXCEPT
{
(void)f;
}
bool operator==(const executor&) const ASIO_NOEXCEPT
{
return true;
}
bool operator!=(const executor&) const ASIO_NOEXCEPT
{
return false;
}
};
namespace asio {
namespace traits {
#if !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
template <typename F>
struct execute_member<executor, F>
{
ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
typedef void result_type;
};
#endif // !defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)
#if !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
template <>
struct equality_comparable<executor>
{
ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
};
#endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
} // namespace traits
} // namespace asio
void is_executor_test()
{
ASIO_CHECK((
!asio::execution::is_executor<
not_an_executor
>::value));
ASIO_CHECK((
asio::execution::is_executor<
executor
>::value));
}
void is_executor_of_test()
{
ASIO_CHECK((
!asio::execution::is_executor_of<
not_an_executor,
void(*)()
>::value));
ASIO_CHECK((
asio::execution::is_executor_of<
executor,
void(*)()
>::value));
}
ASIO_TEST_SUITE
(
"executor",
ASIO_TEST_CASE(is_executor_test)
ASIO_TEST_CASE(is_executor_of_test)
)