diff --git a/CMakeLists.txt b/CMakeLists.txt index d5418ea..c3e250f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/examples/hvec_example.cpp b/examples/hvec_example.cpp new file mode 100644 index 0000000..4ed1d59 --- /dev/null +++ b/examples/hvec_example.cpp @@ -0,0 +1,47 @@ +#include +#include + +#include + +using namespace snplib; + +struct visitor { + using types = std::tuple; + + void operator()(auto& v) + { + using val_t = std::decay_t; + + if constexpr (std::ranges::input_range) { + 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 v{'q', 'w', 'e'}; + + vec.emplace(std::from_range_t{}, v); + + vec.visit(visitor{}); + vec.visitRange(visitor{}); + + vec.clear(); + + std::println("\n\tafter clear() ..."); + vec.visit(visitor{}); + + return 0; +} diff --git a/include/snipplib/containers/snplib_hvec.h b/include/snipplib/containers/snplib_hvec.h index 8211559..7c63704 100644 --- a/include/snipplib/containers/snplib_hvec.h +++ b/include/snipplib/containers/snplib_hvec.h @@ -15,11 +15,20 @@ namespace details template concept snplib_all_func_oper_c = requires(OT obj) { (obj(std::declval&>()), ...); }; +template +concept snplib_all_func_oper_range_c = + requires(OT obj) { (obj(std::declval>&>()), ...); }; + template struct snplib_check_all_func_oper_t { static constexpr bool value = false; }; +template +struct snplib_check_all_func_oper_range_t { + static constexpr bool value = false; +}; + template requires requires { typename std::tuple_size::type; } struct snplib_check_all_func_oper_t { @@ -28,10 +37,21 @@ struct snplib_check_all_func_oper_t { }(std::make_index_sequence::value>{}); }; +template + requires requires { typename std::tuple_size::type; } +struct snplib_check_all_func_oper_range_t { + static constexpr bool value = [](std::index_sequence) { + return snplib_all_func_oper_range_c; + }(std::make_index_sequence::value>{}); +}; + template static constexpr bool snplib_check_all_func_oper_v = snplib_check_all_func_oper_t::value; +template +static constexpr bool snplib_check_all_func_oper_range_v = snplib_check_all_func_oper_range_t::value; + } // namespace details @@ -42,6 +62,13 @@ concept snplib_hvec_visitor_c = requires { requires details::snplib_check_all_func_oper_v; }; +template +concept snplib_hvec_range_visitor_c = requires { + requires snplib_tuple_c; + + requires details::snplib_check_all_func_oper_range_v; +}; + class HeterogenVec { @@ -128,7 +155,7 @@ public: } }); - _copyFunc.emplace_back([](HeterogenVec* from, HeterogenVec* to) { + _copyFunc.emplace_back([](const HeterogenVec* from, HeterogenVec* to) { if (_values.contains(from)) { _values[to] = _values[from]; } @@ -139,16 +166,33 @@ public: _values[this].push_back(std::forward(value)); } + template + void emplace(CtorArgTs&&... args) + { + push(VT(std::forward(args)...)); + } + // per element visiting template void visit(VT&& visitor) { - auto invoke_per_type = [&visitor, this]() { + auto invoke_per_elem = [&visitor, this]() { for (auto& elem : _values[this]) { visitor(elem); } }; + [&invoke_per_elem](std::index_sequence) { + (invoke_per_elem.template operator()>(), ...); + }(std::make_index_sequence>{}); + } + + // per range of type visiting + template + void visitRange(VT&& visitor) + { + auto invoke_per_type = [&visitor, this]() { visitor(_values[this]); }; + [&invoke_per_type](std::index_sequence) { (invoke_per_type.template operator()>(), ...); }(std::make_index_sequence>{}); diff --git a/include/snipplib/network/snplib_network.h b/include/snipplib/network/snplib_network.h index ee7964f..00cbc25 100644 --- a/include/snipplib/network/snplib_network.h +++ b/include/snipplib/network/snplib_network.h @@ -1,6 +1,8 @@ #pragma once +#include #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.start(std::declval()) } -> snplib_async_retval_c; + { t.startSession(std::declval()) } -> snplib_async_retval_c; - t.stop(); + t.stopSession(); }; @@ -84,7 +86,7 @@ protected: }; template -concept snplib_netserver_c = requires(T t) { +concept snplib_netserver_c = std::derived_from && requires(T t) { // static constexpr member std::formattable; []() { [[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 +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 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 _listener{}; + std::set> _sessions{}; + + void startListen() + { + auto sess = co_await _listener->accept(); + if (sess) { + _sessions.insert(sess); + } + } +}; + + } // namespace snplib \ No newline at end of file