...
This commit is contained in:
@@ -32,6 +32,10 @@ if(BUILD_EXAMPLES)
|
|||||||
set(EXAM_HMAP hmap_example)
|
set(EXAM_HMAP hmap_example)
|
||||||
add_executable(${EXAM_HMAP} examples/hmap_example.cpp)
|
add_executable(${EXAM_HMAP} examples/hmap_example.cpp)
|
||||||
target_link_libraries(${EXAM_HMAP} ${PROJECT_NAME})
|
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()
|
endif()
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|||||||
47
examples/hvec_example.cpp
Normal file
47
examples/hvec_example.cpp
Normal 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;
|
||||||
|
}
|
||||||
@@ -15,11 +15,20 @@ namespace details
|
|||||||
template <typename OT, typename TT, size_t... Is>
|
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>&>()), ...); };
|
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>
|
template <typename OT, typename TT>
|
||||||
struct snplib_check_all_func_oper_t {
|
struct snplib_check_all_func_oper_t {
|
||||||
static constexpr bool value = false;
|
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>
|
template <typename OT, typename TT>
|
||||||
requires requires { typename std::tuple_size<TT>::type; }
|
requires requires { typename std::tuple_size<TT>::type; }
|
||||||
struct snplib_check_all_func_oper_t<OT, TT> {
|
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>{});
|
}(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>
|
template <typename OT, typename TT>
|
||||||
static constexpr bool snplib_check_all_func_oper_v = snplib_check_all_func_oper_t<OT, TT>::value;
|
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
|
} // namespace details
|
||||||
|
|
||||||
|
|
||||||
@@ -42,6 +62,13 @@ concept snplib_hvec_visitor_c = requires {
|
|||||||
requires details::snplib_check_all_func_oper_v<T, typename T::types>;
|
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
|
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)) {
|
if (_values<v_t>.contains(from)) {
|
||||||
_values<v_t>[to] = _values<v_t>[from];
|
_values<v_t>[to] = _values<v_t>[from];
|
||||||
}
|
}
|
||||||
@@ -139,16 +166,33 @@ public:
|
|||||||
_values<v_t>[this].push_back(std::forward<VT>(value));
|
_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>
|
template <snplib_hvec_visitor_c VT>
|
||||||
void visit(VT&& visitor)
|
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]) {
|
for (auto& elem : _values<T>[this]) {
|
||||||
visitor(elem);
|
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]<size_t... Is>(std::index_sequence<Is...>) {
|
||||||
(invoke_per_type.template operator()<std::tuple_element_t<Is, typename VT::types>>(), ...);
|
(invoke_per_type.template operator()<std::tuple_element_t<Is, typename VT::types>>(), ...);
|
||||||
}(std::make_index_sequence<std::tuple_size_v<typename VT::types>>{});
|
}(std::make_index_sequence<std::tuple_size_v<typename VT::types>>{});
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <set>
|
||||||
#include "../concepts/snplib_concepts.h"
|
#include "../concepts/snplib_concepts.h"
|
||||||
|
#include "../containers/snplib_hvec.h"
|
||||||
|
|
||||||
namespace snplib
|
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>;
|
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>
|
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
|
// static constexpr member
|
||||||
std::formattable<decltype(T::id), char>;
|
std::formattable<decltype(T::id), char>;
|
||||||
[]() { [[maybe_unused]] static constexpr auto val = T::id; }();
|
[]() { [[maybe_unused]] static constexpr auto val = T::id; }();
|
||||||
@@ -97,4 +99,50 @@ concept snplib_netserver_c = requires(T t) {
|
|||||||
|
|
||||||
{ t.disconnectClients() } -> snplib_error_c;
|
{ 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
|
} // namespace snplib
|
||||||
Reference in New Issue
Block a user