Moved objects into namespace Leonetienne

This commit is contained in:
Leonetienne 2022-05-17 00:03:39 +02:00
parent 954629f6bc
commit 7d9193e3ee
No known key found for this signature in database
GPG Key ID: C33879CD92E9708C
20 changed files with 294 additions and 228 deletions

View File

@ -1,6 +1,8 @@
#include <iostream> #include <iostream>
#include <StringTools/StringTools.h> #include <StringTools/StringTools.h>
using namespace Leonetienne::StringTools;
int main() int main()
{ {
std::vector<std::string> foo = std::vector<std::string> foo =

View File

@ -3,33 +3,37 @@
#include <string> #include <string>
/* Handy utensils to manipulate characters */
class CharTools { namespace Leonetienne::StringTools {
public:
//! Checks whether or not `c` is a vowel. You can define custom vowel characters.
static bool IsVowel(const char c, const std::string &vowels = "euioay");
//! Returns whether or not `c` is a letter. /* Handy utensils to manipulate characters */
static bool IsLetter(const char c); class CharTools {
public:
//! Checks whether or not `c` is a vowel. You can define custom vowel characters.
static bool IsVowel(const char c, const std::string &vowels = "euioay");
//! Returns whether or not `c` is a digit. //! Returns whether or not `c` is a letter.
static bool IsDigit(const char c); static bool IsLetter(const char c);
//! Checks whether or not `c` is an uppercase character. //! Returns whether or not `c` is a digit.
static bool IsUpper(const char c); static bool IsDigit(const char c);
//! Checks whether or not `c` is a lowercase character. //! Checks whether or not `c` is an uppercase character.
static bool IsLower(const char c); static bool IsUpper(const char c);
//! Will return `c` as an uppercase character. //! Checks whether or not `c` is a lowercase character.
static char MakeUpper(char c); static bool IsLower(const char c);
//! Will return `c` as a lowercase character. //! Will return `c` as an uppercase character.
static char MakeLower(char c); static char MakeUpper(char c);
//! Will return `c` with the same capitalization as `sign`. //! Will return `c` as a lowercase character.
static char CopySign(char sign, char c); static char MakeLower(char c);
};
//! Will return `c` with the same capitalization as `sign`.
static char CopySign(char sign, char c);
};
}
#endif //STRINGTOOLS_CHARTOOLS_H #endif //STRINGTOOLS_CHARTOOLS_H

View File

@ -4,40 +4,45 @@
#include <string> #include <string>
#include <vector> #include <vector>
/* Handy utensils to manipulate strings */
class StringTools
{
public:
//! Will replace every occurence of `find` in `str` by `subst`.
static std::string Replace(const std::string& str, const char find, const std::string& subst);
//! Will replace every occurence of `find` in `str` by `subst`. namespace Leonetienne::StringTools {
static std::string Replace(const std::string& str, const std::string& find, const std::string& subst);
//! Will replace every occurence of `find` in `str` by `subst`. /* Handy utensils to manipulate strings */
static std::string Replace(const std::string& str, const char find, const char subst); class StringTools
{
public:
//! Will replace every occurence of `find` in `str` by `subst`.
static std::string Replace(const std::string& str, const char find, const std::string& subst);
//! Will replace every occurence of `find` in `str` by `subst`. //! Will replace every occurence of `find` in `str` by `subst`.
static std::string Replace(const std::string& str, const std::string& find, const char subst); static std::string Replace(const std::string& str, const std::string& find, const std::string& subst);
//! Will make a string all-lowercase. //! Will replace every occurence of `find` in `str` by `subst`.
static std::string Lower(const std::string& str); static std::string Replace(const std::string& str, const char find, const char subst);
//! Will make a string all-uppercase. //! Will replace every occurence of `find` in `str` by `subst`.
static std::string Upper(const std::string& str); static std::string Replace(const std::string& str, const std::string& find, const char subst);
//! Will split a string by a string seperator //! Will make a string all-lowercase.
static std::vector<std::string> Split(const std::string& str, const std::string& seperator); static std::string Lower(const std::string& str);
//! Will pad a string to the left to length l //! Will make a string all-uppercase.
static std::string PadLeft(const std::string& str, const char pad, const std::size_t len); static std::string Upper(const std::string& str);
//! Will pad a string to the right to length l //! Will split a string by a string seperator
static std::string PadRight(const std::string& str, const char pad, const std::size_t len); static std::vector<std::string> Split(const std::string& str, const std::string& seperator);
private: //! Will pad a string to the left to length l
// No instanciation! >:( static std::string PadLeft(const std::string& str, const char pad, const std::size_t len);
StringTools();
}; //! Will pad a string to the right to length l
static std::string PadRight(const std::string& str, const char pad, const std::size_t len);
private:
// No instanciation! >:(
StringTools();
};
}
#endif //STRINGTOOLS_STRINGTOOLS_H #endif //STRINGTOOLS_STRINGTOOLS_H

View File

@ -1,68 +1,73 @@
#include "StringTools/CharTools.h" #include "StringTools/CharTools.h"
#include <algorithm> #include <algorithm>
bool CharTools::IsVowel(const char c, const std::string &vowels) { namespace Leonetienne::StringTools {
const char lc = MakeLower(c);
bool CharTools::IsVowel(const char c, const std::string &vowels) {
const char lc = MakeLower(c);
return std::any_of(
vowels.cbegin(),
vowels.cend(),
[lc](const char vowel) {
return lc == vowel;
}
);
}
bool CharTools::IsLetter(const char c) {
// Re-implementing IsUpper and MakeLower to prevent stack-overflow by endless recursion
const char lowercase_c = !(c & (1<<5)) ? (c | (1<<5)) : c;
return (lowercase_c >= 'a') && (lowercase_c <= 'z');
}
bool CharTools::IsDigit(const char c) {
return (c >= '0') && (c <= '9');
}
bool CharTools::IsUpper(const char c) {
if (!IsLetter(c))
return false;
else
return !(c & (1<<5));
}
bool CharTools::IsLower(const char c) {
// Can't just return !IsUpper(c), because it should still return false for digits and symbols...
if (!IsLetter(c))
return false;
else
return (c & (1<<5));
}
char CharTools::MakeUpper(char c) {
if (!IsLetter(c))
return c;
else if (IsUpper(c))
return c;
else
return c & ~(1<<5);
}
char CharTools::MakeLower(char c) {
if (!IsLetter(c))
return c;
else if (!IsUpper(c))
return c;
else
return c | (1<<5);
}
char CharTools::CopySign(char sign, char c) {
if ((!IsLetter(c)) || (!IsLetter(sign)))
return c;
if (IsUpper(sign))
return MakeUpper(c);
else
return MakeLower(c);
}
return std::any_of(
vowels.cbegin(),
vowels.cend(),
[lc](const char vowel) {
return lc == vowel;
}
);
} }
bool CharTools::IsLetter(const char c) {
// Re-implementing IsUpper and MakeLower to prevent stack-overflow by endless recursion
const char lowercase_c = !(c & (1<<5)) ? (c | (1<<5)) : c;
return (lowercase_c >= 'a') && (lowercase_c <= 'z');
}
bool CharTools::IsDigit(const char c) {
return (c >= '0') && (c <= '9');
}
bool CharTools::IsUpper(const char c) {
if (!IsLetter(c))
return false;
else
return !(c & (1<<5));
}
bool CharTools::IsLower(const char c) {
// Can't just return !IsUpper(c), because it should still return false for digits and symbols...
if (!IsLetter(c))
return false;
else
return (c & (1<<5));
}
char CharTools::MakeUpper(char c) {
if (!IsLetter(c))
return c;
else if (IsUpper(c))
return c;
else
return c & ~(1<<5);
}
char CharTools::MakeLower(char c) {
if (!IsLetter(c))
return c;
else if (!IsUpper(c))
return c;
else
return c | (1<<5);
}
char CharTools::CopySign(char sign, char c) {
if ((!IsLetter(c)) || (!IsLetter(sign)))
return c;
if (IsUpper(sign))
return MakeUpper(c);
else
return MakeLower(c);
}

View File

@ -1,155 +1,160 @@
#include "StringTools/StringTools.h" #include "StringTools/StringTools.h"
#include <sstream> #include <sstream>
std::string StringTools::Replace(const std::string& str, const char find, const std::string& subst) { namespace Leonetienne::StringTools {
std::stringstream ss;
for (std::size_t i = 0; i < str.length(); i++) std::string StringTools::Replace(const std::string& str, const char find, const std::string& subst) {
{ std::stringstream ss;
if (str[i] != find)
ss << str[i];
else
ss << subst;
}
return ss.str(); for (std::size_t i = 0; i < str.length(); i++)
} {
if (str[i] != find)
ss << str[i];
else
ss << subst;
}
std::string StringTools::Replace(const std::string& str, const std::string& find, const std::string& subst) { return ss.str();
if (find.length() == 0) }
return str;
std::stringstream ss; std::string StringTools::Replace(const std::string& str, const std::string& find, const std::string& subst) {
if (find.length() == 0)
return str;
std::size_t posFound = 0; std::stringstream ss;
std::size_t lastFound = 0;
while (posFound != std::string::npos) std::size_t posFound = 0;
{ std::size_t lastFound = 0;
lastFound = posFound;
posFound = str.find(find, posFound);
if (posFound != std::string::npos) while (posFound != std::string::npos)
{ {
ss << str.substr(lastFound, posFound - lastFound) << subst; lastFound = posFound;
posFound += find.length(); posFound = str.find(find, posFound);
}
else
{
ss << str.substr(lastFound, (str.length()) - lastFound);
}
}
return ss.str(); if (posFound != std::string::npos)
} {
ss << str.substr(lastFound, posFound - lastFound) << subst;
posFound += find.length();
}
else
{
ss << str.substr(lastFound, (str.length()) - lastFound);
}
}
std::string StringTools::Replace(const std::string& str, const char find, const char subst) { return ss.str();
std::stringstream ss; }
ss << subst;
return Replace(str, find, ss.str()); std::string StringTools::Replace(const std::string& str, const char find, const char subst) {
} std::stringstream ss;
ss << subst;
std::string StringTools::Replace(const std::string& str, const std::string& find, const char subst) { return Replace(str, find, ss.str());
std::stringstream ss; }
ss << subst;
return Replace(str, find, ss.str()); std::string StringTools::Replace(const std::string& str, const std::string& find, const char subst) {
} std::stringstream ss;
ss << subst;
std::string StringTools::Lower(const std::string& str) { return Replace(str, find, ss.str());
std::stringstream ss; }
for (std::size_t i = 0; i < str.size(); i++) std::string StringTools::Lower(const std::string& str) {
{ std::stringstream ss;
const char c = str[i];
// Quick-accept: regular letters for (std::size_t i = 0; i < str.size(); i++)
if ((c >= 'A') && (c <= 'Z')) {
ss << (char)(c | 32); const char c = str[i];
// Else: keep the character as is // Quick-accept: regular letters
else ss << c; if ((c >= 'A') && (c <= 'Z'))
} ss << (char)(c | 32);
return ss.str(); // Else: keep the character as is
} else ss << c;
}
std::string StringTools::Upper(const std::string& str) { return ss.str();
std::stringstream ss; }
for (std::size_t i = 0; i < str.size(); i++) std::string StringTools::Upper(const std::string& str) {
{ std::stringstream ss;
const char c = str[i];
// Quick-accept: regular letters for (std::size_t i = 0; i < str.size(); i++)
if ((c >= 'a') && (c <= 'z')) {
ss << (char)(c & ~32); const char c = str[i];
// Else: keep the character as is // Quick-accept: regular letters
else ss << c; if ((c >= 'a') && (c <= 'z'))
} ss << (char)(c & ~32);
return ss.str(); // Else: keep the character as is
} else ss << c;
}
std::vector<std::string> StringTools::Split(const std::string& str, const std::string& seperator) { return ss.str();
std::vector<std::string> toRet; }
// Quick-accept: str length is 0
if (str.length() == 0)
toRet.push_back("");
// Quick-accept: seperator length is 0 std::vector<std::string> StringTools::Split(const std::string& str, const std::string& seperator) {
else if (seperator.length() == 0) { std::vector<std::string> toRet;
for (const char c : str) // Quick-accept: str length is 0
toRet.push_back(std::string(&c, (&c) + 1)); if (str.length() == 0)
} toRet.push_back("");
else { // Quick-accept: seperator length is 0
std::size_t idx = 0; else if (seperator.length() == 0) {
while (idx != std::string::npos) { for (const char c : str)
std::size_t lastIdx = idx; toRet.push_back(std::string(&c, (&c) + 1));
idx = str.find(seperator, idx); }
// Grab our substring until the next finding of sep else {
if (idx != std::string::npos) { std::size_t idx = 0;
toRet.push_back(str.substr( while (idx != std::string::npos) {
lastIdx, std::size_t lastIdx = idx;
idx - lastIdx idx = str.find(seperator, idx);
));
idx += seperator.length(); // Grab our substring until the next finding of sep
} if (idx != std::string::npos) {
// No more seperator found. Grab the rest until the end of the string toRet.push_back(str.substr(
else { lastIdx,
toRet.push_back(str.substr( idx - lastIdx
lastIdx ));
));
idx += seperator.length();
}
// No more seperator found. Grab the rest until the end of the string
else {
toRet.push_back(str.substr(
lastIdx
));
}
} }
} }
}
return toRet; return toRet;
}
std::string StringTools::PadLeft(const std::string& str, const char pad, const std::size_t len) {
std::stringstream ss;
for (std::size_t i = str.length(); i < len; i++)
ss << pad;
ss << str;
return ss.str();
}
std::string StringTools::PadRight(const std::string& str, const char pad, const std::size_t len) {
std::stringstream ss;
ss << str;
for (std::size_t i = str.length(); i < len; i++)
ss << pad;
return ss.str();
}
} }
std::string StringTools::PadLeft(const std::string& str, const char pad, const std::size_t len) {
std::stringstream ss;
for (std::size_t i = str.length(); i < len; i++)
ss << pad;
ss << str;
return ss.str();
}
std::string StringTools::PadRight(const std::string& str, const char pad, const std::size_t len) {
std::stringstream ss;
ss << str;
for (std::size_t i = str.length(); i < len; i++)
ss << pad;
return ss.str();
}

View File

@ -1,6 +1,9 @@
#include <StringTools/CharTools.h> #include <StringTools/CharTools.h>
#include "Catch2.h" #include "Catch2.h"
using namespace Leonetienne::StringTools;
TEST_CASE(__FILE__"/JustChars", "[Char][CopySign]") TEST_CASE(__FILE__"/JustChars", "[Char][CopySign]")
{ {
// Setup // Setup

View File

@ -1,6 +1,9 @@
#include <StringTools/CharTools.h> #include <StringTools/CharTools.h>
#include "Catch2.h" #include "Catch2.h"
using namespace Leonetienne::StringTools;
// Tests character digit-ness by checking it against a map // Tests character digit-ness by checking it against a map
TEST_CASE(__FILE__"/MapTest", "[Char][IsUpper]") TEST_CASE(__FILE__"/MapTest", "[Char][IsUpper]")
{ {

View File

@ -1,6 +1,9 @@
#include <StringTools/CharTools.h> #include <StringTools/CharTools.h>
#include "Catch2.h" #include "Catch2.h"
using namespace Leonetienne::StringTools;
// Tests character letter-ness by checking it against a map // Tests character letter-ness by checking it against a map
TEST_CASE(__FILE__"/MapTest", "[Char][IsLetter]") TEST_CASE(__FILE__"/MapTest", "[Char][IsLetter]")
{ {

View File

@ -1,6 +1,9 @@
#include <StringTools/CharTools.h> #include <StringTools/CharTools.h>
#include "Catch2.h" #include "Catch2.h"
using namespace Leonetienne::StringTools;
// Tests character sign by checking it against a map // Tests character sign by checking it against a map
TEST_CASE(__FILE__"/MapTest", "[Char][IsLower]") TEST_CASE(__FILE__"/MapTest", "[Char][IsLower]")
{ {

View File

@ -2,6 +2,9 @@
#include <iostream> #include <iostream>
#include "Catch2.h" #include "Catch2.h"
using namespace Leonetienne::StringTools;
// Tests character sign by checking it against a map // Tests character sign by checking it against a map
TEST_CASE(__FILE__"/MapTest", "[Char][IsUpper]") TEST_CASE(__FILE__"/MapTest", "[Char][IsUpper]")
{ {

View File

@ -1,6 +1,9 @@
#include <StringTools/CharTools.h> #include <StringTools/CharTools.h>
#include "Catch2.h" #include "Catch2.h"
using namespace Leonetienne::StringTools;
// Tests character vowel-ness by checking it against a map // Tests character vowel-ness by checking it against a map
TEST_CASE(__FILE__"/MapTest", "[Char][IsVowel]") TEST_CASE(__FILE__"/MapTest", "[Char][IsVowel]")
{ {

View File

@ -1,6 +1,9 @@
#include <StringTools/CharTools.h> #include <StringTools/CharTools.h>
#include "Catch2.h" #include "Catch2.h"
using namespace Leonetienne::StringTools;
TEST_CASE(__FILE__"/LowerToUpper_NoSymbols", "[Char][MakeLower]") TEST_CASE(__FILE__"/LowerToUpper_NoSymbols", "[Char][MakeLower]")
{ {
// Setup // Setup

View File

@ -1,6 +1,9 @@
#include <StringTools/CharTools.h> #include <StringTools/CharTools.h>
#include "Catch2.h" #include "Catch2.h"
using namespace Leonetienne::StringTools;
TEST_CASE(__FILE__"/LowerToUpper_NoSymbols", "[Char][MakeUpper]") TEST_CASE(__FILE__"/LowerToUpper_NoSymbols", "[Char][MakeUpper]")
{ {
// Setup // Setup

View File

@ -1,6 +1,9 @@
#include <StringTools/StringTools.h> #include <StringTools/StringTools.h>
#include "Catch2.h" #include "Catch2.h"
using namespace Leonetienne::StringTools;
// Tests that lowering an empty string returns an empty string // Tests that lowering an empty string returns an empty string
TEST_CASE(__FILE__"/EmptyString", "[Strings][Lower]") TEST_CASE(__FILE__"/EmptyString", "[Strings][Lower]")
{ {

View File

@ -1,6 +1,9 @@
#include <StringTools/StringTools.h> #include <StringTools/StringTools.h>
#include "Catch2.h" #include "Catch2.h"
using namespace Leonetienne::StringTools;
// Tests that padding to a length shorter adds no padding // Tests that padding to a length shorter adds no padding
TEST_CASE(__FILE__"/PadToShorterLength", "[Strings][PadLeft]") TEST_CASE(__FILE__"/PadToShorterLength", "[Strings][PadLeft]")
{ {

View File

@ -1,6 +1,9 @@
#include <StringTools/StringTools.h> #include <StringTools/StringTools.h>
#include "Catch2.h" #include "Catch2.h"
using namespace Leonetienne::StringTools;
// Tests that padding to a length shorter adds no padding // Tests that padding to a length shorter adds no padding
TEST_CASE(__FILE__"/PadToShorterLength", "[Strings][PadRight]") TEST_CASE(__FILE__"/PadToShorterLength", "[Strings][PadRight]")
{ {

View File

@ -1,6 +1,9 @@
#include <StringTools/StringTools.h> #include <StringTools/StringTools.h>
#include "Catch2.h" #include "Catch2.h"
using namespace Leonetienne::StringTools;
// Tests that replacing something in an empty string returns an empty string // Tests that replacing something in an empty string returns an empty string
TEST_CASE(__FILE__"/EmptyString", "[Strings][ReplaceChar]") TEST_CASE(__FILE__"/EmptyString", "[Strings][ReplaceChar]")
{ {

View File

@ -1,6 +1,9 @@
#include <StringTools/StringTools.h> #include <StringTools/StringTools.h>
#include "Catch2.h" #include "Catch2.h"
using namespace Leonetienne::StringTools;
// Tests that replacing something in an empty string returns an empty string // Tests that replacing something in an empty string returns an empty string
TEST_CASE(__FILE__"/EmptyString", "[Strings][ReplaceString]") TEST_CASE(__FILE__"/EmptyString", "[Strings][ReplaceString]")
{ {

View File

@ -1,6 +1,9 @@
#include <StringTools/StringTools.h> #include <StringTools/StringTools.h>
#include "Catch2.h" #include "Catch2.h"
using namespace Leonetienne::StringTools;
// Tests that splitting an empty string always returns {""} // Tests that splitting an empty string always returns {""}
TEST_CASE(__FILE__"/EmptyString", "[Strings][Split]") TEST_CASE(__FILE__"/EmptyString", "[Strings][Split]")
{ {

View File

@ -1,6 +1,9 @@
#include <StringTools/StringTools.h> #include <StringTools/StringTools.h>
#include "Catch2.h" #include "Catch2.h"
using namespace Leonetienne::StringTools;
// Tests that uppering an empty string returns an empty string // Tests that uppering an empty string returns an empty string
TEST_CASE(__FILE__"/EmptyString", "[Strings][Upper]") TEST_CASE(__FILE__"/EmptyString", "[Strings][Upper]")
{ {