1#ifndef CONVERSION_UTILITIES_STRINGCONVERSION_H
2#define CONVERSION_UTILITIES_STRINGCONVERSION_H
11#include <initializer_list>
18#include <system_error>
21#if __cplusplus >= 201709 && !defined(REFLECTIVE_RAPIDJSON_GENERATOR)
22#ifndef CPP_UTILITIES_USE_RANGES
23#define CPP_UTILITIES_USE_RANGES
40 std::free(stringData);
47using StringData = std::pair<std::unique_ptr<char[], StringDataDeleter>, std::size_t>;
59#ifdef PLATFORM_WINDOWS
72#ifdef CPP_UTILITIES_USE_RANGES
73template <
class Container>
74using ContainerValueType =
typename std::conditional_t<std::ranges::range<Container>,
75 std::iterator_traits<std::remove_cvref_t<std::ranges::iterator_t<Container>>>, Container>::value_type;
77template <
class Container>
using ContainerValueType =
typename Container::value_type;
79template <
class Container>
using DefaultReturnTypeForContainer = ContainerValueType<Container>;
80template <
class Container>
using StringParamForContainer = std::basic_string_view<typename ContainerValueType<Container>::value_type>;
98template <
class Container = std::initializer_list<std::
string>,
class ReturnType = Detail::DefaultReturnTypeForContainer<Container>>
100 bool omitEmpty =
false, Detail::StringParamForContainer<Container>
leftClosure = Detail::StringParamForContainer<Container>(),
101 Detail::StringParamForContainer<Container>
rightClosure = Detail::StringParamForContainer<Container>())
160template <
class Container = std::list<std::
string>>
166 typename Container::value_type *
last =
nullptr;
168 typename Container::value_type::size_type
i = 0, end =
string.size();
178 delimPos = Container::value_type::npos;
180 if (
delimPos == Container::value_type::npos) {
212template <
class Container = std::list<std::
string>>
214 Detail::StringParamForContainer<Container>
string, Detail::StringParamForContainer<Container>
delimiter,
int maxParts = -1)
218 typename Container::value_type::size_type
i = 0, end =
string.size();
222 delimPos = Container::value_type::npos;
224 if (
delimPos == Container::value_type::npos) {
227#if __cplusplus >= 201709
228 if constexpr (
requires {
res.emplace_back(
string); }) {
231#if __cplusplus >= 201709
238#if __cplusplus >= 201709
239 if constexpr (
requires {
res.emplace_back(); }) {
242#if __cplusplus >= 201709
337 typename StringType::size_type
currentPos = 0;
351template <
typename StringType>
354 typename StringType::size_type
currentPos = 0;
367template <
typename StringType1,
typename StringType2,
typename StringType3>
370 for (
typename StringType1::size_type
i = 0; (
i =
str.find(
find,
i)) != StringType1::npos;
i += replace.size()) {
371 str.replace(
i,
find.size(), replace);
378template <
typename StringType>
382 str, std::basic_string_view<typename StringType::value_type>(
find), std::basic_string_view<typename StringType::value_type>(replace));
388template <
typename StringType1,
typename StringType2>
397template <
typename StringType1,
typename StringType2>
443 Traits::EnableIf<std::is_integral<IntegralType>, std::is_signed<IntegralType>> * =
nullptr>
463 res.insert(
res.begin(),
'-');
476template <
typename FloatingType,
class StringType = std::
string, Traits::EnableIf<std::is_
floating_po
int<FloatingType>> * =
nullptr>
479 std::basic_stringstream<typename StringType::value_type>
ss;
491 if (character >=
'0' && character <=
'9') {
492 res = character -
'0';
493 }
else if (character >=
'a' && character <=
'z') {
494 res = character -
'a' + 10;
495 }
else if (character >=
'A' && character <=
'Z') {
496 res = character -
'A' + 10;
505 errorMsg +=
"\" is no valid digit.";
511template <
typename IntegralType,
typename CharType,
typename BaseType = IntegralType>
512void raiseAndAdd(IntegralType &result, BaseType base, CharType character)
514 if (character ==
' ') {
518 if (__builtin_mul_overflow(result, base, &result)
519 || __builtin_add_overflow(result,
charToDigit(character,
static_cast<CharType
>(base)), &result)) {
520 throw ConversionException(
"Number exceeds limit.");
523 result *=
static_cast<IntegralType
>(base);
524 result +=
static_cast<IntegralType
>(charToDigit<CharType>(character,
static_cast<CharType
>(base)));
538 Traits::EnableIf<std::is_integral<IntegralType>, std::is_unsigned<IntegralType>> * =
nullptr>
542 for (
const CharType *end =
string +
size;
string != end; ++string) {
556 Traits::EnableIf<std::is_integral<IntegralType>, std::is_signed<IntegralType>> * =
nullptr>
563 for (;
string != end && *
string ==
' '; ++string)
568 const bool negative = (*
string ==
'-');
573 for (;
string != end; ++string) {
587 Traits::EnableIf<std::is_integral<IntegralType>, Traits::Not<std::is_scalar<std::decay_t<StringType>>>> * =
nullptr>
603 Traits::EnableIf<std::is_floating_point<FloatingType>, Traits::IsSpecializationOf<StringViewType, std::basic_string_view>> * =
nullptr>
606 std::basic_stringstream<typename StringViewType::value_type>
ss;
616 errorMsg +=
"\" is no valid floating point number.";
630 Traits::EnableIf<std::is_floating_point<FloatingType>, Traits::Not<std::is_scalar<std::decay_t<StringType>>>,
631 Traits::Not<Traits::IsSpecializationOf<StringType, std::basic_string_view>>> * =
nullptr>
634 using StringViewType = std::basic_string_view<typename StringType::value_type>;
646 Traits::EnableIf<std::is_integral<IntegralType>, std::is_unsigned<IntegralType>> * =
nullptr>
650 for (; *string; ++string) {
665template <
typename FloatingType,
class CharType, Traits::EnableIf<std::is_
floating_po
int<FloatingType>> * =
nullptr>
679 Traits::EnableIf<std::is_integral<IntegralType>, std::is_signed<IntegralType>> * =
nullptr>
685 for (; *
string && *
string ==
' '; ++string)
690 const bool negative = (*
string ==
'-');
695 for (; *string; ++string) {
712 char buffer[
sizeof(T)];
The ConversionException class is thrown by the various conversion functions of this library when a co...
#define CPP_UTILITIES_EXPORT
Marks the symbol to be exported by the c++utilities library.
typename std::enable_if< All< Condition... >::value, Detail::Enabler >::type EnableIf
Shortcut for std::enable_if to omit ::value and ::type.
Contains all utilities provides by the c++utilities library.
void findAndReplace(StringType1 &str, const StringType2 &find, const StringType3 &replace)
Replaces all occurrences of find with relpace in the specified str.
CPP_UTILITIES_EXPORT StringData convertUtf8ToUtf16BE(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified UTF-8 string to UTF-16 (big-endian).
CPP_UTILITIES_EXPORT StringData convertString(const char *fromCharset, const char *toCharset, const char *inputBuffer, std::size_t inputBufferSize, float outputBufferSizeFactor=1.0f)
Converts the specified string from one character set to another.
std::pair< std::unique_ptr< char[], StringDataDeleter >, std::size_t > StringData
Type used to return string encoding conversion result.
StringType numberToString(IntegralType number, BaseType base=10)
Converts the given number to its equivalent string representation using the specified base.
CPP_UTILITIES_EXPORT StringData convertLatin1ToUtf8(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified Latin-1 string to UTF-8.
CPP_UTILITIES_EXPORT StringData convertUtf16LEToUtf8(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified UTF-16 (little-endian) string to UTF-8.
EmptyPartsTreat
Specifies the role of empty parts when splitting strings.
CPP_UTILITIES_EXPORT std::pair< std::unique_ptr< std::uint8_t[]>, std::uint32_t > decodeBase64(const char *encodedStr, const std::uint32_t strSize)
Decodes the specified Base64 encoded string.
ReturnType joinStrings(const Container &strings, Detail::StringParamForContainer< Container > delimiter=Detail::StringParamForContainer< Container >(), bool omitEmpty=false, Detail::StringParamForContainer< Container > leftClosure=Detail::StringParamForContainer< Container >(), Detail::StringParamForContainer< Container > rightClosure=Detail::StringParamForContainer< Container >())
Joins the given strings using the specified delimiter.
bool startsWith(const StringType &str, const StringType &phrase)
Returns whether str starts with phrase.
IntegralType stringToNumber(const StringType &string, BaseType base=10)
Converts the given string to an unsigned/signed number assuming string uses the specified base.
CPP_UTILITIES_EXPORT void truncateString(std::string &str, char terminationChar='\0')
Truncates all characters after the first occurrence of the specified terminationChar and the terminat...
CPP_UTILITIES_EXPORT StringData convertUtf16BEToUtf8(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified UTF-16 (big-endian) string to UTF-8.
constexpr CharType digitToChar(CharType digit)
Returns the character representation of the specified digit.
Container splitStringSimple(Detail::StringParamForContainer< Container > string, Detail::StringParamForContainer< Container > delimiter, int maxParts=-1)
Splits the given string (which might also be a string view) at the specified delimiter.
auto toArrayOfLines(const std::string &multilineString)
Converts the specified multilineString to an array of lines.
bool containsSubstrings(const StringType &str, std::initializer_list< StringType > substrings)
Returns whether str contains the specified substrings.
CPP_UTILITIES_EXPORT StringData convertUtf8ToLatin1(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified UTF-8 string to Latin-1.
std::string interpretIntegerAsString(T integer, int startOffset=0)
Interprets the given integer at the specified position as std::string using the specified byte order.
bool endsWith(const StringType &str, const StringType &phrase)
Returns whether str ends with phrase.
auto toMultiline(const Container &arrayOfLines)
Converts the specified arrayOfLines to a multiline string.
CPP_UTILITIES_EXPORT StringData convertUtf8ToUtf16LE(const char *inputBuffer, std::size_t inputBufferSize)
Converts the specified UTF-8 string to UTF-16 (little-endian).
CPP_UTILITIES_EXPORT std::string bitrateToString(double speedInKbitsPerSecond, bool useByteInsteadOfBits=false)
Converts the specified bitrate in kbit/s to its equivalent std::string representation.
CharType charToDigit(CharType character, CharType base)
Returns number/digit of the specified character representation using the specified base.
CPP_UTILITIES_EXPORT std::string encodeBase64(const std::uint8_t *data, std::uint32_t dataSize)
Encodes the specified data to Base64.
CPP_UTILITIES_EXPORT std::string dataSizeToString(std::uint64_t sizeInByte, bool includeByte=false)
Converts the specified data size in byte to its equivalent std::string representation.
IntegralType bufferToNumber(const CharType *string, std::size_t size, BaseType base=10)
Converts the given string of size characters to an unsigned numeric value using the specified base.
Container splitString(Detail::StringParamForContainer< Container > string, Detail::StringParamForContainer< Container > delimiter, EmptyPartsTreat emptyPartsRole=EmptyPartsTreat::Keep, int maxParts=-1)
Splits the given string at the specified delimiter.
The StringDataDeleter struct deletes the data of a StringData instance.
void operator()(char *stringData)
Deletes the specified stringData with std::free(), because the memory has been allocated using std::m...