From 82821c00957dc7fcc53cbe3f0ee8ef003ec10312 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Thu, 8 Feb 2024 08:49:19 -0500 Subject: [PATCH 1/6] add to_string values to argparse (make it cleaner --- include/blt/parse/argparse.h | 5 +++- src/blt/parse/argparse.cpp | 57 +++++++++++++++++++++--------------- 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/include/blt/parse/argparse.h b/include/blt/parse/argparse.h index 54d67bc..ddc6d4e 100755 --- a/include/blt/parse/argparse.h +++ b/include/blt/parse/argparse.h @@ -57,7 +57,8 @@ namespace blt arg_vector_t(std::initializer_list f): flags(f) { - if (flags.size() == 1) { + if (flags.size() == 1) + { if (!blt::string::starts_with(flags[0], '-')) { name = flags[0]; @@ -478,6 +479,8 @@ namespace blt std::string to_string(const blt::arg_data_internal_t& v); + std::string to_string(const blt::arg_data_vec_t& v); + } #endif //BLT_TESTS_ARGPARSE_H diff --git a/src/blt/parse/argparse.cpp b/src/blt/parse/argparse.cpp index 247468d..92daea9 100755 --- a/src/blt/parse/argparse.cpp +++ b/src/blt/parse/argparse.cpp @@ -7,6 +7,7 @@ #include #include #include +#include "blt/std/utility.h" namespace blt { @@ -92,36 +93,44 @@ namespace blt std::string to_string(const arg_data_t& v) { - if (std::holds_alternative(v)) - return to_string(std::get(v)); - else if (std::holds_alternative(v)) - { - const auto& vec = std::get(v); - if (vec.size() == 1) - return to_string(vec[0]); - if (vec.empty()) - return "Empty Vector"; - std::string str; - for (const auto& r : vec) - { - str += to_string(r); - str += ' '; - } - return "Vector of contents: " + str; - } - return "Empty"; + return std::visit(blt::lambda_visitor{ + [](const arg_data_internal_t& v) { + return to_string(v); + }, + [](const arg_data_vec_t& v) { + return to_string(v); + } + }, v); } std::string to_string(const arg_data_internal_t& v) { - if (std::holds_alternative(v)) + return std::visit(blt::lambda_visitor{ + [&](const std::string& str) { + return str; + }, + [&](bool b) { + return std::string(b ? "True" : "False"); + }, + [&](int32_t i) { + return std::to_string(i); + } + }, v); + } + + std::string to_string(const blt::arg_data_vec_t& vec) + { + std::string result = "["; + + for (const auto& value : blt::enumerate(vec)) { - return std::get(v); - } else if (std::holds_alternative(v)) - { - return std::get(v) ? "True" : "False"; + result += to_string(value.second); + if (value.first != vec.size() - 1) + result += ", "; } - return std::to_string(std::get(v)); + result += "]"; + + return result; } std::string arg_parse::filename(const std::string& path) From 4f871806ab13a86fa2f6e226452b85d3b34b6eff Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Thu, 8 Feb 2024 09:52:02 -0500 Subject: [PATCH 2/6] make arg_results public --- arg_parse_variant_map.drawio | 83 +++++++++++++++++++++++++++++++++++ blt_argparse_variant_map.png | Bin 0 -> 51833 bytes include/blt/parse/argparse.h | 35 ++++++++------- 3 files changed, 101 insertions(+), 17 deletions(-) create mode 100644 arg_parse_variant_map.drawio create mode 100644 blt_argparse_variant_map.png diff --git a/arg_parse_variant_map.drawio b/arg_parse_variant_map.drawio new file mode 100644 index 0000000..ac232d8 --- /dev/null +++ b/arg_parse_variant_map.drawio @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/blt_argparse_variant_map.png b/blt_argparse_variant_map.png new file mode 100644 index 0000000000000000000000000000000000000000..adaf7f0d4d04d5941a7817536c069ef8021b5080 GIT binary patch literal 51833 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 z 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 literal 0 HcmV?d00001 diff --git a/include/blt/parse/argparse.h b/include/blt/parse/argparse.h index ddc6d4e..476dacf 100755 --- a/include/blt/parse/argparse.h +++ b/include/blt/parse/argparse.h @@ -326,22 +326,6 @@ namespace blt return static_cast(std::stoll(s)); return static_cast(std::stoull(s)); } - - private: - struct - { - friend arg_parse; - private: - std::vector arg_properties_storage; - size_t max_line_length = 80; - // TODO: grouping like git's help - // pre/postfix applied to the help message - std::string prefix; - std::string postfix; - public: - std::vector name_associations; - HASHMAP flag_associations; - } user_args; struct arg_results { @@ -386,7 +370,24 @@ namespace blt return data.find(key.substr(1)) != data.end(); return data.find(key) != data.end(); } - } loaded_args; + }; + private: + struct + { + friend arg_parse; + private: + std::vector arg_properties_storage; + size_t max_line_length = 80; + // TODO: grouping like git's help + // pre/postfix applied to the help message + std::string prefix; + std::string postfix; + public: + std::vector name_associations; + HASHMAP flag_associations; + } user_args; + + arg_results loaded_args; bool subcommand_found = false; bool use_full_name = false; From f3c3a3bc4a1ef9826da789988ec735f3d5e2d790 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Thu, 8 Feb 2024 12:59:15 -0500 Subject: [PATCH 3/6] iterator offsetting --- include/blt/std/ranges.h | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/include/blt/std/ranges.h b/include/blt/std/ranges.h index bb29df4..0b70793 100644 --- a/include/blt/std/ranges.h +++ b/include/blt/std/ranges.h @@ -165,6 +165,41 @@ namespace blt return range_itr(_end - offset, offset == 0); } }; + + template + class itr_offset + { + private: + I begin_; + I end_; + public: + template + itr_offset(I begin, I end, T offset): begin_(begin), end_(end) + { + for (T t = 0; t < offset; t++) + ++begin_; + } + + template + itr_offset(C& container, T offset): begin_(container.begin()), end_(container.end()) + { + for (T t = 0; t < offset; t++) + ++begin_; + } + + auto begin() + { + return begin_; + } + + auto end() + { + return end_; + } + }; + + template + itr_offset(C, T) -> itr_offset; } #endif //BLT_RANGES_H From cf27247eb412d7db797a7f8c992ad2ccf7c4bbf4 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Thu, 8 Feb 2024 13:43:30 -0500 Subject: [PATCH 4/6] enumerate on itr_offset --- include/blt/std/ranges.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/blt/std/ranges.h b/include/blt/std/ranges.h index 0b70793..0bdf6f6 100644 --- a/include/blt/std/ranges.h +++ b/include/blt/std/ranges.h @@ -91,6 +91,12 @@ namespace blt return enumerator{container.begin(), container.end()}; } + template + static inline auto enumerate(T&& container) + { + return enumerator{container.begin(), container.end()}; + } + template struct range { From c89aa61cca993b1c73cb5714c4260a1ade242785 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Thu, 8 Feb 2024 14:08:09 -0500 Subject: [PATCH 5/6] string_view splits, with sv variants for returning vectors of views into the string_view --- include/blt/std/string.h | 60 ++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/include/blt/std/string.h b/include/blt/std/string.h index d4b82b2..43ea9c9 100755 --- a/include/blt/std/string.h +++ b/include/blt/std/string.h @@ -216,31 +216,67 @@ namespace blt::string // taken from https://stackoverflow.com/questions/14265581/parse-split-a-string-in-c-using-string-delimiter-standard-c // extended to return a vector - static inline BLT_CPP20_CONSTEXPR std::vector split(std::string s, std::string_view delim) + static inline BLT_CPP20_CONSTEXPR std::vector split(std::string_view s, std::string_view delim) { size_t pos = 0; + size_t from = 0; std::vector tokens; - while ((pos = s.find(delim)) != std::string::npos) + while ((pos = s.find(delim, from)) != std::string::npos) { - auto token = s.substr(0, pos); - tokens.push_back(token); - s.erase(0, pos + delim.length()); + auto size = pos - from; + auto token = s.substr(from, size); + tokens.emplace_back(token); + from += size + delim.length(); } - tokens.push_back(std::move(s)); + tokens.emplace_back(s.substr(from)); + return tokens; + } + + static inline BLT_CPP20_CONSTEXPR std::vector split(std::string_view s, char delim) + { + size_t pos = 0; + size_t from = 0; + std::vector tokens; + while ((pos = s.find(delim, from)) != std::string::npos) + { + auto size = pos - from; + auto token = s.substr(from, size); + tokens.emplace_back(token); + from += size + 1; + } + tokens.emplace_back(s.substr(from)); return tokens; } - static inline BLT_CPP20_CONSTEXPR std::vector split(std::string s, char delim) + static inline BLT_CPP20_CONSTEXPR std::vector split_sv(std::string_view s, std::string_view delim) { size_t pos = 0; - std::vector tokens; - while ((pos = s.find(delim)) != std::string::npos) + size_t from = 0; + std::vector tokens; + while ((pos = s.find(delim, from)) != std::string::npos) { - auto token = s.substr(0, pos); + auto size = pos - from; + auto token = s.substr(from, size); tokens.push_back(token); - s.erase(0, pos + 1); + from += size + delim.length(); } - tokens.push_back(s); + tokens.push_back(s.substr(from)); + return tokens; + } + + static inline BLT_CPP20_CONSTEXPR std::vector split_sv(std::string_view s, char delim) + { + size_t pos = 0; + size_t from = 0; + std::vector tokens; + while ((pos = s.find(delim, from)) != std::string::npos) + { + auto size = pos - from; + auto token = s.substr(from, size); + tokens.push_back(token); + from += size + 1; + } + tokens.push_back(s.substr(from)); return tokens; } From 80f4cc5e500c382e3126ddfd01ab2faa8b42eaa4 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Thu, 8 Feb 2024 14:14:37 -0500 Subject: [PATCH 6/6] add string tests --- tests/include/string_tests.h | 27 +++++++++++++++++ tests/src/string_tests.cpp | 59 ++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 tests/include/string_tests.h create mode 100644 tests/src/string_tests.cpp diff --git a/tests/include/string_tests.h b/tests/include/string_tests.h new file mode 100644 index 0000000..d44fdc4 --- /dev/null +++ b/tests/include/string_tests.h @@ -0,0 +1,27 @@ +/* + * + * Copyright (C) 2024 Brett Terpstra + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef BLT_TESTS_STRING_H +#define BLT_TESTS_STRING_H + +namespace blt::test +{ + void run_string_test(); +} + +#endif diff --git a/tests/src/string_tests.cpp b/tests/src/string_tests.cpp new file mode 100644 index 0000000..4f3216e --- /dev/null +++ b/tests/src/string_tests.cpp @@ -0,0 +1,59 @@ +/* + * + * Copyright (C) 2024 Brett Terpstra + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include +#include +#include + +namespace blt::test +{ + void run_string_test() + { + std::string str = "I HAVE A LOT OF\tTABULAR\tFORMED MEMORIES"; + + auto s_splits_c = blt::string::split(str, ' '); + auto s_splits_s = blt::string::split(str, "LOT"); + + auto sv_splits_c = blt::string::split_sv(str, ' '); + auto sv_splits_s = blt::string::split_sv(str, "LOT"); + + for (auto v : blt::enumerate(s_splits_c)) + { + if (v.second != sv_splits_c[v.first]) + { + BLT_WARN("THEY DO NOT MATCH!!! '%s' vs '%s'", v.second.c_str(), std::string(sv_splits_c[v.first]).c_str()); + } else + { + BLT_DEBUG(v.second); + } + } + + BLT_INFO(""); + + for (auto v : blt::enumerate(s_splits_s)) + { + if (v.second != sv_splits_s[v.first]) + { + BLT_WARN("THEY DO NOT MATCH!!! '%s' vs '%s'", v.second.c_str(), std::string(sv_splits_s[v.first]).c_str()); + } else + { + BLT_DEBUG(v.second); + } + } + } +} \ No newline at end of file