This commit is contained in:
2026-07-01 18:26:09 +03:00
parent 3ae77a4e2c
commit a7bbc6ff8c

View File

@@ -2,7 +2,6 @@
#include <set>
#include "../concepts/snplib_concepts.h"
#include "../containers/snplib_hvec.h"
namespace snplib
{
@@ -23,6 +22,21 @@ concept snplib_net_endpoint_c = requires(T t, const T t_const) {
};
template <typename T>
concept snplib_net_message_c = requires(T t) {
{ t.toBytes() } -> snplib_output_char_range_c;
// can be constructed from contiguous byte range
requires(
requires {
{ T::fromBytes(std::declval<std::span<const char>>()) } -> std::same_as<T>;
} ||
requires {
{ T::fromBytes(std::declval<std::span<char>>()) } -> std::same_as<T>;
});
};
template <typename T>
concept snplib_net_connection_c = requires(T t) {
// static constexpr member
@@ -46,7 +60,8 @@ concept snplib_net_session_c = std::derived_from<T, std::enable_shared_from_this
snplib_net_connection_c<typename T::connection_t>;
{ t.startSession(std::declval<typename T::connection_t>()) } -> snplib_async_retval_c;
// { t.startSession(std::declval<typename T::connection_t>()) } -> snplib_async_retval_c;
t.startSession(std::declval<typename T::connection_t>());
t.stopSession();
};
@@ -58,73 +73,67 @@ concept snplib_net_listener_c = requires(T t) {
std::formattable<decltype(T::id), char>;
[]() { [[maybe_unused]] static constexpr auto val = T::id; }();
snplib_net_session_c<typename T::session_t>;
snplib_net_connection_c<typename T::connection_t>;
{ t.accept() } -> snplib_async_retval_c<typename T::session_t>;
{ t.accept() } -> snplib_async_retval_c<typename T::connection_t>;
// { t.accept() } -> snplib_expected_c; // must return std::expected<snplib_net_session_c, snplib_error_c>
{ t.startListen() } -> snplib_error_c;
// snplib_net_session_c<typename std::invoke_result_t<decltype(t.accept)>::value_type>;
{ t.start() } -> snplib_error_c;
t.stop();
t.stopListen();
};
struct snplib_netserver_iface_t {
virtual ~snplib_netserver_iface_t() = default;
template <std::derived_from<snplib_netserver_iface_t> SelfT, snplib_net_listener_c LT>
auto start(this SelfT&& self, LT&& listener)
{
return std::forward<SelfT>(self).start(std::forward<LT>(listener));
}
protected:
snplib_netserver_iface_t() = default;
};
template <typename T>
concept snplib_netserver_c = std::derived_from<T, snplib_netserver_iface_t> && requires(T t) {
concept snplib_netserver_c = requires(T t) {
// static constexpr member
std::formattable<decltype(T::id), char>;
[]() { [[maybe_unused]] static constexpr auto val = T::id; }();
// start/stop all listeners
{ t.start() } -> snplib_error_c;
t.startServer();
{ t.stop() } -> snplib_error_c;
t.stopServer();
{ t.disconnectClients() } -> snplib_error_c;
t.disconnectClients();
// { t.startServer() } -> snplib_error_c;
// { t.stopServer() } -> snplib_error_c;
// { t.disconnectClients() } -> snplib_error_c;
};
/* SINGLE-PROTO*/
template <snplib_net_listener_c ListenerT>
template <snplib_net_listener_c ListenerT, snplib_net_session_c SessionT>
requires std::same_as<typename ListenerT::connection_t, typename SessionT::connection_t>
class snplib_generic_netserver_t
{
public:
typedef std::error_code error_t;
using session_t = typename ListenerT::session_t;
// typedef std::error_code error_t;
snplib_generic_netserver_t(std::unique_ptr<ListenerT> listener) : _listener(std::move(listener)) {}
error_t start()
auto startServer()
{
auto err = _listener->start();
if (err) {
return snplib_deduced_error(err, std::make_error_code(std::errc::io_error));
co_return std::unexpect(snplib_deduced_error(err, std::make_error_code(std::errc::io_error)));
}
startListen();
while (true) {
auto connection = co_await _listener->accept();
if (connection) {
auto sptr = std::make_shared<SessionT>();
_sessions.insert(sptr);
sptr->start(std::move(connection.value()));
}
}
}
error_t stop()
error_t stopServer()
{
_listener->stop();
@@ -133,15 +142,7 @@ public:
protected:
std::unique_ptr<ListenerT> _listener{};
std::set<std::weak_ptr<session_t>> _sessions{};
void startListen()
{
auto sess = co_await _listener->accept();
if (sess) {
_sessions.insert(sess);
}
}
std::set<std::weak_ptr<SessionT>> _sessions{};
};