updated for changes with string conversion

This commit is contained in:
matthias@arch 2022-11-01 18:18:49 +01:00
parent 0edbc7c2e7
commit d3e7abc1d2
4 changed files with 34 additions and 61 deletions

View File

@ -1,7 +1,6 @@
#include "file_io.hpp" #include "file_io.hpp"
#include "exceptions.hpp" #include "exceptions.hpp"
#include "util/string.hpp"
#include <algorithm> #include <algorithm>
#include <fstream> #include <fstream>

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
/* #include "util/string_conversion.hpp" */ #include "string/utility.hpp"
#include "util/string.hpp"
#include <map> #include <map>
#include <unordered_map> #include <unordered_map>

View File

@ -2,7 +2,7 @@
#include <vector> #include <vector>
#include "util/string_conversion.hpp" #include "string/to_string.hpp"
#include <iostream> #include <iostream>
#include <string> #include <string>
@ -53,24 +53,8 @@ namespace gz {
/** /**
* @brief Define types that can be logged with Log * @brief Define types that can be logged with Log
* @details * @details
* As of now you can log type T with instance t: * Log can log everything where `gz::toString(const T&)` exists.
* -# Any @ref util::Stringy "string-like type": eg. std::string, std::string_view * See @ref sc_toStringImplemented "this for more details".
* -# Any @ref util::WorksWithStdToString "type that works with std::toString()"
* -# Any @ref util::HasToStringMember "type that has a toString() const member that returns a string"
* -# Any @ref util::ContainerConvertibleToString "type that has a forward_iterator" which references any one of 1-3
* -# Any @ref util::PairConvertibleToString "type with t.first, t.second" provided t.first satisfies one of 1-4 and t.second satisfies 1-4
* -# Any @ref util::MapConvertibleToString "type that has a forward_iterator" which references 5
* -# Any @ref util::Vector2ConvertibleToString "type with t.x and t.y", provided t.x and t.y satisfy one of 1-6
* -# Any @ref util::Vector3ConvertibleToString "type with t.x, t.y, t.z", provided t.x, t.y, t.z satisfy one of 1-6
* -# Any @ref util::Vector4ConvertibleToString "type with t.x, t.y, t.z and t.w", provided t.x, t.y, t.z, t.w satisfy one of 1-6
* -# Any @ref ConvertibleToString "type for which an overload of" <code>util::Stringy toString(const T&)</code> exists in global or gz namespace
*
* The higher number takes precedence in overload resolution for the log function.
*
* 1-6 include for example:
* - int, float, bool...
* - std::vector<std::string>, std::list<unsigned int>
* - std::map<std::string, std::vector<A>> if A.toString() returns a string - ...
*/ */
template<typename T> template<typename T>
concept Logable = ConvertibleToString<T>; concept Logable = ConvertibleToString<T>;
@ -105,12 +89,7 @@ namespace gz {
* @subsection log_concepts Logable types * @subsection log_concepts Logable types
* Log uses concepts to determine if a type is logable and how it should be logged. See the documentation for concept Logable for more details. * Log uses concepts to determine if a type is logable and how it should be logged. See the documentation for concept Logable for more details.
* *
* If you want your custom data type to be logable, it easiest to provide a member function with this signature: * If you want your custom data type to be logable, @ref sc_ov_toString "write an overload for gz::toString()"
* @code
* public:
* std::string toString() const;
* @endcode
* Alternatively, or if the type is not a class overload <code> std::string toString(const T& t) </code> in global or gz namespace.
* *
* @subsection log_threads Thread safety * @subsection log_threads Thread safety
* Log can use a static mutex for thread safety. To use this feature, you have to `#define LOG_MULTITHREAD` @b before including `log.hpp`. * Log can use a static mutex for thread safety. To use this feature, you have to `#define LOG_MULTITHREAD` @b before including `log.hpp`.
@ -176,7 +155,7 @@ class Log {
* @details Depending on the settings of the log instance, the message will be printed to stdout and/or written to the logfile. * @details Depending on the settings of the log instance, the message will be printed to stdout and/or written to the logfile.
* The current date and time is placed before the message. * The current date and time is placed before the message.
* The message will look like this: * The message will look like this:
* <time>: <prefix>: <message> * \<time>: \<prefix>: \<message>
* where time will be white, prefix in prefixColor and message white. * where time will be white, prefix in prefixColor and message white.
* @param args Any number of arguments that satisfy concept Logable * @param args Any number of arguments that satisfy concept Logable
*/ */
@ -187,7 +166,7 @@ class Log {
* @brief Log a message in a certain color * @brief Log a message in a certain color
* @details * @details
* The message will look like this: * The message will look like this:
* <time>: <prefix>: <message0> <message1>... * \<time>: \<prefix>: \<message0> \<message1>...
* where time will be white, prefix in prefixColor, and messageI in colors[I]. * where time will be white, prefix in prefixColor, and messageI in colors[I].
* If there are less colors than message arguments, the last color is used for all remaining messages. * If there are less colors than message arguments, the last color is used for all remaining messages.
* @param args Any number of arguments that satisfy concept Logable * @param args Any number of arguments that satisfy concept Logable
@ -212,7 +191,7 @@ class Log {
* @brief Log an error * @brief Log an error
* @details Prints the message with a red "Error: " prefix. * @details Prints the message with a red "Error: " prefix.
* The message will look like this: * The message will look like this:
* <time>: <prefix>: Error: <message> * \<time>: \<prefix>: Error: \<message>
* where time will be white, prefix in prefixColor, Error in red and message white. * where time will be white, prefix in prefixColor, Error in red and message white.
* @param args Any number of arguments that satisfy concept Logable * @param args Any number of arguments that satisfy concept Logable
*/ */
@ -225,7 +204,7 @@ class Log {
* @brief Log a warning * @brief Log a warning
* @details Prints the message with a yellow "Warning: " prefix. * @details Prints the message with a yellow "Warning: " prefix.
* The message will look like this: * The message will look like this:
* <time>: <prefix>: Warning: <message> * \<time>: \<prefix>: Warning: \<message>
* where time will be white, prefix in prefixColor, Warning in yellow and message white. * where time will be white, prefix in prefixColor, Warning in yellow and message white.
* @param args Any number of arguments that satisfy concept Logable * @param args Any number of arguments that satisfy concept Logable
*/ */
@ -495,8 +474,6 @@ class Log {
this->clog(colors, std::forward<Args>(args)...); this->clog(colors, std::forward<Args>(args)...);
#endif #endif
} }
} // namespace gz } // namespace gz
/** /**

View File

@ -2,8 +2,9 @@
#include "file_io.hpp" #include "file_io.hpp"
#include "exceptions.hpp" #include "exceptions.hpp"
#include "util/string_conversion.hpp" #include "string/conversion.hpp"
#include "util/string.hpp" #include "string/utility.hpp"
#include "concepts.hpp"
#include <functional> #include <functional>
#include <iostream> #include <iostream>
@ -17,9 +18,6 @@
namespace gz { namespace gz {
template<typename T, typename... PackTypes>
concept TypeIsInPack = (std::same_as<T, PackTypes> || ...);
template<typename T> template<typename T>
concept Number = std::integral<T> || std::floating_point<T>; concept Number = std::integral<T> || std::floating_point<T>;
@ -27,16 +25,16 @@ namespace gz {
concept NotNumber = !Number<T>; concept NotNumber = !Number<T>;
/* template<typename T, typename... PackTypes> */ /* template<typename T, typename... PackTypes> */
/* concept IntegralInPack = std::integral<T> && TypeIsInPack<T, PackTypes...>; */ /* concept IntegralInPack = std::integral<T> && util::IsInPack<T, PackTypes...>; */
/* template<typename T, typename... PackTypes> */ /* template<typename T, typename... PackTypes> */
/* concept FloatingPointInPack = std::floating_point<T> && TypeIsInPack<T, PackTypes...>; */ /* concept FloatingPointInPack = std::floating_point<T> && util::IsInPack<T, PackTypes...>; */
template<typename T, typename... PackTypes> template<typename T, typename... PackTypes>
concept NumberInPack = Number<T> && TypeIsInPack<T, PackTypes...>; concept NumberInPack = Number<T> && util::IsInPack<T, PackTypes...>;
template<typename T, typename... PackTypes> template<typename T, typename... PackTypes>
concept NotNumberInPack = NotNumber<T> && TypeIsInPack<T, PackTypes...>; concept NotNumberInPack = NotNumber<T> && util::IsInPack<T, PackTypes...>;
@ -182,7 +180,7 @@ namespace gz {
* @throws InvalidType if T is not a registered type * @throws InvalidType if T is not a registered type
* @throws InvalidType if type T can not be constructed from value (string) * @throws InvalidType if type T can not be constructed from value (string)
*/ */
template<TypeIsInPack<CacheTypes...> T> template<util::IsInPack<CacheTypes...> T>
const T& get(const std::string& key); const T& get(const std::string& key);
/** /**
@ -204,7 +202,7 @@ namespace gz {
* @throws InvalidType if type T can not be constructed from value (string) * @throws InvalidType if type T can not be constructed from value (string)
* @throws InvalidType if the fallback can not be converted to string * @throws InvalidType if the fallback can not be converted to string
*/ */
template<TypeIsInPack<CacheTypes...> T> template<util::IsInPack<CacheTypes...> T>
const T& getOr(const std::string& key, const T& fallback) requires std::copy_constructible<T>; const T& getOr(const std::string& key, const T& fallback) requires std::copy_constructible<T>;
/** /**
@ -215,7 +213,7 @@ namespace gz {
/** /**
* @brief Same as get<T>, but returns a copy of value and not a const reference * @brief Same as get<T>, but returns a copy of value and not a const reference
*/ */
template<TypeIsInPack<CacheTypes...> T> template<util::IsInPack<CacheTypes...> T>
const T getCopy(const std::string& key); const T getCopy(const std::string& key);
/** /**
@ -226,7 +224,7 @@ namespace gz {
/** /**
* @brief Same as getOr<T>, but returns a copy of value and not a const reference * @brief Same as getOr<T>, but returns a copy of value and not a const reference
*/ */
template<TypeIsInPack<CacheTypes...> T> template<util::IsInPack<CacheTypes...> T>
const T getCopyOr(const std::string& key, const T& fallback); const T getCopyOr(const std::string& key, const T& fallback);
/** /**
@ -240,7 +238,7 @@ namespace gz {
/** /**
* @brief Set the value of key to value * @brief Set the value of key to value
* @throws InvalidArgument if value is @ref sm_validity "invalid" * @throws InvalidArgument if value is @ref sm_validity "invalid"
* @throws Exception if an exception occurs during a potential @red sm_callback "callback function" * @throws Exception if an exception occurs during a potential @ref sm_callback "callback function"
*/ */
void set(const std::string& key, const std::string& value); void set(const std::string& key, const std::string& value);
@ -248,9 +246,9 @@ namespace gz {
* @brief Set the value of key to value * @brief Set the value of key to value
* @throws InvalidArgument if value is @ref sm_validity "invalid" * @throws InvalidArgument if value is @ref sm_validity "invalid"
* @throws InvalidType if T is not a registered type * @throws InvalidType if T is not a registered type
* @throws Exception if an exception occurs during a potential @red sm_callback "callback function" * @throws Exception if an exception occurs during a potential @ref sm_callback "callback function"
*/ */
template<TypeIsInPack<CacheTypes...> T> template<util::IsInPack<CacheTypes...> T>
void set(const std::string& key, const T& value); void set(const std::string& key, const T& value);
/** /**
* @} * @}
@ -316,9 +314,9 @@ namespace gz {
* allowedValues vector is no longer valid after this function * allowedValues vector is no longer valid after this function
* @throws InvalidArgument if call is @ref SettingsMangerAllowedValues::hasCorrectFormat "invalid" * @throws InvalidArgument if call is @ref SettingsMangerAllowedValues::hasCorrectFormat "invalid"
*/ */
template<TypeIsInPack<CacheTypes...> T> template<util::IsInPack<CacheTypes...> T>
void setAllowedValues(const std::string& key, std::vector<T>& allowedValues, SettingsManagerAllowedValueTypes type=SM_LIST); void setAllowedValues(const std::string& key, std::vector<T>& allowedValues, SettingsManagerAllowedValueTypes type=SM_LIST);
template<TypeIsInPack<CacheTypes...> T> template<util::IsInPack<CacheTypes...> T>
void setAllowedValues(const std::string& key, std::vector<T>&& allowedValues, SettingsManagerAllowedValueTypes type=SM_LIST) { setAllowedValues<T>(key, allowedValues, type); }; void setAllowedValues(const std::string& key, std::vector<T>&& allowedValues, SettingsManagerAllowedValueTypes type=SM_LIST) { setAllowedValues<T>(key, allowedValues, type); };
/** /**
@ -428,7 +426,7 @@ namespace gz {
template<Number T, StringConvertible... CacheTypes> template<Number T, StringConvertible... CacheTypes>
void hasCorrectFormat(SettingsManagerAllowedValues<CacheTypes...>& av) { void hasCorrectFormat(SettingsManagerAllowedValues<CacheTypes...>& av) {
static_assert(TypeIsInPack<T, CacheTypes...>, "T must be be in pack CacheTypes"); static_assert(util::IsInPack<T, CacheTypes...>, "T must be be in pack CacheTypes");
const std::vector<T>* v = nullptr; const std::vector<T>* v = nullptr;
try { try {
v = &std::get<std::vector<T>>(av.allowedValues); v = &std::get<std::vector<T>>(av.allowedValues);
@ -460,7 +458,7 @@ namespace gz {
/* template<StringConvertible... CacheTypes, NotNumberInPack<std::string, CacheTypes...> T> */ /* template<StringConvertible... CacheTypes, NotNumberInPack<std::string, CacheTypes...> T> */
template<NotNumber T, StringConvertible... CacheTypes> template<NotNumber T, StringConvertible... CacheTypes>
void hasCorrectFormat(SettingsManagerAllowedValues<CacheTypes...>& av) { void hasCorrectFormat(SettingsManagerAllowedValues<CacheTypes...>& av) {
static_assert(TypeIsInPack<T, CacheTypes...>, "T must be be in pack CacheTypes"); static_assert(util::IsInPack<T, CacheTypes...>, "T must be be in pack CacheTypes");
const std::vector<T>* v = nullptr; const std::vector<T>* v = nullptr;
try { try {
v = &std::get<std::vector<T>>(av.allowedValues); v = &std::get<std::vector<T>>(av.allowedValues);
@ -541,9 +539,9 @@ namespace gz {
} }
template<StringConvertible... CacheTypes> template<StringConvertible... CacheTypes>
template<TypeIsInPack<CacheTypes...> T> template<util::IsInPack<CacheTypes...> T>
const T& SettingsManager<CacheTypes...>::get(const std::string& key) { const T& SettingsManager<CacheTypes...>::get(const std::string& key) {
static_assert(TypeIsInPack<T, CacheTypes...>, "Type T is not in parameter pack CacheTypes..."); static_assert(util::IsInPack<T, CacheTypes...>, "Type T is not in parameter pack CacheTypes...");
/* if (!isRegisteredType<T>()) { */ /* if (!isRegisteredType<T>()) { */
/* throw InvalidType("Invalid type: '" + std::string(typeid(T).name()) + "'", "SettingsManager::get"); */ /* throw InvalidType("Invalid type: '" + std::string(typeid(T).name()) + "'", "SettingsManager::get"); */
/* } */ /* } */
@ -581,7 +579,7 @@ namespace gz {
} }
template<StringConvertible... CacheTypes> template<StringConvertible... CacheTypes>
template<TypeIsInPack<CacheTypes...> T> template<util::IsInPack<CacheTypes...> T>
const T& SettingsManager<CacheTypes...>::getOr(const std::string& key, const T& fallback) requires std::copy_constructible<T> { const T& SettingsManager<CacheTypes...>::getOr(const std::string& key, const T& fallback) requires std::copy_constructible<T> {
/* if (!isRegisteredType<T>()) { */ /* if (!isRegisteredType<T>()) { */
/* throw InvalidType("Invalid type: '" + std::string(typeid(T).name()) + "'", "SettingsManager::getOr"); */ /* throw InvalidType("Invalid type: '" + std::string(typeid(T).name()) + "'", "SettingsManager::getOr"); */
@ -611,7 +609,7 @@ namespace gz {
return get(key); return get(key);
} }
template<StringConvertible... CacheTypes> template<StringConvertible... CacheTypes>
template<TypeIsInPack<CacheTypes...> T> template<util::IsInPack<CacheTypes...> T>
const T SettingsManager<CacheTypes...>::getCopy(const std::string& key) { const T SettingsManager<CacheTypes...>::getCopy(const std::string& key) {
return get<T>(key); return get<T>(key);
} }
@ -621,7 +619,7 @@ namespace gz {
return getOr(key, fallback); return getOr(key, fallback);
} }
template<StringConvertible... CacheTypes> template<StringConvertible... CacheTypes>
template<TypeIsInPack<CacheTypes...> T> template<util::IsInPack<CacheTypes...> T>
const T SettingsManager<CacheTypes...>::getCopyOr(const std::string& key, const T& fallback) { const T SettingsManager<CacheTypes...>::getCopyOr(const std::string& key, const T& fallback) {
return getOr<T>(key, fallback); return getOr<T>(key, fallback);
} }
@ -662,7 +660,7 @@ namespace gz {
} }
template<StringConvertible... CacheTypes> template<StringConvertible... CacheTypes>
template<TypeIsInPack<CacheTypes...> T> template<util::IsInPack<CacheTypes...> T>
void SettingsManager<CacheTypes...>::set(const std::string& key, const T& value) { void SettingsManager<CacheTypes...>::set(const std::string& key, const T& value) {
/* if (!isRegisteredType<T>()) { */ /* if (!isRegisteredType<T>()) { */
/* throw InvalidType("Invalid type: '" + std::string(typeid(T).name()) + "'", "SettingsManager::set<" + std::string(typeid(T).name()) + ">"); */ /* throw InvalidType("Invalid type: '" + std::string(typeid(T).name()) + "'", "SettingsManager::set<" + std::string(typeid(T).name()) + ">"); */
@ -817,7 +815,7 @@ namespace gz {
} }
template<StringConvertible... CacheTypes> template<StringConvertible... CacheTypes>
template<TypeIsInPack<CacheTypes...> T> template<util::IsInPack<CacheTypes...> T>
void SettingsManager<CacheTypes...>::setAllowedValues(const std::string& key, std::vector<T>& allowed_vector, SettingsManagerAllowedValueTypes type) { void SettingsManager<CacheTypes...>::setAllowedValues(const std::string& key, std::vector<T>& allowed_vector, SettingsManagerAllowedValueTypes type) {
/* std::cout << "setAllowedValues: " << typeid(std::vector<T>).name() << " - " << typeid(T).name() << "\n"; */ /* std::cout << "setAllowedValues: " << typeid(std::vector<T>).name() << " - " << typeid(T).name() << "\n"; */
SettingsManagerAllowedValues<CacheTypes...> av; SettingsManagerAllowedValues<CacheTypes...> av;