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 0000000..adaf7f0
Binary files /dev/null and b/blt_argparse_variant_map.png differ
diff --git a/include/blt/parse/argparse.h b/include/blt/parse/argparse.h
index 54d67bc..476dacf 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];
@@ -325,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
{
@@ -385,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;
@@ -478,6 +480,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/include/blt/std/ranges.h b/include/blt/std/ranges.h
index 9f9ba7e..80c87c2 100644
--- a/include/blt/std/ranges.h
+++ b/include/blt/std/ranges.h
@@ -93,6 +93,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
{
@@ -168,6 +174,42 @@ namespace blt
}
};
+ 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;
+
+
inline constexpr std::size_t dynamic_extent = std::numeric_limits::max();
template
@@ -182,7 +224,7 @@ namespace blt
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;
-
+
private:
public:
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;
}
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)
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