Skip to content

Commit

Permalink
added an into_expected algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
dietmarkuehl committed Sep 15, 2024
1 parent 1a863e9 commit 7fa2d61
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 17 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ FetchContent_Declare(
execution26
# for local development, use SOURCE_DIR <path-to>/execution26
GIT_REPOSITORY https://github.com/beman-project/execution26
GIT_TAG 5ad85cb
GIT_TAG 22affb6
)
FetchContent_MakeAvailable(execution26)

Expand Down
2 changes: 1 addition & 1 deletion examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ set(LIBRARIES
include(GNUInstallDirs)

set(EXAMPLES
http-server
empty
server
http-server
client
task
)
Expand Down
54 changes: 54 additions & 0 deletions examples/demo_algorithm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
#include <type_traits>
#include <utility>
#include <variant>
#include <version>
#if 202202L <= __cpp_lib_expected
# include<expected>
#endif

#include <iostream> //-dk:TODO remove

// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -70,6 +75,13 @@ namespace demo::detail
template <typename T>
using decayed_set_value_t = typename decayed_set_value<T>::type;

template <typename... T>
struct decayed_tuple_or_single { using type = ::std::tuple<::std::decay_t<T>...>; };
template <typename T>
struct decayed_tuple_or_single<T> { using type = ::std::decay_t<T>; };
template <typename... T>
using decayed_tuple_or_single_t = typename decayed_tuple_or_single<T...>::type;

template <typename> struct make_type_list;
template <template <typename> class L, typename... T>
struct make_type_list<L<T...>>
Expand Down Expand Up @@ -99,6 +111,16 @@ namespace demo
};
inline constexpr into_error_t into_error{};

#if 202202L <= __cpp_lib_expected
struct into_expected_t
{
auto operator()() const;
template <ex::sender Sender>
auto operator()(Sender&&) const;
};
inline constexpr into_expected_t into_expected{};
#endif

struct when_any_t
{
template <typename> struct env;
Expand Down Expand Up @@ -190,6 +212,38 @@ inline auto demo::into_error_t::operator()(Fun&& fun) const

// ----------------------------------------------------------------------------

#if 202202L <= __cpp_lib_expected
inline auto demo::into_expected_t::operator()() const
{
return beman::net29::detail::ex::detail::sender_adaptor{*this};
}
template <beman::net29::detail::ex::sender Sender>
inline auto demo::into_expected_t::operator()(Sender&& s) const
{
using value_type = ex::value_types_of_t<
Sender,
ex::empty_env,
demo::detail::decayed_tuple_or_single_t,
std::type_identity_t
>;
using error_type = ex::error_types_of_t<Sender>;
return ::std::forward<Sender>(s)
| beman::net29::detail::ex::then([]<typename... A>(A&&... a)noexcept{
return std::expected<value_type, error_type>(
::std::in_place_t{}, ::std::forward<A>(a)...
);
})
| beman::net29::detail::ex::upon_error([]<typename E>(E&& e)noexcept{
return std::expected<value_type, error_type>(
::std::unexpect_t{}, ::std::forward<E>(e)
);
})
;
}
#endif

// ----------------------------------------------------------------------------

template <typename Receiver>
struct demo::when_any_t::state_base
{
Expand Down
28 changes: 13 additions & 15 deletions examples/http-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "demo_scope.hpp"
#include "demo_task.hpp"
#include <iostream>
#include <expected>
#include <string>
#include <fstream>
#include <sstream>
Expand Down Expand Up @@ -53,28 +54,25 @@ auto timeout(auto scheduler, auto duration, auto sender)
return demo::when_any(
std::move(sender),
net::resume_after(scheduler, duration)
| demo::into_error([]{ return std::error_code(); })
);
| demo::into_error([]{ return std::error_code(); })
)
;
}

auto make_client(auto scheduler, auto stream) -> demo::task<>
{
char buffer[16];
std::string request;
try{
while (auto n = co_await timeout(scheduler, 3s, net::async_receive(stream, net::buffer(buffer))))
{
std::string_view sv(buffer, n);
request += sv;
if (request.npos != sv.find("\r\n\r\n")) {
co_await process_request(stream, std::move(request));
break;
}
}
}
catch (...)
while (auto n = co_await
(timeout(scheduler, 2s, net::async_receive(stream, net::buffer(buffer)))
| demo::into_expected()))
{
std::cout << "ex: timeout\n";
std::string_view sv(buffer, n.value());
request += sv;
if (request.npos != sv.find("\r\n\r\n")) {
co_await process_request(stream, std::move(request));
break;
}
}
std::cout << "client done\n";
}
Expand Down

0 comments on commit 7fa2d61

Please sign in to comment.