From 175644e8c1c09a5f3d48788d5800a0e36cc16957 Mon Sep 17 00:00:00 2001 From: reuk Date: Tue, 7 Apr 2020 10:28:16 +0100 Subject: [PATCH] String: Provide range-for comaptibility --- .../juce_core/text/juce_CharPointer_UTF8.h | 30 ++++++++-------- modules/juce_core/text/juce_String.cpp | 11 ++++++ modules/juce_core/text/juce_String.h | 35 +++++++++++++++++-- 3 files changed, 58 insertions(+), 18 deletions(-) diff --git a/modules/juce_core/text/juce_CharPointer_UTF8.h b/modules/juce_core/text/juce_CharPointer_UTF8.h index 8df23f7021..0ff18134c4 100644 --- a/modules/juce_core/text/juce_CharPointer_UTF8.h +++ b/modules/juce_core/text/juce_CharPointer_UTF8.h @@ -36,44 +36,44 @@ class CharPointer_UTF8 final public: using CharType = char; - inline explicit CharPointer_UTF8 (const CharType* rawPointer) noexcept + explicit CharPointer_UTF8 (const CharType* rawPointer) noexcept : data (const_cast (rawPointer)) { } - inline CharPointer_UTF8 (const CharPointer_UTF8& other) = default; + CharPointer_UTF8 (const CharPointer_UTF8& other) = default; - inline CharPointer_UTF8 operator= (CharPointer_UTF8 other) noexcept + CharPointer_UTF8 operator= (CharPointer_UTF8 other) noexcept { data = other.data; return *this; } - inline CharPointer_UTF8 operator= (const CharType* text) noexcept + CharPointer_UTF8 operator= (const CharType* text) noexcept { data = const_cast (text); return *this; } /** This is a pointer comparison, it doesn't compare the actual text. */ - inline bool operator== (CharPointer_UTF8 other) const noexcept { return data == other.data; } - inline bool operator!= (CharPointer_UTF8 other) const noexcept { return data != other.data; } - inline bool operator<= (CharPointer_UTF8 other) const noexcept { return data <= other.data; } - inline bool operator< (CharPointer_UTF8 other) const noexcept { return data < other.data; } - inline bool operator>= (CharPointer_UTF8 other) const noexcept { return data >= other.data; } - inline bool operator> (CharPointer_UTF8 other) const noexcept { return data > other.data; } + bool operator== (CharPointer_UTF8 other) const noexcept { return data == other.data; } + bool operator!= (CharPointer_UTF8 other) const noexcept { return data != other.data; } + bool operator<= (CharPointer_UTF8 other) const noexcept { return data <= other.data; } + bool operator< (CharPointer_UTF8 other) const noexcept { return data < other.data; } + bool operator>= (CharPointer_UTF8 other) const noexcept { return data >= other.data; } + bool operator> (CharPointer_UTF8 other) const noexcept { return data > other.data; } /** Returns the address that this pointer is pointing to. */ - inline CharType* getAddress() const noexcept { return data; } + CharType* getAddress() const noexcept { return data; } /** Returns the address that this pointer is pointing to. */ - inline operator const CharType*() const noexcept { return data; } + operator const CharType*() const noexcept { return data; } /** Returns true if this pointer is pointing to a null character. */ - inline bool isEmpty() const noexcept { return *data == 0; } + bool isEmpty() const noexcept { return *data == 0; } /** Returns true if this pointer is not pointing to a null character. */ - inline bool isNotEmpty() const noexcept { return *data != 0; } + bool isNotEmpty() const noexcept { return *data != 0; } /** Returns the unicode character that this pointer is pointing to. */ juce_wchar operator*() const noexcept @@ -348,7 +348,7 @@ public: } /** Writes a null character to this string (leaving the pointer's position unchanged). */ - inline void writeNull() const noexcept + void writeNull() const noexcept { *data = 0; } diff --git a/modules/juce_core/text/juce_String.cpp b/modules/juce_core/text/juce_String.cpp index 77f01787d3..48b1160826 100644 --- a/modules/juce_core/text/juce_String.cpp +++ b/modules/juce_core/text/juce_String.cpp @@ -2935,6 +2935,17 @@ public: expectEquals (serialiseDouble (-test.first), "-" + test.second); } } + + { + beginTest ("Loops"); + + String str (CharPointer_UTF8 ("\xc2\xaf\\_(\xe3\x83\x84)_/\xc2\xaf")); + std::vector parts { 175, 92, 95, 40, 12484, 41, 95, 47, 175 }; + size_t index = 0; + + for (auto c : str) + expectEquals (c, parts[index++]); + } } }; diff --git a/modules/juce_core/text/juce_String.h b/modules/juce_core/text/juce_String.h index 430b5b37fa..1a569f68be 100644 --- a/modules/juce_core/text/juce_String.h +++ b/modules/juce_core/text/juce_String.h @@ -307,13 +307,13 @@ public: Note that there's also an isNotEmpty() method to help write readable code. @see containsNonWhitespaceChars() */ - inline bool isEmpty() const noexcept { return text.isEmpty(); } + bool isEmpty() const noexcept { return text.isEmpty(); } /** Returns true if the string contains at least one character. Note that there's also an isEmpty() method to help write readable code. @see containsNonWhitespaceChars() */ - inline bool isNotEmpty() const noexcept { return ! text.isEmpty(); } + bool isNotEmpty() const noexcept { return ! text.isEmpty(); } /** Resets this string to be empty. */ void clear() noexcept; @@ -919,6 +919,35 @@ public: template static String formatted (const String& formatStr, Args... args) { return formattedRaw (formatStr.toRawUTF8(), args...); } + /** Returns an iterator pointing at the beginning of the string. */ + CharPointerType begin() const { return getCharPointer(); } + + /** Returns an iterator pointing at the terminating null of the string. + + Note that this has to find the terminating null before returning it, so prefer to + call this once before looping and then reuse the result, rather than calling 'end()' + each time through the loop. + + @code + String str = ...; + + // BEST + for (auto c : str) + DBG (c); + + // GOOD + for (auto ptr = str.begin(), end = str.end(); ptr != end; ++ptr) + DBG (*ptr); + + std::for_each (str.begin(), str.end(), [] (juce_wchar c) { DBG (c); }); + + // BAD + for (auto ptr = str.begin(); ptr != str.end(); ++ptr) + DBG (*ptr); + @endcode + */ + CharPointerType end() const { return begin().findTerminatingNull(); } + //============================================================================== // Numeric conversions.. @@ -1209,7 +1238,7 @@ public: that is returned must not be stored anywhere, as it can be deleted whenever the string changes. */ - inline CharPointerType getCharPointer() const noexcept { return text; } + CharPointerType getCharPointer() const noexcept { return text; } /** Returns a pointer to a UTF-8 version of this string.