diff --git a/include/lol/base/string.h b/include/lol/base/string.h new file mode 100644 index 00000000..ae472bab --- /dev/null +++ b/include/lol/base/string.h @@ -0,0 +1,142 @@ +// +// Lol Engine +// +// Copyright © 2010—2020 Sam Hocevar +// © 2013—2015 Benjamin “Touky” Huet +// +// Lol Engine is free software. It comes without any warranty, to +// the extent permitted by applicable law. You can redistribute it +// and/or modify it under the terms of the Do What the Fuck You Want +// to Public License, Version 2, as published by the WTFPL Task Force. +// See http://www.wtfpl.net/ for more details. +// + +#pragma once + +// +// The string tools +// ———————————————— +// Contains some utilities to work with std::string objects. +// + +#include +#include +#include // std::transform +#include // va_list +#include // size_t + +namespace lol +{ + +// Split a string along a single separator +template +std::vector> split(std::basic_string const &s, + T sep = T('\n')) +{ + std::vector> ret; + size_t start = 0, end = 0; + while ((end = s.find(sep, start)) != std::basic_string::npos) + { + ret.push_back(s.substr(start, end - start)); + start = end + 1; + } + ret.push_back(s.substr(start)); + return ret; +} + +// Split a string along multiple separator +template +std::vector> split(std::basic_string const &s, + std::basic_string const &seps) +{ + std::vector ret; + size_t start = s.find_first_not_of(seps), end = 0; + + while ((end = s.find_first_of(seps, start)) != std::basic_string::npos) + { + ret.push_back(s.substr(start, end - start)); + start = s.find_first_not_of(seps, end); + } + if (start != std::string::npos) + ret.push_back(s.substr(start)); + + return ret; + +} + +// Check whether a string starts or ends with a given substring +template +bool starts_with(std::basic_string const &s, + std::basic_string const &prefix) +{ + return s.size() >= prefix.size() && + s.compare(0, prefix.size(), prefix) == 0; +} + +template +bool ends_with(std::basic_string const &s, + std::basic_string const &suffix) +{ + return s.size() >= suffix.size() && + s.compare(s.size() - suffix.size(), suffix.size(), suffix) == 0; +} + +// Convert a string to lowercase or uppercase +template +std::basic_string tolower(std::basic_string const &s) +{ + std::string ret; + std::transform(s.begin(), s.end(), std::back_inserter(ret), + [](T c){ return std::tolower(c); }); + return ret; +} + +template +std::basic_string toupper(std::basic_string const &s) +{ + std::string ret; + std::transform(s.begin(), s.end(), std::back_inserter(ret), + [](T c){ return std::toupper(c); }); + return ret; +} + +// Format a string, printf-style +template LOL_ATTR_FORMAT(1, 2) +std::basic_string format(T const *format, ...) +{ + va_list ap; + va_start(ap, format); + std::string ret = vformat(format, ap); + va_end(ap); + return ret; +} + +template +std::basic_string vformat(char const *format, va_list ap) +{ + va_list ap2; +#if defined va_copy || !defined _MSC_VER + // Visual Studio 2010 does not support va_copy. + va_copy(ap2, ap); +#else + ap2 = ap; +#endif + + // vsnprintf() tells us how many characters we need, not counting + // the terminating null character. + size_t needed = vsnprintf(nullptr, 0, format, ap2); + +#if defined va_copy || !defined _MSC_VER + // do not call va_end() if va_copy() wasn't called. + va_end(ap2); +#endif + + std::string ret; + ret.resize(needed); + vsnprintf(&ret[0], needed + 1, format, ap); + + return ret; +} + +} /* namespace lol */ + diff --git a/legacy/lol/base/string.h b/legacy/lol/base/string.h deleted file mode 100644 index d32efd0f..00000000 --- a/legacy/lol/base/string.h +++ /dev/null @@ -1,46 +0,0 @@ -// -// Lol Engine -// -// Copyright © 2010—2018 Sam Hocevar -// © 2013—2015 Benjamin “Touky” Huet -// -// Lol Engine is free software. It comes without any warranty, to -// the extent permitted by applicable law. You can redistribute it -// and/or modify it under the terms of the Do What the Fuck You Want -// to Public License, Version 2, as published by the WTFPL Task Force. -// See http://www.wtfpl.net/ for more details. -// - -#pragma once - -// -// The string tools -// ---------------- -// Contains some utilities to work with std::string objects. -// - -#include - -namespace lol -{ - -/* Split a string along a single separator */ -array split(std::string const &s, char sep = '\n'); - -/* Split a string along multiple separators */ -array split(std::string const &s, std::string const &seps); - -/* Check whether a string starts or ends with a given substring */ -bool starts_with(std::string const &s, std::string const &prefix); -bool ends_with(std::string const &s, std::string const &suffix); - -/* Convert a string to lowercase or uppercase */ -std::string tolower(std::string const &s); -std::string toupper(std::string const &s); - -/* Format a string, printf-style */ -std::string format(char const *format, ...) LOL_ATTR_FORMAT(1, 2); -std::string vformat(char const *format, va_list ap); - -} /* namespace lol */ -