From aeba6ffc31afbd78c5ee3569a753ff1bc6fee4ec Mon Sep 17 00:00:00 2001 From: "matthias@arch" Date: Tue, 1 Nov 2022 18:16:32 +0100 Subject: [PATCH] removed util directory --- src/{util => }/regex.cpp | 0 src/{util => }/regex.hpp | 0 src/{util => }/util.cpp | 0 src/{util => }/util.hpp | 0 src/util/string.cpp | 59 ---- src/util/string.hpp | 77 ---- src/util/string_concepts.hpp | 177 ---------- src/util/string_conversion.cpp | 119 ------- src/util/string_conversion.hpp | 627 --------------------------------- 9 files changed, 1059 deletions(-) rename src/{util => }/regex.cpp (100%) rename src/{util => }/regex.hpp (100%) rename src/{util => }/util.cpp (100%) rename src/{util => }/util.hpp (100%) delete mode 100644 src/util/string.cpp delete mode 100644 src/util/string.hpp delete mode 100644 src/util/string_concepts.hpp delete mode 100644 src/util/string_conversion.cpp delete mode 100644 src/util/string_conversion.hpp diff --git a/src/util/regex.cpp b/src/regex.cpp similarity index 100% rename from src/util/regex.cpp rename to src/regex.cpp diff --git a/src/util/regex.hpp b/src/regex.hpp similarity index 100% rename from src/util/regex.hpp rename to src/regex.hpp diff --git a/src/util/util.cpp b/src/util.cpp similarity index 100% rename from src/util/util.cpp rename to src/util.cpp diff --git a/src/util/util.hpp b/src/util.hpp similarity index 100% rename from src/util/util.hpp rename to src/util.hpp diff --git a/src/util/string.cpp b/src/util/string.cpp deleted file mode 100644 index 6c576f7..0000000 --- a/src/util/string.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "string.hpp" - -#include -#include - - -namespace gz::util { - -std::vector splitStringInVector(std::string& s, char separator) { - // remove linebreaks from the end - if (*(s.end()) == '\n') { s.erase(s.end()); } - - /* std::unique_ptr> params (new std::unordered_map); */ - std::vector v; - std::stringstream ss(s); - std::string temp; - - while (std::getline(ss, temp, separator)) { - // if has "=": store latter part in vector - if (temp.find("=") != std::string::npos) { - int eqPos = temp.find("="); - v.emplace_back(temp.substr(eqPos + 1, temp.length())); - } - else { - v.emplace_back(temp); - } - } - return v; -} - - -template -std::vector splitStringInVector(const std::string_view& s, const std::string& separator, bool skipEmptyStrings) { - std::vector v; - - std::string::size_type posStart = 0; - std::string::size_type posEnd = s.find(separator, posStart); - while (posEnd != std::string::npos) { - if (!(skipEmptyStrings and posStart == posEnd)) { - v.emplace_back(T(s.begin() + posStart, s.begin() + posEnd)); - } - posStart = posEnd + 1; - posEnd = s.find(separator, posStart); - } - // last element - if (posStart < s.size()) { - v.emplace_back(T(s.begin() + posStart, s.end())); - } - // if last char is separator, append empty string - else if (!skipEmptyStrings and posStart == s.size()) { - v.emplace_back(T(s.begin(), s.begin())); - } - return v; -} - -template std::vector splitStringInVector(const std::string_view&, const std::string&, bool); -template std::vector splitStringInVector(const std::string_view&, const std::string&, bool); - -} // namespace gz::util diff --git a/src/util/string.hpp b/src/util/string.hpp deleted file mode 100644 index 296c5d9..0000000 --- a/src/util/string.hpp +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace gz::util { - template - concept SplitStringInVectorImplemented = std::same_as || std::same_as; - - /** - * @brief Split a string at a separator into a vector - * @details - * Splits a string at a separator.\n - * Two templates exist, one where the vector will hold std::string_views into s - * and one where it will hold std::strings. - * Behavior: - * - the elements of the returned vector will not contain the separator. - * - if the separator is not in s, the vector will contain s as only element. - * - empty elements will occur if: - * - separator is the first char - * - separator is the last char - * - two or more separator appear after each other\n - * You can turn this behaviour off by setting skipEmptyStrings to true - * @note - * The string_view variant has the advantage of being faster, however:\n - * The string_views will reference the original string, so it must not be changed or destroyed - * as long as the string_views are used! - */ - template - std::vector splitStringInVector(const std::string_view& s, const std::string& separator, bool skipEmptyStrings=false); - - /** - * @name Map with string type as key, works with strings, string_view and char* - * @{ - */ - struct string_hash - { - using hash_type = std::hash; - using is_transparent = void; - - size_t operator()(const char* str) const { return hash_type{}(str); } - size_t operator()(std::string_view str) const { return hash_type{}(str); } - size_t operator()(std::string const& str) const { return hash_type{}(str); } - }; - /** - * @brief A unordered_map where you can use string_views to access elements - * @details - * To retrieve an element using a string view, you need to do this: - * @code - * std::string_view sv = ...; - * gz::util::unordered_string_map smap = { ... }; - * ... - * if (smap.contains(sv)) { - * return smap.find(sv)->second; - * } - * @endcode - * The at() member and [] operator do not work with the string_view. - */ - template - using unordered_string_map = std::unordered_map>; - /** - * @brief same as unordered_string_map, but using std::map instead of std::unordered_map - */ - template - using string_map = std::map>; - /** - * @} - */ - -} // namespace gz::util - -/** - * @file - * @brief Contains utility for strings - */ diff --git a/src/util/string_concepts.hpp b/src/util/string_concepts.hpp deleted file mode 100644 index 204ee3c..0000000 --- a/src/util/string_concepts.hpp +++ /dev/null @@ -1,177 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#define GZ_UTIL_STRING_CONCEPTS - -namespace gz::util { - -// -// CONVERT TO STRING CONCEPTS -// - // ELEMENTARY TYPES - /// same as std::string - template - concept Stringy = std::same_as || std::convertible_to; - - /// can construct std::string from T - template - concept CanConstructString = !Stringy && requires(const T& t) { - { std::string(t) } -> std::same_as; - }; - - /// has .to_string() const member - template - concept HasToStringMember = !Stringy && requires(const T& t) { { t.toString() }-> Stringy; }; - - /// works with std::to_string(), except bool - template - concept WorksWithStdToString = !std::same_as && !Stringy && !HasToStringMember && requires(const T& t) { { std::to_string(t) } -> Stringy; }; - - template - concept _ElementaryTypeConvertibleToString = Stringy || HasToStringMember || WorksWithStdToString; - - - // CONTAINER - /// Forward range having string-convertible elements - template - concept ContainerConvertibleToString = !_ElementaryTypeConvertibleToString and std::ranges::forward_range and _ElementaryTypeConvertibleToString>; - - template - concept _ElementaryTypeOrForwardRangeConvertibleToString = _ElementaryTypeConvertibleToString || ContainerConvertibleToString; - - /// Pair having string-convertible elements - template - concept PairConvertibleToString = !ContainerConvertibleToString and requires(const T& p) { - requires _ElementaryTypeOrForwardRangeConvertibleToString; - requires _ElementaryTypeOrForwardRangeConvertibleToString; - }; - - /// Container having string-convertible pairs - template - concept MapConvertibleToString = !PairConvertibleToString and !_ElementaryTypeOrForwardRangeConvertibleToString and - std::ranges::forward_range and PairConvertibleToString>; - - template - concept _ContainerTypeConvertibleToString = PairConvertibleToString || ContainerConvertibleToString || MapConvertibleToString; - - template - concept _ElementaryTypeOrContainerConvertibleToString = _ElementaryTypeConvertibleToString || _ContainerTypeConvertibleToString; - - // VECTOR - /// Type having string-convertible x, y members and sizeof(T) == 2 * sizeof(x) - template - concept Vector2ConvertibleToString = !_ElementaryTypeOrContainerConvertibleToString && - requires(T t) { - { t.x } -> _ElementaryTypeOrContainerConvertibleToString; - { t.y } -> _ElementaryTypeOrContainerConvertibleToString; - requires sizeof(t.x) * 2 == sizeof(T); - }; - /// Type having string-convertible x, y, z members and sizeof(T) == 3 * sizeof(x) - template - concept Vector3ConvertibleToString = !_ElementaryTypeOrContainerConvertibleToString && - requires(T t) { - { t.x } -> _ElementaryTypeOrContainerConvertibleToString; - { t.y } -> _ElementaryTypeOrContainerConvertibleToString; - { t.z } -> _ElementaryTypeOrContainerConvertibleToString; - requires sizeof(t.x) * 3 == sizeof(T); - }; - /// Type having string-convertible x, y, z, w members and sizeof(T) == 4 * sizeof(x) - template - concept Vector4ConvertibleToString = !_ElementaryTypeOrContainerConvertibleToString && - requires(T t) { - { t.x } -> _ElementaryTypeOrContainerConvertibleToString; - { t.y } -> _ElementaryTypeOrContainerConvertibleToString; - { t.z } -> _ElementaryTypeOrContainerConvertibleToString; - { t.w } -> _ElementaryTypeOrContainerConvertibleToString; - requires sizeof(t.x) * 4 == sizeof(T); - }; - - /// Type having string-convertible width, height members and sizeof(T) == 2 * sizeof(width) - template - concept Extent2DConvertibleToString = !_ElementaryTypeOrContainerConvertibleToString && - requires(T t) { - { t.width } -> _ElementaryTypeOrContainerConvertibleToString; - { t.height } -> _ElementaryTypeOrContainerConvertibleToString; - requires sizeof(t.width) * 2 == sizeof(T); - }; - /// Type having string-convertible width, height, depth members and sizeof(T) == 3 * sizeof(width) - template - concept Extent3DConvertibleToString = !_ElementaryTypeOrContainerConvertibleToString && - requires(T t) { - { t.width } -> _ElementaryTypeOrContainerConvertibleToString; - { t.height } -> _ElementaryTypeOrContainerConvertibleToString; - { t.depth } -> _ElementaryTypeOrContainerConvertibleToString; - requires sizeof(t.width) * 3 == sizeof(T); - }; - - // POINTER - /// Everything from string-convertibleNoPtr but "behind" a pointer - template - concept PointerConvertibleToString = !_ElementaryTypeOrContainerConvertibleToString and - requires(const T t) { { *t } -> _ElementaryTypeOrContainerConvertibleToString; }; - - -// HEX/OCT/BIN - // Forward range holding integers - template - concept IntegralForwardRange = std::ranges::forward_range and std::integral>; - -} // namespace gz::util - - -// -// CONVERT TO STRING -// -template -concept False = false; -/** - * @brief Declaration of fromString in global namespace, so that concepts can use it - * @details - * This declaration only exists so that ::fromString can be used in concepts. - */ -template -T fromString(const std::string& s); -/** - * @brief Declaration of toString in global namespace, so that concepts can use it - * This declaration only exists so that ::toString can be used in concepts. - */ -template -std::string toString(const T& s); - -namespace gz::util { - template - concept ConstructibleFromStringGlobal = requires(const std::string& s) { - { ::fromString(s) } -> std::same_as; - }; - template - concept ConvertibleToStringGlobal = requires(const T& t) { - { ::toString(t) } -> Stringy; - }; - - /** - * @brief toString is implemented for these types - */ - template - concept GetTypeFromStringImplemented = - std::same_as or - std::same_as or - std::same_as or - std::same_as or - std::same_as or - std::same_as or - std::same_as or - std::same_as or - std::same_as or - std::same_as; -} - -/** - * @file - * @brief Concepts used for the to_string() functions - * @details - * These concepts are used - */ diff --git a/src/util/string_conversion.cpp b/src/util/string_conversion.cpp deleted file mode 100644 index 203fc31..0000000 --- a/src/util/string_conversion.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include "string_conversion.hpp" -#include "../exceptions.hpp" -#include "regex.hpp" - - -namespace gz { - -bool isInt(const std::string& s) { - return std::regex_match(s, re::types::intT); -} -bool isInt(const std::string_view& s) { - return re::regex_match(s, re::types::intT); -} -bool isUInt(const std::string& s) { - return std::regex_match(s, re::types::uintT); -} -bool isUInt(const std::string_view& s) { - return re::regex_match(s, re::types::uintT); -} -bool isFloal(const std::string& s) { - return std::regex_match(s, re::types::floatT); -} -bool isFloat(const std::string_view& s) { - return re::regex_match(s, re::types::floatT); -} - - -int getIntOr(const std::string& s, int fallback) noexcept { - try { - fallback = std::stoi(s); - } - catch (...) {} - return fallback; -} - - -unsigned int getUnsignedIntOr(const std::string& s, unsigned int fallback) noexcept { - try { - fallback = std::stoul(s); - } - catch (...) {} - return fallback; -} - - -double getDoubleOr(const std::string& s, double fallback) noexcept { - try { - fallback = std::stod(s); - } - catch (...) {} - return fallback; -} - - -float getFloatOr(const std::string& s, float fallback) noexcept { - try { - fallback = std::stof(s); - } - catch (...) {} - return fallback; -} - - -bool getBoolOr(const std::string& s, bool fallback) noexcept { - if (s == "true" or s == "True" or s == "1") { - fallback = true; - } - else if (s == "false" or s == "False" or s == "0") { - fallback = false; - } - return fallback; -} - - -std::string getStringOr(const std::string& s, const std::string& fallback) noexcept { - if (s == "") { return fallback; } - else { return s; } -} - - -// TODO: remove? -/* // int = 0, double = 1, string = 2 */ -/* std::variant getVariant(std::string value, GetVariantType type, bool bFallback, int iFallback, double dFallback, const char* sFallback) { */ -/* std::variant val = value; */ -/* /1* cout << "id-attr" << id << attr << "val: " << std::get(val); *1/ */ -/* switch (type) { */ -/* // to integer */ -/* case INT: */ -/* val = getIntOr(value, iFallback); */ -/* break; */ -/* case DOUBLE: */ -/* val = getDoubleOr(value, dFallback); */ -/* break; */ -/* case BOOL: */ -/* val = getBoolOr(value, bFallback); */ -/* break; */ -/* case STRING: */ -/* val = getStringOr(value, sFallback); */ -/* break; */ -/* } */ -/* return val; */ -/* } */ - -// -// CONVERT FROM STRING -// -template<> -bool fromString(const std::string& s) { - if (s == "true" or s == "True" or s == "1") { - return true; - } - else if (s == "false" or s == "False" or s == "0") { - return false; - } - throw InvalidArgument("s is not a bool: '" + s + "'", "fromString"); -} - - -} // namespace gz diff --git a/src/util/string_conversion.hpp b/src/util/string_conversion.hpp deleted file mode 100644 index 1a52ead..0000000 --- a/src/util/string_conversion.hpp +++ /dev/null @@ -1,627 +0,0 @@ -#pragma once - -#include "string_concepts.hpp" - -#include -#include - -#ifdef FORMAT -#include -#else -#include -#include -#endif - -namespace gz { - -/** - * @name Functions that determine if s is a string representation of a certain type, using regex. - * @{ - */ - bool isInt(const std::string& s); - bool isInt(const std::string_view& s); - bool isUInt(const std::string& s); - bool isUInt(const std::string_view& s); - bool isFloat(const std::string& s); - bool isFloat(const std::string_view& s); -/** - * @} - */ - - -/** - * @name Convert to type or return fallback - * @todo Use string_views without constructing a std::string - * @{ - */ - int getIntOr(const std::string& s, int fallback=0) noexcept; - inline int getIntOr(const std::string_view& s, int fallback=0) noexcept { return getIntOr(std::string(s), fallback); } - - unsigned int getUnsignedIntOr(const std::string& s, unsigned int fallback=0) noexcept; - /* inline unsigned int getUnsignedIntOr(const std::string&& s, unsigned int fallback=0) { return getUnsignedIntOr(s, fallback); } */ - inline unsigned int getUnsignedIntOr(const std::string_view& s, unsigned int fallback=0) noexcept { return getUnsignedIntOr(std::string(s), fallback); } - - double getDoubleOr(const std::string& s, double fallback=0) noexcept; - /* inline double getDoubleOr(const std::string&& s, double fallback=0) { return getDoubleOr(s, fallback); } */ - inline double getDoubleOr(const std::string_view& s, double fallback=0) noexcept { return getDoubleOr(std::string(s), fallback); } - - float getFloatOr(const std::string& s, float fallback=0) noexcept; - /* inline float getFloatOr(const std::string&& s, float fallback=0) { return getDoubleOr(s, fallback); } */ - inline float getFloatOr(const std::string_view& s, float fallback=0) noexcept { return getDoubleOr(std::string(s), fallback); } - - bool getBoolOr(const std::string& s, bool fallback=false) noexcept; - /* inline bool getBoolOr(const std::string&& s, bool fallback=false) { return getBoolOr(s, fallback); } */ - inline bool getBoolOr(const std::string_view& s, bool fallback=false) noexcept { return getBoolOr(std::string(s), fallback); } - - /** - * @brief Returns the string or fallback if string is empty. - */ - std::string getStringOr(const std::string& s, const std::string& fallback="none") noexcept; -/** - * @} - */ - // TODO: remove? - /* enum GetVariantType { */ - /* INT, DOUBLE, STRING, BOOL, */ - /* }; */ - /* - * @brief Converts the given string to the requested type and puts returns it in a variant - * @details - * Tries to convert the string to the specified type. - * If that fails a default value is returned. - * This is either 1 for int or double or "none" for strings. - * - * @param value String which should be converted - * @param type GetVariantType datatype to return in the variant - * - * @returns Variant containing the value in the given datatype. - */ - /* std::variant getVariant(std::string value, GetVariantType type=STRING, bool bFallback=false, int iFallback=0, double dFallback=0, const char* sFallback="none"); */ - -// -// CONVERT TO STRING -// -/** - * @name Converting a type to string - * @{ - */ - /** - * @brief Return the string - * @returns static_cast(t) - */ - template - inline std::string toString(const T& t) { - return static_cast(t); - } - - /** - * @brief Construct a string from a string like-type - * @returns std::string(t) - */ - template - inline std::string toString(const T& t) { - return std::string(t); - } - - /** - * @overload - * @brief Construct a string from a type having a toString() const member function - * @returns t.toString() - */ - template - inline std::string toString(const T& t) { - return t.toString(); - } - - /** - * @overload - * @brief Construct a string from a number - * @returns std::to_string(t) - */ - template - inline std::string toString(const T& t) { - return std::to_string(t); - } - - /** - * @brief Construct a string from a boolean - * @details - * Unlike std::to_string(bool), which returns 0 or 1, this function returns "true" or "false" - * @returns "true" or "false" - */ - inline std::string toString(const bool& b) { - return b ? "true" : "false"; - } - - /** - * @overload - * @brief Construct a string from a forward range - * @returns [ x1, x2, ... ] - */ - template - std::string toString(const T& t) { - std::string s = "[ "; - for (auto it = t.begin(); it != t.end(); it++) { - s += toString(*it) + ", "; - } - if (s.size() > 2) { - s.erase(s.size() - 2); - } - s += " ]"; - return s; - } - - /** - * @overload - * @brief Construct a string from a pair - * @returns ( first, second ) - */ - template - inline std::string toString(const T& t) { - return "( " + toString(t.first) + ", " + toString(t.second) + " )"; - } - - /** - * @overload - * @brief Construct a string from a forward range holding a pair, eg a map - * @returns { first: second, first: second, ... } - */ - template - std::string toString(const T& t) { - std::string s = "{ "; - for (const auto& [k, v] : t) { - s += toString(k) + ": "; - s += toString(v) + ", "; - } - if (s.size() > 2) { - s.erase(s.size() - 2); - } - s += " }"; - return s; - } - - /** - * @overload - * @brief Construct a string from the element the pointer points at - * @returns *t - */ - template - inline std::string toString(const T& t) { - return toString(*t); - } - - /** - * @overload - * @brief Construct a string from a vector with x, y members - * @returns ( x, y ) - */ - template - inline std::string toString(const T& t) { - std::string s = "( "; - s += toString(t.x) + ", "; - s += toString(t.y) + " )"; - return s; - } - - /** - * @overload - * @brief Construct a string from a vector with x, y members - * @returns ( x, y, z ) - */ - template - inline std::string toString(const T& t) { - std::string s = "( "; - s += toString(t.x) + ", "; - s += toString(t.y) + ", "; - s += toString(t.z) + " )"; - return s; - } - - /** - * @overload - * @brief Construct a string from a vector with x, y, z, w members - * @returns ( x, y, z, w ) - */ - template - inline std::string toString(const T& t) { - std::string s = "( "; - s += toString(t.x) + ", "; - s += toString(t.y) + ", "; - s += toString(t.z) + ", "; - s += toString(t.w) + " )"; - return s; - } - - /** - * @overload - * @brief Construct a string from a type having width and height members - * @returns ( width, height ) - */ - template - inline std::string toString(const T& t) { - std::string s = "( "; - s += toString(t.width) + ", "; - s += toString(t.height) + " ) "; - return s; - } - - /** - * @overload - * @brief Construct a string from a type having width and height members - * @returns ( width, height, depth ) - */ - template - inline std::string toString(const T& t) { - std::string s = "( "; - s += toString(t.width) + ", "; - s += toString(t.height) + ", "; - s += toString(t.depth) + " ) "; - return s; - } - /** - * @overload - * @brief Construct a string from a type that has toString declared in global namespace - */ - template - inline std::string toString(const T& t) { - return ::toString(t); - } -/** -* @} -*/ - -// -// CONVERT FROM STRING -// -/** - * @name Construct a type from a string - * @note - * The fromString() functions (except for the bool one) simply return std::stoXX. These can throw std::invalid_argument and std::out_of_range. - * See https://en.cppreference.com/w/cpp/string/basic_string/stol - */ - /// @{ - /** - * @brief Declaration of fromString, but only for the types for which it is implemented - */ - template - T fromString(const std::string& s); - - /// @returns std::stoi(s) - template<> inline int fromString(const std::string& s) { - return std::stoi(s); - } - /// @returns std::stol(s) - template<> inline long fromString(const std::string& s) { - return std::stol(s); - } - /// @returns std::stoll(s) - template<> inline long long fromString(const std::string& s) { - return std::stoll(s); - } - /// @returns std::stoul(s) - template<> inline unsigned int fromString(const std::string& s) { - return std::stoul(s); - } - /// @returns std::stoul(s) - template<> inline unsigned long fromString(const std::string& s) { - return std::stoul(s); - } - /// @returns std::stoull(s) - template<> inline unsigned long long fromString(const std::string& s) { - return std::stoull(s); - } - /// @returns std::stof(s) - template<> inline float fromString(const std::string& s) { - return std::stof(s); - } - /// @returns std::stod(s) - template<> inline double fromString(const std::string& s) { - return std::stod(s); - } - /// @returns std::stold(s) - template<> inline long double fromString(const std::string& s) { - return std::stold(s); - } - /** - * @brief Convert a string to bool - * @details - * - returns true if s = "true" or "True" or "1" - * - returns false if s = "false" or "False" or "0" - * - throws InvalidArgument otherwise - */ - template<> bool fromString(const std::string& s); - - /** - * @overload - * @brief Construct T from a string using a fromString that is declared in global namespace - */ - template - inline T fromString(const std::string& s) { - return ::fromString(s); - } - /// @} - -// -// CONCEPTS -// - /** - * @brief Any type where toString(t) const exists returns a string-like type - * @note The function only has to exist, it does not have to be noexcept! - */ - template - concept ConvertibleToString = requires(const T& t) { - { toString(t) } -> util::Stringy; - }; - /* concept CovertibleToString = requires(const T& t) { { toString(t) }; }; */ - - /** - * @brief Any type where fromString(string) exists and returns T - * @note The function only has to exist, it does not have to be noexcept! - */ - template - concept ConstructibleFromString = requires(const std::string& s) { - { fromString(s) } -> std::same_as; - }; - - /** - * @brief Any type where toString(t) and fromString(string) exist - */ - template - concept StringConvertible = ConvertibleToString and ConstructibleFromString; - - - - -// -// HEX/OCT -// -/** - * @name Converting an integer to/from a hex/oct/bin string - * @todo Move to std::format, when P0645R10 is implemented in gcc libstd - * @note - * The fromHexString() and fromOctString() functions use `std::hex`, while fromBinString() uses `std::bitset`. Both can throw `std::invalid_argument` and the latter can also throw `std::out_of_range`. - * See https://en.cppreference.com/w/cpp/utility/bitset/bitset and https://en.cppreference.com/w/cpp/io/manip/hex - */ - /// @{ - /** - * @brief Convert an integer to hexdecimal string (prefixed with 0x) - * @param digits - * Minimum number of digits. Defaults to the amount of digits required to represent the largest possible number of type T. - * If digits is smaller than the needed amount to represent t, the needed amount is used. - */ - template - std::string toHexString(const T& t, char digits=sizeof(T)*2) { -#ifdef FORMAT - return std::format("{:#0" + std::to_string(digits) + "x}", t); -#endif - std::stringstream ss; - ss << "0x" << std::setfill('0') << std::setw(digits) << std::hex << t; - return std::string(ss.str()); - } - - /** - * @brief Convert a hexadecimal string (may be prefixed with 0x) to integer - */ - template - T fromHexString(const std::string& s) { - T t; - std::stringstream ss; - ss << std::hex << s; - ss >> t; - return t; - } - - /** - * @brief Convert an integer to octal string (prefixed with 0) - * @param digits - * Minimum number of digits. Defaults to the amount of digits required to represent the largest possible number of type T. - * If digits is smaller than the needed amount to represent t, the needed amount is used. - */ - template - std::string toOctString(const T& t, char digits=sizeof(T)*4) { -#ifdef FORMAT - // TODO test when possible - return std::format("{:#0" + std::to_string(digits) + "o}", t); -#endif - std::stringstream ss; - ss << "0" << std::setfill('0') << std::setw(digits) << std::oct << t; - return std::string(ss.str()); - } - - /** - * @brief Convert an octal string (may be prefixed with 0) to integer - */ - template - T fromOctString(const std::string& s) { - T t; - std::stringstream ss; - ss << std::oct << s; - ss >> t; - return t; - } - - /** - * @brief Convert an integer to binary string (prefixed with 0b) - */ - template - std::string toBinString(const T& t) { -#ifdef FORMAT - // TODO test when possible - return std::format("{:#0" + std::to_string(digits) + "b}", t); -#endif - return std::string("0b") + std::bitset(t).to_string(); - } - - /** - * @brief Convert binary string (may be prefixed with 0b) to integer - */ - template - T fromBinString(const std::string& s) { - if (s.starts_with("0b")) { - return static_cast(std::bitset(s, 2).to_ullong()); - } - else { - return static_cast(std::bitset(s).to_ullong()); - } - } - - - /** - * @overload - * @brief Construct a string where the elements from a forward range are in hexadecimal format - * @returns [ 0x0001, 0x0002, ... ] - */ - template - std::string toHexString(const T& t) { - std::string s = "[ "; - for (auto it = t.begin(); it != t.end(); it++) { - s += toHexString(*it) + ", "; - } - if (s.size() > 2) { - s.erase(s.size() - 2); - } - s += " ]"; - return s; - } - /** - * @overload - * @brief Construct a string where the elements from a forward range are in octal format - * @returns [ 00001, 00002, ... ] - */ - template - std::string toOctString(const T& t) { - std::string s = "[ "; - for (auto it = t.begin(); it != t.end(); it++) { - s += toOctString(*it) + ", "; - } - if (s.size() > 2) { - s.erase(s.size() - 2); - } - s += " ]"; - return s; - } - /** - * @overload - * @brief Construct a string where the elements from a forward range are in octal format - * @returns [ 0b0001, 0b0010, ... ] - */ - template - std::string toBinString(const T& t) { - std::string s = "[ "; - for (auto it = t.begin(); it != t.end(); it++) { - s += toBinString(*it) + ", "; - } - if (s.size() > 2) { - s.erase(s.size() - 2); - } - s += " ]"; - return s; - } - /// @} - -} // namespace gz - -/** - * @file - * @brief Contains utilities for type conversions from string - */ - -namespace gz { -/** - * @page string_conversion String conversion - * @section sc_about About - * This library provides utility for string conversion, from and to std::string. - * The string conversion functions are declared in string_conversion.hpp and can be imported with `#include `. - * - * There also three important concepts, ConvertibleToString, ConstructibleFromString and @ref StringConvertible which are - * used in the @ref Log "logger" and the @ref SettingsManager "settings manager" to log and store types. - * - * If you want to use your own data type with one of these, - * you can easily @ref sc_overloads "write your own string conversion" function for your custom datatype. - * - * @section sc_toString Convert to string - * You can use the toString() function to turn certain types into strings. - * Concepts are used to determine the correct overload of the function. - * - * The concept ConvertibleToString is satisfied for types that can be converted to string - * using toString(). - * - * @section sc_fromString Construct from string - * You can use the fromString() function to create certain types from a string. - * - * The concept ConstructibleFromString is satisfied for types that can be constructed from a string with fromString(). - * - * When constructing something from a string, there is of course the problem that errors occur at runtime when - * the string is unsuitable for construction. In this case, the fromString functions from this library throw a InvalidArgument exception. - * - * @section sc_overloads Overloading the string conversion functions - * @subsection sc_toString_ov Overload for toString - * If you want your custom type to be convertible to string, you have different options. - * You can either add an toString() const member to your class or overload - * std::string toString(const T&). - * Example for a class called Custom - * @code - * std::string toString(const Custom& c) { - * std::string s; - * ... - * return s; - * } - * @endcode - * @note - * To satisfy the concept, any overload must be visible to the compiler when the concept is processed, - * so you have to declare it before including `util/string_concepts.hpp` (which is also included by `util/string_conversion.hpp`, `settings_manager.hpp` and `log.hpp`). - * To ease troubleshooting the include order, `util/string_conversion.hpp` defines the macro `GZ_UTIL_STRING_CONCEPTS`, - * so you can place an assertion like this before declaring your overloads: - * @code - * #ifdef GZ_UTIL_STRING_CONCEPTS - * static_assert(false, "gz-util/util/string_conversion.hpp must not be included before this file!"); - * #endif - * @endcode - * - * @subsection sc_fromString_ov Overload for fromString - * Writing an overload for fromString needs a little bit more boiler plate. - * Since fromString is a templated function, you need to declare it as such. - * The function declaration in this library uses a concept so that it is only - * declared for the types that are actully implemented. - * Example for a class called Custom - * @code - * // declare as template, but only for Custom - * template T> - * Custom fromString(const std::string& s); - * - * // instantiation/definition, but only for Custom - * template<> - * Custom fromString(const std::string& s) { - * ... - * return Custom(...); - * }; - * @endcode - * - * @subsection sc_notes Notes - * You should write your function so that the output of one can be used as input of the other. - * In other words: - * @code - * Custom c1; - * Custom c2 = fromString(toString(c1)); - * assert(c1 == c2); - * @endcode - * - * SettingsManager expects the strings from toString() to be a single line. - * If it has multiple lines, it will not load it correctly when loading from a file. - * - * @todo Implement fromString for vectors that hold ConstructibleFromString types - * @todo Make macro for all types/concepts where someone would want to implement fromString and toString explicitly, eg vectors - * - * @section sc_int_types Converting integers to/from strings with different base - * The functions toHexString(), toOctString() and toBinString() can be used to get a - * string of an integers representation in 16 / 8 / 2 basis. - * - * The functions fromHexString(), fromOctString() and fromBinString() can be used to get an integer - * from a string representation of an integer in 16 / 8 / 2 basis. - * These function can throw std::invalid_argument and std::out_of_range. - * - * @note toHexString() and toOctString() do not work well with `(unsigned) char` (`(u)int8_t`). - * - * - */ -} // namespace gz