From 138408125c23f05acc79bcd4adb8ec5faee1923e Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 8 Jun 2024 22:24:55 +0200 Subject: [PATCH] string: add VarList --- include/hyprutils/string/VarList.hpp | 67 ++++++++++++++++++++++++++++ src/string/VarList.cpp | 39 ++++++++++++++++ tests/string.cpp | 5 +++ 3 files changed, 111 insertions(+) create mode 100644 include/hyprutils/string/VarList.hpp create mode 100644 src/string/VarList.cpp diff --git a/include/hyprutils/string/VarList.hpp b/include/hyprutils/string/VarList.hpp new file mode 100644 index 0000000..a876111 --- /dev/null +++ b/include/hyprutils/string/VarList.hpp @@ -0,0 +1,67 @@ +#pragma once +#include +#include +#include + +namespace Hyprutils { + namespace String { + class CVarList { + public: + /** Split string into arg list + @param lastArgNo stop splitting after argv reaches maximum size, last arg will contain rest of unsplit args + @param delim if delimiter is 's', use std::isspace + @param removeEmpty remove empty args from argv + */ + CVarList(const std::string& in, const size_t maxSize = 0, const char delim = ',', const bool removeEmpty = false); + + ~CVarList() = default; + + size_t size() const { + return m_vArgs.size(); + } + + std::string join(const std::string& joiner, size_t from = 0, size_t to = 0) const; + + void map(std::function func) { + for (auto& s : m_vArgs) + func(s); + } + + void append(const std::string arg) { + m_vArgs.emplace_back(arg); + } + + std::string operator[](const size_t& idx) const { + if (idx >= m_vArgs.size()) + return ""; + return m_vArgs[idx]; + } + + // for range-based loops + std::vector::iterator begin() { + return m_vArgs.begin(); + } + std::vector::const_iterator begin() const { + return m_vArgs.begin(); + } + std::vector::iterator end() { + return m_vArgs.end(); + } + std::vector::const_iterator end() const { + return m_vArgs.end(); + } + + bool contains(const std::string& el) { + for (auto& a : m_vArgs) { + if (a == el) + return true; + } + + return false; + } + + private: + std::vector m_vArgs; + }; + } +} diff --git a/src/string/VarList.cpp b/src/string/VarList.cpp new file mode 100644 index 0000000..0256087 --- /dev/null +++ b/src/string/VarList.cpp @@ -0,0 +1,39 @@ +#include +#include +#include +#include + +using namespace Hyprutils::String; + +Hyprutils::String::CVarList::CVarList(const std::string& in, const size_t lastArgNo, const char delim, const bool removeEmpty) { + if (in.empty()) + m_vArgs.emplace_back(""); + + std::string args{in}; + size_t idx = 0; + size_t pos = 0; + std::ranges::replace_if( + args, [&](const char& c) { return delim == 's' ? std::isspace(c) : c == delim; }, 0); + + for (const auto& s : args | std::views::split(0)) { + if (removeEmpty && s.empty()) + continue; + if (++idx == lastArgNo) { + m_vArgs.emplace_back(trim(in.substr(pos))); + break; + } + pos += s.size() + 1; + m_vArgs.emplace_back(trim(std::string_view{s}.data())); + } +} + +std::string Hyprutils::String::CVarList::join(const std::string& joiner, size_t from, size_t to) const { + size_t last = to == 0 ? size() : to; + + std::string rolling; + for (size_t i = from; i < last; ++i) { + rolling += m_vArgs[i] + (i + 1 < last ? joiner : ""); + } + + return rolling; +} \ No newline at end of file diff --git a/tests/string.cpp b/tests/string.cpp index 40a7ba7..64bcaf6 100644 --- a/tests/string.cpp +++ b/tests/string.cpp @@ -1,4 +1,5 @@ #include +#include #include "shared.hpp" using namespace Hyprutils::String; @@ -29,5 +30,9 @@ int main(int argc, char** argv, char** envp) { EXPECT(isNumber("0.9999s", true), false); EXPECT(isNumber("s0.9999", true), false); + CVarList list("hello world!", 0, 's', true); + EXPECT(list[0], "hello"); + EXPECT(list[1], "world!"); + return ret; } \ No newline at end of file