This commit is contained in:
2026-06-30 12:10:27 +03:00
parent 6389be046b
commit 573e58edb6
4 changed files with 148 additions and 5 deletions

View File

@@ -15,11 +15,20 @@ namespace details
template <typename OT, typename TT, size_t... Is>
concept snplib_all_func_oper_c = requires(OT obj) { (obj(std::declval<std::tuple_element_t<Is, TT>&>()), ...); };
template <typename OT, typename TT, size_t... Is>
concept snplib_all_func_oper_range_c =
requires(OT obj) { (obj(std::declval<std::vector<std::tuple_element_t<Is, TT>>&>()), ...); };
template <typename OT, typename TT>
struct snplib_check_all_func_oper_t {
static constexpr bool value = false;
};
template <typename OT, typename TT>
struct snplib_check_all_func_oper_range_t {
static constexpr bool value = false;
};
template <typename OT, typename TT>
requires requires { typename std::tuple_size<TT>::type; }
struct snplib_check_all_func_oper_t<OT, TT> {
@@ -28,10 +37,21 @@ struct snplib_check_all_func_oper_t<OT, TT> {
}(std::make_index_sequence<std::tuple_size<TT>::value>{});
};
template <typename OT, typename TT>
requires requires { typename std::tuple_size<TT>::type; }
struct snplib_check_all_func_oper_range_t<OT, TT> {
static constexpr bool value = []<std::size_t... Is>(std::index_sequence<Is...>) {
return snplib_all_func_oper_range_c<OT, TT, Is...>;
}(std::make_index_sequence<std::tuple_size<TT>::value>{});
};
template <typename OT, typename TT>
static constexpr bool snplib_check_all_func_oper_v = snplib_check_all_func_oper_t<OT, TT>::value;
template <typename OT, typename TT>
static constexpr bool snplib_check_all_func_oper_range_v = snplib_check_all_func_oper_range_t<OT, TT>::value;
} // namespace details
@@ -42,6 +62,13 @@ concept snplib_hvec_visitor_c = requires {
requires details::snplib_check_all_func_oper_v<T, typename T::types>;
};
template <typename T>
concept snplib_hvec_range_visitor_c = requires {
requires snplib_tuple_c<typename T::types>;
requires details::snplib_check_all_func_oper_range_v<T, typename T::types>;
};
class HeterogenVec
{
@@ -128,7 +155,7 @@ public:
}
});
_copyFunc.emplace_back([](HeterogenVec* from, HeterogenVec* to) {
_copyFunc.emplace_back([](const HeterogenVec* from, HeterogenVec* to) {
if (_values<v_t>.contains(from)) {
_values<v_t>[to] = _values<v_t>[from];
}
@@ -139,16 +166,33 @@ public:
_values<v_t>[this].push_back(std::forward<VT>(value));
}
template <typename VT, typename... CtorArgTs>
void emplace(CtorArgTs&&... args)
{
push(VT(std::forward<CtorArgTs>(args)...));
}
// per element visiting
template <snplib_hvec_visitor_c VT>
void visit(VT&& visitor)
{
auto invoke_per_type = [&visitor, this]<typename T>() {
auto invoke_per_elem = [&visitor, this]<typename T>() {
for (auto& elem : _values<T>[this]) {
visitor(elem);
}
};
[&invoke_per_elem]<size_t... Is>(std::index_sequence<Is...>) {
(invoke_per_elem.template operator()<std::tuple_element_t<Is, typename VT::types>>(), ...);
}(std::make_index_sequence<std::tuple_size_v<typename VT::types>>{});
}
// per range of type visiting
template <snplib_hvec_visitor_c VT>
void visitRange(VT&& visitor)
{
auto invoke_per_type = [&visitor, this]<typename T>() { visitor(_values<T>[this]); };
[&invoke_per_type]<size_t... Is>(std::index_sequence<Is...>) {
(invoke_per_type.template operator()<std::tuple_element_t<Is, typename VT::types>>(), ...);
}(std::make_index_sequence<std::tuple_size_v<typename VT::types>>{});

View File

@@ -1,6 +1,8 @@
#pragma once
#include <set>
#include "../concepts/snplib_concepts.h"
#include "../containers/snplib_hvec.h"
namespace snplib
{
@@ -44,9 +46,9 @@ concept snplib_net_session_c = std::derived_from<T, std::enable_shared_from_this
snplib_net_connection_c<typename T::connection_t>;
{ t.start(std::declval<typename T::connection_t>()) } -> snplib_async_retval_c;
{ t.startSession(std::declval<typename T::connection_t>()) } -> snplib_async_retval_c;
t.stop();
t.stopSession();
};
@@ -84,7 +86,7 @@ protected:
};
template <typename T>
concept snplib_netserver_c = requires(T t) {
concept snplib_netserver_c = std::derived_from<T, snplib_netserver_iface_t> && requires(T t) {
// static constexpr member
std::formattable<decltype(T::id), char>;
[]() { [[maybe_unused]] static constexpr auto val = T::id; }();
@@ -97,4 +99,50 @@ concept snplib_netserver_c = requires(T t) {
{ t.disconnectClients() } -> snplib_error_c;
};
/* SINGLE-PROTO*/
template <snplib_net_listener_c ListenerT>
class snplib_generic_netserver_t
{
public:
typedef std::error_code error_t;
using session_t = typename ListenerT::session_t;
snplib_generic_netserver_t(std::unique_ptr<ListenerT> listener) : _listener(std::move(listener)) {}
error_t start()
{
auto err = _listener->start();
if (err) {
return snplib_deduced_error(err, std::make_error_code(std::errc::io_error));
}
startListen();
}
error_t stop()
{
_listener->stop();
return {};
}
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);
}
}
};
} // namespace snplib