Commit e6f6dab9 authored by Dominik Charousset's avatar Dominik Charousset

Merge branch 'topic/neverlord/expected'

parents d9aca2e1 747abb49
......@@ -24,6 +24,8 @@ is based on [Keep a Changelog](https://keepachangelog.com).
- Not initializing the meta objects table now prints a diagnosis message before
aborting the program. Previously, the application would usually just crash due
to a `nullptr`-access inside some CAF function.
- The class `expected` now implements the monadic member functions from C++23
`std::expected` as well as `value_or`.
### Fixed
......@@ -46,6 +48,14 @@ is based on [Keep a Changelog](https://keepachangelog.com).
actors or activities, scheduled actors now limit the amount of actions that
may run in one iteration (#1364).
### Deprecated
- All member functions from `caf::expected` that have no equivalent in
`std::expected` are now deprecated. Further, `caf::expected<unit_t>` as well
as constructing from `unit_t` are deprecated as well. The reasoning behind
this decision is that `caf::expected` should eventually become an alias for
`std::expected<T, caf::error>`.
## [0.19.0-rc.1] - 2022-10-31
### Added
......
......@@ -46,9 +46,10 @@ void caf_main(actor_system& system) {
auto cell2 = system.spawn(unchecked_cell);
// --(rst-spawn-cell-end)--
auto f = make_function_view(cell1);
cout << "cell value: " << f(get_atom_v) << endl;
cout << "cell value: " << caf::to_string(f(get_atom_v)) << endl;
f(put_atom_v, 20);
cout << "cell value (after setting to 20): " << f(get_atom_v) << endl;
cout << "cell value (after setting to 20): " << caf::to_string(f(get_atom_v))
<< endl;
// Get an unchecked cell and send it some garbage. Triggers an "unexpected
// message" error (and terminates cell2!).
anon_send(cell2, "hello there!");
......
......@@ -125,6 +125,7 @@ std::ostream& operator<<(std::ostream& out, const expected<int>& x) {
}
void caf_main(actor_system& sys) {
using std::cout;
// Spawn our matrix.
static constexpr int rows = 3;
static constexpr int columns = 6;
......@@ -140,18 +141,18 @@ void caf_main(actor_system& sys) {
// Print out matrix.
for (int row = 0; row < rows; ++row) {
for (int column = 0; column < columns; ++column)
std::cout << std::setw(4) << f(get_atom_v, row, column) << ' ';
std::cout << '\n';
cout << std::setw(4) << f(get_atom_v, row, column) << ' ';
cout << '\n';
}
// Print out AVG for each row and column.
for (int row = 0; row < rows; ++row)
std::cout << "AVG(row " << row
<< ") = " << f(get_atom_v, average_atom_v, row_atom_v, row)
<< '\n';
cout << "AVG(row " << row << ") = "
<< caf::to_string(f(get_atom_v, average_atom_v, row_atom_v, row))
<< '\n';
for (int column = 0; column < columns; ++column)
std::cout << "AVG(column " << column
<< ") = " << f(get_atom_v, average_atom_v, column_atom_v, column)
<< '\n';
cout << "AVG(column " << column << ") = "
<< caf::to_string(f(get_atom_v, average_atom_v, column_atom_v, column))
<< '\n';
}
CAF_MAIN(id_block::fan_out_request)
......@@ -94,7 +94,8 @@ void client_repl(function_view<calculator> f) {
usage();
else
cout << " = "
<< (words[1] == "+" ? f(add_atom_v, *x, *y) : f(sub_atom_v, *x, *y))
<< caf::to_string(words[1] == "+" ? f(add_atom_v, *x, *y)
: f(sub_atom_v, *x, *y))
<< "\n";
}
}
......
......@@ -544,6 +544,9 @@ struct is_expected : std::false_type {};
template <class T>
struct is_expected<expected<T>> : std::true_type {};
template <class T>
constexpr bool is_expected_v = is_expected<T>::value;
// Checks whether `T` and `U` are integers of the same size and signedness.
// clang-format off
template <class T, class U,
......
This diff is collapsed.
......@@ -52,20 +52,6 @@ private:
std::tuple<Ts...>* storage_;
};
template <>
class function_view_storage<unit_t> {
public:
using type = function_view_storage;
explicit function_view_storage(unit_t&) {
// nop
}
void operator()() {
// nop
}
};
struct CAF_CORE_EXPORT function_view_storage_catch_all {
message* storage_;
......@@ -95,11 +81,6 @@ struct function_view_flattened_result<std::tuple<T>> {
using type = T;
};
template <>
struct function_view_flattened_result<std::tuple<void>> {
using type = unit_t;
};
template <class T>
using function_view_flattened_result_t =
typename function_view_flattened_result<T>::type;
......@@ -174,13 +155,24 @@ public:
if (!impl_)
return result_type{sec::bad_function_call};
error err;
function_view_result<value_type> result;
self_->request(impl_, timeout, std::forward<Ts>(xs)...)
.receive([&](error& x) { err = std::move(x); },
typename function_view_storage<value_type>::type{result.value});
if (err)
return result_type{err};
return result_type{flatten(result.value)};
if constexpr (std::is_void_v<value_type>) {
self_->request(impl_, timeout, std::forward<Ts>(xs)...)
.receive([&](error& x) { err = std::move(x); }, [] {});
if (err)
return result_type{err};
else
return result_type{};
} else {
function_view_result<value_type> result;
self_->request(impl_, timeout, std::forward<Ts>(xs)...)
.receive([&](error& x) { err = std::move(x); },
typename function_view_storage<value_type>::type{
result.value});
if (err)
return result_type{err};
else
return result_type{flatten(result.value)};
}
}
void assign(type x) {
......
This diff is collapsed.
......@@ -788,12 +788,12 @@ expected<void> read_port(native_socket fd, SockAddrType& sa) {
socket_size_type len = sizeof(SockAddrType);
CALL_CFUN(res, detail::cc_zero, "getsockname",
getsockname(fd, reinterpret_cast<sockaddr*>(&sa), &len));
return unit;
return {};
}
expected<void> set_inaddr_any(native_socket, sockaddr_in& sa) {
sa.sin_addr.s_addr = INADDR_ANY;
return unit;
return {};
}
expected<void> set_inaddr_any(native_socket fd, sockaddr_in6& sa) {
......@@ -804,7 +804,7 @@ expected<void> set_inaddr_any(native_socket fd, sockaddr_in6& sa) {
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
reinterpret_cast<setsockopt_ptr>(&off),
static_cast<socket_size_type>(sizeof(off))));
return unit;
return {};
}
template <int Family, int SockType = SOCK_STREAM>
......
......@@ -128,7 +128,7 @@ expected<void> child_process_inherit(native_socket fd, bool new_value) {
// calculate and set new flags
auto wf = (!new_value) ? (rf | FD_CLOEXEC) : (rf & (~(FD_CLOEXEC)));
CALL_CFUN(set_res, detail::cc_not_minus1, "fcntl", fcntl(fd, F_SETFD, wf));
return unit;
return {};
}
expected<void> keepalive(native_socket fd, bool new_value) {
......@@ -137,7 +137,7 @@ expected<void> keepalive(native_socket fd, bool new_value) {
CALL_CFUN(res, detail::cc_zero, "setsockopt",
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &value,
static_cast<unsigned>(sizeof(value))));
return unit;
return {};
}
expected<void> nonblocking(native_socket fd, bool new_value) {
......@@ -147,7 +147,7 @@ expected<void> nonblocking(native_socket fd, bool new_value) {
// calculate and set new flags
auto wf = new_value ? (rf | O_NONBLOCK) : (rf & (~(O_NONBLOCK)));
CALL_CFUN(set_res, detail::cc_not_minus1, "fcntl", fcntl(fd, F_SETFL, wf));
return unit;
return {};
}
expected<void> allow_sigpipe(native_socket fd, bool new_value) {
......@@ -157,12 +157,12 @@ expected<void> allow_sigpipe(native_socket fd, bool new_value) {
setsockopt(fd, SOL_SOCKET, no_sigpipe_socket_flag, &value,
static_cast<unsigned>(sizeof(value))));
}
return unit;
return {};
}
expected<void> allow_udp_connreset(native_socket, bool) {
// nop; SIO_UDP_CONNRESET only exists on Windows
return unit;
return {};
}
std::pair<native_socket, native_socket> create_pipe() {
......@@ -353,7 +353,7 @@ expected<void> send_buffer_size(native_socket fd, int new_value) {
setsockopt(fd, SOL_SOCKET, SO_SNDBUF,
reinterpret_cast<setsockopt_ptr>(&new_value),
static_cast<socket_size_type>(sizeof(int))));
return unit;
return {};
}
expected<void> tcp_nodelay(native_socket fd, bool new_value) {
......@@ -363,7 +363,7 @@ expected<void> tcp_nodelay(native_socket fd, bool new_value) {
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
reinterpret_cast<setsockopt_ptr>(&flag),
static_cast<socket_size_type>(sizeof(flag))));
return unit;
return {};
}
bool is_error(signed_size_type res, bool is_nonblock) {
......
......@@ -23,6 +23,10 @@
} \
void CAF_UNIQUE(test)::run_test_impl()
#define SUBCASE(description) \
CAF_MESSAGE(description); \
if (true)
#define GIVEN(description) \
CAF_MESSAGE("GIVEN " description); \
if (true)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment