change naming scheme (delete "snplib_" prefix)

This commit is contained in:
2026-09-18 11:55:21 +03:00
parent 09f4647ede
commit d3cd9e269e
16 changed files with 443 additions and 548 deletions

View File

@@ -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);

View File

@@ -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};

View File

@@ -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());

View File

@@ -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&>()) };

View File

@@ -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

View File

@@ -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:

View File

@@ -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]); };

View File

@@ -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) {

View File

@@ -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

View File

@@ -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!!!

View File

@@ -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) {

View File

@@ -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, &params]<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, &params, &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;
}
};

View File

@@ -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)...);
}
}

View File

@@ -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) {

View File

@@ -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

View File

@@ -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();