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

@@ -32,6 +32,10 @@ if(BUILD_EXAMPLES)
set(EXAM_HMAP hmap_example)
add_executable(${EXAM_HMAP} examples/hmap_example.cpp)
target_link_libraries(${EXAM_HMAP} ${PROJECT_NAME})
set(EXAM_HVEC hvec_example)
add_executable(${EXAM_HVEC} examples/hvec_example.cpp)
target_link_libraries(${EXAM_HVEC} ${PROJECT_NAME})
endif()
include(GNUInstallDirs)

47
examples/hvec_example.cpp Normal file
View File

@@ -0,0 +1,47 @@
#include <print>
#include <vector>
#include <snipplib/containers/snplib_hvec.h>
using namespace snplib;
struct visitor {
using types = std::tuple<std::string, unsigned long>;
void operator()(auto& v)
{
using val_t = std::decay_t<decltype(v)>;
if constexpr (std::ranges::input_range<val_t>) {
std::println("range val = {}", v);
} else {
std::println("val = {}", v);
}
}
};
int main()
{
HeterogenVec vec;
vec.push(1.1);
vec.push(std::string{"AAA"});
vec.push(100UL);
vec.push(200UL);
vec.push(300UL);
std::vector<char> v{'q', 'w', 'e'};
vec.emplace<std::string>(std::from_range_t{}, v);
vec.visit(visitor{});
vec.visitRange(visitor{});
vec.clear();
std::println("\n\tafter clear() ...");
vec.visit(visitor{});
return 0;
}

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