| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-21 17:31:56 +02:00
										 |  |  | #pragma once
 | 
					
						
							| 
									
										
										
										
											2019-09-13 21:12:26 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup bli | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2020-06-09 10:27:24 +02:00
										 |  |  |  * A `blender::StringRef` references a const char array owned by someone else. It is just a pointer | 
					
						
							|  |  |  |  * and a size. Since the memory is not owned, StringRef should not be used to transfer ownership of | 
					
						
							|  |  |  |  * the string. The data referenced by a StringRef cannot be mutated through it. | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |  * A StringRef is NOT null-terminated. This makes it much more powerful within C++, because we can | 
					
						
							|  |  |  |  * also cut off parts of the end without creating a copy. When interfacing with C code that expects | 
					
						
							| 
									
										
										
										
											2020-06-09 10:27:24 +02:00
										 |  |  |  * null-terminated strings, `blender::StringRefNull` can be used. It is essentially the same as | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |  * StringRef, but with the restriction that the string has to be null-terminated. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Whenever possible, string parameters should be of type StringRef and the string return type | 
					
						
							|  |  |  |  * should be StringRefNull. Don't forget that the StringRefNull does not own the string, so don't | 
					
						
							|  |  |  |  * return it when the string exists only in the scope of the function. This convention makes | 
					
						
							|  |  |  |  * functions usable in the most contexts. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2020-06-09 10:27:24 +02:00
										 |  |  |  * blender::StringRef vs. std::string_view: | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |  *   Both types are certainly very similar. The main benefit of using StringRef in Blender is that | 
					
						
							|  |  |  |  *   this allows us to add convenience methods at any time. Especially, when doing a lot of string | 
					
						
							|  |  |  |  *   manipulation, this helps to keep the code clean. Furthermore, we need StringRefNull anyway, | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  |  *   because there is a lot of C code that expects null-terminated strings. Conversion between | 
					
						
							|  |  |  |  *   StringRef and string_view is very cheap and can be done at api boundaries at essentially no | 
					
						
							|  |  |  |  *   cost. Another benefit of using StringRef is that it uses signed integers, thus developers | 
					
						
							|  |  |  |  *   have to deal less with issues resulting from unsigned integers. | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <cstring>
 | 
					
						
							|  |  |  | #include <sstream>
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include <string>
 | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  | #include <string_view>
 | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 11:58:47 +02:00
										 |  |  | #include "BLI_span.hh"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "BLI_utildefines.h"
 | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 10:27:24 +02:00
										 |  |  | namespace blender { | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | class StringRef; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * A common base class for StringRef and StringRefNull. This should never be used in other files. | 
					
						
							|  |  |  |  * It only exists to avoid some code duplication. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  | class StringRefBase { | 
					
						
							|  |  |  |  protected: | 
					
						
							| 
									
										
										
										
											2020-07-03 14:15:05 +02:00
										 |  |  |   const char *data_; | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   int64_t size_; | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr StringRefBase(const char *data, const int64_t size) : data_(data), size_(size) | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  |   /* Similar to string_view::npos, but signed. */ | 
					
						
							|  |  |  |   static constexpr int64_t not_found = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Return the (byte-)length of the referenced string, without any null-terminator. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr int64_t size() const | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:15:05 +02:00
										 |  |  |     return size_; | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr bool is_empty() const | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     return size_ == 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Return a pointer to the start of the string. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr const char *data() const | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:15:05 +02:00
										 |  |  |     return data_; | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr operator Span<char>() const | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:15:05 +02:00
										 |  |  |     return Span<char>(data_, size_); | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |   /**
 | 
					
						
							| 
									
										
										
										
											2020-06-30 20:54:31 +10:00
										 |  |  |    * Implicitly convert to std::string. This is convenient in most cases, but you have to be a bit | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |    * careful not to convert to std::string accidentally. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   operator std::string() const | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  |     return std::string(data_, static_cast<size_t>(size_)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr operator std::string_view() const | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     return std::string_view(data_, static_cast<size_t>(size_)); | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr const char *begin() const | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:15:05 +02:00
										 |  |  |     return data_; | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr const char *end() const | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:15:05 +02:00
										 |  |  |     return data_ + size_; | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr IndexRange index_range() const | 
					
						
							| 
									
										
										
										
											2020-09-03 16:13:34 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     return IndexRange(size_); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Copy the string into a buffer. The buffer has to be one byte larger than the size of the | 
					
						
							|  |  |  |    * string, because the copied string will be null-terminated. Only use this when you are | 
					
						
							|  |  |  |    * absolutely sure that the buffer is large enough. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-04-24 23:35:17 +02:00
										 |  |  |   void unsafe_copy(char *dst) const | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2021-09-22 19:45:18 +02:00
										 |  |  |     if (size_ > 0) { | 
					
						
							|  |  |  |       memcpy(dst, data_, static_cast<size_t>(size_)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-07-03 14:15:05 +02:00
										 |  |  |     dst[size_] = '\0'; | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Copy the string into a buffer. The copied string will be null-terminated. This invokes | 
					
						
							|  |  |  |    * undefined behavior when dst_size is too small. (Should we define the behavior?) | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   void copy(char *dst, const int64_t dst_size) const | 
					
						
							| 
									
										
										
										
											2020-04-24 23:35:17 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:15:05 +02:00
										 |  |  |     if (size_ < dst_size) { | 
					
						
							| 
									
										
										
										
											2020-04-24 23:35:17 +02:00
										 |  |  |       this->unsafe_copy(dst); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       BLI_assert(false); | 
					
						
							|  |  |  |       dst[0] = '\0'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Copy the string into a char array. The copied string will be null-terminated. This invokes | 
					
						
							|  |  |  |    * undefined behavior when dst is too small. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-11-20 17:29:21 +01:00
										 |  |  |   template<size_t N> void copy(char (&dst)[N]) const | 
					
						
							| 
									
										
										
										
											2020-04-24 23:35:17 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     this->copy(dst, N); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Returns true when the string begins with the given prefix. Otherwise false. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr bool startswith(StringRef prefix) const; | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Returns true when the string ends with the given suffix. Otherwise false. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr bool endswith(StringRef suffix) const; | 
					
						
							| 
									
										
										
										
											2020-02-10 13:54:57 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr StringRef substr(int64_t start, const int64_t size) const; | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Get the first char in the string. This invokes undefined behavior when the string is empty. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr const char &front() const | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     BLI_assert(size_ >= 1); | 
					
						
							|  |  |  |     return data_[0]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Get the last char in the string. This invokes undefined behavior when the string is empty. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr const char &back() const | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     BLI_assert(size_ >= 1); | 
					
						
							|  |  |  |     return data_[size_ - 1]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * The behavior of those functions matches the standard library implementation of | 
					
						
							|  |  |  |    * std::string_view. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr int64_t find(char c, int64_t pos = 0) const; | 
					
						
							|  |  |  |   constexpr int64_t find(StringRef str, int64_t pos = 0) const; | 
					
						
							|  |  |  |   constexpr int64_t rfind(char c, int64_t pos = INT64_MAX) const; | 
					
						
							|  |  |  |   constexpr int64_t rfind(StringRef str, int64_t pos = INT64_MAX) const; | 
					
						
							|  |  |  |   constexpr int64_t find_first_of(StringRef chars, int64_t pos = 0) const; | 
					
						
							|  |  |  |   constexpr int64_t find_first_of(char c, int64_t pos = 0) const; | 
					
						
							|  |  |  |   constexpr int64_t find_last_of(StringRef chars, int64_t pos = INT64_MAX) const; | 
					
						
							|  |  |  |   constexpr int64_t find_last_of(char c, int64_t pos = INT64_MAX) const; | 
					
						
							|  |  |  |   constexpr int64_t find_first_not_of(StringRef chars, int64_t pos = 0) const; | 
					
						
							|  |  |  |   constexpr int64_t find_first_not_of(char c, int64_t pos = 0) const; | 
					
						
							|  |  |  |   constexpr int64_t find_last_not_of(StringRef chars, int64_t pos = INT64_MAX) const; | 
					
						
							|  |  |  |   constexpr int64_t find_last_not_of(char c, int64_t pos = INT64_MAX) const; | 
					
						
							| 
									
										
										
										
											2021-07-27 17:30:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Return a new StringRef that does not contain leading and trailing whitespace. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   constexpr StringRef trim() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Return a new StringRef that removes all the leading and trailing characters | 
					
						
							|  |  |  |    * that occur in `characters_to_remove`. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   constexpr StringRef trim(StringRef characters_to_remove) const; | 
					
						
							|  |  |  |   constexpr StringRef trim(char character_to_remove) const; | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |  * References a null-terminated const char array. | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | class StringRefNull : public StringRefBase { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr StringRefNull() : StringRefBase("", 0) | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |   /**
 | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  |    * Construct a StringRefNull from a null terminated c-string. The pointer must not point to | 
					
						
							|  |  |  |    * NULL. | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-08-07 18:24:59 +02:00
										 |  |  |   StringRefNull(const char *str) : StringRefBase(str, static_cast<int64_t>(strlen(str))) | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |     BLI_assert(str != nullptr); | 
					
						
							| 
									
										
										
										
											2020-07-03 14:15:05 +02:00
										 |  |  |     BLI_assert(data_[size_] == '\0'); | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Construct a StringRefNull from a null terminated c-string. This invokes undefined behavior | 
					
						
							|  |  |  |    * when the given size is not the correct size of the string. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr StringRefNull(const char *str, const int64_t size) : StringRefBase(str, size) | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-08-07 18:24:59 +02:00
										 |  |  |     BLI_assert(static_cast<int64_t>(strlen(str)) == size); | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Reference a std::string. Remember that when the std::string is destructed, the StringRefNull | 
					
						
							|  |  |  |    * will point to uninitialized memory. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-07-17 12:38:15 +02:00
										 |  |  |   StringRefNull(const std::string &str) : StringRefNull(str.c_str()) | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Get the char at the given index. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr char operator[](const int64_t index) const | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |     BLI_assert(index >= 0); | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |     /* Use '<=' instead of just '<', so that the null character can be accessed as well. */ | 
					
						
							| 
									
										
										
										
											2020-07-03 14:15:05 +02:00
										 |  |  |     BLI_assert(index <= size_); | 
					
						
							|  |  |  |     return data_[index]; | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-07-17 12:38:15 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * Returns the beginning of a null-terminated char array. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * This is like ->data(), but can only be called on a StringRefNull. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr const char *c_str() const | 
					
						
							| 
									
										
										
										
											2020-07-17 12:38:15 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     return data_; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |  * References a const char array. It might not be null terminated. | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | class StringRef : public StringRefBase { | 
					
						
							|  |  |  |  public: | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr StringRef() : StringRefBase(nullptr, 0) | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * StringRefNull can be converted into StringRef, but not the other way around. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr StringRef(StringRefNull other) : StringRefBase(other.data(), other.size()) | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Create a StringRef from a null-terminated c-string. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr StringRef(const char *str) | 
					
						
							|  |  |  |       : StringRefBase(str, str ? static_cast<int64_t>(std::char_traits<char>::length(str)) : 0) | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr StringRef(const char *str, const int64_t length) : StringRefBase(str, length) | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-10 18:26:11 +02:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Create a StringRef from a start and end pointer. This invokes undefined behavior when the | 
					
						
							|  |  |  |    * second point points to a smaller address than the first one. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr StringRef(const char *begin, const char *one_after_end) | 
					
						
							| 
									
										
										
										
											2020-08-07 18:24:59 +02:00
										 |  |  |       : StringRefBase(begin, static_cast<int64_t>(one_after_end - begin)) | 
					
						
							| 
									
										
										
										
											2020-06-10 18:26:11 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     BLI_assert(begin <= one_after_end); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Reference a std::string. Remember that when the std::string is destructed, the StringRef | 
					
						
							|  |  |  |    * will point to uninitialized memory. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-08-07 18:24:59 +02:00
										 |  |  |   StringRef(const std::string &str) : StringRefBase(str.data(), static_cast<int64_t>(str.size())) | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr StringRef(std::string_view view) | 
					
						
							|  |  |  |       : StringRefBase(view.data(), static_cast<int64_t>(view.size())) | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   /**
 | 
					
						
							| 
									
										
										
										
											2021-02-20 22:05:27 +01:00
										 |  |  |    * Returns a new StringRef that does not contain the first n chars. This invokes undefined | 
					
						
							|  |  |  |    * behavior when n is negative. | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr StringRef drop_prefix(const int64_t n) const | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |     BLI_assert(n >= 0); | 
					
						
							| 
									
										
										
										
											2021-02-20 22:05:27 +01:00
										 |  |  |     const int64_t clamped_n = std::min(n, size_); | 
					
						
							|  |  |  |     const int64_t new_size = size_ - clamped_n; | 
					
						
							|  |  |  |     return StringRef(data_ + clamped_n, new_size); | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  |    * Return a new StringRef with the given prefix being skipped. This invokes undefined behavior if | 
					
						
							|  |  |  |    * the string does not begin with the given prefix. | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2021-02-20 22:05:27 +01:00
										 |  |  |   constexpr StringRef drop_known_prefix(StringRef prefix) const | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     BLI_assert(this->startswith(prefix)); | 
					
						
							|  |  |  |     return this->drop_prefix(prefix.size()); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  |   /**
 | 
					
						
							| 
									
										
										
										
											2021-02-20 22:05:27 +01:00
										 |  |  |    * Return a new StringRef that does not contain the last n chars. This invokes undefined behavior | 
					
						
							|  |  |  |    * when n is negative. | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr StringRef drop_suffix(const int64_t n) const | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  |   { | 
					
						
							|  |  |  |     BLI_assert(n >= 0); | 
					
						
							| 
									
										
										
										
											2021-02-20 22:05:27 +01:00
										 |  |  |     const int64_t new_size = std::max<int64_t>(0, size_ - n); | 
					
						
							|  |  |  |     return StringRef(data_, new_size); | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Get the char at the given index. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  |   constexpr char operator[](int64_t index) const | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |     BLI_assert(index >= 0); | 
					
						
							| 
									
										
										
										
											2020-07-03 14:15:05 +02:00
										 |  |  |     BLI_assert(index < size_); | 
					
						
							|  |  |  |     return data_[index]; | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* More inline functions
 | 
					
						
							|  |  |  |  ***************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline std::ostream &operator<<(std::ostream &stream, StringRef ref) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   stream << std::string(ref); | 
					
						
							|  |  |  |   return stream; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline std::ostream &operator<<(std::ostream &stream, StringRefNull ref) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   stream << std::string(ref.data(), (size_t)ref.size()); | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |   return stream; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2020-06-13 12:50:07 +10:00
										 |  |  |  * Adding two #StringRefs will allocate an std::string. | 
					
						
							|  |  |  |  * This is not efficient, but convenient in most cases. | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  | inline std::string operator+(StringRef a, StringRef b) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return std::string(a) + std::string(b); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  | /* This does not compare StringRef and std::string_view, because of ambiguous overloads. This is
 | 
					
						
							|  |  |  |  * not a problem when std::string_view is only used at api boundaries. To compare a StringRef and a | 
					
						
							|  |  |  |  * std::string_view, one should convert the std::string_view to StringRef (which is very cheap). | 
					
						
							| 
									
										
										
										
											2020-08-11 13:19:09 +10:00
										 |  |  |  * Ideally, we only use StringRef in our code to avoid this problem altogether. */ | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  | constexpr inline bool operator==(StringRef a, StringRef b) | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   if (a.size() != b.size()) { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   return STREQLEN(a.data(), b.data(), (size_t)a.size()); | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  | constexpr inline bool operator!=(StringRef a, StringRef b) | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return !(a == b); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  | constexpr inline bool operator<(StringRef a, StringRef b) | 
					
						
							| 
									
										
										
										
											2020-09-07 16:09:48 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return std::string_view(a) < std::string_view(b); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  | constexpr inline bool operator>(StringRef a, StringRef b) | 
					
						
							| 
									
										
										
										
											2020-09-07 16:09:48 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return std::string_view(a) > std::string_view(b); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  | constexpr inline bool operator<=(StringRef a, StringRef b) | 
					
						
							| 
									
										
										
										
											2020-09-07 16:09:48 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return std::string_view(a) <= std::string_view(b); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  | constexpr inline bool operator>=(StringRef a, StringRef b) | 
					
						
							| 
									
										
										
										
											2020-09-07 16:09:48 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return std::string_view(a) >= std::string_view(b); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Return true when the string starts with the given prefix. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  | constexpr inline bool StringRefBase::startswith(StringRef prefix) const | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:15:05 +02:00
										 |  |  |   if (size_ < prefix.size_) { | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   for (int64_t i = 0; i < prefix.size_; i++) { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:15:05 +02:00
										 |  |  |     if (data_[i] != prefix.data_[i]) { | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |       return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Return true when the string ends with the given suffix. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  | constexpr inline bool StringRefBase::endswith(StringRef suffix) const | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:15:05 +02:00
										 |  |  |   if (size_ < suffix.size_) { | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   const int64_t offset = size_ - suffix.size_; | 
					
						
							|  |  |  |   for (int64_t i = 0; i < suffix.size_; i++) { | 
					
						
							| 
									
										
										
										
											2020-07-03 14:15:05 +02:00
										 |  |  |     if (data_[offset + i] != suffix.data_[i]) { | 
					
						
							| 
									
										
										
										
											2019-09-12 16:51:55 +02:00
										 |  |  |       return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2021-02-20 22:05:27 +01:00
										 |  |  |  * Return a new #StringRef containing only a sub-string of the original string. This invokes | 
					
						
							|  |  |  |  * undefined if the start or max_size is negative. | 
					
						
							| 
									
										
										
										
											2020-06-09 10:10:56 +02:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  | constexpr inline StringRef StringRefBase::substr(const int64_t start, | 
					
						
							|  |  |  |                                                  const int64_t max_size = INT64_MAX) const | 
					
						
							| 
									
										
										
										
											2020-02-10 13:54:57 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  |   BLI_assert(max_size >= 0); | 
					
						
							| 
									
										
										
										
											2020-07-20 12:16:20 +02:00
										 |  |  |   BLI_assert(start >= 0); | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  |   const int64_t substr_size = std::min(max_size, size_ - start); | 
					
						
							|  |  |  |   return StringRef(data_ + start, substr_size); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  | constexpr inline int64_t index_or_npos_to_int64(size_t index) | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   /* The compiler will probably optimize this check away. */ | 
					
						
							|  |  |  |   if (index == std::string_view::npos) { | 
					
						
							|  |  |  |     return StringRef::not_found; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return static_cast<int64_t>(index); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  | constexpr inline int64_t StringRefBase::find(char c, int64_t pos) const | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   BLI_assert(pos >= 0); | 
					
						
							|  |  |  |   return index_or_npos_to_int64(std::string_view(*this).find(c, static_cast<size_t>(pos))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  | constexpr inline int64_t StringRefBase::find(StringRef str, int64_t pos) const | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   BLI_assert(pos >= 0); | 
					
						
							|  |  |  |   return index_or_npos_to_int64(std::string_view(*this).find(str, static_cast<size_t>(pos))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  | constexpr inline int64_t StringRefBase::find_first_of(StringRef chars, int64_t pos) const | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   BLI_assert(pos >= 0); | 
					
						
							|  |  |  |   return index_or_npos_to_int64( | 
					
						
							|  |  |  |       std::string_view(*this).find_first_of(chars, static_cast<size_t>(pos))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  | constexpr inline int64_t StringRefBase::find_first_of(char c, int64_t pos) const | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return this->find_first_of(StringRef(&c, 1), pos); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  | constexpr inline int64_t StringRefBase::find_last_of(StringRef chars, int64_t pos) const | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   BLI_assert(pos >= 0); | 
					
						
							|  |  |  |   return index_or_npos_to_int64( | 
					
						
							|  |  |  |       std::string_view(*this).find_last_of(chars, static_cast<size_t>(pos))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  | constexpr inline int64_t StringRefBase::find_last_of(char c, int64_t pos) const | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return this->find_last_of(StringRef(&c, 1), pos); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  | constexpr inline int64_t StringRefBase::find_first_not_of(StringRef chars, int64_t pos) const | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   BLI_assert(pos >= 0); | 
					
						
							|  |  |  |   return index_or_npos_to_int64( | 
					
						
							|  |  |  |       std::string_view(*this).find_first_not_of(chars, static_cast<size_t>(pos))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  | constexpr inline int64_t StringRefBase::find_first_not_of(char c, int64_t pos) const | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return this->find_first_not_of(StringRef(&c, 1), pos); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  | constexpr inline int64_t StringRefBase::find_last_not_of(StringRef chars, int64_t pos) const | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   BLI_assert(pos >= 0); | 
					
						
							|  |  |  |   return index_or_npos_to_int64( | 
					
						
							|  |  |  |       std::string_view(*this).find_last_not_of(chars, static_cast<size_t>(pos))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 13:02:28 +05:30
										 |  |  | constexpr inline int64_t StringRefBase::find_last_not_of(char c, int64_t pos) const | 
					
						
							| 
									
										
										
										
											2020-08-10 18:13:28 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return this->find_last_not_of(StringRef(&c, 1), pos); | 
					
						
							| 
									
										
										
										
											2020-02-10 13:54:57 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-27 17:30:33 +02:00
										 |  |  | constexpr StringRef StringRefBase::trim() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return this->trim(" \t\r\n"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | constexpr StringRef StringRefBase::trim(const char character_to_remove) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return this->trim(StringRef(&character_to_remove, 1)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Return a new StringRef that removes all the leading and trailing characters | 
					
						
							|  |  |  |  * that occur in `characters_to_remove`. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | constexpr StringRef StringRefBase::trim(StringRef characters_to_remove) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const int64_t find_front = this->find_first_not_of(characters_to_remove); | 
					
						
							|  |  |  |   if (find_front == not_found) { | 
					
						
							|  |  |  |     return StringRef(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   const int64_t find_end = this->find_last_not_of(characters_to_remove); | 
					
						
							|  |  |  |   /* `find_end` cannot be `not_found`, because that means the string is only
 | 
					
						
							|  |  |  |    * `characters_to_remove`, in which case `find_front` would already have | 
					
						
							|  |  |  |    * been `not_found`. */ | 
					
						
							|  |  |  |   BLI_assert_msg(find_end != not_found, | 
					
						
							|  |  |  |                  "forward search found characters-to-not-remove, but backward search did not"); | 
					
						
							|  |  |  |   const int64_t substr_len = find_end - find_front + 1; | 
					
						
							|  |  |  |   return this->substr(find_front, substr_len); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-09 10:27:24 +02:00
										 |  |  | }  // namespace blender
 |