Brett 2024-02-09 00:14:43 -05:00
commit 7ac20db077
8 changed files with 315 additions and 55 deletions

View File

@ -0,0 +1,83 @@
<mxfile host="app.diagrams.net" modified="2024-02-08T14:03:18.674Z" agent="Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0" etag="npPGfaTE6qVV9GBzyjgA" version="23.1.2" type="device">
<diagram name="Page-1" id="FljCu8qqvPwneiU56IGs">
<mxGraphModel dx="1430" dy="767" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="_DS3495almi1g_SXSTfi-13" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="_DS3495almi1g_SXSTfi-1" target="_DS3495almi1g_SXSTfi-3">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="440" y="240" />
<mxPoint x="240" y="240" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="_DS3495almi1g_SXSTfi-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="_DS3495almi1g_SXSTfi-1" target="_DS3495almi1g_SXSTfi-2">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="440" y="240" />
<mxPoint x="635" y="240" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="_DS3495almi1g_SXSTfi-1" value="&lt;div&gt;&lt;p style=&quot;font-family:&#39;JetBrains Mono&#39;,monospace;font-size:9.8pt;&quot;&gt;&lt;span style=&quot;background-color: rgb(255, 248, 247);&quot;&gt;arg_data_t&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="380" y="130" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="_DS3495almi1g_SXSTfi-15" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="_DS3495almi1g_SXSTfi-2" target="_DS3495almi1g_SXSTfi-5">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="_DS3495almi1g_SXSTfi-2" value="&lt;div&gt;&lt;pre style=&quot;font-family:&#39;JetBrains Mono&#39;,monospace;font-size:9.8pt;&quot;&gt;&lt;font style=&quot;background-color: rgb(252, 245, 245);&quot; color=&quot;#030303&quot;&gt;arg_data_vec_t&lt;/font&gt;&lt;/pre&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="560" y="280" width="150" height="60" as="geometry" />
</mxCell>
<mxCell id="_DS3495almi1g_SXSTfi-10" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="_DS3495almi1g_SXSTfi-3" target="_DS3495almi1g_SXSTfi-6">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="_DS3495almi1g_SXSTfi-11" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="_DS3495almi1g_SXSTfi-3" target="_DS3495almi1g_SXSTfi-7">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="_DS3495almi1g_SXSTfi-12" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="_DS3495almi1g_SXSTfi-3" target="_DS3495almi1g_SXSTfi-9">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="_DS3495almi1g_SXSTfi-3" value="&lt;div&gt;&lt;pre style=&quot;font-family:&#39;JetBrains Mono&#39;,monospace;font-size:9.8pt;&quot;&gt;&lt;font style=&quot;background-color: rgb(255, 248, 247);&quot; color=&quot;#030303&quot;&gt;arg_data_internal_t&lt;/font&gt;&lt;/pre&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="160" y="280" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="_DS3495almi1g_SXSTfi-23" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="_DS3495almi1g_SXSTfi-5" target="_DS3495almi1g_SXSTfi-19">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="_DS3495almi1g_SXSTfi-5" value="&lt;pre style=&quot;font-family:&#39;JetBrains Mono&#39;,monospace;font-size:9.8pt;&quot;&gt;std::vector&amp;lt;arg_data_internal_t&amp;gt;&lt;/pre&gt;" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="497.5" y="440" width="275" height="60" as="geometry" />
</mxCell>
<mxCell id="_DS3495almi1g_SXSTfi-6" value="&lt;div style=&quot;background-color: rgb(30, 31, 34);&quot;&gt;&lt;pre style=&quot;font-family:&#39;JetBrains Mono&#39;,monospace;font-size:9.8pt;&quot;&gt;&lt;span style=&quot;background-color: rgb(255, 248, 247);&quot;&gt;std::string&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="40" y="440" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="_DS3495almi1g_SXSTfi-7" value="&lt;div style=&quot;background-color: rgb(30, 31, 34);&quot;&gt;&lt;pre style=&quot;font-family:&#39;JetBrains Mono&#39;,monospace;font-size:9.8pt;&quot;&gt;&lt;span style=&quot;background-color: rgb(255, 248, 247);&quot;&gt;bool&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="180" y="440" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="_DS3495almi1g_SXSTfi-9" value="&lt;div style=&quot;background-color: rgb(30, 31, 34);&quot;&gt;&lt;pre style=&quot;font-family:&#39;JetBrains Mono&#39;,monospace;font-size:9.8pt;&quot;&gt;&lt;span style=&quot;background-color: rgb(255, 248, 247);&quot;&gt;int32_t&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="320" y="440" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="_DS3495almi1g_SXSTfi-16" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="_DS3495almi1g_SXSTfi-19" target="_DS3495almi1g_SXSTfi-20">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="_DS3495almi1g_SXSTfi-17" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="_DS3495almi1g_SXSTfi-19" target="_DS3495almi1g_SXSTfi-21">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="_DS3495almi1g_SXSTfi-18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="_DS3495almi1g_SXSTfi-19" target="_DS3495almi1g_SXSTfi-22">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="_DS3495almi1g_SXSTfi-19" value="&lt;div style=&quot;background-color: rgb(30, 31, 34);&quot;&gt;&lt;pre style=&quot;font-family:&#39;JetBrains Mono&#39;,monospace;font-size:9.8pt;&quot;&gt;&lt;span style=&quot;background-color: rgb(255, 248, 247);&quot;&gt;arg_data_internal_t&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="555" y="560" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="_DS3495almi1g_SXSTfi-20" value="&lt;div style=&quot;background-color: rgb(30, 31, 34);&quot;&gt;&lt;pre style=&quot;font-family:&#39;JetBrains Mono&#39;,monospace;font-size:9.8pt;&quot;&gt;&lt;font style=&quot;background-color: rgb(255, 248, 247);&quot;&gt;std::string&lt;/font&gt;&lt;/pre&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="435" y="720" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="_DS3495almi1g_SXSTfi-21" value="&lt;div style=&quot;background-color:#1e1f22;color:#bcbec4&quot;&gt;&lt;pre style=&quot;font-family:&#39;JetBrains Mono&#39;,monospace;font-size:9.8pt;&quot;&gt;&lt;font style=&quot;background-color: rgb(255, 248, 247);&quot; color=&quot;#000000&quot;&gt;bool&lt;/font&gt;&lt;/pre&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="575" y="720" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="_DS3495almi1g_SXSTfi-22" value="&lt;div&gt;&lt;pre style=&quot;font-family:&#39;JetBrains Mono&#39;,monospace;font-size:9.8pt;&quot;&gt;&lt;span style=&quot;background-color: rgb(255, 248, 247);&quot;&gt;int32_t&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="715" y="720" width="120" height="60" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

@ -57,7 +57,8 @@ namespace blt
arg_vector_t(std::initializer_list<std::string> f): flags(f) arg_vector_t(std::initializer_list<std::string> f): flags(f)
{ {
if (flags.size() == 1) { if (flags.size() == 1)
{
if (!blt::string::starts_with(flags[0], '-')) if (!blt::string::starts_with(flags[0], '-'))
{ {
name = flags[0]; name = flags[0];
@ -326,22 +327,6 @@ namespace blt
return static_cast<T>(std::stoull(s)); return static_cast<T>(std::stoull(s));
} }
private:
struct
{
friend arg_parse;
private:
std::vector<arg_properties_t*> 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<arg_properties_t*> name_associations;
HASHMAP<std::string, arg_properties_t*> flag_associations;
} user_args;
struct arg_results struct arg_results
{ {
friend arg_parse; friend arg_parse;
@ -385,7 +370,24 @@ namespace blt
return data.find(key.substr(1)) != data.end(); return data.find(key.substr(1)) != data.end();
return data.find(key) != data.end(); return data.find(key) != data.end();
} }
} loaded_args; };
private:
struct
{
friend arg_parse;
private:
std::vector<arg_properties_t*> 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<arg_properties_t*> name_associations;
HASHMAP<std::string, arg_properties_t*> flag_associations;
} user_args;
arg_results loaded_args;
bool subcommand_found = false; bool subcommand_found = false;
bool use_full_name = 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_internal_t& v);
std::string to_string(const blt::arg_data_vec_t& v);
} }
#endif //BLT_TESTS_ARGPARSE_H #endif //BLT_TESTS_ARGPARSE_H

View File

@ -93,6 +93,12 @@ namespace blt
return enumerator{container.begin(), container.end()}; return enumerator{container.begin(), container.end()};
} }
template<typename T>
static inline auto enumerate(T&& container)
{
return enumerator{container.begin(), container.end()};
}
template<typename T> template<typename T>
struct range struct range
{ {
@ -168,6 +174,42 @@ namespace blt
} }
}; };
template<typename I>
class itr_offset
{
private:
I begin_;
I end_;
public:
template<typename T>
itr_offset(I begin, I end, T offset): begin_(begin), end_(end)
{
for (T t = 0; t < offset; t++)
++begin_;
}
template<typename C, typename T>
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<typename C, typename T>
itr_offset(C, T) -> itr_offset<typename C::iterator>;
inline constexpr std::size_t dynamic_extent = std::numeric_limits<std::size_t>::max(); inline constexpr std::size_t dynamic_extent = std::numeric_limits<std::size_t>::max();
template<typename T, std::size_t extend = dynamic_extent> template<typename T, std::size_t extend = dynamic_extent>

View File

@ -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 // taken from https://stackoverflow.com/questions/14265581/parse-split-a-string-in-c-using-string-delimiter-standard-c
// extended to return a vector // extended to return a vector
static inline BLT_CPP20_CONSTEXPR std::vector<std::string> split(std::string s, std::string_view delim) static inline BLT_CPP20_CONSTEXPR std::vector<std::string> split(std::string_view s, std::string_view delim)
{ {
size_t pos = 0; size_t pos = 0;
size_t from = 0;
std::vector<std::string> tokens; std::vector<std::string> tokens;
while ((pos = s.find(delim)) != std::string::npos) while ((pos = s.find(delim, from)) != std::string::npos)
{ {
auto token = s.substr(0, pos); auto size = pos - from;
tokens.push_back(token); auto token = s.substr(from, size);
s.erase(0, pos + delim.length()); tokens.emplace_back(token);
from += size + delim.length();
} }
tokens.push_back(std::move(s)); tokens.emplace_back(s.substr(from));
return tokens; return tokens;
} }
static inline BLT_CPP20_CONSTEXPR std::vector<std::string> split(std::string s, char delim) static inline BLT_CPP20_CONSTEXPR std::vector<std::string> split(std::string_view s, char delim)
{ {
size_t pos = 0; size_t pos = 0;
size_t from = 0;
std::vector<std::string> tokens; std::vector<std::string> tokens;
while ((pos = s.find(delim)) != std::string::npos) while ((pos = s.find(delim, from)) != std::string::npos)
{ {
auto token = s.substr(0, pos); auto size = pos - from;
tokens.push_back(token); auto token = s.substr(from, size);
s.erase(0, pos + 1); tokens.emplace_back(token);
from += size + 1;
} }
tokens.push_back(s); tokens.emplace_back(s.substr(from));
return tokens;
}
static inline BLT_CPP20_CONSTEXPR std::vector<std::string_view> split_sv(std::string_view s, std::string_view delim)
{
size_t pos = 0;
size_t from = 0;
std::vector<std::string_view> 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 + delim.length();
}
tokens.push_back(s.substr(from));
return tokens;
}
static inline BLT_CPP20_CONSTEXPR std::vector<std::string_view> split_sv(std::string_view s, char delim)
{
size_t pos = 0;
size_t from = 0;
std::vector<std::string_view> 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; return tokens;
} }

View File

@ -7,6 +7,7 @@
#include <iostream> #include <iostream>
#include <blt/std/string.h> #include <blt/std/string.h>
#include <algorithm> #include <algorithm>
#include "blt/std/utility.h"
namespace blt namespace blt
{ {
@ -92,36 +93,44 @@ namespace blt
std::string to_string(const arg_data_t& v) std::string to_string(const arg_data_t& v)
{ {
if (std::holds_alternative<arg_data_internal_t>(v)) return std::visit(blt::lambda_visitor{
return to_string(std::get<arg_data_internal_t>(v)); [](const arg_data_internal_t& v) {
else if (std::holds_alternative<arg_data_vec_t>(v)) return to_string(v);
{ },
const auto& vec = std::get<arg_data_vec_t>(v); [](const arg_data_vec_t& v) {
if (vec.size() == 1) return to_string(v);
return to_string(vec[0]); }
if (vec.empty()) }, v);
return "Empty Vector";
std::string str;
for (const auto& r : vec)
{
str += to_string(r);
str += ' ';
}
return "Vector of contents: " + str;
}
return "Empty";
} }
std::string to_string(const arg_data_internal_t& v) std::string to_string(const arg_data_internal_t& v)
{ {
if (std::holds_alternative<std::string>(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<std::string>(v); result += to_string(value.second);
} else if (std::holds_alternative<bool>(v)) if (value.first != vec.size() - 1)
{ result += ", ";
return std::get<bool>(v) ? "True" : "False";
} }
return std::to_string(std::get<int32_t>(v)); result += "]";
return result;
} }
std::string arg_parse::filename(const std::string& path) std::string arg_parse::filename(const std::string& path)

View File

@ -0,0 +1,27 @@
/*
* <Short Description>
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef BLT_TESTS_STRING_H
#define BLT_TESTS_STRING_H
namespace blt::test
{
void run_string_test();
}
#endif

View File

@ -0,0 +1,59 @@
/*
* <Short Description>
* 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 <https://www.gnu.org/licenses/>.
*/
#include <string_tests.h>
#include <blt/std/utility.h>
#include <blt/std/string.h>
#include <blt/std/logging.h>
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);
}
}
}
}