From dae1243185849043a8a4572db0f2913b249e88a6 Mon Sep 17 00:00:00 2001 From: JDierkse Date: Mon, 10 Feb 2020 20:31:06 +0100 Subject: [PATCH] Initial commit --- .gitignore | 8 ++ .gitmodules | 3 + Makefile | 1 + Makefile.conf | 6 + Makefile.target | 13 +++ Makefiles | 1 + Utilities/Makefile | 1 + Utilities/StringAlgorithm.cpp | 103 +++++++++++++++++ Utilities/Tribool.cpp | 138 +++++++++++++++++++++++ include/StringAlgorithm.h | 33 ++++++ include/Tribool.h | 203 ++++++++++++++++++++++++++++++++++ 11 files changed, 510 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 120000 Makefile create mode 100644 Makefile.conf create mode 100644 Makefile.target create mode 160000 Makefiles create mode 120000 Utilities/Makefile create mode 100644 Utilities/StringAlgorithm.cpp create mode 100644 Utilities/Tribool.cpp create mode 100644 include/StringAlgorithm.h create mode 100644 include/Tribool.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5c150de --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +*.o.* +*.d.* +*.a.* +.*.swp +.AppleDouble +lib +Libraries +fixPermissions.sh diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..876e403 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Makefiles"] + path = Makefiles + url = https://gogs.dierkse.nl/JDierkse/Makefiles diff --git a/Makefile b/Makefile new file mode 120000 index 0000000..6aa5187 --- /dev/null +++ b/Makefile @@ -0,0 +1 @@ +Makefiles/Makefile \ No newline at end of file diff --git a/Makefile.conf b/Makefile.conf new file mode 100644 index 0000000..db925bb --- /dev/null +++ b/Makefile.conf @@ -0,0 +1,6 @@ +# +# Makefile.conf +# + +CFLAGS += -I$(ROOTPATH) -I$(ROOTPATH)/include +DEBUGDIR := .debug diff --git a/Makefile.target b/Makefile.target new file mode 100644 index 0000000..45baf98 --- /dev/null +++ b/Makefile.target @@ -0,0 +1,13 @@ +# +# Makefile.target +# + +Utilities.a.$(ARCH) : $(OBJECTS) + $(call build_target_library_arch,$@,$^) + +Utilities.a: + $(call build_target,$@) + +.DEFAULT_GOAL := Utilities.a + +TARGETS += Utilities.a diff --git a/Makefiles b/Makefiles new file mode 160000 index 0000000..61894c4 --- /dev/null +++ b/Makefiles @@ -0,0 +1 @@ +Subproject commit 61894c4588eb2b85e342a6f923eeb7ac97c3fe64 diff --git a/Utilities/Makefile b/Utilities/Makefile new file mode 120000 index 0000000..d0b0e8e --- /dev/null +++ b/Utilities/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/Utilities/StringAlgorithm.cpp b/Utilities/StringAlgorithm.cpp new file mode 100644 index 0000000..fc65a55 --- /dev/null +++ b/Utilities/StringAlgorithm.cpp @@ -0,0 +1,103 @@ +#include "StringAlgorithm.h" +#include +#include +#include +#include + + +namespace Utilities { +namespace Internal { + +size_t find_nth(const std::string& haystack, size_t pos, const std::string& needle, size_t nth) +{ + size_t found_pos = haystack.find(needle, pos); + if (0 == nth || std::string::npos == found_pos) + return found_pos; + return find_nth(haystack, found_pos + 1, needle, nth - 1); +} + +} // namespace Internal + +bool equals(const std::string& str1, const std::string& str2) +{ + return (str1.compare(str2) == 0); +} + +bool iequals(const std::string& str1, const std::string& str2) +{ + std::string s1(str1); + std::string s2(str2); + std::transform(s1.begin(), s1.end(), s1.begin(), ::tolower); + std::transform(s2.begin(), s2.end(), s2.begin(), ::tolower); + + return equals(s1, s2); +} + +bool starts_with(const std::string& subject, const std::string& find) +{ + return (subject.find(find) == 0); +} + +bool istarts_with(const std::string& subject, const std::string& find) +{ + std::string s(subject); + std::string f(find); + std::transform(s.begin(), s.end(), s.begin(), ::tolower); + std::transform(f.begin(), f.end(), f.begin(), ::tolower); + + return starts_with(s, f); +} + +std::vector split(const std::string& subject, const char& delimiter) +{ + std::stringstream ss(subject); + std::string item; + std::vector elems; + while (std::getline(ss, item, delimiter)) + elems.push_back(std::move(item)); + + if (subject.back() == delimiter) + elems.push_back(""); + + return elems; +} + +std::vector split(const std::string& subject, const std::string delimiters) +{ + std::string s(subject); + char delimiter = delimiters.front(); + + for (const char& c : delimiters) + std::replace(s.begin(), s.end(), c, delimiter); + + return split(s, delimiter); +} + +void erase_all(std::string& subject, const char& item) +{ + subject.erase(std::remove(subject.begin(), subject.end(), item), subject.end()); +} + +bool contains(const std::string& subject, const std::string& find) +{ + return (subject.find(find) != std::string::npos); +} + +bool icontains(const std::string& subject, const std::string& find) +{ + std::string s(subject); + std::string f(find); + std::transform(s.begin(), s.end(), s.begin(), ::tolower); + std::transform(f.begin(), f.end(), f.begin(), ::tolower); + + return contains(s, f); +} + +std::string::const_iterator find_nth(const std::string& haystack, const std::string& needle, size_t nth) +{ + auto iterator = haystack.begin(); + std::advance(iterator, Internal::find_nth(haystack, 0, needle, nth)); + return iterator; +} + +} // namespace Utilities diff --git a/Utilities/Tribool.cpp b/Utilities/Tribool.cpp new file mode 100644 index 0000000..4634229 --- /dev/null +++ b/Utilities/Tribool.cpp @@ -0,0 +1,138 @@ +#include "Tribool.h" + + +namespace Utilities { + +Tribool::Tribool() : m_value(TriboolValue::Indeterminate) +{ +} + +Tribool::Tribool(bool value) : m_value(value? TriboolValue::True : TriboolValue::False) +{ +} + +Tribool::Tribool(const Tribool::IndeterminateKeywordType&) : m_value(TriboolValue::Indeterminate) +{ +} + +Tribool::operator bool() const +{ + return m_value == TriboolValue::True? true: false; +} + +Tribool Tribool::operator!() const +{ + return m_value == TriboolValue::False? Tribool(true): + m_value == TriboolValue::True? Tribool(false): + Tribool(Indeterminate); +} + +Tribool Tribool::operator&&(const Tribool& other) const +{ + return (static_cast(!*this) || static_cast(!other))? + Tribool(false): + ((static_cast(*this) && static_cast(other))? + Tribool(true) : Tribool(Indeterminate)); +} + +Tribool operator&&(const Tribool& lhs, bool rhs) +{ + return rhs? lhs: Tribool(false); +} + +Tribool operator&&(bool lhs, const Tribool& rhs) +{ + return lhs? rhs: Tribool(false); +} + +Tribool operator&&(const Tribool::IndeterminateKeywordType&, const Tribool& rhs) +{ + return !rhs? Tribool(false) : Tribool(Tribool::Indeterminate); +} + +Tribool operator&&(const Tribool& lhs, const Tribool::IndeterminateKeywordType&) +{ + return !lhs? Tribool(false) : Tribool(Tribool::Indeterminate); +} + +Tribool Tribool::operator||(const Tribool& other) const +{ + return (static_cast(!*this) && static_cast(!other))? + Tribool(false): + ((static_cast(*this) || static_cast(other))? + Tribool(true): Tribool(Tribool::Indeterminate)); +} + +Tribool operator||(const Tribool& lhs, bool rhs) +{ + return rhs? Tribool(true) : lhs; +} + +Tribool operator||(bool lhs, const Tribool& rhs) +{ + return lhs? Tribool(true) : rhs; +} + +Tribool operator||(const Tribool::IndeterminateKeywordType&, const Tribool& rhs) +{ + return rhs? Tribool(true) : Tribool(Tribool::Indeterminate); +} + +Tribool operator||(const Tribool& lhs, const Tribool::IndeterminateKeywordType&) +{ + return lhs? Tribool(true) : Tribool(Tribool::Indeterminate); +} + +Tribool Tribool::operator==(const Tribool& other) const +{ + return (Tribool::Indeterminate(*this) || Tribool::Indeterminate(other))? + Tribool::Indeterminate: ((*this && other) || (!*this && !other)); +} + +Tribool operator==(const Tribool& lhs, bool rhs) +{ + return lhs == Tribool(rhs); +} + +Tribool operator==(bool lhs, const Tribool& rhs) +{ + return Tribool(lhs) == rhs; +} + +Tribool operator==(const Tribool::IndeterminateKeywordType&, const Tribool& rhs) +{ + return Tribool(Tribool::Indeterminate) == rhs; +} + +Tribool operator==(const Tribool& lhs, const Tribool::IndeterminateKeywordType&) +{ + return Tribool(Tribool::Indeterminate) == lhs; +} + +Tribool Tribool::operator!=(const Tribool& other) const +{ + return (Tribool::Indeterminate(*this) || Tribool::Indeterminate(other))? + Tribool::Indeterminate: !((*this && other) || (!*this && !other)); +} + +Tribool operator!=(const Tribool& lhs, bool rhs) +{ + return lhs != Tribool(rhs); +} + +Tribool operator!=(bool lhs, const Tribool& rhs) +{ + return Tribool(lhs) != rhs; +} + +Tribool operator!=(const Tribool::IndeterminateKeywordType&, const Tribool& rhs) +{ + return Tribool(Tribool::Indeterminate) != rhs; +} + +Tribool operator!=(const Tribool& lhs, const Tribool::IndeterminateKeywordType&) +{ + return Tribool(Tribool::Indeterminate) != lhs; +} + +} // namespace Utilities diff --git a/include/StringAlgorithm.h b/include/StringAlgorithm.h new file mode 100644 index 0000000..2b70ba3 --- /dev/null +++ b/include/StringAlgorithm.h @@ -0,0 +1,33 @@ +#ifndef STRINGALGORITHM_H +#define STRINGALGORITHM_H + +#include +#include + + +namespace Utilities { +namespace Internal { + +size_t find_nth(const std::string& haystack, size_t pos, const std::string& needle, size_t nth); + +} // namespace Internal + +bool equals(const std::string& str1, const std::string& str2); +bool iequals(const std::string& str1, const std::string& str2); + +bool starts_with(const std::string& subject, const std::string& string); +bool istarts_with(const std::string& subject, const std::string& string); + +std::vector split(const std::string& subject, const char& delimiter); +std::vector split(const std::string& subject, const std::string delimiters); + +void erase_all(std::string& subject, const char& item); + +bool contains(const std::string& subject, const std::string& find); +bool icontains(const std::string& subject, const std::string& find); + +std::string::const_iterator find_nth(const std::string& haystack, const std::string& needle, size_t nth); + +} // namespace Utilities + +#endif // STRINGALGORITHM_H diff --git a/include/Tribool.h b/include/Tribool.h new file mode 100644 index 0000000..1a82bfc --- /dev/null +++ b/include/Tribool.h @@ -0,0 +1,203 @@ +#ifndef TRIBOOL_H +#define TRIBOOL_H + +#include + + +namespace Utilities { + +class Tribool +{ +public: + struct IndeterminateType + { + }; + + typedef bool (*IndeterminateKeywordType)(Tribool, IndeterminateType); + +public: + Tribool(); + Tribool(bool value); + Tribool(const IndeterminateKeywordType& value); + + explicit operator bool() const; + Tribool operator!() const; + + Tribool operator&&(const Tribool& other) const; + friend Tribool operator&&(const Tribool& lhs, bool rhs); + friend Tribool operator&&(bool lhs, const Tribool& rhs); + friend Tribool operator&&(const IndeterminateKeywordType& lhs, const Tribool& rhs); + friend Tribool operator&&(const Tribool& lhs, const IndeterminateKeywordType& rhs); + + Tribool operator||(const Tribool& other) const; + friend Tribool operator||(const Tribool& lhs, bool rhs); + friend Tribool operator||(bool lhs, const Tribool& rhs); + friend Tribool operator||(const IndeterminateKeywordType& lhs, const Tribool& rhs); + friend Tribool operator||(const Tribool& lhs, const IndeterminateKeywordType& rhs); + + Tribool operator==(const Tribool& other) const; + friend Tribool operator==(const Tribool& lhs, bool rhs); + friend Tribool operator==(bool lhs, const Tribool& rhs); + friend Tribool operator==(const IndeterminateKeywordType& lhs, const Tribool& rhs); + friend Tribool operator==(const Tribool& lhs, const IndeterminateKeywordType& rhs); + + Tribool operator!=(const Tribool& other) const; + friend Tribool operator!=(const Tribool& lhs, bool rhs); + friend Tribool operator!=(bool lhs, const Tribool& rhs); + friend Tribool operator!=(const IndeterminateKeywordType& lhs, const Tribool& rhs); + friend Tribool operator!=(const Tribool& lhs, const IndeterminateKeywordType& rhs); + + static inline bool Indeterminate(Tribool x, Tribool::IndeterminateType = Tribool::IndeterminateType()) + { + return x.m_value == Tribool::TriboolValue::Indeterminate; + } + +private: + class TriboolValue + { + public: + enum type + { + True, + False, + Indeterminate + }; + }; + +private: + TriboolValue::type m_value; +}; + + +template +inline std::basic_ostream& operator<<(std::basic_ostream& out, Tribool x) +{ + if (!Tribool::Indeterminate(x)) { + out << static_cast(x); + } + else + { + typename std::basic_ostream::sentry cerberus(out); + if (cerberus) + { + if (out.flags() & std::ios_base::boolalpha) + out << "indeterminate"; + else + out << 2; + } + } + return out; +} + +template +inline std::basic_ostream& operator<<(std::basic_ostream& out, bool (*)(Tribool, Tribool::IndeterminateType)) +{ + return out << Tribool(Tribool::Indeterminate); +} + +template +std::basic_istream& operator>>(std::basic_istream& in, Tribool& x) +{ + if (in.flags() & std::ios_base::boolalpha) + { + typename std::basic_istream::sentry cerberus(in); + if (cerberus) + { + typedef std::basic_string string_type; + + string_type falsename = "false"; + string_type truename = "true"; + string_type indeterminatename = "indeterminate"; + + typename string_type::size_type pos = 0; + bool falsename_ok = true; + bool truename_ok = true; + bool indeterminatename_ok = true; + + while ((falsename_ok && pos < falsename.size()) || (truename_ok && pos < truename.size()) || (indeterminatename_ok && pos < indeterminatename.size())) + { + typename Traits::int_type c = in.get(); + if (c == Traits::eof()) + return in; + + bool matched = false; + if (falsename_ok && pos < falsename.size()) + { + if (Traits::eq(Traits::to_char_type(c), falsename[pos])) + matched = true; + else + falsename_ok = false; + } + + if (truename_ok && pos < truename.size()) + { + if (Traits::eq(Traits::to_char_type(c), truename[pos])) + matched = true; + else + truename_ok = false; + } + + if (indeterminatename_ok && pos < indeterminatename.size()) + { + if (Traits::eq(Traits::to_char_type(c), indeterminatename[pos])) + matched = true; + else + indeterminatename_ok = false; + } + + if (matched) + ++pos; + if (pos > falsename.size()) + falsename_ok = false; + if (pos > truename.size()) + truename_ok = false; + if (pos > indeterminatename.size()) + indeterminatename_ok = false; + } + + if (pos == 0) + { + in.setstate(std::ios_base::failbit); + } + else + { + if (falsename_ok) + x = false; + else if (truename_ok) + x = true; + else if (indeterminatename_ok) + x = Tribool::Indeterminate; + else + in.setstate(std::ios_base::failbit); + } + } + } + else + { + long value; + if (in >> value) + { + switch (value) + { + case 0: + x = false; + break; + case 1: + x = true; + break; + case 2: + x = Tribool::Indeterminate; + break; + default: + in.setstate(std::ios_base::failbit); + break; + } + } + } + + return in; +} + +} // namespace Utilities + +#endif // TRIBOOL_H