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 special array for holding a list of strings. 29 30 @see String, StringPairArray 31 32 @tags{Core} 33 */ 34 class JUCE_API StringArray 35 { 36 public: 37 //============================================================================== 38 /** Creates an empty string array */ 39 StringArray() noexcept; 40 41 /** Creates a copy of another string array */ 42 StringArray (const StringArray&); 43 44 /** Move constructor */ 45 StringArray (StringArray&&) noexcept; 46 47 /** Creates an array containing a single string. */ 48 StringArray (const String& firstValue); 49 50 /** Creates an array containing a list of strings. */ 51 template <typename... OtherElements> StringArray(StringRef firstValue,OtherElements &&...otherValues)52 StringArray (StringRef firstValue, OtherElements&&... otherValues) 53 : strings (firstValue, std::forward<OtherElements> (otherValues)...) {} 54 55 /** Creates an array containing a list of strings. */ 56 StringArray (const std::initializer_list<const char*>& strings); 57 58 /** Creates a StringArray by moving from an Array<String> */ 59 StringArray (Array<String>&&) noexcept; 60 61 /** Creates a StringArray from an array of objects which can be implicitly converted to Strings. */ 62 template <typename Type> StringArray(const Array<Type> & stringArray)63 StringArray (const Array<Type>& stringArray) 64 { 65 addArray (stringArray.begin(), stringArray.end()); 66 } 67 68 /** Creates an array from a raw array of strings. 69 @param strings an array of strings to add 70 @param numberOfStrings how many items there are in the array 71 */ 72 StringArray (const String* strings, int numberOfStrings); 73 74 /** Creates a copy of an array of string literals. 75 @param strings an array of strings to add. Null pointers in the array will be 76 treated as empty strings 77 @param numberOfStrings how many items there are in the array 78 */ 79 StringArray (const char* const* strings, int numberOfStrings); 80 81 /** Creates a copy of a null-terminated array of string literals. 82 83 Each item from the array passed-in is added, until it encounters a null pointer, 84 at which point it stops. 85 */ 86 explicit StringArray (const char* const* strings); 87 88 /** Creates a copy of a null-terminated array of string literals. 89 Each item from the array passed-in is added, until it encounters a null pointer, 90 at which point it stops. 91 */ 92 explicit StringArray (const wchar_t* const* strings); 93 94 /** Creates a copy of an array of string literals. 95 @param strings an array of strings to add. Null pointers in the array will be 96 treated as empty strings 97 @param numberOfStrings how many items there are in the array 98 */ 99 StringArray (const wchar_t* const* strings, int numberOfStrings); 100 101 /** Destructor. */ 102 ~StringArray(); 103 104 /** Copies the contents of another string array into this one */ 105 StringArray& operator= (const StringArray&); 106 107 /** Move assignment operator */ 108 StringArray& operator= (StringArray&&) noexcept; 109 110 /** Copies a StringArray from an array of objects which can be implicitly converted to Strings. */ 111 template <typename Type> 112 StringArray& operator= (const Array<Type>& stringArray) 113 { 114 addArray (stringArray.begin(), stringArray.end()); 115 return *this; 116 } 117 118 /** Swaps the contents of this and another StringArray. */ 119 void swapWith (StringArray&) noexcept; 120 121 //============================================================================== 122 /** Compares two arrays. 123 Comparisons are case-sensitive. 124 @returns true only if the other array contains exactly the same strings in the same order 125 */ 126 bool operator== (const StringArray&) const noexcept; 127 128 /** Compares two arrays. 129 Comparisons are case-sensitive. 130 @returns false if the other array contains exactly the same strings in the same order 131 */ 132 bool operator!= (const StringArray&) const noexcept; 133 134 //============================================================================== 135 /** Returns the number of strings in the array */ size()136 inline int size() const noexcept { return strings.size(); } 137 138 /** Returns true if the array is empty, false otherwise. */ isEmpty()139 inline bool isEmpty() const noexcept { return size() == 0; } 140 141 /** Returns one of the strings from the array. 142 143 If the index is out-of-range, an empty string is returned. 144 145 Obviously the reference returned shouldn't be stored for later use, as the 146 string it refers to may disappear when the array changes. 147 */ 148 const String& operator[] (int index) const noexcept; 149 150 /** Returns a reference to one of the strings in the array. 151 This lets you modify a string in-place in the array, but you must be sure that 152 the index is in-range. 153 */ 154 String& getReference (int index) noexcept; 155 156 /** Returns a reference to one of the strings in the array. 157 This lets you modify a string in-place in the array, but you must be sure that 158 the index is in-range. 159 */ 160 const String& getReference (int index) const noexcept; 161 162 /** Returns a pointer to the first String in the array. 163 This method is provided for compatibility with standard C++ iteration mechanisms. 164 */ begin()165 inline String* begin() noexcept { return strings.begin(); } 166 167 /** Returns a pointer to the first String in the array. 168 This method is provided for compatibility with standard C++ iteration mechanisms. 169 */ begin()170 inline const String* begin() const noexcept { return strings.begin(); } 171 172 /** Returns a pointer to the String which follows the last element in the array. 173 This method is provided for compatibility with standard C++ iteration mechanisms. 174 */ end()175 inline String* end() noexcept { return strings.end(); } 176 177 /** Returns a pointer to the String which follows the last element in the array. 178 This method is provided for compatibility with standard C++ iteration mechanisms. 179 */ end()180 inline const String* end() const noexcept { return strings.end(); } 181 182 183 /** Searches for a string in the array. 184 185 The comparison will be case-insensitive if the ignoreCase parameter is true. 186 187 @returns true if the string is found inside the array 188 */ 189 bool contains (StringRef stringToLookFor, 190 bool ignoreCase = false) const; 191 192 /** Searches for a string in the array. 193 194 The comparison will be case-insensitive if the ignoreCase parameter is true. 195 196 @param stringToLookFor the string to try to find 197 @param ignoreCase whether the comparison should be case-insensitive 198 @param startIndex the first index to start searching from 199 @returns the index of the first occurrence of the string in this array, 200 or -1 if it isn't found. 201 */ 202 int indexOf (StringRef stringToLookFor, 203 bool ignoreCase = false, 204 int startIndex = 0) const; 205 206 //============================================================================== 207 /** Appends a string at the end of the array. */ 208 void add (String stringToAdd); 209 210 /** Inserts a string into the array. 211 212 This will insert a string into the array at the given index, moving 213 up the other elements to make room for it. 214 If the index is less than zero or greater than the size of the array, 215 the new string will be added to the end of the array. 216 */ 217 void insert (int index, String stringToAdd); 218 219 /** Adds a string to the array as long as it's not already in there. 220 The search can optionally be case-insensitive. 221 222 @return true if the string has been added, false otherwise. 223 */ 224 bool addIfNotAlreadyThere (const String& stringToAdd, bool ignoreCase = false); 225 226 /** Replaces one of the strings in the array with another one. 227 228 If the index is higher than the array's size, the new string will be 229 added to the end of the array; if it's less than zero nothing happens. 230 */ 231 void set (int index, String newString); 232 233 /** Appends some strings from another array to the end of this one. 234 235 @param other the array to add 236 @param startIndex the first element of the other array to add 237 @param numElementsToAdd the maximum number of elements to add (if this is 238 less than zero, they are all added) 239 */ 240 void addArray (const StringArray& other, 241 int startIndex = 0, 242 int numElementsToAdd = -1); 243 244 /** Adds items from a range of start/end iterators of some kind of objects which 245 can be implicitly converted to Strings. 246 */ 247 template <typename Iterator> addArray(Iterator && start,Iterator && end)248 void addArray (Iterator&& start, Iterator&& end) 249 { 250 ensureStorageAllocated (size() + (int) static_cast<size_t> (end - start)); 251 252 while (start != end) 253 strings.add (*start++); 254 } 255 256 /** Merges the strings from another array into this one. 257 This will not add a string that already exists. 258 259 @param other the array to add 260 @param ignoreCase ignore case when merging 261 */ 262 void mergeArray (const StringArray& other, 263 bool ignoreCase = false); 264 265 /** Breaks up a string into tokens and adds them to this array. 266 267 This will tokenise the given string using whitespace characters as the 268 token delimiters, and will add these tokens to the end of the array. 269 @returns the number of tokens added 270 @see fromTokens 271 */ 272 int addTokens (StringRef stringToTokenise, bool preserveQuotedStrings); 273 274 /** Breaks up a string into tokens and adds them to this array. 275 276 This will tokenise the given string (using the string passed in to define the 277 token delimiters), and will add these tokens to the end of the array. 278 279 @param stringToTokenise the string to tokenise 280 @param breakCharacters a string of characters, any of which will be considered 281 to be a token delimiter. 282 @param quoteCharacters if this string isn't empty, it defines a set of characters 283 which are treated as quotes. Any text occurring 284 between quotes is not broken up into tokens. 285 @returns the number of tokens added 286 @see fromTokens 287 */ 288 int addTokens (StringRef stringToTokenise, 289 StringRef breakCharacters, 290 StringRef quoteCharacters); 291 292 /** Breaks up a string into lines and adds them to this array. 293 294 This breaks a string down into lines separated by \\n or \\r\\n, and adds each line 295 to the array. Line-break characters are omitted from the strings that are added to 296 the array. 297 */ 298 int addLines (StringRef stringToBreakUp); 299 300 /** Returns an array containing the tokens in a given string. 301 302 This will tokenise the given string using whitespace characters as the 303 token delimiters, and return the parsed tokens as an array. 304 @see addTokens 305 */ 306 static StringArray fromTokens (StringRef stringToTokenise, 307 bool preserveQuotedStrings); 308 309 /** Returns an array containing the tokens in a given string. 310 311 This will tokenise the given string using the breakCharacters string to define 312 the token delimiters, and will return the parsed tokens as an array. 313 314 @param stringToTokenise the string to tokenise 315 @param breakCharacters a string of characters, any of which will be considered 316 to be a token delimiter. 317 @param quoteCharacters if this string isn't empty, it defines a set of characters 318 which are treated as quotes. Any text occurring 319 between quotes is not broken up into tokens. 320 @see addTokens 321 */ 322 static StringArray fromTokens (StringRef stringToTokenise, 323 StringRef breakCharacters, 324 StringRef quoteCharacters); 325 326 /** Returns an array containing the lines in a given string. 327 328 This breaks a string down into lines separated by \\n or \\r\\n, and returns an 329 array containing these lines. Line-break characters are omitted from the strings that 330 are added to the array. 331 */ 332 static StringArray fromLines (StringRef stringToBreakUp); 333 334 //============================================================================== 335 /** Removes all elements from the array. */ 336 void clear(); 337 338 /** Removes all elements from the array without freeing the array's allocated storage. 339 @see clear 340 */ 341 void clearQuick(); 342 343 /** Removes a string from the array. 344 If the index is out-of-range, no action will be taken. 345 */ 346 void remove (int index); 347 348 /** Finds a string in the array and removes it. 349 This will remove all occurrences of the given string from the array. 350 The comparison may be case-insensitive depending on the ignoreCase parameter. 351 */ 352 void removeString (StringRef stringToRemove, 353 bool ignoreCase = false); 354 355 /** Removes a range of elements from the array. 356 357 This will remove a set of elements, starting from the given index, 358 and move subsequent elements down to close the gap. 359 360 If the range extends beyond the bounds of the array, it will 361 be safely clipped to the size of the array. 362 363 @param startIndex the index of the first element to remove 364 @param numberToRemove how many elements should be removed 365 */ 366 void removeRange (int startIndex, int numberToRemove); 367 368 /** Removes any duplicated elements from the array. 369 370 If any string appears in the array more than once, only the first occurrence of 371 it will be retained. 372 373 @param ignoreCase whether to use a case-insensitive comparison 374 */ 375 void removeDuplicates (bool ignoreCase); 376 377 /** Removes empty strings from the array. 378 @param removeWhitespaceStrings if true, strings that only contain whitespace 379 characters will also be removed 380 */ 381 void removeEmptyStrings (bool removeWhitespaceStrings = true); 382 383 /** Moves one of the strings to a different position. 384 385 This will move the string to a specified index, shuffling along 386 any intervening elements as required. 387 388 So for example, if you have the array { 0, 1, 2, 3, 4, 5 } then calling 389 move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }. 390 391 @param currentIndex the index of the value to be moved. If this isn't a 392 valid index, then nothing will be done 393 @param newIndex the index at which you'd like this value to end up. If this 394 is less than zero, the value will be moved to the end 395 of the array 396 */ 397 void move (int currentIndex, int newIndex) noexcept; 398 399 /** Deletes any whitespace characters from the starts and ends of all the strings. */ 400 void trim(); 401 402 /** Adds numbers to the strings in the array, to make each string unique. 403 404 This will add numbers to the ends of groups of similar strings. 405 e.g. if there are two "moose" strings, they will become "moose (1)" and "moose (2)" 406 407 @param ignoreCaseWhenComparing whether the comparison used is case-insensitive 408 @param appendNumberToFirstInstance whether the first of a group of similar strings 409 also has a number appended to it. 410 @param preNumberString when adding a number, this string is added before the number. 411 If you pass nullptr, a default string will be used, which adds 412 brackets around the number. 413 @param postNumberString this string is appended after any numbers that are added. 414 If you pass nullptr, a default string will be used, which adds 415 brackets around the number. 416 */ 417 void appendNumbersToDuplicates (bool ignoreCaseWhenComparing, 418 bool appendNumberToFirstInstance, 419 CharPointer_UTF8 preNumberString = CharPointer_UTF8 (nullptr), 420 CharPointer_UTF8 postNumberString = CharPointer_UTF8 (nullptr)); 421 422 //============================================================================== 423 /** Joins the strings in the array together into one string. 424 425 This will join a range of elements from the array into a string, separating 426 them with a given string. 427 428 e.g. joinIntoString (",") will turn an array of "a" "b" and "c" into "a,b,c". 429 430 @param separatorString the string to insert between all the strings 431 @param startIndex the first element to join 432 @param numberOfElements how many elements to join together. If this is less 433 than zero, all available elements will be used. 434 */ 435 String joinIntoString (StringRef separatorString, 436 int startIndex = 0, 437 int numberOfElements = -1) const; 438 439 //============================================================================== 440 /** Sorts the array into alphabetical order. 441 @param ignoreCase if true, the comparisons used will not be case-sensitive. 442 */ 443 void sort (bool ignoreCase); 444 445 /** Sorts the array using extra language-aware rules to do a better job of comparing 446 words containing spaces and numbers. 447 @see String::compareNatural() 448 */ 449 void sortNatural(); 450 451 //============================================================================== 452 /** Increases the array's internal storage to hold a minimum number of elements. 453 454 Calling this before adding a large known number of elements means that 455 the array won't have to keep dynamically resizing itself as the elements 456 are added, and it'll therefore be more efficient. 457 */ 458 void ensureStorageAllocated (int minNumElements); 459 460 /** Reduces the amount of storage being used by the array. 461 462 Arrays typically allocate slightly more storage than they need, and after 463 removing elements, they may have quite a lot of unused space allocated. 464 This method will reduce the amount of allocated storage to a minimum. 465 */ 466 void minimiseStorageOverheads(); 467 468 /** This is the array holding the actual strings. This is public to allow direct access 469 to array methods that may not already be provided by the StringArray class. 470 */ 471 Array<String> strings; 472 473 private: 474 JUCE_LEAK_DETECTOR (StringArray) 475 }; 476 477 } // namespace juce 478