change naming scheme (delete "snplib_" prefix)
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
int main()
|
||||
{
|
||||
auto logger = snplib::snplib_spdlog_logger_t::makeConsoleLogger("console");
|
||||
auto logger = snplib::spdlog_logger_t::makeConsoleLogger("console");
|
||||
|
||||
logger.setLoglevel(spdlog::level::err);
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ int main()
|
||||
{
|
||||
std::println("{:*^80}\n", " STOP-SEQ PROTOCOL ");
|
||||
|
||||
snplib::snplib_netproto_stopseq_t<> proto;
|
||||
snplib::netproto_stopseq_t<> proto;
|
||||
|
||||
std::string bytes{"SET VAL1 10\n"};
|
||||
std::vector bytes_vec{std::from_range, bytes};
|
||||
@@ -61,9 +61,9 @@ int main()
|
||||
|
||||
std::println("\n\n{:*^80}\n", " BINARY-BLOB PROTOCOL ");
|
||||
|
||||
snplib::snplib_netproto_binary_blob_t<> bb_proto;
|
||||
snplib::netproto_binary_blob_t<> bb_proto;
|
||||
|
||||
snplib::snplib_random_string_generator_t<> rstr_gen;
|
||||
snplib::random_string_generator_t<> rstr_gen;
|
||||
|
||||
bytes = rstr_gen.generate(15);
|
||||
bytes_vec = {std::from_range, bytes};
|
||||
|
||||
@@ -10,36 +10,36 @@ int main()
|
||||
std::string si = " dewf wek e lwekjflkj ";
|
||||
std::println("s = '{}'", si);
|
||||
|
||||
auto s = snplib_trim_spaces(si);
|
||||
auto s = trim_spaces(si);
|
||||
|
||||
std::println("s = '{}'", s);
|
||||
|
||||
auto sv = snplib_trim_spaces_as_view(si, TrimType::TRIM_LEFT);
|
||||
auto sv = trim_spaces_as_view(si, TrimType::TRIM_LEFT);
|
||||
|
||||
std::println("sv(TrimType::TRIM_LEFT) = '{}'", sv);
|
||||
|
||||
sv = snplib_trim_spaces_as_view(si, TrimType::TRIM_RIGHT);
|
||||
sv = trim_spaces_as_view(si, TrimType::TRIM_RIGHT);
|
||||
|
||||
std::println("sv(TrimType::TRIM_RIGHT) = '{}'", sv);
|
||||
|
||||
sv = snplib_trim_spaces_as_view(si, TrimType::TRIM_BOTH);
|
||||
sv = trim_spaces_as_view(si, TrimType::TRIM_BOTH);
|
||||
|
||||
std::println("sv(TrimType::TRIM_BOTH) = '{}'", sv);
|
||||
|
||||
const char cstr[] = " dwelkj 3827 dwjh 2398 ";
|
||||
std::println("C-ish string: '{}'", cstr);
|
||||
std::println("C-ish(TrimType::TRIM_BOTH) = '{}'", snplib_trim_spaces_as_view(cstr));
|
||||
std::println("C-ish(TrimType::TRIM_BOTH) = '{}'", trim_spaces_as_view(cstr));
|
||||
|
||||
std::list ll{' ', ' ', '2', ' ', 'e', '4', 's', ' ', ' '};
|
||||
std::println("std::list: {}", ll);
|
||||
std::println("std::ranges::subrange(TrimType::TRIM_BOTH) = '{}'", snplib_trim_spaces_as_view(ll));
|
||||
std::println("std::ranges::subrange(TrimType::TRIM_BOTH) = '{}'", trim_spaces_as_view(ll));
|
||||
// std::println("std::ranges::subrange(TrimType::TRIM_BOTH) = '{}'",
|
||||
// std::views::all(snplib_trim_spaces_as_view(ll)));
|
||||
|
||||
si = "123; we; d34534; ";
|
||||
|
||||
std::vector<std::string_view> rv;
|
||||
rv = snplib_split_char_range<decltype(rv)>(si, "; ");
|
||||
rv = split_char_range<decltype(rv)>(si, "; ");
|
||||
|
||||
std::println("\n\nstr = '{}'", si);
|
||||
|
||||
@@ -49,7 +49,7 @@ int main()
|
||||
}
|
||||
std::println("");
|
||||
|
||||
rv = snplib_split_char_range<decltype(rv)>(si, "; ", 1, 2);
|
||||
rv = split_char_range<decltype(rv)>(si, "; ", 1, 2);
|
||||
std::print("2 elems starting from 1: ");
|
||||
for (auto& el : rv) {
|
||||
std::print("'{}' ", el);
|
||||
@@ -61,7 +61,7 @@ int main()
|
||||
std::vector v{std::from_range, si};
|
||||
ll = {std::from_range, si};
|
||||
|
||||
snplib_keyvalue_expr_t kv{v};
|
||||
keyvalue_expr_t kv{v};
|
||||
|
||||
std::println("\n\nKV = {}", v);
|
||||
std::println("key = '{}'", kv.key());
|
||||
@@ -73,7 +73,7 @@ int main()
|
||||
kv.setKeyValue("VAL", std::make_tuple(1, std::string{"RRR"}, 10.24));
|
||||
std::println("\n\nKV = {}", v);
|
||||
|
||||
snplib_keyvalue_expr_t kvl{ll};
|
||||
keyvalue_expr_t kvl{ll};
|
||||
|
||||
std::println("\n\nKV = {}", ll);
|
||||
std::println("key = '{}'", kvl.key());
|
||||
@@ -84,8 +84,8 @@ int main()
|
||||
std::println("valueSeq = '{}'", kvl.valueSeq<std::list<std::string>>());
|
||||
|
||||
std::println("\nOwning 'key-value'");
|
||||
// snplib_keyvalue_expr_t<std::vector<char>> kv1;
|
||||
snplib_keyvalue_expr_t kv1;
|
||||
// keyvalue_expr_t<std::vector<char>> kv1;
|
||||
keyvalue_expr_t kv1;
|
||||
|
||||
kv1.setKeyValue("KEY", 7.7);
|
||||
kv1.appendValue(std::string{"dekjlwe1"});
|
||||
@@ -96,8 +96,8 @@ int main()
|
||||
std::println("valueSeq = '{}'\n", kv1.valueSeq());
|
||||
|
||||
si = std::string{"dekjlwe2"};
|
||||
kv1.setValue(7.7, snplib_serialization_params_t{}, si, snplib_serialization_params_t{}, 100,
|
||||
snplib_serialization_params_t{});
|
||||
kv1.setValue(7.7, serialization_params_t{}, si, serialization_params_t{}, 100,
|
||||
serialization_params_t{});
|
||||
|
||||
std::println("key = '{}'", kv1.key());
|
||||
std::println("value = '{}'", kv1.value());
|
||||
@@ -105,14 +105,14 @@ int main()
|
||||
|
||||
|
||||
si = std::string{"dekjlwe3"};
|
||||
kv1.setValue(snplib_serialization_params_t{}, 7.7, si, 100);
|
||||
kv1.setValue(serialization_params_t{}, 7.7, si, 100);
|
||||
|
||||
std::println("key = '{}'", kv1.key());
|
||||
std::println("value = '{}'", kv1.value());
|
||||
std::println("valueSeq = '{}'\n", kv1.valueSeq());
|
||||
|
||||
si = "WER";
|
||||
kv1.appendValue(snplib_serialization_params_t{}, 77.77, si, 1111);
|
||||
kv1.appendValue(serialization_params_t{}, 77.77, si, 1111);
|
||||
|
||||
std::println("key = '{}'", kv1.key());
|
||||
std::println("value = '{}'", kv1.value());
|
||||
@@ -120,7 +120,7 @@ int main()
|
||||
|
||||
|
||||
|
||||
snplib_random_string_generator_t<> rstr_gen;
|
||||
random_string_generator_t<> rstr_gen;
|
||||
|
||||
std::println("\n\n");
|
||||
std::println("RAND STR: {}", rstr_gen.generate());
|
||||
|
||||
@@ -12,78 +12,75 @@ namespace snplib
|
||||
/* type T is hashable */
|
||||
|
||||
template <typename T>
|
||||
concept snplib_hashable_c = requires(T t) {
|
||||
concept hashable_c = requires(T t) {
|
||||
{ std::hash<T>{}(t) } -> std::convertible_to<size_t>;
|
||||
};
|
||||
|
||||
/* some concepts for various types of char sequence */
|
||||
|
||||
template <typename T, typename CharT = char>
|
||||
concept snplib_char_range_c = std::ranges::range<T> && std::same_as<std::ranges::range_value_t<T>, CharT>;
|
||||
concept char_range_c = std::ranges::range<T> && std::same_as<std::ranges::range_value_t<T>, CharT>;
|
||||
|
||||
template <typename T, typename CharT = char>
|
||||
concept snplib_input_char_range_c = std::ranges::input_range<T> && std::same_as<std::ranges::range_value_t<T>, CharT>;
|
||||
concept input_char_range_c = std::ranges::input_range<T> && std::same_as<std::ranges::range_value_t<T>, CharT>;
|
||||
|
||||
template <typename T, typename CharT = char>
|
||||
concept snplib_output_char_range_c = std::ranges::output_range<T, CharT>;
|
||||
concept output_char_range_c = std::ranges::output_range<T, CharT>;
|
||||
|
||||
template <typename T, typename CharT = char>
|
||||
concept snplib_char_view_c = std::ranges::view<T> && std::same_as<std::ranges::range_value_t<T>, CharT>;
|
||||
concept char_view_c = std::ranges::view<T> && std::same_as<std::ranges::range_value_t<T>, CharT>;
|
||||
|
||||
template <typename T, typename CharT = char>
|
||||
concept snplib_view_or_output_char_range_c = snplib_char_view_c<T> || snplib_output_char_range_c<T, CharT>;
|
||||
concept view_or_output_char_range_c = char_view_c<T> || output_char_range_c<T, CharT>;
|
||||
|
||||
template <typename T, typename CharT = char>
|
||||
concept snplib_range_of_char_views_or_output_ranges_c =
|
||||
std::ranges::range<T> && snplib_view_or_output_char_range_c<std::ranges::range_value_t<T>, CharT>;
|
||||
concept range_of_char_views_or_output_ranges_c =
|
||||
std::ranges::range<T> && view_or_output_char_range_c<std::ranges::range_value_t<T>, CharT>;
|
||||
|
||||
|
||||
template <typename T, typename CharT = char>
|
||||
concept snplib_char_range_or_range_of_char_ranges_c =
|
||||
snplib_char_range_c<T, CharT> ||
|
||||
(std::ranges::range<T> && snplib_char_range_c<std::ranges::range_value_t<T>, CharT>);
|
||||
concept char_range_or_range_of_char_ranges_c =
|
||||
char_range_c<T, CharT> || (std::ranges::range<T> && char_range_c<std::ranges::range_value_t<T>, CharT>);
|
||||
|
||||
|
||||
template <typename T, typename CharT = char>
|
||||
concept snplib_pointer_to_char_c =
|
||||
std::is_pointer_v<T> && std::same_as<CharT, std::remove_const_t<std::remove_pointer_t<T>>>;
|
||||
concept pointer_to_char_c = std::is_pointer_v<T> && std::same_as<CharT, std::remove_const_t<std::remove_pointer_t<T>>>;
|
||||
|
||||
|
||||
|
||||
/* std::chrono related concepts */
|
||||
|
||||
template <typename T>
|
||||
concept snplib_time_duration_c = requires(T t) {
|
||||
concept time_duration_c = requires(T t) {
|
||||
[]<typename R, typename P>(std::type_identity<std::chrono::duration<R, P>>) {
|
||||
|
||||
}(std::type_identity<std::remove_cvref_t<T>>());
|
||||
};
|
||||
|
||||
template <typename T, typename ClockT>
|
||||
concept snplib_time_point_c = requires(T t) {
|
||||
concept time_point_c = requires(T t) {
|
||||
[]<typename DurT>(std::type_identity<std::chrono::time_point<ClockT, DurT>>) {
|
||||
|
||||
}(std::type_identity<std::remove_cvref_t<T>>());
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
concept snplib_systime_point_c = snplib_time_point_c<T, std::chrono::system_clock>;
|
||||
concept systime_point_c = time_point_c<T, std::chrono::system_clock>;
|
||||
|
||||
|
||||
template <typename T>
|
||||
concept snplib_utctime_point_c = snplib_time_point_c<T, std::chrono::utc_clock>;
|
||||
concept utctime_point_c = time_point_c<T, std::chrono::utc_clock>;
|
||||
|
||||
template <typename T>
|
||||
concept snplib_anytime_point_c =
|
||||
snplib_systime_point_c<T> || snplib_utctime_point_c<T> || snplib_time_point_c<T, std::chrono::tai_clock> ||
|
||||
snplib_time_point_c<T, std::chrono::gps_clock> || snplib_time_point_c<T, std::chrono::file_clock> ||
|
||||
snplib_time_point_c<T, std::chrono::local_t>;
|
||||
concept anytime_point_c = systime_point_c<T> || utctime_point_c<T> || time_point_c<T, std::chrono::tai_clock> ||
|
||||
time_point_c<T, std::chrono::gps_clock> || time_point_c<T, std::chrono::file_clock> ||
|
||||
time_point_c<T, std::chrono::local_t>;
|
||||
|
||||
|
||||
/* callables (NOTE: does not working for templated functions/methods and generic lambdas!) */
|
||||
|
||||
template <typename T>
|
||||
concept snplib_callable_c = std::is_function_v<T> || (std::is_object_v<T> && requires(T) { &T::operator(); });
|
||||
concept callable_c = std::is_function_v<T> || (std::is_object_v<T> && requires(T) { &T::operator(); });
|
||||
|
||||
|
||||
/* std::tuple-like types */
|
||||
@@ -92,33 +89,33 @@ namespace details
|
||||
{
|
||||
|
||||
template <typename T, size_t... Is>
|
||||
concept snplib_get_all_indices_c = requires(T t) { (std::get<Is>(t), ...); };
|
||||
concept get_all_indices_c = requires(T t) { (std::get<Is>(t), ...); };
|
||||
|
||||
template <typename T>
|
||||
struct snplib_check_indices_t {
|
||||
struct check_indices_t {
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
// Specialize to extract the index sequence matching the tuple size
|
||||
template <typename T>
|
||||
requires requires { typename std::tuple_size<T>::type; }
|
||||
struct snplib_check_indices_t<T> {
|
||||
struct check_indices_t<T> {
|
||||
static constexpr bool value = []<std::size_t... Is>(std::index_sequence<Is...>) {
|
||||
return snplib_get_all_indices_c<T, Is...>;
|
||||
return get_all_indices_c<T, Is...>;
|
||||
}(std::make_index_sequence<std::tuple_size<T>::value>{});
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
static constexpr bool snplib_check_indices_v = snplib_check_indices_t<T>::value;
|
||||
static constexpr bool check_indices_v = check_indices_t<T>::value;
|
||||
|
||||
} // namespace details
|
||||
|
||||
template <typename T>
|
||||
concept snplib_tuple_like_c = details::snplib_check_indices_v<std::remove_cvref_t<T>>;
|
||||
concept tuple_like_c = details::check_indices_v<std::remove_cvref_t<T>>;
|
||||
|
||||
// strictly std::tuple
|
||||
template <typename T>
|
||||
concept snplib_tuple_c = requires {
|
||||
concept tuple_c = requires {
|
||||
[]<typename... Ts>(std::type_identity<std::tuple<Ts...>>) {}(std::type_identity<std::remove_cvref_t<T>>{});
|
||||
};
|
||||
|
||||
@@ -127,24 +124,23 @@ concept snplib_tuple_c = requires {
|
||||
|
||||
// std::array, std::span(v_t, N), std::tuple
|
||||
template <typename T>
|
||||
concept snplib_fixed_size_range_c =
|
||||
std::ranges::range<T> && requires { std::tuple_size<std::remove_cvref_t<T>>::value; };
|
||||
concept fixed_size_range_c = std::ranges::range<T> && requires { std::tuple_size<std::remove_cvref_t<T>>::value; };
|
||||
|
||||
// non-resizable ranges
|
||||
template <typename T>
|
||||
concept snplib_non_resizable_range_c = std::ranges::range<T> && !requires(T r, std::size_t n) { r.resize(n); };
|
||||
concept non_resizable_range_c = std::ranges::range<T> && !requires(T r, std::size_t n) { r.resize(n); };
|
||||
|
||||
// a range with its own data life-time management
|
||||
template <typename T>
|
||||
concept snplib_owning_range_c = std::ranges::range<T> && !std::is_reference_v<T> &&
|
||||
!std::ranges::enable_view<std::decay_t<T>> && std::is_move_constructible_v<T>;
|
||||
concept owning_range_c = std::ranges::range<T> && !std::is_reference_v<T> &&
|
||||
!std::ranges::enable_view<std::decay_t<T>> && std::is_move_constructible_v<T>;
|
||||
|
||||
/* an concept for error-type */
|
||||
|
||||
//
|
||||
// a default-constructible type wich can be converted to bool-type
|
||||
// NOTE: in the SNIPPETS LIBRARY it is assumed that default constructed
|
||||
// objects of the 'snplib_error_c' types are converted to 'false', i.e.:
|
||||
// objects of the 'ret_error_c' types are converted to 'false', i.e.:
|
||||
//
|
||||
// T v;
|
||||
// bool ok = v == false; // 'ok' must be 'true'
|
||||
@@ -152,7 +148,7 @@ concept snplib_owning_range_c = std::ranges::range<T> && !std::is_reference_v<T>
|
||||
//
|
||||
|
||||
template <typename T>
|
||||
concept snplib_error_c = std::constructible_from<T> && requires(T&& t) {
|
||||
concept ret_error_c = std::constructible_from<T> && requires(T&& t) {
|
||||
static_cast<bool>(std::forward<T>(t));
|
||||
|
||||
// { !std::forward<T>(t) } -> std::convertible_to<bool>;
|
||||
@@ -160,8 +156,8 @@ concept snplib_error_c = std::constructible_from<T> && requires(T&& t) {
|
||||
|
||||
// utility function to deduce error-type
|
||||
|
||||
template <snplib_error_c ErrT, snplib_error_c FallbackErrT>
|
||||
static auto snplib_deduced_error(ErrT const& err, FallbackErrT const& fallback_err)
|
||||
template <ret_error_c ErrT, ret_error_c FallbackErrT>
|
||||
static auto deduced_ret_error(ErrT const& err, FallbackErrT const& fallback_err)
|
||||
{
|
||||
if constexpr (std::same_as<ErrT, FallbackErrT>) {
|
||||
return err;
|
||||
@@ -184,14 +180,14 @@ static auto snplib_deduced_error(ErrT const& err, FallbackErrT const& fallback_e
|
||||
|
||||
|
||||
template <typename T>
|
||||
concept snplib_expected_c = requires {
|
||||
[]<typename ValT, snplib_error_c ErrT>(std::type_identity<std::expected<ValT, ErrT>>) {
|
||||
concept ret_expected_c = requires {
|
||||
[]<typename ValT, ret_error_c ErrT>(std::type_identity<std::expected<ValT, ErrT>>) {
|
||||
}(std::type_identity<std::remove_cvref_t<T>>{});
|
||||
};
|
||||
|
||||
// template <typename T, typename ValT>
|
||||
// concept snplib_expected_c = requires {
|
||||
// []<snplib_error_c ErrT>(std::type_identity<std::expected<ValT, ErrT>>) {
|
||||
// concept ret_expected_c = requires {
|
||||
// []<ret_error_c ErrT>(std::type_identity<std::expected<ValT, ErrT>>) {
|
||||
// }(std::type_identity<std::remove_cvref_t<T>>{});
|
||||
// };
|
||||
|
||||
@@ -199,7 +195,7 @@ concept snplib_expected_c = requires {
|
||||
// result of asynchronous callable
|
||||
|
||||
template <typename T, typename UT = void>
|
||||
concept snplib_awaiter_c = requires(T t, std::coroutine_handle<> hndl) {
|
||||
concept result_awaiter_c = requires(T t, std::coroutine_handle<> hndl) {
|
||||
{ t.await_ready() } -> std::convertible_to<bool>;
|
||||
|
||||
// await_suspend can return void, bool, or a coroutine_handle
|
||||
@@ -211,20 +207,20 @@ concept snplib_awaiter_c = requires(T t, std::coroutine_handle<> hndl) {
|
||||
|
||||
|
||||
template <typename T, typename UT = void>
|
||||
concept snplib_awaitable_c = snplib_awaiter_c<T, UT> || requires(T t) {
|
||||
{ t.operator co_await() } -> snplib_awaiter_c<UT>;
|
||||
concept result_awaitable_c = result_awaiter_c<T, UT> || requires(T t) {
|
||||
{ t.operator co_await() } -> result_awaiter_c<UT>;
|
||||
};
|
||||
|
||||
|
||||
template <typename T, typename UT = void>
|
||||
concept snplib_async_retval_c = snplib_awaitable_c<T, UT> && snplib_expected_c<UT>;
|
||||
concept async_retval_c = result_awaitable_c<T, UT> && ret_expected_c<UT>;
|
||||
|
||||
|
||||
|
||||
/* a concept for generic logger class */
|
||||
|
||||
template <typename T>
|
||||
concept snplib_logger_c = requires(T t) {
|
||||
concept logger_c = requires(T t) {
|
||||
{ t.logInfo(std::declval<std::string const&>()) };
|
||||
{ t.logWarn(std::declval<std::string const&>()) };
|
||||
{ t.logDebug(std::declval<std::string const&>()) };
|
||||
|
||||
@@ -12,10 +12,10 @@ namespace snplib
|
||||
|
||||
// helper classes
|
||||
template <typename... Ts>
|
||||
struct snplib_func_traits_helper_t;
|
||||
struct func_traits_helper_t;
|
||||
|
||||
template <typename R>
|
||||
struct snplib_func_traits_helper_t<R> {
|
||||
struct func_traits_helper_t<R> {
|
||||
using ret_t = R;
|
||||
using args_t = std::tuple<>;
|
||||
using arg1_t = void;
|
||||
@@ -23,7 +23,7 @@ struct snplib_func_traits_helper_t<R> {
|
||||
};
|
||||
|
||||
template <typename R, typename Arg, typename... Args>
|
||||
struct snplib_func_traits_helper_t<R, Arg, Args...> {
|
||||
struct func_traits_helper_t<R, Arg, Args...> {
|
||||
using ret_t = R;
|
||||
using args_t = std::tuple<Arg, Args...>;
|
||||
using arg1_t = Arg;
|
||||
@@ -32,13 +32,13 @@ struct snplib_func_traits_helper_t<R, Arg, Args...> {
|
||||
|
||||
|
||||
template <typename F>
|
||||
struct snplib_func_traits_t {
|
||||
struct func_traits_t {
|
||||
// use of an empty struct here to match std::invoke_result behaivior (at least of GCC)
|
||||
};
|
||||
|
||||
// special case
|
||||
template <>
|
||||
struct snplib_func_traits_t<std::nullptr_t> {
|
||||
struct func_traits_t<std::nullptr_t> {
|
||||
using ret_t = std::nullptr_t;
|
||||
using args_t = std::tuple<>;
|
||||
using arg1_t = std::nullptr_t;
|
||||
@@ -46,77 +46,68 @@ struct snplib_func_traits_t<std::nullptr_t> {
|
||||
};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct snplib_func_traits_t<R (*)(Args...)> : snplib_func_traits_helper_t<R, Args...> {
|
||||
};
|
||||
struct func_traits_t<R (*)(Args...)> : func_traits_helper_t<R, Args...> {};
|
||||
|
||||
template <typename R, typename... Args>
|
||||
struct snplib_func_traits_t<R(Args...)> : snplib_func_traits_helper_t<R, Args...> {
|
||||
};
|
||||
struct func_traits_t<R(Args...)> : func_traits_helper_t<R, Args...> {};
|
||||
|
||||
template <typename C, typename R, typename... Args>
|
||||
struct snplib_func_traits_t<R (C::*)(Args...)> : snplib_func_traits_helper_t<R, Args...> {
|
||||
};
|
||||
struct func_traits_t<R (C::*)(Args...)> : func_traits_helper_t<R, Args...> {};
|
||||
|
||||
template <typename C, typename R, typename... Args>
|
||||
struct snplib_func_traits_t<R (C::*)(Args...) const> : snplib_func_traits_helper_t<R, Args...> {
|
||||
};
|
||||
struct func_traits_t<R (C::*)(Args...) const> : func_traits_helper_t<R, Args...> {};
|
||||
|
||||
template <typename F>
|
||||
requires snplib_callable_c<F>
|
||||
struct snplib_func_traits_t<F> : snplib_func_traits_t<decltype(&F::operator())> {
|
||||
};
|
||||
requires callable_c<F>
|
||||
struct func_traits_t<F> : func_traits_t<decltype(&F::operator())> {};
|
||||
|
||||
template <typename F>
|
||||
struct snplib_func_traits_t<F&> : snplib_func_traits_t<F> {
|
||||
};
|
||||
struct func_traits_t<F&> : func_traits_t<F> {};
|
||||
|
||||
template <typename F>
|
||||
struct snplib_func_traits_t<const F&> : snplib_func_traits_t<F> {
|
||||
};
|
||||
struct func_traits_t<const F&> : func_traits_t<F> {};
|
||||
|
||||
template <typename F>
|
||||
struct snplib_func_traits_t<F&&> : snplib_func_traits_t<F> {
|
||||
};
|
||||
struct func_traits_t<F&&> : func_traits_t<F> {};
|
||||
|
||||
template <typename T>
|
||||
using snplib_func_arg1_t = typename snplib_func_traits_t<T>::arg1_t;
|
||||
using func_arg1_t = typename func_traits_t<T>::arg1_t;
|
||||
|
||||
|
||||
/* create a std::tuple from the input types except the last one*/
|
||||
template <typename... Ts>
|
||||
struct snplib_tuple_except_last_helper_t;
|
||||
struct tuple_except_last_helper_t;
|
||||
|
||||
template <typename T>
|
||||
struct snplib_tuple_except_last_helper_t<T> {
|
||||
struct tuple_except_last_helper_t<T> {
|
||||
using tuple_t = std::tuple<>;
|
||||
};
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct snplib_tuple_except_last_helper_t<T, Ts...> {
|
||||
using tuple_t =
|
||||
decltype(std::tuple_cat(std::declval<std::tuple<T>>(),
|
||||
std::declval<typename snplib_tuple_except_last_helper_t<Ts...>::tuple_t>()));
|
||||
struct tuple_except_last_helper_t<T, Ts...> {
|
||||
using tuple_t = decltype(std::tuple_cat(std::declval<std::tuple<T>>(),
|
||||
std::declval<typename tuple_except_last_helper_t<Ts...>::tuple_t>()));
|
||||
};
|
||||
|
||||
|
||||
template <typename... Ts>
|
||||
using snplib_tuple_except_last_t = typename snplib_tuple_except_last_helper_t<Ts...>::tuple_t;
|
||||
using tuple_except_last_t = typename tuple_except_last_helper_t<Ts...>::tuple_t;
|
||||
|
||||
|
||||
template <typename... Ts>
|
||||
struct snplib_last_in_pack_helper_t;
|
||||
struct last_in_pack_helper_t;
|
||||
|
||||
template <typename T>
|
||||
struct snplib_last_in_pack_helper_t<T> {
|
||||
struct last_in_pack_helper_t<T> {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct snplib_last_in_pack_helper_t<T, Ts...> {
|
||||
using type = typename snplib_last_in_pack_helper_t<Ts...>::type;
|
||||
struct last_in_pack_helper_t<T, Ts...> {
|
||||
using type = typename last_in_pack_helper_t<Ts...>::type;
|
||||
};
|
||||
|
||||
template <typename... Ts>
|
||||
using snplib_last_in_pack_t = typename snplib_last_in_pack_helper_t<Ts...>::type;
|
||||
using last_in_pack_t = typename last_in_pack_helper_t<Ts...>::type;
|
||||
|
||||
} // namespace snplib
|
||||
@@ -15,7 +15,7 @@ namespace snplib
|
||||
/* (A HETEROGENEOUS UNORDERED MAP) */
|
||||
|
||||
|
||||
template <snplib_hashable_c KeyT>
|
||||
template <hashable_c KeyT>
|
||||
class HeterogenMap
|
||||
{
|
||||
protected:
|
||||
@@ -421,7 +421,7 @@ using hmap_expected_t = std::expected<VT, hmap_error_t>;
|
||||
|
||||
|
||||
|
||||
template <snplib_hashable_c KeyT>
|
||||
template <hashable_c KeyT>
|
||||
class hmap
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -13,60 +13,60 @@ 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>&>()), ...); };
|
||||
concept 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 =
|
||||
concept 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 {
|
||||
struct check_all_func_oper_t {
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
template <typename OT, typename TT>
|
||||
struct snplib_check_all_func_oper_range_t {
|
||||
struct 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> {
|
||||
struct check_all_func_oper_t<OT, TT> {
|
||||
static constexpr bool value = []<std::size_t... Is>(std::index_sequence<Is...>) {
|
||||
return snplib_all_func_oper_c<OT, TT, Is...>;
|
||||
return all_func_oper_c<OT, TT, Is...>;
|
||||
}(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> {
|
||||
struct 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...>;
|
||||
return 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;
|
||||
static constexpr bool check_all_func_oper_v = 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;
|
||||
static constexpr bool check_all_func_oper_range_v = check_all_func_oper_range_t<OT, TT>::value;
|
||||
|
||||
} // namespace details
|
||||
|
||||
|
||||
template <typename T>
|
||||
concept snplib_hvec_visitor_c = requires {
|
||||
requires snplib_tuple_c<typename T::types>;
|
||||
concept hvec_visitor_c = requires {
|
||||
requires tuple_c<typename T::types>;
|
||||
|
||||
requires details::snplib_check_all_func_oper_v<T, typename T::types>;
|
||||
requires details::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>;
|
||||
concept hvec_range_visitor_c = requires {
|
||||
requires tuple_c<typename T::types>;
|
||||
|
||||
requires details::snplib_check_all_func_oper_range_v<T, typename T::types>;
|
||||
requires details::check_all_func_oper_range_v<T, typename T::types>;
|
||||
};
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ public:
|
||||
}
|
||||
|
||||
// per element visiting
|
||||
template <snplib_hvec_visitor_c VT>
|
||||
template <hvec_visitor_c VT>
|
||||
void visit(VT&& visitor)
|
||||
{
|
||||
auto invoke_per_elem = [&visitor, this]<typename T>() {
|
||||
@@ -188,7 +188,7 @@ public:
|
||||
}
|
||||
|
||||
// per range of type visiting
|
||||
template <snplib_hvec_visitor_c VT>
|
||||
template <hvec_visitor_c VT>
|
||||
void visitRange(VT&& visitor)
|
||||
{
|
||||
auto invoke_per_type = [&visitor, this]<typename T>() { visitor(_values<T>[this]); };
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
namespace snplib
|
||||
{
|
||||
|
||||
class snplib_endpoint_t
|
||||
class net_endpoint_t
|
||||
{
|
||||
public:
|
||||
static constexpr std::string_view id{"SNPLIB-NET-ENDPOINT"};
|
||||
@@ -77,26 +77,26 @@ public:
|
||||
localProtoTypeSerial};
|
||||
|
||||
|
||||
template <snplib_input_char_range_c R>
|
||||
snplib_endpoint_t(const R& ept)
|
||||
template <input_char_range_c R>
|
||||
net_endpoint_t(const R& ept)
|
||||
{
|
||||
fromRange(ept);
|
||||
}
|
||||
|
||||
snplib_endpoint_t(const snplib_endpoint_t& other)
|
||||
net_endpoint_t(const net_endpoint_t& other)
|
||||
{
|
||||
copyInst(other);
|
||||
}
|
||||
|
||||
snplib_endpoint_t(snplib_endpoint_t&& other)
|
||||
net_endpoint_t(net_endpoint_t&& other)
|
||||
{
|
||||
moveInst(std::move(other));
|
||||
}
|
||||
|
||||
virtual ~snplib_endpoint_t() = default;
|
||||
virtual ~net_endpoint_t() = default;
|
||||
|
||||
|
||||
snplib_endpoint_t& operator=(const snplib_endpoint_t& other)
|
||||
net_endpoint_t& operator=(const net_endpoint_t& other)
|
||||
{
|
||||
copyInst(other);
|
||||
|
||||
@@ -104,7 +104,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
snplib_endpoint_t& operator=(snplib_endpoint_t&& other)
|
||||
net_endpoint_t& operator=(net_endpoint_t&& other)
|
||||
{
|
||||
moveInst(std::move(other));
|
||||
|
||||
@@ -112,7 +112,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
template <snplib_input_char_range_c R>
|
||||
template <input_char_range_c R>
|
||||
requires std::ranges::contiguous_range<R>
|
||||
bool fromRange(const R& ept)
|
||||
{
|
||||
@@ -181,7 +181,7 @@ public:
|
||||
if (isLocal()) { // check for special values
|
||||
idx = 0;
|
||||
if (std::ranges::any_of(validLocalProtoTypes, [&idx, this](const auto& el) {
|
||||
bool ok = snplib_char_ranges_compare(_host, el, true);
|
||||
bool ok = char_ranges_compare(_host, el, true);
|
||||
if (!ok) {
|
||||
++idx;
|
||||
}
|
||||
@@ -211,7 +211,7 @@ public:
|
||||
return _endpoint;
|
||||
}
|
||||
|
||||
template <snplib_view_or_output_char_range_c R>
|
||||
template <view_or_output_char_range_c R>
|
||||
R proto() const
|
||||
{
|
||||
return part<R>(PROTO_PART);
|
||||
@@ -222,7 +222,7 @@ public:
|
||||
return proto<std::string_view>();
|
||||
}
|
||||
|
||||
template <snplib_view_or_output_char_range_c R>
|
||||
template <view_or_output_char_range_c R>
|
||||
R host() const
|
||||
{
|
||||
return part<R>(HOST_PART);
|
||||
@@ -238,7 +238,7 @@ public:
|
||||
return _port;
|
||||
}
|
||||
|
||||
template <snplib_view_or_output_char_range_c R>
|
||||
template <view_or_output_char_range_c R>
|
||||
R portView() const
|
||||
{
|
||||
return part<R>(PORT_PART);
|
||||
@@ -249,11 +249,11 @@ public:
|
||||
return portView<std::string_view>();
|
||||
}
|
||||
|
||||
template <snplib_output_char_range_c R, snplib_input_char_range_c RR = std::string_view>
|
||||
template <output_char_range_c R, input_char_range_c RR = std::string_view>
|
||||
R path(RR&& root_path) const
|
||||
{
|
||||
if (_path.empty()) {
|
||||
if constexpr (snplib_output_char_range_c<R>) {
|
||||
if constexpr (output_char_range_c<R>) {
|
||||
R res;
|
||||
std::ranges::copy(std::forward<RR>(root_path), std::back_inserter(res));
|
||||
|
||||
@@ -285,13 +285,13 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template <snplib_input_char_range_c RR = std::string_view>
|
||||
template <input_char_range_c RR = std::string_view>
|
||||
std::string path(RR&& root_path) const
|
||||
{
|
||||
return path<std::string, RR>(std::forward<RR>(root_path));
|
||||
}
|
||||
|
||||
template <snplib_view_or_output_char_range_c R>
|
||||
template <view_or_output_char_range_c R>
|
||||
R path() const
|
||||
{
|
||||
return part<R>(PATH_PART);
|
||||
@@ -353,8 +353,8 @@ public:
|
||||
// add '\0' char (or replace special-meaning char/char-sequence) to construct UNIX abstract namespace
|
||||
// endpoint path
|
||||
template <typename T = std::nullptr_t>
|
||||
snplib_endpoint_t& makeAbstract(const T& mark = nullptr)
|
||||
requires(snplib_input_char_range_c<T> || std::same_as<std::remove_cv_t<T>, char> ||
|
||||
net_endpoint_t& makeAbstract(const T& mark = nullptr)
|
||||
requires(input_char_range_c<T> || std::same_as<std::remove_cv_t<T>, char> ||
|
||||
std::is_null_pointer_v<std::remove_cv_t<T>>)
|
||||
{
|
||||
if (!(isLocalStream() || isLocalSeqpacket())) { // only local proto is valid!
|
||||
@@ -393,8 +393,8 @@ protected:
|
||||
ssize_t idx = 0;
|
||||
|
||||
// case-insensitive look-up
|
||||
bool found = std::ranges::any_of(snplib_endpoint_t::validProtoMarks, [&idx, &proto_mark](const auto& el) {
|
||||
bool ok = snplib_char_ranges_compare(proto_mark, el, true);
|
||||
bool found = std::ranges::any_of(net_endpoint_t::validProtoMarks, [&idx, &proto_mark](const auto& el) {
|
||||
bool ok = char_ranges_compare(proto_mark, el, true);
|
||||
|
||||
if (!ok) {
|
||||
++idx;
|
||||
@@ -408,7 +408,7 @@ protected:
|
||||
|
||||
enum EndpointPart { PROTO_PART, HOST_PART, PATH_PART, PORT_PART };
|
||||
|
||||
template <snplib_view_or_output_char_range_c R>
|
||||
template <view_or_output_char_range_c R>
|
||||
R part(EndpointPart what) const
|
||||
{
|
||||
R res;
|
||||
@@ -445,7 +445,7 @@ protected:
|
||||
return res;
|
||||
}
|
||||
|
||||
void copyInst(const snplib_endpoint_t& other)
|
||||
void copyInst(const net_endpoint_t& other)
|
||||
{
|
||||
if (&other != this) {
|
||||
if (other._isValid) {
|
||||
@@ -481,7 +481,7 @@ protected:
|
||||
}
|
||||
|
||||
|
||||
void moveInst(snplib_endpoint_t&& other)
|
||||
void moveInst(net_endpoint_t&& other)
|
||||
{
|
||||
if (&other != this) {
|
||||
if (other._isValid) {
|
||||
|
||||
@@ -27,36 +27,36 @@ static constexpr char SNPLIB_DEFAULT_NETMSG_KEYVALUE_DELIM[] = "=";
|
||||
static constexpr char SNPLIB_DEFAULT_NETMSG_VALUEVALUE_DELIM[] = ",";
|
||||
|
||||
|
||||
template <snplib_char_range_c CharRangeT = std::vector<char>>
|
||||
class snplib_netmsg_t : public snplib_keyvalue_expr_t<CharRangeT>
|
||||
template <char_range_c CharRangeT = std::vector<char>>
|
||||
class keyval_netmsg_t : public keyvalue_expr_t<CharRangeT>
|
||||
{
|
||||
protected:
|
||||
using base_t = snplib_keyvalue_expr_t<CharRangeT>;
|
||||
using base_t = keyvalue_expr_t<CharRangeT>;
|
||||
|
||||
public:
|
||||
using base_t::config_t;
|
||||
|
||||
snplib_netmsg_t(base_t::config_t config = {.keyval_delim = SNPLIB_DEFAULT_NETMSG_KEYVALUE_DELIM,
|
||||
keyval_netmsg_t(base_t::config_t config = {.keyval_delim = SNPLIB_DEFAULT_NETMSG_KEYVALUE_DELIM,
|
||||
.valseq_delim = SNPLIB_DEFAULT_NETMSG_VALUEVALUE_DELIM})
|
||||
: base_t(std::move(config))
|
||||
{
|
||||
}
|
||||
|
||||
snplib_netmsg_t(CharRangeT& r,
|
||||
keyval_netmsg_t(CharRangeT& r,
|
||||
base_t::config_t config = {.keyval_delim = SNPLIB_DEFAULT_NETMSG_KEYVALUE_DELIM,
|
||||
.valseq_delim = SNPLIB_DEFAULT_NETMSG_VALUEVALUE_DELIM})
|
||||
: base_t(r, std::move(config))
|
||||
{
|
||||
}
|
||||
|
||||
~snplib_netmsg_t() = default;
|
||||
~keyval_netmsg_t() = default;
|
||||
|
||||
template <snplib_char_range_c R>
|
||||
static snplib_netmsg_t fromBytes(R&& r,
|
||||
template <char_range_c R>
|
||||
static keyval_netmsg_t fromBytes(R&& r,
|
||||
base_t::config_t config = {.keyval_delim = SNPLIB_DEFAULT_NETMSG_KEYVALUE_DELIM,
|
||||
.valseq_delim = SNPLIB_DEFAULT_NETMSG_VALUEVALUE_DELIM})
|
||||
{
|
||||
snplib_netmsg_t msg;
|
||||
keyval_netmsg_t msg;
|
||||
|
||||
// deep copy
|
||||
if constexpr (std::same_as<CharRangeT, std::remove_cvref_t<R>>) {
|
||||
@@ -70,10 +70,10 @@ public:
|
||||
}
|
||||
|
||||
|
||||
template <snplib_char_range_c OR>
|
||||
template <char_range_c OR>
|
||||
OR toBytes() const
|
||||
{
|
||||
return snplib_transform_char_range<OR>(this->_byteSeq);
|
||||
return transform_char_range<OR>(this->_byteSeq);
|
||||
}
|
||||
|
||||
std::vector<char> toBytes() const
|
||||
|
||||
@@ -25,13 +25,13 @@ namespace snplib
|
||||
static constexpr char SNPLIB_DEFAULT_NETPROTO_STOP_SEQ[] = "\n";
|
||||
|
||||
template <const char* STOP_SEQ = SNPLIB_DEFAULT_NETPROTO_STOP_SEQ>
|
||||
requires(snplib_char_array_size(STOP_SEQ) > 0)
|
||||
struct snplib_netproto_stopseq_t {
|
||||
requires(char_array_size(STOP_SEQ) > 0)
|
||||
struct netproto_stopseq_t {
|
||||
static constexpr std::string_view NETPROTO_STOP_SEQ{STOP_SEQ};
|
||||
|
||||
// returns 2-element range of the input messsage and stop-sequence
|
||||
template <std::ranges::range OR, snplib_input_char_range_c IR>
|
||||
requires snplib_char_range_c<std::ranges::range_value_t<OR>> // range of char ranges
|
||||
template <std::ranges::range OR, input_char_range_c IR>
|
||||
requires char_range_c<std::ranges::range_value_t<OR>> // range of char ranges
|
||||
OR toBytes(IR&& message)
|
||||
{
|
||||
OR res;
|
||||
@@ -43,7 +43,7 @@ struct snplib_netproto_stopseq_t {
|
||||
}
|
||||
|
||||
// returns a copy of the input message + tralling stop-sequence
|
||||
template <snplib_output_char_range_c OR, snplib_input_char_range_c IR>
|
||||
template <output_char_range_c OR, input_char_range_c IR>
|
||||
OR toBytes(IR&& message)
|
||||
{
|
||||
OR res;
|
||||
@@ -54,7 +54,7 @@ struct snplib_netproto_stopseq_t {
|
||||
return res;
|
||||
}
|
||||
|
||||
template <snplib_input_char_range_c IR>
|
||||
template <input_char_range_c IR>
|
||||
auto toBytes(IR&& message)
|
||||
{
|
||||
if constexpr (std::ranges::contiguous_range<IR>) {
|
||||
@@ -65,7 +65,7 @@ struct snplib_netproto_stopseq_t {
|
||||
}
|
||||
}
|
||||
|
||||
template <std::ranges::range OR, snplib_input_char_range_c IR>
|
||||
template <std::ranges::range OR, input_char_range_c IR>
|
||||
std::expected<OR, std::error_code> fromBytes(IR&& bytes)
|
||||
{
|
||||
auto found = std::ranges::search(std::forward<IR>(bytes), NETPROTO_STOP_SEQ);
|
||||
@@ -84,8 +84,8 @@ struct snplib_netproto_stopseq_t {
|
||||
|
||||
if constexpr (ret_view) {
|
||||
return OR(bytes.begin(), found.begin()); // return without stop-sequence!!!
|
||||
} else if constexpr (snplib_output_char_range_c<OR>) {
|
||||
if constexpr (!snplib_fixed_size_range_c<OR>) {
|
||||
} else if constexpr (output_char_range_c<OR>) {
|
||||
if constexpr (!fixed_size_range_c<OR>) {
|
||||
if constexpr (std::constructible_from<OR, std::ranges::iterator_t<inp_t>,
|
||||
std::ranges::iterator_t<inp_t>>) {
|
||||
return OR(bytes.begin(), found.begin()); // return without stop-sequence!!!
|
||||
@@ -121,7 +121,7 @@ struct snplib_netproto_stopseq_t {
|
||||
|
||||
template <typename IR>
|
||||
auto fromBytes(IR&& bytes)
|
||||
requires snplib_input_char_range_c<std::remove_cvref_t<IR>>
|
||||
requires input_char_range_c<std::remove_cvref_t<IR>>
|
||||
{
|
||||
using or_t = std::conditional_t<std::ranges::contiguous_range<IR>, std::span<const char>,
|
||||
std::ranges::subrange<std::ranges::iterator_t<IR>>>;
|
||||
@@ -144,12 +144,12 @@ struct snplib_netproto_stopseq_t {
|
||||
template <size_t SZ_FIELD_WIDTH = 8>
|
||||
requires(SZ_FIELD_WIDTH > 0 &&
|
||||
SZ_FIELD_WIDTH <= 16) // not greater than allowed for 64-bit unsigned integer representation
|
||||
struct snplib_netproto_binary_blob_t {
|
||||
struct netproto_binary_blob_t {
|
||||
static constexpr size_t BLOB_SIZE_FIELD{SZ_FIELD_WIDTH};
|
||||
|
||||
static constexpr std::array<char, 6> BLOB_SIZE_FIELD_FORMAT{'{', ':', '0', '0' + BLOB_SIZE_FIELD, 'X', '}'};
|
||||
|
||||
template <snplib_input_char_range_c IR>
|
||||
template <input_char_range_c IR>
|
||||
auto toBytes(IR&& message)
|
||||
{
|
||||
static thread_local std::string Nbytes{};
|
||||
@@ -167,7 +167,7 @@ struct snplib_netproto_binary_blob_t {
|
||||
}
|
||||
|
||||
|
||||
template <snplib_char_range_c OR, snplib_input_char_range_c IR>
|
||||
template <char_range_c OR, input_char_range_c IR>
|
||||
std::expected<OR, std::error_code> fromBytes(IR&& bytes)
|
||||
{
|
||||
using inp_t = std::remove_cvref_t<IR>;
|
||||
@@ -187,9 +187,9 @@ struct snplib_netproto_binary_blob_t {
|
||||
|
||||
std::optional<size_t> blob_sz;
|
||||
if constexpr (std::ranges::contiguous_range<IR>) {
|
||||
blob_sz = snplib_num_from_range<size_t>(std::span(bytes.begin(), BLOB_SIZE_FIELD), 16);
|
||||
blob_sz = char_range_to_number<size_t>(std::span(bytes.begin(), BLOB_SIZE_FIELD), 16);
|
||||
} else {
|
||||
blob_sz = snplib_num_from_range<size_t>(bytes | std::views::take(BLOB_SIZE_FIELD), 16);
|
||||
blob_sz = char_range_to_number<size_t>(bytes | std::views::take(BLOB_SIZE_FIELD), 16);
|
||||
}
|
||||
|
||||
if (!blob_sz) {
|
||||
@@ -209,8 +209,8 @@ struct snplib_netproto_binary_blob_t {
|
||||
|
||||
if constexpr (ret_view) {
|
||||
return OR(it_start, it_end); // return without blob size field
|
||||
} else if constexpr (snplib_output_char_range_c<OR>) {
|
||||
if constexpr (!snplib_fixed_size_range_c<OR>) {
|
||||
} else if constexpr (output_char_range_c<OR>) {
|
||||
if constexpr (!fixed_size_range_c<OR>) {
|
||||
if constexpr (std::constructible_from<OR, std::ranges::iterator_t<inp_t>,
|
||||
std::ranges::iterator_t<inp_t>>) {
|
||||
return OR(it_start, it_end); // return without blob size field!!!
|
||||
|
||||
@@ -10,12 +10,12 @@ namespace snplib
|
||||
|
||||
|
||||
template <typename T>
|
||||
concept snplib_net_endpoint_c = requires(T t, const T t_const) {
|
||||
concept net_endpoint_c = requires(T t, const T t_const) {
|
||||
// static constexpr member
|
||||
std::formattable<decltype(T::id), char>;
|
||||
[]() { [[maybe_unused]] static constexpr auto val = T::id; }();
|
||||
|
||||
{ t.endpoint() } -> snplib_char_range_c;
|
||||
{ t.endpoint() } -> char_range_c;
|
||||
|
||||
{ t_const.proto() } -> std::formattable<char>;
|
||||
{ t_const.host() } -> std::formattable<char>;
|
||||
@@ -25,23 +25,23 @@ concept snplib_net_endpoint_c = requires(T t, const T t_const) {
|
||||
|
||||
|
||||
template <typename T, typename CharRangeT = std::vector<char>>
|
||||
concept snplib_net_proto_c = requires(T t) {
|
||||
concept net_proto_c = requires(T t) {
|
||||
// from session-level representation to transport-level one
|
||||
{ t.toBytes(std::declval<CharRangeT>()) } -> snplib_char_range_or_range_of_char_ranges_c;
|
||||
{ t.toBytes(std::declval<CharRangeT>()) } -> char_range_or_range_of_char_ranges_c;
|
||||
|
||||
requires(
|
||||
requires {
|
||||
{ t.fromBytes(std::declval<std::span<const char>>()) } -> snplib_char_range_c;
|
||||
{ t.fromBytes(std::declval<std::span<const char>>()) } -> char_range_c;
|
||||
} ||
|
||||
requires {
|
||||
{ t.fromBytes(std::declval<std::span<char>>()) } -> snplib_char_range_c;
|
||||
{ t.fromBytes(std::declval<std::span<char>>()) } -> char_range_c;
|
||||
});
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
concept snplib_net_message_c = requires(const T t_const) {
|
||||
// { t.toBytes() } -> snplib_char_range_or_range_of_char_ranges_c;
|
||||
{ t_const.toBytes() } -> snplib_char_range_c;
|
||||
concept net_message_c = requires(const T t_const) {
|
||||
// { t.toBytes() } -> char_range_or_range_of_char_ranges_c;
|
||||
{ t_const.toBytes() } -> char_range_c;
|
||||
|
||||
// can be constructed from contiguous byte range
|
||||
requires(
|
||||
@@ -54,32 +54,32 @@ concept snplib_net_message_c = requires(const T t_const) {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
concept snplib_net_connection_c = requires(T t) {
|
||||
concept net_connection_c = requires(T t) {
|
||||
// static constexpr member
|
||||
std::formattable<decltype(T::id), char>;
|
||||
[]() { [[maybe_unused]] static constexpr auto val = T::id; }();
|
||||
|
||||
typename T::message_t; // minimal allowed unit of read/write operations
|
||||
|
||||
{ t.send(std::declval<typename T::message_t>()) } -> snplib_async_retval_c;
|
||||
{ t.recv() } -> snplib_async_retval_c<typename T::message_t>;
|
||||
{ t.send(std::declval<typename T::message_t>()) } -> async_retval_c;
|
||||
{ t.recv() } -> async_retval_c<typename T::message_t>;
|
||||
|
||||
t.close();
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
concept snplib_net_session_c =
|
||||
concept net_session_c =
|
||||
std::derived_from<T, std::enable_shared_from_this<T>> &&
|
||||
requires(T t, const T t_const) {
|
||||
typename T::ident_t;
|
||||
typename T::context_t;
|
||||
|
||||
snplib_net_connection_c<typename T::connection_t>;
|
||||
net_connection_c<typename T::connection_t>;
|
||||
|
||||
{ t_const.ident() } -> std::same_as<typename T::ident_t>;
|
||||
|
||||
// { t.startSession(std::declval<typename T::connection_t>()) } -> snplib_async_retval_c;
|
||||
// { t.startSession(std::declval<typename T::connection_t>()) } -> async_retval_c;
|
||||
t.startSession(std::declval<typename T::connection_t>());
|
||||
|
||||
t.stopSession();
|
||||
@@ -92,27 +92,27 @@ concept snplib_net_session_c =
|
||||
|
||||
|
||||
template <typename T>
|
||||
concept snplib_net_listener_c = requires(T t, const T t_const) {
|
||||
concept net_listener_c = requires(T t, const T t_const) {
|
||||
// static constexpr member
|
||||
std::formattable<decltype(T::id), char>;
|
||||
[]() { [[maybe_unused]] static constexpr auto val = T::id; }();
|
||||
|
||||
snplib_net_connection_c<typename T::connection_t>;
|
||||
net_connection_c<typename T::connection_t>;
|
||||
|
||||
{ t.accept() } -> snplib_async_retval_c<typename T::connection_t>;
|
||||
{ t.accept() } -> async_retval_c<typename T::connection_t>;
|
||||
|
||||
{ t.startListen() } -> snplib_error_c;
|
||||
{ t.startListen() } -> ret_error_c;
|
||||
|
||||
t.stopListen();
|
||||
|
||||
{ t_const.endpoint() } -> snplib_net_endpoint_c;
|
||||
{ t_const.endpoint() } -> net_endpoint_c;
|
||||
};
|
||||
|
||||
|
||||
// a type that defines at least two compile-time constants:
|
||||
// ROLE_SERVER and ROLE_CLIENT
|
||||
template <typename T>
|
||||
concept snplib_net_initiator_role_c = requires {
|
||||
concept net_initiator_role_c = requires {
|
||||
[]() {
|
||||
[[maybe_unused]] static constexpr std::array arr{// server role (listener of connections)
|
||||
T::ROLE_SERVER,
|
||||
@@ -122,36 +122,36 @@ concept snplib_net_initiator_role_c = requires {
|
||||
};
|
||||
|
||||
// default library-wide type of network connection initiator role
|
||||
enum class snplib_net_initiator_role_e : int { ROLE_SERVER, ROLE_CLIENT };
|
||||
enum class net_initiator_role_e : int { ROLE_SERVER, ROLE_CLIENT };
|
||||
|
||||
|
||||
template <typename T>
|
||||
concept snplib_net_initiator_c =
|
||||
concept net_initiator_c =
|
||||
requires(T t, const T t_const) {
|
||||
// common part
|
||||
requires snplib_net_initiator_role_c<decltype(T::ROLE)>;
|
||||
requires net_initiator_role_c<decltype(T::ROLE)>;
|
||||
[]() { [[maybe_unused]] static constexpr auto val = T::ROLE; }();
|
||||
|
||||
snplib_net_connection_c<typename T::connection_t>;
|
||||
net_connection_c<typename T::connection_t>;
|
||||
|
||||
{ t_const.endpoint() } -> snplib_net_endpoint_c;
|
||||
{ t_const.endpoint() } -> net_endpoint_c;
|
||||
} && ((T::ROLE != decltype(T::ROLE)::ROLE_SERVER) || requires(T t) { // use of short-circuiting logic!!!
|
||||
// server-role
|
||||
{ t.accept() } -> snplib_async_retval_c<typename T::connection_t>;
|
||||
{ t.accept() } -> async_retval_c<typename T::connection_t>;
|
||||
|
||||
{ t.startListen() } -> snplib_error_c;
|
||||
{ t.startListen() } -> ret_error_c;
|
||||
|
||||
t.stopListen();
|
||||
}) && ((T::ROLE != decltype(T::ROLE)::ROLE_CLIENT) || requires(T t) { // use of short-circuiting logic!!!
|
||||
// client-role
|
||||
{ t.open() } -> snplib_async_retval_c<typename T::connection_t>;
|
||||
{ t.open() } -> async_retval_c<typename T::connection_t>;
|
||||
t.close();
|
||||
});
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
concept snplib_netserver_c = requires(T t) {
|
||||
concept netserver_c = requires(T t) {
|
||||
// static constexpr member
|
||||
std::formattable<decltype(T::id), char>;
|
||||
[]() { [[maybe_unused]] static constexpr auto val = T::id; }();
|
||||
@@ -163,18 +163,18 @@ concept snplib_netserver_c = requires(T t) {
|
||||
t.stopServer();
|
||||
|
||||
t.disconnectClients();
|
||||
// { t.startServer() } -> snplib_error_c;
|
||||
// { t.startServer() } -> error_c;
|
||||
|
||||
// { t.stopServer() } -> snplib_error_c;
|
||||
// { t.stopServer() } -> error_c;
|
||||
|
||||
// { t.disconnectClients() } -> snplib_error_c;
|
||||
// { t.disconnectClients() } -> error_c;
|
||||
};
|
||||
|
||||
|
||||
template <typename T, typename SessionT>
|
||||
concept snplib_session_manager_c =
|
||||
concept session_manager_c =
|
||||
requires(T t, SessionT::context_t cnx) {
|
||||
requires snplib_net_session_c<SessionT>;
|
||||
requires net_session_c<SessionT>;
|
||||
|
||||
typename T::session_ptr_t; // e.g. std::shared_ptr<SessionT>
|
||||
|
||||
@@ -198,8 +198,8 @@ concept snplib_session_manager_c =
|
||||
|
||||
/* SINGLE-PROTO*/
|
||||
|
||||
template <snplib_net_session_c SessionT>
|
||||
class snplib_session_manager_t
|
||||
template <net_session_c SessionT>
|
||||
class session_manager_t
|
||||
{
|
||||
public:
|
||||
typedef std::shared_ptr<SessionT> session_ptr_t;
|
||||
@@ -217,7 +217,7 @@ public:
|
||||
//
|
||||
// delegates an implementation to the derived class
|
||||
//
|
||||
template <std::derived_from<snplib_session_manager_t> SelfT>
|
||||
template <std::derived_from<session_manager_t> SelfT>
|
||||
auto startSession(this SelfT&& self, session_ptr_t ptr)
|
||||
{
|
||||
std::lock_guard lock(self._setMutex);
|
||||
@@ -261,12 +261,9 @@ protected:
|
||||
|
||||
|
||||
|
||||
template <snplib_net_listener_c ListenerT,
|
||||
snplib_net_session_c SessionT,
|
||||
snplib_session_manager_c<SessionT> SessManagerT,
|
||||
snplib_logger_c LoggerT>
|
||||
template <net_listener_c ListenerT, net_session_c SessionT, session_manager_c<SessionT> SessManagerT, logger_c LoggerT>
|
||||
requires std::same_as<typename ListenerT::connection_t, typename SessionT::connection_t>
|
||||
class snplib_generic_netserver_t : protected SessManagerT, public LoggerT
|
||||
class generic_netserver_t : protected SessManagerT, public LoggerT
|
||||
{
|
||||
public:
|
||||
// typedef std::error_code error_t;
|
||||
@@ -278,14 +275,14 @@ public:
|
||||
using LoggerT::logWarn;
|
||||
|
||||
template <typename... SessManagerCtorArgTs, typename... LoggerCtorArgTs>
|
||||
snplib_generic_netserver_t(std::tuple<SessManagerCtorArgTs...> sess_manager_ctor_args,
|
||||
std::tuple<LoggerCtorArgTs...> logger_ctor_args)
|
||||
generic_netserver_t(std::tuple<SessManagerCtorArgTs...> sess_manager_ctor_args,
|
||||
std::tuple<LoggerCtorArgTs...> logger_ctor_args)
|
||||
: SessManagerT(std::make_from_tuple<SessManagerT>(std::move(sess_manager_ctor_args))),
|
||||
LoggerT(std::make_from_tuple<LoggerT>(std::move(logger_ctor_args)))
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~snplib_generic_netserver_t()
|
||||
virtual ~generic_netserver_t()
|
||||
{
|
||||
for (auto& wptr : _listeners) {
|
||||
if (auto sptr = wptr.lock()) {
|
||||
@@ -300,7 +297,7 @@ public:
|
||||
{
|
||||
auto err = listener->startListen();
|
||||
if (err) {
|
||||
co_return std::unexpect(snplib_deduced_error(err, std::make_error_code(std::errc::io_error)));
|
||||
co_return std::unexpect(deduced_ret_error(err, std::make_error_code(std::errc::io_error)));
|
||||
}
|
||||
|
||||
auto listener_sptr = std::make_shared<ListenerT>(std::move(listener));
|
||||
@@ -320,7 +317,7 @@ public:
|
||||
{
|
||||
auto err = _listener->start();
|
||||
if (err) {
|
||||
co_return std::unexpect(snplib_deduced_error(err, std::make_error_code(std::errc::io_error)));
|
||||
co_return std::unexpect(deduced_ret_error(err, std::make_error_code(std::errc::io_error)));
|
||||
}
|
||||
|
||||
while (true) {
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace snplib
|
||||
|
||||
/* SERIALIZATION/DESERIALIZATION PROCESS ERROR TYPE */
|
||||
|
||||
typedef std::error_code snplib_serialization_error_t;
|
||||
typedef std::error_code serialization_error_t;
|
||||
|
||||
/* SERIALIZATION/DESERIALIZATION PROCESS TUNING PARAMETERS */
|
||||
|
||||
@@ -22,20 +22,20 @@ static constexpr std::string_view SNPLIB_SERIALIZING_DEFAULT_ELEM_DELIMITER{","}
|
||||
|
||||
|
||||
template <typename T>
|
||||
concept snplib_serialization_params_c = std::copyable<T> && requires(T t) {
|
||||
concept serialization_params_c = std::copyable<T> && requires(T t) {
|
||||
// delimiter between items of serializing values sequence
|
||||
requires snplib_output_char_range_c<decltype(t.elem_delim)>;
|
||||
requires output_char_range_c<decltype(t.elem_delim)>;
|
||||
|
||||
// delimiter between items of aggregative (multi-element) serializing value
|
||||
requires snplib_output_char_range_c<decltype(t.seq_delim)>;
|
||||
requires output_char_range_c<decltype(t.seq_delim)>;
|
||||
|
||||
// a format string for std::chrono::time_point types
|
||||
requires snplib_output_char_range_c<decltype(t.timepoint_format)>;
|
||||
requires output_char_range_c<decltype(t.timepoint_format)>;
|
||||
};
|
||||
|
||||
|
||||
// default serializatio/deserialization process parameters type
|
||||
struct snplib_serialization_params_t {
|
||||
struct serialization_params_t {
|
||||
std::string elem_delim{SNPLIB_SERIALIZING_DEFAULT_ELEM_DELIMITER};
|
||||
std::string seq_delim{SNPLIB_SERIALIZING_DEFAULT_SEQ_DELIMITER};
|
||||
|
||||
@@ -48,64 +48,64 @@ struct snplib_serialization_params_t {
|
||||
|
||||
/* SERIALIZER/DESERIALIZER CONCEPTS */
|
||||
|
||||
template <snplib_error_c RetT>
|
||||
struct snplib_serializer_interface_t {
|
||||
virtual ~snplib_serializer_interface_t() = default;
|
||||
template <ret_error_c RetT>
|
||||
struct serializer_interface_t {
|
||||
virtual ~serializer_interface_t() = default;
|
||||
|
||||
typedef RetT error_t;
|
||||
|
||||
template <std::derived_from<snplib_serializer_interface_t> SelfT, snplib_output_char_range_c R, typename ValueT>
|
||||
template <std::derived_from<serializer_interface_t> SelfT, output_char_range_c R, typename ValueT>
|
||||
RetT operator()(this SelfT&& self, R& output, ValueT const& value)
|
||||
{
|
||||
return std::forward<SelfT>(self)(output, value);
|
||||
}
|
||||
|
||||
template <std::derived_from<snplib_serializer_interface_t> SelfT, snplib_output_char_range_c R, typename ValueT>
|
||||
RetT operator()(this SelfT&& self, R& output, ValueT const& value, snplib_serialization_params_c auto const& params)
|
||||
template <std::derived_from<serializer_interface_t> SelfT, output_char_range_c R, typename ValueT>
|
||||
RetT operator()(this SelfT&& self, R& output, ValueT const& value, serialization_params_c auto const& params)
|
||||
{
|
||||
return std::forward<SelfT>(self)(output, value, params);
|
||||
}
|
||||
|
||||
protected:
|
||||
snplib_serializer_interface_t() = default;
|
||||
serializer_interface_t() = default;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
concept snplib_serializer_c =
|
||||
std::derived_from<T, snplib_serializer_interface_t<typename T::error_t>> && requires(T t, const T t_const) {
|
||||
concept serializer_c =
|
||||
std::derived_from<T, serializer_interface_t<typename T::error_t>> && requires(T t, const T t_const) {
|
||||
// static const variable with name of the serializer
|
||||
requires std::formattable<decltype(T::serializerName), char> && std::is_const_v<decltype(T::serializerName)>;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <snplib_error_c RetT>
|
||||
struct snplib_deserializer_interface_t {
|
||||
virtual ~snplib_deserializer_interface_t() = default;
|
||||
template <ret_error_c RetT>
|
||||
struct deserializer_interface_t {
|
||||
virtual ~deserializer_interface_t() = default;
|
||||
|
||||
typedef RetT error_t;
|
||||
|
||||
template <std::derived_from<snplib_deserializer_interface_t> SelfT, snplib_input_char_range_c R, typename ValueT>
|
||||
template <std::derived_from<deserializer_interface_t> SelfT, input_char_range_c R, typename ValueT>
|
||||
RetT operator()(this SelfT&& self, R const& input, ValueT& value)
|
||||
{
|
||||
return std::forward<SelfT>(self)(input, value);
|
||||
}
|
||||
|
||||
template <std::derived_from<snplib_deserializer_interface_t> SelfT, snplib_input_char_range_c R, typename ValueT>
|
||||
RetT operator()(this SelfT&& self, R const& input, ValueT& value, snplib_serialization_params_c auto& params)
|
||||
template <std::derived_from<deserializer_interface_t> SelfT, input_char_range_c R, typename ValueT>
|
||||
RetT operator()(this SelfT&& self, R const& input, ValueT& value, serialization_params_c auto& params)
|
||||
{
|
||||
return std::forward<SelfT>(self)(input, value, params);
|
||||
}
|
||||
|
||||
protected:
|
||||
snplib_deserializer_interface_t() = default;
|
||||
deserializer_interface_t() = default;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
concept snplib_deserializer_c =
|
||||
std::derived_from<T, snplib_deserializer_interface_t<typename T::error_t>> && requires(T t, const T t_const) {
|
||||
concept deserializer_c =
|
||||
std::derived_from<T, deserializer_interface_t<typename T::error_t>> && requires(T t, const T t_const) {
|
||||
// static const variable with name of the deserializer
|
||||
requires std::formattable<decltype(T::deserializerName), char> &&
|
||||
std::is_const_v<decltype(T::deserializerName)>;
|
||||
@@ -115,13 +115,9 @@ concept snplib_deserializer_c =
|
||||
|
||||
/* SERIALIZATION/DESERIALIZATION PROCESS ERROR CODES */
|
||||
|
||||
enum class snplib_serializer_error_e : int { ERROR_OK, ERROR_UNDERLYING_SERIALIZER };
|
||||
enum class serializer_error_e : int { ERROR_OK, ERROR_UNDERLYING_SERIALIZER };
|
||||
|
||||
enum class snplib_deserializer_error_e : int {
|
||||
ERROR_OK,
|
||||
ERROR_UNDERLYING_DESERIALIZER,
|
||||
ERROR_INVALID_SERIALIZED_VALUE
|
||||
};
|
||||
enum class deserializer_error_e : int { ERROR_OK, ERROR_UNDERLYING_DESERIALIZER, ERROR_INVALID_SERIALIZED_VALUE };
|
||||
|
||||
} // end of namespace snplib
|
||||
|
||||
@@ -130,12 +126,12 @@ namespace std
|
||||
{
|
||||
|
||||
template <>
|
||||
class is_error_code_enum<snplib::snplib_serializer_error_e> : public true_type
|
||||
class is_error_code_enum<snplib::serializer_error_e> : public true_type
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
class is_error_code_enum<snplib::snplib_deserializer_error_e> : public true_type
|
||||
class is_error_code_enum<snplib::deserializer_error_e> : public true_type
|
||||
{
|
||||
};
|
||||
|
||||
@@ -152,8 +148,8 @@ namespace snplib
|
||||
|
||||
/* error categories */
|
||||
|
||||
struct snplib_serializer_error_category_t : public std::error_category {
|
||||
snplib_serializer_error_category_t() : std::error_category() {}
|
||||
struct serializer_error_category_t : public std::error_category {
|
||||
serializer_error_category_t() : std::error_category() {}
|
||||
|
||||
const char* name() const noexcept
|
||||
{
|
||||
@@ -162,28 +158,28 @@ struct snplib_serializer_error_category_t : public std::error_category {
|
||||
|
||||
std::string message(int ec) const
|
||||
{
|
||||
snplib_serializer_error_e err = static_cast<snplib_serializer_error_e>(ec);
|
||||
serializer_error_e err = static_cast<serializer_error_e>(ec);
|
||||
|
||||
switch (err) {
|
||||
case snplib_serializer_error_e::ERROR_OK:
|
||||
case serializer_error_e::ERROR_OK:
|
||||
return "OK";
|
||||
case snplib_serializer_error_e::ERROR_UNDERLYING_SERIALIZER:
|
||||
case serializer_error_e::ERROR_UNDERLYING_SERIALIZER:
|
||||
return "error returned by underlying serializer";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
static const snplib_serializer_error_category_t& get()
|
||||
static const serializer_error_category_t& get()
|
||||
{
|
||||
static const snplib_serializer_error_category_t constInst;
|
||||
static const serializer_error_category_t constInst;
|
||||
return constInst;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct snplib_deserializer_error_category_t : public std::error_category {
|
||||
snplib_deserializer_error_category_t() : std::error_category() {}
|
||||
struct deserializer_error_category_t : public std::error_category {
|
||||
deserializer_error_category_t() : std::error_category() {}
|
||||
|
||||
const char* name() const noexcept
|
||||
{
|
||||
@@ -192,58 +188,56 @@ struct snplib_deserializer_error_category_t : public std::error_category {
|
||||
|
||||
std::string message(int ec) const
|
||||
{
|
||||
snplib_deserializer_error_e err = static_cast<snplib_deserializer_error_e>(ec);
|
||||
deserializer_error_e err = static_cast<deserializer_error_e>(ec);
|
||||
|
||||
switch (err) {
|
||||
case snplib_deserializer_error_e::ERROR_OK:
|
||||
case deserializer_error_e::ERROR_OK:
|
||||
return "OK";
|
||||
case snplib_deserializer_error_e::ERROR_UNDERLYING_DESERIALIZER:
|
||||
case deserializer_error_e::ERROR_UNDERLYING_DESERIALIZER:
|
||||
return "error returned by underlying deserializer";
|
||||
case snplib_deserializer_error_e::ERROR_INVALID_SERIALIZED_VALUE:
|
||||
case deserializer_error_e::ERROR_INVALID_SERIALIZED_VALUE:
|
||||
return "invalid serialized value";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
static const snplib_deserializer_error_category_t& get()
|
||||
static const deserializer_error_category_t& get()
|
||||
{
|
||||
static const snplib_deserializer_error_category_t constInst;
|
||||
static const deserializer_error_category_t constInst;
|
||||
return constInst;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline std::error_code make_error_code(snplib_serializer_error_e ec)
|
||||
inline std::error_code make_error_code(serializer_error_e ec)
|
||||
{
|
||||
return std::error_code(static_cast<int>(ec), snplib_serializer_error_category_t::get());
|
||||
return std::error_code(static_cast<int>(ec), serializer_error_category_t::get());
|
||||
}
|
||||
|
||||
inline std::error_code make_error_code(snplib_deserializer_error_e ec)
|
||||
inline std::error_code make_error_code(deserializer_error_e ec)
|
||||
{
|
||||
return std::error_code(static_cast<int>(ec), snplib_deserializer_error_category_t::get());
|
||||
return std::error_code(static_cast<int>(ec), deserializer_error_category_t::get());
|
||||
}
|
||||
|
||||
|
||||
/* BASE SERIALIZER CLASS (FOR IMPLEMENTATIONS BELOW) */
|
||||
|
||||
struct snplib_serializer_base_t : snplib_serializer_interface_t<snplib_serialization_error_t> {
|
||||
virtual ~snplib_serializer_base_t() = default;
|
||||
struct serializer_base_t : serializer_interface_t<serialization_error_t> {
|
||||
virtual ~serializer_base_t() = default;
|
||||
|
||||
using typename snplib_serializer_interface_t<snplib_serialization_error_t>::error_t;
|
||||
using typename serializer_interface_t<serialization_error_t>::error_t;
|
||||
|
||||
protected:
|
||||
snplib_serializer_base_t() = default;
|
||||
serializer_base_t() = default;
|
||||
|
||||
static void addElemDelimiter(snplib_output_char_range_c auto& output,
|
||||
snplib_serialization_params_c auto const& params)
|
||||
static void addElemDelimiter(output_char_range_c auto& output, serialization_params_c auto const& params)
|
||||
{
|
||||
std::format_to(std::back_inserter(output), "{}", params.elem_delim);
|
||||
}
|
||||
|
||||
|
||||
static void addSeqDelimiter(snplib_output_char_range_c auto& output,
|
||||
snplib_serialization_params_c auto const& params)
|
||||
static void addSeqDelimiter(output_char_range_c auto& output, serialization_params_c auto const& params)
|
||||
{
|
||||
std::format_to(std::back_inserter(output), "{}", params.seq_delim);
|
||||
}
|
||||
@@ -251,24 +245,24 @@ protected:
|
||||
|
||||
template <typename VT, typename R>
|
||||
requires(std::ranges::input_range<R> && std::same_as<VT, std::ranges::range_value_t<R>>)
|
||||
static error_t serializeRange(snplib_serializer_c auto& sr,
|
||||
static error_t serializeRange(serializer_c auto& sr,
|
||||
R const& r,
|
||||
snplib_output_char_range_c auto& output,
|
||||
snplib_serialization_params_c auto const& params)
|
||||
output_char_range_c auto& output,
|
||||
serialization_params_c auto const& params)
|
||||
{
|
||||
size_t i = 0, N = std::ranges::size(r);
|
||||
|
||||
for (auto const& el : r) {
|
||||
auto err = sr(output, el, params);
|
||||
if (err) {
|
||||
return snplib_deduced_error(err, snplib_serializer_error_e::ERROR_UNDERLYING_SERIALIZER);
|
||||
return deduced_ret_error(err, serializer_error_e::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
if (++i < N) {
|
||||
snplib_serializer_base_t::addElemDelimiter(output, params);
|
||||
serializer_base_t::addElemDelimiter(output, params);
|
||||
}
|
||||
}
|
||||
|
||||
return snplib_serializer_error_e::ERROR_OK;
|
||||
return serializer_error_e::ERROR_OK;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -277,20 +271,20 @@ protected:
|
||||
/* BASE DESERIALIZER CLASS (FOR IMPLEMENTATIONS BELOW) */
|
||||
|
||||
|
||||
struct snplib_deserializer_base_t : snplib_deserializer_interface_t<snplib_serialization_error_t> {
|
||||
using typename snplib_deserializer_interface_t<snplib_serialization_error_t>::error_t;
|
||||
struct deserializer_base_t : deserializer_interface_t<serialization_error_t> {
|
||||
using typename deserializer_interface_t<serialization_error_t>::error_t;
|
||||
|
||||
virtual ~snplib_deserializer_base_t() = default;
|
||||
virtual ~deserializer_base_t() = default;
|
||||
|
||||
|
||||
protected:
|
||||
snplib_deserializer_base_t() = default;
|
||||
deserializer_base_t() = default;
|
||||
|
||||
//
|
||||
// empty == true, if the 'input' is empty or if all elements consist of only spaces
|
||||
//
|
||||
static std::vector<std::string_view> splitValueIntoElements(snplib_input_char_range_c auto const& input,
|
||||
snplib_serialization_params_c auto const& params,
|
||||
static std::vector<std::string_view> splitValueIntoElements(input_char_range_c auto const& input,
|
||||
serialization_params_c auto const& params,
|
||||
bool& empty)
|
||||
{
|
||||
static_assert(std::ranges::contiguous_range<decltype(input)>, "NOT IMPLEMENTED FOR NON-CONTIGUIUS RANGES!!!");
|
||||
@@ -301,7 +295,7 @@ protected:
|
||||
empty = true;
|
||||
|
||||
std::ranges::for_each(std::views::split(input, params.elem_delim), [&res, &empty](auto const& el) {
|
||||
std::back_inserter(res) = snplib_trim_spaces_as_view(std::string_view{el.begin(), el.end()});
|
||||
std::back_inserter(res) = trim_spaces_as_view(std::string_view{el.begin(), el.end()});
|
||||
if (empty && res.back().size()) {
|
||||
empty = false;
|
||||
}
|
||||
@@ -315,14 +309,14 @@ protected:
|
||||
|
||||
|
||||
template <typename VT, std::ranges::output_range<VT> R, typename... DeserParamsT>
|
||||
static error_t deserializingRange(snplib_deserializer_c auto& dsr,
|
||||
snplib_input_char_range_c auto const& input,
|
||||
static error_t deserializingRange(deserializer_c auto& dsr,
|
||||
input_char_range_c auto const& input,
|
||||
R& r,
|
||||
snplib_serialization_params_c auto const& params)
|
||||
serialization_params_c auto const& params)
|
||||
{
|
||||
if (std::ranges::size(input) == 0) { // ignore an empty input, just return empty range?!!
|
||||
r = R{};
|
||||
return snplib_deserializer_error_e::ERROR_OK;
|
||||
return deserializer_error_e::ERROR_OK;
|
||||
}
|
||||
|
||||
// auto r_str = std::views::split(input, params.seq_delim);
|
||||
@@ -334,11 +328,11 @@ protected:
|
||||
// auto err = dsr(el, val, std::forward<DeserParamsT>(params)...);
|
||||
auto err = dsr(el, val, params);
|
||||
if (err) {
|
||||
return snplib_deduced_error(err, snplib_deserializer_error_e::ERROR_UNDERLYING_DESERIALIZER);
|
||||
return deduced_ret_error(err, deserializer_error_e::ERROR_UNDERLYING_DESERIALIZER);
|
||||
}
|
||||
|
||||
if (it == r.end()) {
|
||||
if constexpr (!snplib_fixed_size_range_c<R>) {
|
||||
if constexpr (!fixed_size_range_c<R>) {
|
||||
std::back_inserter(r) = val;
|
||||
it = r.end();
|
||||
}
|
||||
@@ -348,7 +342,7 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
return snplib_deserializer_error_e::ERROR_OK;
|
||||
return deserializer_error_e::ERROR_OK;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -357,13 +351,13 @@ protected:
|
||||
/* MAIN (FALLBACK) TEMPLATED IMPLEMENTATION OF SERIALIZER/DESERIALIZER */
|
||||
|
||||
template <typename VT>
|
||||
struct snplib_serializer_t : snplib_serializer_base_t {
|
||||
struct serializer_t : serializer_base_t {
|
||||
constexpr static std::string_view serializerName{"SNPLIB-FALLBACK-SERIALIZER"};
|
||||
|
||||
template <snplib_serialization_params_c ParamsT = snplib_serialization_params_t>
|
||||
error_t operator()(snplib_output_char_range_c auto& output,
|
||||
template <serialization_params_c ParamsT = serialization_params_t>
|
||||
error_t operator()(output_char_range_c auto& output,
|
||||
VT const& value,
|
||||
ParamsT const& params = snplib_serialization_params_t{})
|
||||
ParamsT const& params = serialization_params_t{})
|
||||
{
|
||||
if constexpr (std::convertible_to<VT, std::string>) {
|
||||
std::string s = value;
|
||||
@@ -375,35 +369,35 @@ struct snplib_serializer_t : snplib_serializer_base_t {
|
||||
if constexpr (std::same_as<value_t, char>) {
|
||||
std::ranges::copy(value, std::back_inserter(output));
|
||||
} else {
|
||||
snplib_serializer_t<value_t> sr;
|
||||
serializer_t<value_t> sr;
|
||||
|
||||
return snplib_serializer_base_t::serializeRange<value_t>(sr, value, output, params);
|
||||
return serializer_base_t::serializeRange<value_t>(sr, value, output, params);
|
||||
}
|
||||
} else if constexpr (snplib_tuple_like_c<VT>) {
|
||||
} else if constexpr (tuple_like_c<VT>) {
|
||||
return [&output, ¶ms]<size_t I = 0>(this auto&& self, VT const& tp) -> error_t {
|
||||
if constexpr (I < (std::tuple_size_v<VT> - 1)) {
|
||||
auto err = snplib_serializer_t<std::tuple_element_t<I, VT>>{}(output, std::get<I>(tp), params);
|
||||
auto err = serializer_t<std::tuple_element_t<I, VT>>{}(output, std::get<I>(tp), params);
|
||||
if (err) {
|
||||
return snplib_deduced_error(err, snplib_serializer_error_e::ERROR_UNDERLYING_SERIALIZER);
|
||||
return deduced_ret_error(err, serializer_error_e::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
snplib_serializer_base_t::addElemDelimiter(output, params);
|
||||
serializer_base_t::addElemDelimiter(output, params);
|
||||
|
||||
return std::forward<decltype(self)>(self).template operator()<I + 1>(tp);
|
||||
// } else if constexpr (I < (std::tuple_size_v<VT> - 1)) { // the last element
|
||||
} else { // the last element
|
||||
auto err = snplib_serializer_t<std::tuple_element_t<I, VT>>{}(output, std::get<I>(tp), params);
|
||||
auto err = serializer_t<std::tuple_element_t<I, VT>>{}(output, std::get<I>(tp), params);
|
||||
if (err) {
|
||||
return snplib_deduced_error(err, snplib_serializer_error_e::ERROR_UNDERLYING_SERIALIZER);
|
||||
return deduced_ret_error(err, serializer_error_e::ERROR_UNDERLYING_SERIALIZER);
|
||||
}
|
||||
|
||||
return snplib_serializer_error_e::ERROR_OK;
|
||||
return serializer_error_e::ERROR_OK;
|
||||
}
|
||||
}(value);
|
||||
} else if constexpr (snplib_anytime_point_c<VT>) {
|
||||
} else if constexpr (anytime_point_c<VT>) {
|
||||
std::string_view fmt{params.timepoint_format};
|
||||
std::vformat_to(std::back_inserter(output), fmt, std::make_format_args(value));
|
||||
} else if constexpr (snplib_time_duration_c<VT>) {
|
||||
} else if constexpr (time_duration_c<VT>) {
|
||||
std::format_to(std::back_inserter(output), "{}", value.count());
|
||||
} else if constexpr (std::integral<VT>) {
|
||||
std::vformat_to(std::back_inserter(output), std::string_view{params.integer_format},
|
||||
@@ -417,34 +411,34 @@ struct snplib_serializer_t : snplib_serializer_base_t {
|
||||
static_assert(false, "UNSUPPORTED TYPE!!!");
|
||||
}
|
||||
|
||||
return snplib_serializer_error_e::ERROR_OK;
|
||||
return serializer_error_e::ERROR_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename VT>
|
||||
struct snplib_deserializer_t : snplib_deserializer_base_t {
|
||||
struct deserializer_t : deserializer_base_t {
|
||||
static constexpr std::string_view deserializerName{"SNPLIB-FALLBACK-DESERIALIZER"};
|
||||
|
||||
virtual ~snplib_deserializer_t() = default;
|
||||
virtual ~deserializer_t() = default;
|
||||
|
||||
|
||||
template <snplib_serialization_params_c ParamsT = snplib_serialization_params_t>
|
||||
error_t operator()(snplib_input_char_range_c auto const& input,
|
||||
template <serialization_params_c ParamsT = serialization_params_t>
|
||||
error_t operator()(input_char_range_c auto const& input,
|
||||
VT& value,
|
||||
ParamsT const& params = snplib_serialization_params_t{})
|
||||
ParamsT const& params = serialization_params_t{})
|
||||
{
|
||||
if constexpr (std::is_arithmetic_v<VT>) {
|
||||
auto v = snplib_num_from_range<VT>(snplib_trim_spaces<std::string>(input));
|
||||
auto v = char_range_to_number<VT>(trim_spaces<std::string>(input));
|
||||
if (!v.has_value()) {
|
||||
return snplib_deserializer_error_e::ERROR_INVALID_SERIALIZED_VALUE;
|
||||
return deserializer_error_e::ERROR_INVALID_SERIALIZED_VALUE;
|
||||
}
|
||||
|
||||
value = v.value();
|
||||
} else if constexpr (snplib_output_char_range_c<VT>) {
|
||||
} else if constexpr (output_char_range_c<VT>) {
|
||||
VT r;
|
||||
if constexpr (snplib_fixed_size_range_c<VT>) {
|
||||
if constexpr (fixed_size_range_c<VT>) {
|
||||
size_t N =
|
||||
std::ranges::size(r) <= std::ranges::size(input) ? std::ranges::size(r) : std::ranges::size(input);
|
||||
|
||||
@@ -469,10 +463,10 @@ struct snplib_deserializer_t : snplib_deserializer_base_t {
|
||||
// no reference or constants allowed
|
||||
static_assert(!(std::is_reference_v<el_t> || std::is_const_v<el_t>), "INVALID RANGE ELEMENT TYPE!!!");
|
||||
|
||||
snplib_deserializer_t<el_t> dsr;
|
||||
deserializer_t<el_t> dsr;
|
||||
|
||||
return deserializingRange<el_t>(dsr, input, value, params);
|
||||
} else if constexpr (snplib_tuple_like_c<VT>) {
|
||||
} else if constexpr (tuple_like_c<VT>) {
|
||||
bool empty;
|
||||
auto elems = splitValueIntoElements(input, params, &empty);
|
||||
if (empty) {
|
||||
@@ -481,37 +475,35 @@ struct snplib_deserializer_t : snplib_deserializer_base_t {
|
||||
return [&input, ¶ms, &elems]<size_t I = 0>(this auto& self, VT& tp) {
|
||||
if constexpr (I < std::tuple_size_v<VT>) {
|
||||
if (I < elems.size()) {
|
||||
auto err =
|
||||
snplib_deserializer_t<std::tuple_element_t<I, VT>>{}(elems[I], std::get<I>(tp), params);
|
||||
auto err = deserializer_t<std::tuple_element_t<I, VT>>{}(elems[I], std::get<I>(tp), params);
|
||||
if (err) {
|
||||
return snplib_deduced_error(err,
|
||||
snplib_deserializer_error_e::ERROR_UNDERLYING_DESERIALIZER);
|
||||
return deduced_ret_error(err, deserializer_error_e::ERROR_UNDERLYING_DESERIALIZER);
|
||||
}
|
||||
|
||||
return self.template operator()<I + 1>(tp);
|
||||
} else {
|
||||
return snplib_deserializer_error_e::ERROR_OK;
|
||||
return deserializer_error_e::ERROR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return snplib_deserializer_error_e::ERROR_OK;
|
||||
return deserializer_error_e::ERROR_OK;
|
||||
}(value);
|
||||
}
|
||||
|
||||
} else if constexpr (snplib_anytime_point_c<VT>) {
|
||||
std::istringstream ist{snplib_trim_spaces<std::string>(input)};
|
||||
} else if constexpr (anytime_point_c<VT>) {
|
||||
std::istringstream ist{trim_spaces<std::string>(input)};
|
||||
std::chrono::from_stream(ist, params.timepoint_format.c_str(), value);
|
||||
if (ist.fail()) {
|
||||
return snplib_deserializer_error_e::ERROR_INVALID_SERIALIZED_VALUE;
|
||||
return deserializer_error_e::ERROR_INVALID_SERIALIZED_VALUE;
|
||||
}
|
||||
} else if constexpr (snplib_time_duration_c<VT>) {
|
||||
} else if constexpr (time_duration_c<VT>) {
|
||||
typename VT::rep vd;
|
||||
|
||||
snplib_deserializer_t<typename VT::rep> dsr;
|
||||
deserializer_t<typename VT::rep> dsr;
|
||||
|
||||
auto err = dsr(snplib_trim_spaces_as_view(input), vd, params);
|
||||
auto err = dsr(trim_spaces_as_view(input), vd, params);
|
||||
if (err) {
|
||||
return snplib_deduced_error(err, snplib_deserializer_error_e::ERROR_UNDERLYING_DESERIALIZER);
|
||||
return deduced_ret_error(err, deserializer_error_e::ERROR_UNDERLYING_DESERIALIZER);
|
||||
}
|
||||
|
||||
value = VT{vd};
|
||||
@@ -520,7 +512,7 @@ struct snplib_deserializer_t : snplib_deserializer_base_t {
|
||||
}
|
||||
|
||||
|
||||
return snplib_deserializer_error_e::ERROR_OK;
|
||||
return deserializer_error_e::ERROR_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
namespace snplib
|
||||
{
|
||||
|
||||
template <snplib_input_char_range_c R>
|
||||
template <input_char_range_c R>
|
||||
static constexpr size_t hash_FNV1a(const R& r)
|
||||
{
|
||||
static_assert(sizeof(size_t) == 8 || sizeof(size_t) == 4, "The ONLY 32 or 64-bit std::size_t are supported!!!");
|
||||
@@ -52,8 +52,8 @@ static constexpr size_t hash_FNV1a(std::forward_iterator auto begin, std::sentin
|
||||
|
||||
|
||||
// Boost implementation of hash combining
|
||||
template <snplib_hashable_c T, snplib_hashable_c... Ts>
|
||||
static constexpr void snplib_hash_combine(std::size_t& seed, const T& v, Ts&&... vs)
|
||||
template <hashable_c T, hashable_c... Ts>
|
||||
static constexpr void hash_combine(std::size_t& seed, const T& v, Ts&&... vs)
|
||||
{
|
||||
static constexpr auto digits = std::numeric_limits<std::size_t>::digits;
|
||||
static_assert(digits == 64 || digits == 32, "The ONLY 32 or 64-bit std::size_t are supported!!!");
|
||||
@@ -80,7 +80,7 @@ static constexpr void snplib_hash_combine(std::size_t& seed, const T& v, Ts&&...
|
||||
}
|
||||
|
||||
if constexpr (sizeof...(Ts)) {
|
||||
snplib_hash_combine(seed, std::forward<Ts>(vs)...);
|
||||
hash_combine(seed, std::forward<Ts>(vs)...);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,14 +12,14 @@ namespace snplib
|
||||
|
||||
|
||||
template <typename T>
|
||||
concept snplib_serializable_c = requires { snplib_serializer_t<std::remove_cvref_t<T>>{}; };
|
||||
concept serializable_c = requires { serializer_t<std::remove_cvref_t<T>>{}; };
|
||||
|
||||
template <snplib_char_range_c CharRangeT = std::vector<char>>
|
||||
template <char_range_c CharRangeT = std::vector<char>>
|
||||
requires(std::ranges::viewable_range<CharRangeT> && !std::ranges::borrowed_range<CharRangeT>)
|
||||
class snplib_keyvalue_expr_t
|
||||
class keyvalue_expr_t
|
||||
{
|
||||
public:
|
||||
static constexpr bool mutableContent = snplib_output_char_range_c<CharRangeT>;
|
||||
static constexpr bool mutableContent = output_char_range_c<CharRangeT>;
|
||||
static constexpr bool contiguousContent =
|
||||
std::ranges::viewable_range<CharRangeT> && std::ranges::contiguous_range<CharRangeT>;
|
||||
|
||||
@@ -34,24 +34,24 @@ public:
|
||||
};
|
||||
|
||||
// inner char-sequence storage
|
||||
constexpr snplib_keyvalue_expr_t(config_t cfg = config_t{})
|
||||
requires snplib_owning_range_c<CharRangeT>
|
||||
constexpr keyvalue_expr_t(config_t cfg = config_t{})
|
||||
requires owning_range_c<CharRangeT>
|
||||
: _ownByteSeq(), _byteSeq(_ownByteSeq), _config(cfg), _isValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
// outter char-sequence storage
|
||||
constexpr snplib_keyvalue_expr_t(CharRangeT& bytes, config_t cfg = config_t{})
|
||||
constexpr keyvalue_expr_t(CharRangeT& bytes, config_t cfg = config_t{})
|
||||
: _ownByteSeq(), _byteSeq(bytes), _config(cfg)
|
||||
{
|
||||
fromCharRange(bytes, cfg);
|
||||
}
|
||||
|
||||
virtual ~snplib_keyvalue_expr_t() = default;
|
||||
virtual ~keyvalue_expr_t() = default;
|
||||
|
||||
// parse from char range (deep copy of the input bytes)
|
||||
error_t fromCharRange(snplib_input_char_range_c auto&& bytes, config_t cfg = config_t{})
|
||||
requires(!std::same_as<CharRangeT, std::remove_cvref_t<decltype(bytes)>> && snplib_owning_range_c<CharRangeT>)
|
||||
error_t fromCharRange(input_char_range_c auto&& bytes, config_t cfg = config_t{})
|
||||
requires(!std::same_as<CharRangeT, std::remove_cvref_t<decltype(bytes)>> && owning_range_c<CharRangeT>)
|
||||
{
|
||||
if constexpr (requires(CharRangeT t) { t.clear(std::declval<size_t>()); }) {
|
||||
_ownByteSeq.clear();
|
||||
@@ -74,15 +74,15 @@ public:
|
||||
|
||||
// key and value
|
||||
|
||||
auto bs = snplib_trim_spaces_as_view(bytes, TrimType::TRIM_LEFT);
|
||||
auto bs = trim_spaces_as_view(bytes, TrimType::TRIM_LEFT);
|
||||
auto found = std::ranges::search(bs, _config.keyval_delim);
|
||||
|
||||
if (found.empty()) { // no value
|
||||
_key = snplib_trim_spaces_as_view(bs, TrimType::TRIM_RIGHT);
|
||||
_key = trim_spaces_as_view(bs, TrimType::TRIM_RIGHT);
|
||||
|
||||
_value = decltype(_value)();
|
||||
} else {
|
||||
_key = snplib_trim_spaces_as_view(decltype(_key)(bs.begin(), found.begin()), TrimType::TRIM_RIGHT);
|
||||
_key = trim_spaces_as_view(decltype(_key)(bs.begin(), found.begin()), TrimType::TRIM_RIGHT);
|
||||
|
||||
// do not delete space at the end of value-string!
|
||||
_value = decltype(_value)(found.end(), bs.end());
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
// split value to elements
|
||||
|
||||
if (!_value.empty()) {
|
||||
_valueSeq = snplib_split_char_range<decltype(_valueSeq)>(_value, _config.valseq_delim);
|
||||
_valueSeq = split_char_range<decltype(_valueSeq)>(_value, _config.valseq_delim);
|
||||
}
|
||||
|
||||
if (_key.empty() && !mutableContent) { // at least key must be present
|
||||
@@ -109,10 +109,10 @@ public:
|
||||
return _isValid;
|
||||
}
|
||||
|
||||
template <snplib_char_range_c R>
|
||||
template <char_range_c R>
|
||||
constexpr R key() const
|
||||
{
|
||||
return snplib_transform_char_range<R>(_key);
|
||||
return transform_char_range<R>(_key);
|
||||
}
|
||||
|
||||
constexpr auto key() const
|
||||
@@ -120,10 +120,10 @@ public:
|
||||
return _key;
|
||||
}
|
||||
|
||||
template <snplib_char_range_c R>
|
||||
template <char_range_c R>
|
||||
constexpr R value() const
|
||||
{
|
||||
return snplib_transform_char_range<R>(_value);
|
||||
return transform_char_range<R>(_value);
|
||||
}
|
||||
|
||||
constexpr auto value() const
|
||||
@@ -134,7 +134,7 @@ public:
|
||||
|
||||
template <std::ranges::range OR>
|
||||
requires(std::ranges::output_range<OR, std::ranges::range_value_t<OR>> &&
|
||||
snplib_char_range_c<std::ranges::range_value_t<OR>>)
|
||||
char_range_c<std::ranges::range_value_t<OR>>)
|
||||
OR valueSeq(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
|
||||
{
|
||||
using el_t = std::ranges::range_value_t<OR>;
|
||||
@@ -174,7 +174,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
template <snplib_char_range_c OR>
|
||||
template <char_range_c OR>
|
||||
OR valueJoinSeq(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
|
||||
{
|
||||
if (N == 0 || _valueSeq.empty() || start >= _valueSeq.size()) {
|
||||
@@ -191,7 +191,7 @@ public:
|
||||
return OR{_valueSeq[start].cbegin(), _valueSeq[last_idx].cend()};
|
||||
} else if constexpr (std::constructible_from<OR, std::string_view>) {
|
||||
return OR{std::string_view{_valueSeq[start].begin(), _valueSeq[last_idx].end()}};
|
||||
} else if constexpr (snplib_output_char_range_c<OR>) {
|
||||
} else if constexpr (output_char_range_c<OR>) {
|
||||
OR res;
|
||||
|
||||
std::copy(_valueSeq[start].begin(), _valueSeq[last_idx].end(), std::back_inserter(res));
|
||||
@@ -202,16 +202,16 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template <snplib_serializable_c KeyT, snplib_serialization_params_c SParT = snplib_serialization_params_t>
|
||||
template <serializable_c KeyT, serialization_params_c SParT = serialization_params_t>
|
||||
requires mutableContent
|
||||
error_t setKey(KeyT&& key, SParT const& sparams = snplib_serialization_params_t{})
|
||||
error_t setKey(KeyT&& key, SParT const& sparams = serialization_params_t{})
|
||||
{
|
||||
// _byteSeq.clear();
|
||||
_byteSeq = CharRangeT();
|
||||
|
||||
auto err = snplib_serializer_t<std::remove_cvref_t<KeyT>>{}(_byteSeq, std::forward<KeyT>(key), sparams);
|
||||
auto err = serializer_t<std::remove_cvref_t<KeyT>>{}(_byteSeq, std::forward<KeyT>(key), sparams);
|
||||
if (err) {
|
||||
return snplib_deduced_error(err, std::make_error_code(std::errc::invalid_argument));
|
||||
return deduced_ret_error(err, std::make_error_code(std::errc::invalid_argument));
|
||||
}
|
||||
|
||||
_key = {_byteSeq.begin(), _byteSeq.end()};
|
||||
@@ -221,9 +221,9 @@ public:
|
||||
return {};
|
||||
}
|
||||
|
||||
template <snplib_serializable_c ValueT, snplib_serialization_params_c SParT = snplib_serialization_params_t>
|
||||
template <serializable_c ValueT, serialization_params_c SParT = serialization_params_t>
|
||||
requires mutableContent
|
||||
error_t setValue(ValueT&& value, SParT sparams = snplib_serialization_params_t{})
|
||||
error_t setValue(ValueT&& value, SParT sparams = serialization_params_t{})
|
||||
{
|
||||
size_t key_sz = _key.size();
|
||||
size_t keyval_delim_pos = _key.size() + _config.keyval_delim.size();
|
||||
@@ -235,9 +235,9 @@ public:
|
||||
_byteSeq = {_byteSeq.begin(), it};
|
||||
}
|
||||
|
||||
auto err = snplib_serializer_t<std::remove_cvref_t<ValueT>>{}(_byteSeq, std::forward<ValueT>(value), sparams);
|
||||
auto err = serializer_t<std::remove_cvref_t<ValueT>>{}(_byteSeq, std::forward<ValueT>(value), sparams);
|
||||
if (err) {
|
||||
return snplib_deduced_error(err, std::make_error_code(std::errc::invalid_argument));
|
||||
return deduced_ret_error(err, std::make_error_code(std::errc::invalid_argument));
|
||||
}
|
||||
|
||||
// a reallocation of the byte sequence may occur so one needs to reinit _key and _value
|
||||
@@ -254,9 +254,9 @@ public:
|
||||
}
|
||||
|
||||
|
||||
template <snplib_serializable_c ValueT, snplib_serialization_params_c SParT = snplib_serialization_params_t>
|
||||
template <serializable_c ValueT, serialization_params_c SParT = serialization_params_t>
|
||||
requires mutableContent
|
||||
error_t appendValue(ValueT&& value, SParT sparams = snplib_serialization_params_t{})
|
||||
error_t appendValue(ValueT&& value, SParT sparams = serialization_params_t{})
|
||||
{
|
||||
if (_valueSeq.empty()) {
|
||||
return setValue(std::forward<ValueT>(value), std::move(sparams));
|
||||
@@ -271,9 +271,9 @@ public:
|
||||
|
||||
auto prev_size = std::ranges::distance(_byteSeq);
|
||||
|
||||
auto err = snplib_serializer_t<std::remove_cvref_t<ValueT>>{}(_byteSeq, std::forward<ValueT>(value), sparams);
|
||||
auto err = serializer_t<std::remove_cvref_t<ValueT>>{}(_byteSeq, std::forward<ValueT>(value), sparams);
|
||||
if (err) {
|
||||
return snplib_deduced_error(err, std::make_error_code(std::errc::invalid_argument));
|
||||
return deduced_ret_error(err, std::make_error_code(std::errc::invalid_argument));
|
||||
}
|
||||
|
||||
// a reallocation of the byte sequence may occur so one needs to reinit _key and _value
|
||||
@@ -284,7 +284,7 @@ public:
|
||||
std::advance(it, _config.keyval_delim.size());
|
||||
_value = {it, _byteSeq.end()};
|
||||
|
||||
_valueSeq = snplib_split_char_range<decltype(_valueSeq)>(_value, _config.valseq_delim);
|
||||
_valueSeq = split_char_range<decltype(_valueSeq)>(_value, _config.valseq_delim);
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -301,22 +301,22 @@ public:
|
||||
|
||||
// "val-spar" pairs
|
||||
constexpr auto is_val_spar_pairs =
|
||||
!snplib_serialization_params_c<ArgT> && []<size_t... Is>(std::index_sequence<Is...>) {
|
||||
!serialization_params_c<ArgT> && []<size_t... Is>(std::index_sequence<Is...>) {
|
||||
if constexpr (NARGS % 2) { // NARGS must be an even
|
||||
return false;
|
||||
}
|
||||
|
||||
using args_t = std::tuple<ArgT, ArgTs...>;
|
||||
|
||||
return ((snplib_serializable_c<std::tuple_element_t<Is * 2, args_t>> &&
|
||||
snplib_serialization_params_c<std::tuple_element_t<Is * 2 + 1, args_t>>) &&
|
||||
return ((serializable_c<std::tuple_element_t<Is * 2, args_t>> &&
|
||||
serialization_params_c<std::tuple_element_t<Is * 2 + 1, args_t>>) &&
|
||||
...);
|
||||
}(std::make_index_sequence<NARGS / 2>{});
|
||||
|
||||
|
||||
constexpr auto is_val_seq =
|
||||
snplib_serialization_params_c<ArgT> && []<size_t... Is>(std::index_sequence<Is...>) {
|
||||
return (snplib_serializable_c<std::tuple_element_t<Is, std::tuple<ArgTs...>>> && ...);
|
||||
serialization_params_c<ArgT> && []<size_t... Is>(std::index_sequence<Is...>) {
|
||||
return (serializable_c<std::tuple_element_t<Is, std::tuple<ArgTs...>>> && ...);
|
||||
}(std::make_index_sequence<sizeof...(ArgTs)>{});
|
||||
|
||||
static_assert(is_val_spar_pairs || is_val_seq, "Unsupported input parameter types!");
|
||||
@@ -325,7 +325,7 @@ public:
|
||||
return [this](this auto&& self, auto&& v1, auto&& sp1, auto&&... prs) -> error_t {
|
||||
auto err = appendValue(std::forward<decltype(v1)>(v1), std::forward<decltype(sp1)>(sp1));
|
||||
if (err) {
|
||||
return snplib_deduced_error(err, std::make_error_code(std::errc::invalid_argument));
|
||||
return deduced_ret_error(err, std::make_error_code(std::errc::invalid_argument));
|
||||
}
|
||||
|
||||
if constexpr (sizeof...(prs)) {
|
||||
@@ -342,7 +342,7 @@ public:
|
||||
auto err = appendValue(
|
||||
std::forward<std::tuple_element_t<I, tp_t>>(std::get<I>(std::forward<decltype(tp)>(tp))), sp);
|
||||
if (err) {
|
||||
return snplib_deduced_error(err, std::make_error_code(std::errc::invalid_argument));
|
||||
return deduced_ret_error(err, std::make_error_code(std::errc::invalid_argument));
|
||||
}
|
||||
|
||||
return std::forward<decltype(self)>(self).template operator()<I + 1>(
|
||||
@@ -363,11 +363,9 @@ public:
|
||||
return appendValue(std::forward<ArgT>(arg), std::forward<ArgTs>(args)...);
|
||||
}
|
||||
|
||||
template <snplib_serializable_c KeyT,
|
||||
snplib_serializable_c ValueT,
|
||||
snplib_serialization_params_c SParT = snplib_serialization_params_t>
|
||||
template <serializable_c KeyT, serializable_c ValueT, serialization_params_c SParT = serialization_params_t>
|
||||
requires mutableContent
|
||||
error_t setKeyValue(KeyT&& key, ValueT&& value, SParT sparams = snplib_serialization_params_t{})
|
||||
error_t setKeyValue(KeyT&& key, ValueT&& value, SParT sparams = serialization_params_t{})
|
||||
{
|
||||
auto err = setKey(std::forward<KeyT>(key), sparams);
|
||||
if (err) {
|
||||
|
||||
@@ -13,51 +13,10 @@
|
||||
namespace snplib
|
||||
{
|
||||
|
||||
/* snplib_logger_c-like class adaptor to use formating */
|
||||
|
||||
// template <snplib_logger_c LoggerT>
|
||||
// struct snplib_logger_fmt_adaptor_t : public LoggerT {
|
||||
// template<typename ...CtorArgTs>
|
||||
// snplib_logger_fmt_adaptor_t(CtorArgTs&&... ctor_args): LoggerT(std::forward<CtorArgTs>(ctor_args)...) {}
|
||||
|
||||
// ~snplib_logger_fmt_adaptor_t() = default;
|
||||
|
||||
// template <std::formattable<char>... ArgTs>
|
||||
// auto logInfo(std::format_string<ArgTs...> fmt, ArgTs&&... args)
|
||||
// {
|
||||
// return logInfo(std::format(fmt, std::forward<ArgTs>(args)...));
|
||||
// }
|
||||
|
||||
// template <std::formattable<char>... ArgTs>
|
||||
// auto logWarn(std::format_string<ArgTs...> fmt, ArgTs&&... args)
|
||||
// {
|
||||
// return logWarn(std::format(fmt, std::forward<ArgTs>(args)...));
|
||||
// }
|
||||
|
||||
// template <std::formattable<char>... ArgTs>
|
||||
// auto logDebug(std::format_string<ArgTs...> fmt, ArgTs&&... args)
|
||||
// {
|
||||
// return logDebug(std::format(fmt, std::forward<ArgTs>(args)...));
|
||||
// }
|
||||
|
||||
// template <std::formattable<char>... ArgTs>
|
||||
// auto logError(std::format_string<ArgTs...> fmt, ArgTs&&... args)
|
||||
// {
|
||||
// return logError(std::format(fmt, std::forward<ArgTs>(args)...));
|
||||
// }
|
||||
|
||||
// template <std::formattable<char>... ArgTs>
|
||||
// auto logTrace(std::format_string<ArgTs...> fmt, ArgTs&&... args)
|
||||
// {
|
||||
// return logTrace(std::format(fmt, std::forward<ArgTs>(args)...));
|
||||
// }
|
||||
// };
|
||||
|
||||
|
||||
|
||||
/* a NULL-logger */
|
||||
|
||||
struct snplib_null_logger_t {
|
||||
struct null_logger_t {
|
||||
void logInfo(std::string const&) {}
|
||||
void logWarn(std::string const&) {}
|
||||
void logDebug(std::string const&) {}
|
||||
@@ -70,7 +29,7 @@ struct snplib_null_logger_t {
|
||||
|
||||
/* SPDLOG-library based advanced single/multithreaded logger */
|
||||
|
||||
class snplib_spdlog_logger_t
|
||||
class spdlog_logger_t
|
||||
{
|
||||
protected:
|
||||
std::shared_ptr<spdlog::logger> _loggerSPtr;
|
||||
@@ -110,35 +69,35 @@ public:
|
||||
/* some factory static methods */
|
||||
|
||||
template <std::ranges::input_range R = decltype(LOGGER_DEFAULT_FORMAT)>
|
||||
requires snplib_input_char_range_c<std::ranges::range_value_t<R>>
|
||||
static snplib_spdlog_logger_t makeConsoleLogger(std::string const& logger_name,
|
||||
R const& pattern_range = LOGGER_DEFAULT_FORMAT)
|
||||
requires input_char_range_c<std::ranges::range_value_t<R>>
|
||||
static spdlog_logger_t makeConsoleLogger(std::string const& logger_name,
|
||||
R const& pattern_range = LOGGER_DEFAULT_FORMAT)
|
||||
{
|
||||
return snplib_spdlog_logger_t(spdlog::stdout_logger_mt(logger_name), pattern_range);
|
||||
return spdlog_logger_t(spdlog::stdout_logger_mt(logger_name), pattern_range);
|
||||
}
|
||||
|
||||
template <std::ranges::input_range R = decltype(LOGGER_DEFAULT_FORMAT)>
|
||||
requires snplib_input_char_range_c<std::ranges::range_value_t<R>>
|
||||
static snplib_spdlog_logger_t makeConsoleErrLogger(std::string const& logger_name,
|
||||
R const& pattern_range = LOGGER_DEFAULT_FORMAT)
|
||||
requires input_char_range_c<std::ranges::range_value_t<R>>
|
||||
static spdlog_logger_t makeConsoleErrLogger(std::string const& logger_name,
|
||||
R const& pattern_range = LOGGER_DEFAULT_FORMAT)
|
||||
{
|
||||
return snplib_spdlog_logger_t(spdlog::stderr_logger_mt(logger_name), pattern_range);
|
||||
return spdlog_logger_t(spdlog::stderr_logger_mt(logger_name), pattern_range);
|
||||
}
|
||||
|
||||
|
||||
template <std::ranges::input_range R = decltype(LOGGER_DEFAULT_FORMAT)>
|
||||
requires snplib_input_char_range_c<std::ranges::range_value_t<R>>
|
||||
static snplib_spdlog_logger_t makeNullLogger(std::string const& logger_name)
|
||||
requires input_char_range_c<std::ranges::range_value_t<R>>
|
||||
static spdlog_logger_t makeNullLogger(std::string const& logger_name)
|
||||
{
|
||||
return snplib_spdlog_logger_t(spdlog::null_logger_mt(logger_name));
|
||||
return spdlog_logger_t(spdlog::null_logger_mt(logger_name));
|
||||
}
|
||||
|
||||
|
||||
/* constructor and destructor */
|
||||
|
||||
template <std::ranges::input_range R = decltype(LOGGER_DEFAULT_FORMAT)>
|
||||
requires snplib_input_char_range_c<std::ranges::range_value_t<R>>
|
||||
snplib_spdlog_logger_t(std::shared_ptr<spdlog::logger> logger, R const& pattern_range = LOGGER_DEFAULT_FORMAT)
|
||||
requires input_char_range_c<std::ranges::range_value_t<R>>
|
||||
spdlog_logger_t(std::shared_ptr<spdlog::logger> logger, R const& pattern_range = LOGGER_DEFAULT_FORMAT)
|
||||
: _loggerSPtr(logger)
|
||||
{
|
||||
if (std::distance(pattern_range.begin(), pattern_range.end())) {
|
||||
@@ -158,7 +117,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
virtual ~snplib_spdlog_logger_t() = default;
|
||||
virtual ~spdlog_logger_t() = default;
|
||||
|
||||
void setLoglevel(spdlog::level::level_enum level)
|
||||
{
|
||||
@@ -268,7 +227,7 @@ public:
|
||||
|
||||
|
||||
// 'after_idx' is 0-based index!
|
||||
void addMarkToPatternIdx(snplib_input_char_range_c auto&& mark, size_t after_idx = 1)
|
||||
void addMarkToPatternIdx(input_char_range_c auto&& mark, size_t after_idx = 1)
|
||||
requires(!std::is_pointer_v<std::decay_t<decltype(mark)>>)
|
||||
{
|
||||
if constexpr (std::is_pointer_v<std::decay_t<decltype(mark)>>) {
|
||||
@@ -298,7 +257,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(snplib_logger_c<snplib_spdlog_logger_t>);
|
||||
static_assert(logger_c<spdlog_logger_t>);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -11,12 +11,12 @@ namespace snplib
|
||||
{
|
||||
|
||||
// compile-time size of zero-terminated char array
|
||||
static consteval size_t snplib_char_array_size(const char* arr)
|
||||
static consteval size_t char_array_size(const char* arr)
|
||||
{
|
||||
return *arr ? 1 + snplib_char_array_size(arr + 1) : 0;
|
||||
return *arr ? 1 + char_array_size(arr + 1) : 0;
|
||||
}
|
||||
|
||||
constexpr static bool snplib_is_space(char in) noexcept
|
||||
constexpr static bool is_space_sym(char in) noexcept
|
||||
{
|
||||
static constexpr std::array ws = {' ', '\t', '\n', '\v', '\r', '\f'};
|
||||
return std::ranges::any_of(ws, [in](auto p) { return p == in; });
|
||||
@@ -25,10 +25,8 @@ constexpr static bool snplib_is_space(char in) noexcept
|
||||
|
||||
enum class TrimType { TRIM_RIGHT = 0b01, TRIM_LEFT = 0b10, TRIM_BOTH = 0b11 };
|
||||
|
||||
template <snplib_output_char_range_c OR, snplib_input_char_range_c R, typename IsSpaceFuncT = decltype(snplib_is_space)>
|
||||
constexpr static OR snplib_trim_spaces(R&& r,
|
||||
TrimType type = TrimType::TRIM_BOTH,
|
||||
IsSpaceFuncT&& is_space_func = snplib_is_space)
|
||||
template <output_char_range_c OR, input_char_range_c R, typename IsSpaceFuncT = decltype(is_space_sym)>
|
||||
constexpr static OR trim_spaces(R&& r, TrimType type = TrimType::TRIM_BOTH, IsSpaceFuncT&& is_space_func = is_space_sym)
|
||||
{
|
||||
if (type == TrimType::TRIM_LEFT) {
|
||||
auto res = r | std::views::drop_while(is_space_func);
|
||||
@@ -45,58 +43,24 @@ constexpr static OR snplib_trim_spaces(R&& r,
|
||||
return OR{};
|
||||
}
|
||||
|
||||
template <snplib_input_char_range_c R, typename IsSpaceFuncT = decltype(snplib_is_space)>
|
||||
constexpr static std::string snplib_trim_spaces(R&& r,
|
||||
TrimType type = TrimType::TRIM_BOTH,
|
||||
IsSpaceFuncT&& is_space_func = snplib_is_space)
|
||||
template <input_char_range_c R, typename IsSpaceFuncT = decltype(is_space_sym)>
|
||||
constexpr static std::string trim_spaces(R&& r,
|
||||
TrimType type = TrimType::TRIM_BOTH,
|
||||
IsSpaceFuncT&& is_space_func = is_space_sym)
|
||||
{
|
||||
return snplib_trim_spaces<std::string>(std::forward<R>(r), type, std::forward<IsSpaceFuncT>(is_space_func));
|
||||
return trim_spaces<std::string>(std::forward<R>(r), type, std::forward<IsSpaceFuncT>(is_space_func));
|
||||
}
|
||||
|
||||
// template <snplib_input_char_range_c R, typename IsSpaceFuncT = decltype(snplib_is_space)>
|
||||
// constexpr static std::string_view snplib_trim_spaces_as_view(R&& r,
|
||||
// TrimType type = TrimType::TRIM_BOTH,
|
||||
// IsSpaceFuncT&& is_space_func = snplib_is_space)
|
||||
// requires std::ranges::contiguous_range<R>
|
||||
// {
|
||||
// auto end = std::forward<R>(r).end();
|
||||
|
||||
// auto f1 = std::forward<R>(r).begin();
|
||||
|
||||
// if (type != TrimType::TRIM_RIGHT) {
|
||||
// // look for the first non-space symbol
|
||||
// f1 = std::ranges::find_if_not(std::forward<R>(r), std::forward<IsSpaceFuncT>(is_space_func));
|
||||
// if (f1 == end) { // all are spaces!
|
||||
// return std::string_view();
|
||||
// }
|
||||
// }
|
||||
|
||||
// auto f2 = end;
|
||||
|
||||
// if (type != TrimType::TRIM_LEFT) {
|
||||
// auto f3 = f1;
|
||||
|
||||
// do {
|
||||
// f2 = std::ranges::find_if(++f3, end, std::forward<IsSpaceFuncT>(is_space_func));
|
||||
// if (f2 == end)
|
||||
// break;
|
||||
// f3 = std::ranges::find_if_not(f2 + 1, end, std::forward<IsSpaceFuncT>(is_space_func));
|
||||
// } while (f3 != end);
|
||||
// }
|
||||
|
||||
// return std::string_view(f1, f2);
|
||||
// }
|
||||
|
||||
|
||||
template <std::ranges::viewable_range R, typename IsSpaceFuncT = decltype(snplib_is_space)>
|
||||
requires(snplib_char_range_c<R> && std::ranges::borrowed_range<R>)
|
||||
constexpr static auto snplib_trim_spaces_as_view(R&& r,
|
||||
TrimType type = TrimType::TRIM_BOTH,
|
||||
IsSpaceFuncT&& is_space_func = snplib_is_space)
|
||||
template <std::ranges::viewable_range R, typename IsSpaceFuncT = decltype(is_space_sym)>
|
||||
requires(char_range_c<R> && std::ranges::borrowed_range<R>)
|
||||
constexpr static auto trim_spaces_as_view(R&& r,
|
||||
TrimType type = TrimType::TRIM_BOTH,
|
||||
IsSpaceFuncT&& is_space_func = is_space_sym)
|
||||
{
|
||||
if constexpr (std::is_pointer_v<std::decay_t<R>>) { // char*, const char*, char[] ('\0' terminates C-ish string)
|
||||
return snplib_trim_spaces_as_view(std::string_view(std::forward<R>(r)), type,
|
||||
std::forward<IsSpaceFuncT>(is_space_func));
|
||||
return trim_spaces_as_view(std::string_view(std::forward<R>(r)), type,
|
||||
std::forward<IsSpaceFuncT>(is_space_func));
|
||||
} else {
|
||||
auto it_left = r.begin();
|
||||
auto it_right = r.end();
|
||||
@@ -122,8 +86,8 @@ constexpr static auto snplib_trim_spaces_as_view(R&& r,
|
||||
}
|
||||
|
||||
|
||||
template <snplib_input_char_range_c R1, snplib_input_char_range_c R2>
|
||||
static constexpr bool snplib_char_ranges_compare(R1&& what, R2&& where, bool case_insensitive = false)
|
||||
template <input_char_range_c R1, input_char_range_c R2>
|
||||
static constexpr bool char_ranges_compare(R1&& what, R2&& where, bool case_insensitive = false)
|
||||
{
|
||||
auto sz1 = std::ranges::distance(what.begin(), what.end()), sz2 = std::ranges::distance(where.begin(), where.end());
|
||||
|
||||
@@ -150,12 +114,12 @@ static constexpr bool snplib_char_ranges_compare(R1&& what, R2&& where, bool cas
|
||||
//
|
||||
// or_ctor_args - to use with non-default-constructible classes (or just for non-default constructors)
|
||||
//
|
||||
template <snplib_char_range_c OR, snplib_char_range_c IR, typename... CTorTs>
|
||||
static constexpr OR snplib_transform_char_range(IR&& r, CTorTs&&... or_ctor_args)
|
||||
template <char_range_c OR, char_range_c IR, typename... CTorTs>
|
||||
static constexpr OR transform_char_range(IR&& r, CTorTs&&... or_ctor_args)
|
||||
{
|
||||
using val_t = std::remove_cvref_t<IR>;
|
||||
|
||||
static constexpr bool ret_view = snplib_char_view_c<OR> && std::ranges::viewable_range<val_t>;
|
||||
static constexpr bool ret_view = char_view_c<OR> && std::ranges::viewable_range<val_t>;
|
||||
|
||||
if constexpr (std::same_as<OR, val_t>) { // just a copy
|
||||
return r;
|
||||
@@ -166,7 +130,7 @@ static constexpr OR snplib_transform_char_range(IR&& r, CTorTs&&... or_ctor_args
|
||||
return OR{r.begin(), r.end()};
|
||||
} else if constexpr (std::constructible_from<OR, val_t>) {
|
||||
return OR(std::forward<IR>(r));
|
||||
} else if constexpr (snplib_output_char_range_c<OR>) {
|
||||
} else if constexpr (output_char_range_c<OR>) {
|
||||
OR res(std::forward<CTorTs>(or_ctor_args)...);
|
||||
std::ranges::copy(std::forward<IR>(r), std::back_inserter(res));
|
||||
return res;
|
||||
@@ -176,21 +140,20 @@ static constexpr OR snplib_transform_char_range(IR&& r, CTorTs&&... or_ctor_args
|
||||
}
|
||||
|
||||
|
||||
template <std::ranges::range OR, snplib_input_char_range_c IR, snplib_input_char_range_c DR>
|
||||
static constexpr OR snplib_split_char_range(IR&& input,
|
||||
DR&& delim,
|
||||
size_t start = 0,
|
||||
size_t N = std::numeric_limits<size_t>::max())
|
||||
template <std::ranges::range OR, input_char_range_c IR, input_char_range_c DR>
|
||||
static constexpr OR split_char_range(IR&& input,
|
||||
DR&& delim,
|
||||
size_t start = 0,
|
||||
size_t N = std::numeric_limits<size_t>::max())
|
||||
requires(std::ranges::output_range<OR, std::ranges::range_value_t<OR>> && !std::ranges::borrowed_range<OR> &&
|
||||
snplib_view_or_output_char_range_c<std::ranges::range_value_t<OR>>)
|
||||
view_or_output_char_range_c<std::ranges::range_value_t<OR>>)
|
||||
{
|
||||
static_assert(
|
||||
snplib_char_view_c<std::ranges::range_value_t<OR>> && std::ranges::viewable_range<std::remove_cvref_t<IR>>,
|
||||
"Incompatible input and output types!");
|
||||
static_assert(char_view_c<std::ranges::range_value_t<OR>> && std::ranges::viewable_range<std::remove_cvref_t<IR>>,
|
||||
"Incompatible input and output types!");
|
||||
|
||||
|
||||
if constexpr (std::is_pointer_v<std::decay_t<DR>>) { // char*, const char*, char[]
|
||||
return snplib_split_char_range<OR>(std::forward<IR>(input), std::string_view(delim), start, N);
|
||||
return split_char_range<OR>(std::forward<IR>(input), std::string_view(delim), start, N);
|
||||
} else {
|
||||
OR res;
|
||||
|
||||
@@ -246,18 +209,17 @@ static constexpr OR snplib_split_char_range(IR&& input,
|
||||
}
|
||||
|
||||
|
||||
template <snplib_output_char_range_c OR, std::ranges::input_range IR, snplib_input_char_range_c DR>
|
||||
OR snplib_join_char_ranges(IR&& input, DR&& delim, size_t start = 0, size_t N = std::numeric_limits<size_t>::max())
|
||||
requires(snplib_char_range_c<std::ranges::range_value_t<IR>>)
|
||||
template <output_char_range_c OR, std::ranges::input_range IR, input_char_range_c DR>
|
||||
OR join_char_ranges(IR&& input, DR&& delim, size_t start = 0, size_t N = std::numeric_limits<size_t>::max())
|
||||
requires(char_range_c<std::ranges::range_value_t<IR>>)
|
||||
{
|
||||
using el_t = std::ranges::range_value_t<IR>;
|
||||
|
||||
if constexpr (std::is_pointer_v<std::decay_t<DR>>) { // char*, const char*, char[]
|
||||
if constexpr (std::constructible_from<el_t, decltype(std::begin(delim)), decltype(std::end(delim))>) {
|
||||
return snplib_join_char_ranges<OR>(std::forward<IR>(input), el_t(std::begin(delim), std::end(delim)), start,
|
||||
N);
|
||||
return join_char_ranges<OR>(std::forward<IR>(input), el_t(std::begin(delim), std::end(delim)), start, N);
|
||||
} else {
|
||||
return snplib_join_char_ranges<OR>(std::forward<IR>(input), std::string_view(delim), start, N);
|
||||
return join_char_ranges<OR>(std::forward<IR>(input), std::string_view(delim), start, N);
|
||||
}
|
||||
} else {
|
||||
OR res;
|
||||
@@ -267,11 +229,11 @@ OR snplib_join_char_ranges(IR&& input, DR&& delim, size_t start = 0, size_t N =
|
||||
if constexpr (std::same_as<el_t, d_t>) {
|
||||
std::ranges::copy(std::forward<IR>(input) | std::views::join_with(std::forward<DR>(delim)),
|
||||
std::back_inserter(res));
|
||||
} else if constexpr (snplib_char_view_c<el_t> && std::ranges::viewable_range<d_t>) {
|
||||
} else if constexpr (char_view_c<el_t> && std::ranges::viewable_range<d_t>) {
|
||||
el_t d{delim.begin(), delim.end()};
|
||||
|
||||
std::ranges::copy(std::forward<IR>(input) | std::views::join_with(d), std::back_inserter(res));
|
||||
} else if constexpr (snplib_output_char_range_c<el_t>) {
|
||||
} else if constexpr (output_char_range_c<el_t>) {
|
||||
el_t d;
|
||||
std::ranges::copy(delim, std::back_inserter(d));
|
||||
|
||||
@@ -292,8 +254,8 @@ OR snplib_join_char_ranges(IR&& input, DR&& delim, size_t start = 0, size_t N =
|
||||
|
||||
|
||||
|
||||
template <typename T, snplib_input_char_range_c R>
|
||||
static std::optional<T> snplib_num_from_range(
|
||||
template <typename T, input_char_range_c R>
|
||||
static std::optional<T> char_range_to_number(
|
||||
R&& r,
|
||||
std::conditional_t<std::integral<T>, int, std::chars_format> fmt =
|
||||
[]() {
|
||||
@@ -307,7 +269,7 @@ static std::optional<T> snplib_num_from_range(
|
||||
if constexpr (!std::ranges::contiguous_range<R>) {
|
||||
std::string sval(std::from_range, std::forward<R>(r));
|
||||
|
||||
return snplib_num_from_range<T>(sval);
|
||||
return char_range_to_number<T>(sval);
|
||||
}
|
||||
|
||||
T val;
|
||||
@@ -360,7 +322,7 @@ static std::optional<T> snplib_num_from_range(
|
||||
|
||||
|
||||
template <std::uniform_random_bit_generator RANDOM_GEN_T = std::mt19937_64>
|
||||
class snplib_random_string_generator_t
|
||||
class random_string_generator_t
|
||||
{
|
||||
private:
|
||||
std::random_device _randomDev{};
|
||||
@@ -379,30 +341,30 @@ public:
|
||||
|
||||
static constexpr size_t DEFAULT_RANDOM_STR_LEN = 32;
|
||||
|
||||
snplib_random_string_generator_t() : _randomGen(_randomDev()) {}
|
||||
random_string_generator_t() : _randomGen(_randomDev()) {}
|
||||
|
||||
template <typename SEED_T>
|
||||
snplib_random_string_generator_t(SEED_T seed) : _randomGen(seed)
|
||||
random_string_generator_t(SEED_T seed) : _randomGen(seed)
|
||||
{
|
||||
}
|
||||
|
||||
template <snplib_output_char_range_c OR,
|
||||
snplib_input_char_range_c IR = decltype(snplib_random_string_generator_t::DEFAULT_RANDOM_CHAR_RANGE)>
|
||||
OR generate(size_t len = snplib_random_string_generator_t::DEFAULT_RANDOM_STR_LEN,
|
||||
IR char_range = snplib_random_string_generator_t::DEFAULT_RANDOM_CHAR_RANGE)
|
||||
template <output_char_range_c OR,
|
||||
input_char_range_c IR = decltype(random_string_generator_t::DEFAULT_RANDOM_CHAR_RANGE)>
|
||||
OR generate(size_t len = random_string_generator_t::DEFAULT_RANDOM_STR_LEN,
|
||||
IR char_range = random_string_generator_t::DEFAULT_RANDOM_CHAR_RANGE)
|
||||
{
|
||||
OR res;
|
||||
|
||||
size_t max_idx = std::ranges::size(char_range);
|
||||
if (max_idx < 2) {
|
||||
char_range = snplib_random_string_generator_t::DEFAULT_RANDOM_CHAR_RANGE;
|
||||
max_idx = snplib_random_string_generator_t::DEFAULT_RANDOM_CHAR_RANGE.size();
|
||||
char_range = random_string_generator_t::DEFAULT_RANDOM_CHAR_RANGE;
|
||||
max_idx = random_string_generator_t::DEFAULT_RANDOM_CHAR_RANGE.size();
|
||||
}
|
||||
|
||||
std::uniform_int_distribution<size_t> rdist(0, --max_idx);
|
||||
|
||||
if (!len) {
|
||||
len = snplib_random_string_generator_t::DEFAULT_RANDOM_STR_LEN;
|
||||
len = random_string_generator_t::DEFAULT_RANDOM_STR_LEN;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
@@ -412,17 +374,17 @@ public:
|
||||
return res;
|
||||
}
|
||||
|
||||
template <snplib_input_char_range_c IR = decltype(snplib_random_string_generator_t::DEFAULT_RANDOM_CHAR_RANGE)>
|
||||
std::string generate(size_t len = snplib_random_string_generator_t::DEFAULT_RANDOM_STR_LEN,
|
||||
IR char_range = snplib_random_string_generator_t::DEFAULT_RANDOM_CHAR_RANGE)
|
||||
template <input_char_range_c IR = decltype(random_string_generator_t::DEFAULT_RANDOM_CHAR_RANGE)>
|
||||
std::string generate(size_t len = random_string_generator_t::DEFAULT_RANDOM_STR_LEN,
|
||||
IR char_range = random_string_generator_t::DEFAULT_RANDOM_CHAR_RANGE)
|
||||
{
|
||||
return generate<std::string>(len, char_range);
|
||||
}
|
||||
|
||||
template <snplib_output_char_range_c OR>
|
||||
template <output_char_range_c OR>
|
||||
OR UUIDv4String()
|
||||
{
|
||||
OR res = generate(36, snplib_random_string_generator_t::UUID_STRING_RANGE);
|
||||
OR res = generate(36, random_string_generator_t::UUID_STRING_RANGE);
|
||||
auto iter = res.begin();
|
||||
size_t i = 0;
|
||||
for (size_t idx : std::array<size_t, 4>{8, 13, 18, 23}) {
|
||||
@@ -445,7 +407,7 @@ public:
|
||||
|
||||
// NOTE: return std::string_view
|
||||
template <typename T>
|
||||
consteval auto snplib_get_type_name(T&&)
|
||||
consteval auto type_name_as_string(T&&)
|
||||
{
|
||||
return []<typename VT>(const std::source_location loc = std::source_location::current()) {
|
||||
const std::string_view fname = loc.function_name();
|
||||
@@ -457,7 +419,7 @@ consteval auto snplib_get_type_name(T&&)
|
||||
|
||||
// NOTE: return std::string_view
|
||||
template <typename T>
|
||||
consteval auto snplib_get_type_name()
|
||||
consteval auto type_name_as_string()
|
||||
{
|
||||
return []<typename VT>(const std::source_location loc = std::source_location::current()) {
|
||||
const std::string_view fname = loc.function_name();
|
||||
|
||||
Reference in New Issue
Block a user