Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion include/trompeloeil/coro.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,18 @@
#ifndef TROMPELOEIL_CORO_HPP
#define TROMPELOEIL_CORO_HPP

#if __cplusplus < 202002L
# error "C++20 is required"
#endif

#if defined(__cpp_impl_coroutine)
# define TROMPELOEIL_COROUTINES_SUPPORTED 1
#else
# error "Coroutines are not supported by this compiler"
#endif

#ifdef TROMPELOEIL_COROUTINES_SUPPORTED
#include <ranges>

#ifndef TROMPELOEIL_MOCK_HPP_
#include "mock.hpp"
Expand All @@ -45,14 +50,22 @@ namespace trompeloeil
{
static auto func()
{
if constexpr (requires {std::declval<T>().operator co_await();})
if constexpr (requires(T coro){ coro.operator co_await(); })
{
return type_wrapper<decltype(std::declval<T>().operator co_await().await_resume())>{};
}
else
if constexpr (requires(T coro){ coro.await_resume(); })
{
return type_wrapper<decltype(std::declval<T>().await_resume())>{};
}
else
{
static_assert(
std::ranges::input_range<T>,
"non-awaitable coroutine shall be a range");
return type_wrapper<std::ranges::range_value_t<T>>{};
}
}
using type = typename decltype(func())::type;
};
Expand Down
51 changes: 51 additions & 0 deletions test/test_co_mock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
#include "test_reporter.hpp"
#include <optional>

#include <version>
#ifdef __cpp_lib_generator
#include <generator>
#endif

using trompeloeil::_;

namespace {
Expand All @@ -35,6 +40,10 @@ namespace {
MAKE_MOCK0 (voidret, coro::task<void>());
MAKE_MOCK1 (unique, coro::task<iptr>(iptr));
MAKE_MOCK0 (gen, coro::generator<int>());

#ifdef __cpp_lib_generator
MAKE_MOCK0 (stdgen, std::generator<int>());
#endif // __cpp_lib_generator
};
}

Expand Down Expand Up @@ -198,4 +207,46 @@ TEST_CASE_METHOD(
REQUIRE(v == 3);
REQUIRE(reports.empty());
}

#ifdef __cpp_lib_generator
TEST_CASE_METHOD(
Fixture,
"CO_YIELD with std::generator",
"[coro]")
{
co_mock m;
REQUIRE_CALL(m, stdgen())
.CO_YIELD(5)
.CO_YIELD(8)
.CO_YIELD(3)
.CO_YIELD(0)
.CO_RETURN();

auto gen = m.stdgen();

SECTION("as iterator")
{
auto it = std::ranges::begin(gen);
REQUIRE(*it == 5);
++it;
REQUIRE(it != std::ranges::end(gen));
REQUIRE(*it == 8);
++it;
REQUIRE(it != std::ranges::end(gen));
REQUIRE(*it == 3);
++it;
REQUIRE(it != std::ranges::end(gen));
REQUIRE(*it == 0);
++it;
REQUIRE(it == std::ranges::end(gen));
}

SECTION("as range")
{
REQUIRE(std::ranges::equal(gen, std::array{5, 8, 3, 0}));
}

REQUIRE(reports.empty());
}
#endif // __cpp_lib_generator
#endif
Loading