1 /* 2 ============================================================================== 3 4 This file is part of the JUCE library. 5 Copyright (c) 2020 - Raw Material Software Limited 6 7 JUCE is an open source library subject to commercial or open-source 8 licensing. 9 10 The code included in this file is provided under the terms of the ISC license 11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission 12 To use, copy, modify, and/or distribute this software for any purpose with or 13 without fee is hereby granted provided that the above copyright notice and 14 this permission notice appear in all copies. 15 16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER 17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE 18 DISCLAIMED. 19 20 ============================================================================== 21 */ 22 23 namespace juce 24 { 25 26 //============================================================================== 27 /** 28 A simple class for holding temporary references to a string literal or String. 29 30 Unlike a real String object, the StringRef does not allocate any memory or 31 take ownership of the strings you give to it - it simply holds a reference to 32 a string that has been allocated elsewhere. 33 The main purpose of the class is to be used instead of a const String& as the type 34 of function arguments where the caller may pass either a string literal or a String 35 object. This means that when the called uses a string literal, there's no need 36 for an temporary String object to be allocated, and this cuts down overheads 37 substantially. 38 39 Because the class is simply a wrapper around a pointer, you should always pass 40 it by value, not by reference. 41 42 @code 43 void myStringFunction1 (const String&); 44 void myStringFunction2 (StringRef); 45 46 myStringFunction1 ("abc"); // Implicitly allocates a temporary String object. 47 myStringFunction2 ("abc"); // Much faster, as no local allocations are needed. 48 @endcode 49 50 For examples of it in use, see the XmlElement or StringArray classes. 51 52 Bear in mind that there are still many cases where it's better to use an argument 53 which is a const String&. For example if the function stores the string or needs 54 to internally create a String from the argument, then it's better for the original 55 argument to already be a String. 56 57 @see String 58 59 @tags{Core} 60 */ 61 class JUCE_API StringRef final 62 { 63 public: 64 /** Creates a StringRef from a raw string literal. 65 The StringRef object does NOT take ownership or copy this data, so you must 66 ensure that the data does not change during the lifetime of the StringRef. 67 Note that this pointer cannot be null! 68 */ 69 StringRef (const char* stringLiteral) noexcept; 70 71 /** Creates a StringRef from a raw char pointer. 72 The StringRef object does NOT take ownership or copy this data, so you must 73 ensure that the data does not change during the lifetime of the StringRef. 74 */ 75 StringRef (String::CharPointerType stringLiteral) noexcept; 76 77 /** Creates a StringRef from a String. 78 The StringRef object does NOT take ownership or copy the data from the String, 79 so you must ensure that the String is not modified or deleted during the lifetime 80 of the StringRef. 81 */ 82 StringRef (const String& string) noexcept; 83 84 /** Creates a StringRef from a String. 85 The StringRef object does NOT take ownership or copy the data from the std::string, 86 so you must ensure that the source string object is not modified or deleted during 87 the lifetime of the StringRef. 88 */ 89 StringRef (const std::string& string); 90 91 /** Creates a StringRef pointer to an empty string. */ 92 StringRef() noexcept; 93 94 //============================================================================== 95 /** Returns a raw pointer to the underlying string data. */ 96 operator const String::CharPointerType::CharType*() const noexcept { return text.getAddress(); } 97 /** Returns a pointer to the underlying string data as a char pointer object. */ CharPointerType()98 operator String::CharPointerType() const noexcept { return text; } 99 100 /** Returns true if the string is empty. */ isEmpty()101 bool isEmpty() const noexcept { return text.isEmpty(); } 102 /** Returns true if the string is not empty. */ isNotEmpty()103 bool isNotEmpty() const noexcept { return ! text.isEmpty(); } 104 /** Returns the number of characters in the string. */ length()105 int length() const noexcept { return (int) text.length(); } 106 107 /** Retrieves a character by index. */ 108 juce_wchar operator[] (int index) const noexcept { return text[index]; } 109 110 /** Compares this StringRef with a String. */ 111 bool operator== (const String& s) const noexcept { return text.compare (s.getCharPointer()) == 0; } 112 /** Compares this StringRef with a String. */ 113 bool operator!= (const String& s) const noexcept { return text.compare (s.getCharPointer()) != 0; } 114 /** Compares this StringRef with a String. */ 115 bool operator< (const String& s) const noexcept { return text.compare (s.getCharPointer()) < 0; } 116 /** Compares this StringRef with a String. */ 117 bool operator<= (const String& s) const noexcept { return text.compare (s.getCharPointer()) <= 0; } 118 /** Compares this StringRef with a String. */ 119 bool operator> (const String& s) const noexcept { return text.compare (s.getCharPointer()) > 0; } 120 /** Compares this StringRef with a String. */ 121 bool operator>= (const String& s) const noexcept { return text.compare (s.getCharPointer()) >= 0; } 122 123 /** Case-sensitive comparison of two StringRefs. */ 124 bool operator== (StringRef s) const noexcept { return text.compare (s.text) == 0; } 125 /** Case-sensitive comparison of two StringRefs. */ 126 bool operator!= (StringRef s) const noexcept { return text.compare (s.text) != 0; } 127 128 //============================================================================== 129 /** The text that is referenced. */ 130 String::CharPointerType text; 131 132 #if JUCE_STRING_UTF_TYPE != 8 && ! defined (DOXYGEN) 133 // Sorry, non-UTF8 people, you're unable to take advantage of StringRef, because 134 // you've chosen a character encoding that doesn't match C++ string literals. 135 String stringCopy; 136 #endif 137 }; 138 139 //============================================================================== 140 /** Case-sensitive comparison of two strings. */ 141 JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, StringRef string2) noexcept; 142 /** Case-sensitive comparison of two strings. */ 143 JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, StringRef string2) noexcept; 144 /** Case-sensitive comparison of two strings. */ 145 JUCE_API bool JUCE_CALLTYPE operator< (const String& string1, StringRef string2) noexcept; 146 /** Case-sensitive comparison of two strings. */ 147 JUCE_API bool JUCE_CALLTYPE operator<= (const String& string1, StringRef string2) noexcept; 148 /** Case-sensitive comparison of two strings. */ 149 JUCE_API bool JUCE_CALLTYPE operator> (const String& string1, StringRef string2) noexcept; 150 /** Case-sensitive comparison of two strings. */ 151 JUCE_API bool JUCE_CALLTYPE operator>= (const String& string1, StringRef string2) noexcept; 152 153 inline String operator+ (String s1, StringRef s2) { return s1 += String (s2.text); } 154 inline String operator+ (StringRef s1, const String& s2) { return String (s1.text) + s2; } 155 inline String operator+ (const char* s1, StringRef s2) { return String (s1) + String (s2.text); } 156 inline String operator+ (StringRef s1, const char* s2) { return String (s1.text) + String (s2); } 157 158 } // namespace juce 159