Browse Source

使用concept来描述部分接口

tags/v2.9.7
tearshark 4 years ago
parent
commit
254c13b21e

+ 1
- 0
librf/src/def.h View File

@@ -79,4 +79,5 @@ RESUMEF_NS
#include "exception.inl"
#include "type_traits.inl"
#include "type_concept.inl"
#include "macro_def.inl"

+ 4
- 1
librf/src/scheduler.h View File

@@ -30,7 +30,10 @@ RESUMEF_NS
void run();
//void break_all();
template<class _Ty, typename = std::enable_if_t<traits::is_callable_v<_Ty> || traits::is_future_v<_Ty> || traits::is_generator_v<_Ty> >>
template<class _Ty
COMMA_RESUMEF_ENABLE_IF(traits::is_callable_v<_Ty> || traits::is_future_v<_Ty> || traits::is_generator_v<_Ty>)
>
RESUMEF_REQUIRES(traits::is_callable_v<_Ty> || traits::is_future_v<_Ty> || traits::is_generator_v<_Ty>)
inline void operator + (_Ty&& t_)
{
if constexpr (traits::is_callable_v<_Ty>)

+ 70
- 0
librf/src/type_concept.inl View File

@@ -0,0 +1,70 @@
#pragma once
#include <concepts>
RESUMEF_NS
{
#define RESUMEF_ENABLE_CONCEPT 1
#if RESUMEF_ENABLE_CONCEPT
template<typename T>
concept _AwaitorT = requires(T && v)
{
{ v.await_ready() } -> bool;
{ v.await_suspend(std::declval<std::experimental::coroutine_handle<promise_t<>>>()) };
{ v.await_resume() };
};
template<typename T>
concept _HasStateT = _AwaitorT<T> && requires(T && v)
{
{ v._state };
};
template<typename T>
concept _FutureT = _AwaitorT<T> && _HasStateT<T> && requires
{
{ T::value_type };
{ T::state_type };
{ T::promise_type };
};
template<typename T>
concept _CallableT = std::invocable<T>;
template<typename T>
concept _GeneratorT = std::is_same_v<T, generator_t<_Ty>>;
template<typename T>
concept _WhenTaskT = _AwaitorT<T> || _CallableT<T>;
template<typename T>
concept _WhenIterT = requires(T&& u, T&& v)
{
{ ++u } -> T;
{ u != v } -> bool;
{ *u };
//requires _WhenTaskT<*u>;
};
#define COMMA_RESUMEF_ENABLE_IF(...) ,typename=std::enable_if_t<__VA_ARGS__>
#define RESUMEF_ENABLE_IF(...) typename=std::enable_if_t<__VA_ARGS__>
#define RESUMEF_REQUIRES(...) requires __VA_ARGS__
#else
#define _AwaitorT typename
#define _HasStateT typename
#define _FutureT typename
#define _CallableT typename
#define _GeneratorT typename
#define _WhenTaskT typename
#define _WhenIterT typename
#define COMMA_RESUMEF_ENABLE_IF(...) ,typename=std::enable_if_t<__VA_ARGS__>
#define RESUMEF_ENABLE_IF(...) typename=std::enable_if_t<__VA_ARGS__>
#define RESUMEF_REQUIRES(...)
#endif
}

+ 29
- 15
librf/src/type_traits.inl View File

@@ -163,21 +163,35 @@ RESUMEF_NS
using value_type = decltype(std::declval<type>().await_resume());
};

template<typename _Function>
inline auto _IsCallable(_Function&& _Func, int) -> decltype(_Func(), std::true_type())
{
(_Func);
return std::true_type();
}
template<typename _Function>
inline std::false_type _IsCallable(_Function&&, ...)
{
return std::false_type();
}
template<typename _Function>
using is_callable = decltype(_IsCallable(std::declval<_Function>(), 0));
template<typename _Function>
constexpr bool is_callable_v = is_callable<_Function>::value;
template<typename _Ty, class = std::void_t<>>
struct is_callable : std::false_type{};
template<typename _Ty>
struct is_callable<_Ty, std::void_t<decltype(std::declval<_Ty>()())>> : std::true_type {};
template<typename _Ty>
constexpr bool is_callable_v = is_callable<_Ty>::value;

template<class _Ty, class = std::void_t<>>
struct is_iterator : std::false_type {};
template<class _Ty>
struct is_iterator
<_Ty,
std::void_t<
decltype(++std::declval<_Ty>())
, decltype(std::declval<_Ty>() != std::declval<_Ty>())
, decltype(*std::declval<_Ty>())
>
>
: std::true_type{};
template<class _Ty>
struct is_iterator<_Ty&> : is_iterator<_Ty> {};
template<class _Ty>
struct is_iterator<_Ty&&> : is_iterator<_Ty> {};
template<class _Ty>
struct is_iterator<const _Ty> : is_iterator<_Ty> {};
template<class _Ty>
struct is_iterator<const _Ty&> : is_iterator<_Ty> {};

template<class _Ty>
constexpr bool is_iterator_v = is_iterator<remove_cvref_t<_Ty>>::value;
}
}

+ 26
- 30
librf/src/when_v2.h View File

@@ -107,7 +107,7 @@ RESUMEF_NS
template<class _Ty>
struct awaitor_result_impl<_Ty, true> : awaitor_result_impl<decltype(std::declval<_Ty>()()), false> {};
template<class _Ty>
using awaitor_result_t = typename awaitor_result_impl<_Ty>::value_type;
using awaitor_result_t = typename awaitor_result_impl<std::remove_reference_t<_Ty>>::value_type;


template<class _Ty>
@@ -222,11 +222,11 @@ RESUMEF_NS

inline namespace when_v2
{
template<class... _Awaitable,
class = std::enable_if_t<std::conjunction_v<detail::is_when_task<_Awaitable>...>>
template<_WhenTaskT... _Awaitable
COMMA_RESUMEF_ENABLE_IF(std::conjunction_v<detail::is_when_task<_Awaitable>...>)
>
auto when_all(scheduler_t& sch, _Awaitable&&... args)
-> detail::when_future_t<std::tuple<detail::awaitor_result_t<_Awaitable>...> >
decltype(auto) when_all(scheduler_t& sch, _Awaitable&&... args)
// -> detail::when_future_t<std::tuple<detail::awaitor_result_t<_Awaitable>...> >
{
using tuple_type = std::tuple<detail::awaitor_result_t<_Awaitable>...>;

@@ -236,14 +236,13 @@ inline namespace when_v2
return awaitor;
}

template<class _Iter,
class _Awaitable = decltype(*std::declval<_Iter>()),
class = std::enable_if_t<detail::is_when_task_v<_Awaitable>>
template<_WhenIterT _Iter
COMMA_RESUMEF_ENABLE_IF(traits::is_iterator_v<_Iter> && detail::is_when_task_v<decltype(*std::declval<_Iter>())>)
>
auto when_all(scheduler_t& sch, _Iter begin, _Iter end)
-> detail::when_future_t<std::vector<detail::awaitor_result_t<_Awaitable> > >
auto when_all(scheduler_t& sch, _Iter begin, _Iter end)
// -> detail::when_future_t<std::vector<detail::awaitor_result_t<decltype(*std::declval<_Iter>())> > >
{
using value_type = detail::awaitor_result_t<_Awaitable>;
using value_type = detail::awaitor_result_t<decltype(*std::declval<_Iter>())>;
using vector_type = std::vector<value_type>;

detail::when_future_t<vector_type> awaitor{ std::distance(begin, end) };
@@ -253,8 +252,8 @@ inline namespace when_v2
return awaitor;
}

template<class... _Awaitable,
class = std::enable_if_t<std::conjunction_v<detail::is_when_task<_Awaitable>...>>
template<_WhenTaskT... _Awaitable
COMMA_RESUMEF_ENABLE_IF(std::conjunction_v<detail::is_when_task<_Awaitable>...>)
>
auto when_all(_Awaitable&&... awaitor)
-> future_t<std::tuple<detail::awaitor_result_t<_Awaitable>...>>
@@ -262,12 +261,11 @@ inline namespace when_v2
co_return co_await when_all(*current_scheduler(), std::forward<_Awaitable>(awaitor)...);
}

template<class _Iter,
class _Awaitable = decltype(*std::declval<_Iter>()),
class = std::enable_if_t<detail::is_when_task_v<_Awaitable>>
template<_WhenIterT _Iter
COMMA_RESUMEF_ENABLE_IF(traits::is_iterator_v<_Iter> && detail::is_when_task_v<decltype(*std::declval<_Iter>())>)
>
auto when_all(_Iter begin, _Iter end)
-> future_t<std::vector<detail::awaitor_result_t<_Awaitable>>>
auto when_all(_Iter begin, _Iter end)
-> future_t<std::vector<detail::awaitor_result_t<decltype(*std::declval<_Iter>())>>>
{
co_return co_await when_all(*current_scheduler(), begin, end);
}
@@ -277,11 +275,11 @@ inline namespace when_v2



template<class... _Awaitable,
class = std::enable_if_t<std::conjunction_v<detail::is_when_task<_Awaitable>...>>
template<_WhenTaskT... _Awaitable
COMMA_RESUMEF_ENABLE_IF(std::conjunction_v<detail::is_when_task<_Awaitable>...>)
>
auto when_any(scheduler_t& sch, _Awaitable&&... args)
-> detail::when_future_t<detail::when_any_pair>
// -> detail::when_future_t<detail::when_any_pair>
{
detail::when_future_t<detail::when_any_pair> awaitor{ sizeof...(_Awaitable) > 0 ? 1 : 0 };
awaitor._values->first = -1;
@@ -290,11 +288,10 @@ inline namespace when_v2
return awaitor;
}

template<class _Iter,
typename _Awaitable = decltype(*std::declval<_Iter>()),
class = std::enable_if_t<detail::is_when_task_v<_Awaitable>>
template<_WhenIterT _Iter
COMMA_RESUMEF_ENABLE_IF(traits::is_iterator_v<_Iter> && detail::is_when_task_v<decltype(*std::declval<_Iter>())>)
>
auto when_any(scheduler_t& sch, _Iter begin, _Iter end)
auto when_any(scheduler_t& sch, _Iter begin, _Iter end)
-> detail::when_future_t<detail::when_any_pair>
{
detail::when_future_t<detail::when_any_pair> awaitor{ begin == end ? 0 : 1 };
@@ -304,8 +301,8 @@ inline namespace when_v2
return awaitor;
}

template<class... _Awaitable,
class = std::enable_if_t<std::conjunction_v<detail::is_when_task<_Awaitable>...>>
template<_WhenTaskT... _Awaitable
COMMA_RESUMEF_ENABLE_IF(std::conjunction_v<detail::is_when_task<_Awaitable>...>)
>
auto when_any(_Awaitable&&... awaitor)
-> future_t<detail::when_any_pair>
@@ -313,9 +310,8 @@ inline namespace when_v2
co_return co_await when_any(*current_scheduler(), std::forward<_Awaitable>(awaitor)...);
}

template<class _Iter,
typename _Awaitable = decltype(*std::declval<_Iter>()),
class = std::enable_if_t<detail::is_when_task_v<_Awaitable>>
template<_WhenIterT _Iter
COMMA_RESUMEF_ENABLE_IF(traits::is_iterator_v<_Iter> && detail::is_when_task_v<decltype(*std::declval<_Iter>())>)
>
auto when_any(_Iter begin, _Iter end)
-> future_t<detail::when_any_pair>

+ 1
- 1
vs_proj/librf.cpp View File

@@ -44,7 +44,7 @@ int main(int argc, const char* argv[])
//test_ring_queue<resumef::ring_queue_lockfree<int, uint64_t>>();
//resumable_main_switch_scheduler();
//resumable_main_when_all();
resumable_main_when_all();
//resumable_main_event_v2();
//return 0;

+ 3
- 2
vs_proj/librf.vcxproj View File

@@ -40,13 +40,13 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>ClangCL</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>ClangCL</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
@@ -262,6 +262,7 @@
<None Include="..\librf\src\macro_def.inl" />
<None Include="..\librf\src\promise.inl" />
<None Include="..\librf\src\state.inl" />
<None Include="..\librf\src\type_concept.inl" />
<None Include="..\librf\src\type_traits.inl" />
<None Include="..\README.md" />
</ItemGroup>

+ 3
- 0
vs_proj/librf.vcxproj.filters View File

@@ -258,5 +258,8 @@
<None Include="..\librf\src\event_v2.inl">
<Filter>librf\src</Filter>
</None>
<None Include="..\librf\src\type_concept.inl">
<Filter>librf\src</Filter>
</None>
</ItemGroup>
</Project>

Loading…
Cancel
Save