Added splitFixed() function to avoid heap-allocation when the number of (expected) splits is known at compile-time.
This commit is contained in:
		
							parent
							
								
									8e117e0f47
								
							
						
					
					
						commit
						aff59724fc
					
				| @ -72,10 +72,12 @@ template <typename TRange, typename TValue = typename TRange::value_type> | |||||||
| 
 | 
 | ||||||
| namespace detail | namespace detail | ||||||
| { | { | ||||||
| template<typename TChar, typename TTraits> | template<typename TChar, typename TTraits, typename TOutIterator> | ||||||
| std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_view<TChar, TTraits> stringView, | void splitImpl(std::basic_string_view<TChar, TTraits> stringView, | ||||||
|                std::basic_string_view<TChar, TTraits> separator, |                std::basic_string_view<TChar, TTraits> separator, | ||||||
|                                                               const SplitOptions& options) |                const SplitOptions& options, | ||||||
|  |                TOutIterator outIterator, | ||||||
|  |                std::size_t& numEmitted) | ||||||
| { | { | ||||||
|     using sv_t = std::basic_string_view<TChar, TTraits>; |     using sv_t = std::basic_string_view<TChar, TTraits>; | ||||||
| 
 | 
 | ||||||
| @ -84,14 +86,20 @@ std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_ | |||||||
| 
 | 
 | ||||||
|     if (separator.empty()) |     if (separator.empty()) | ||||||
|     { |     { | ||||||
|         return {}; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     std::vector<sv_t> result; |     auto emit = [&](std::string_view result) | ||||||
|  |     { | ||||||
|  |         *outIterator = result; | ||||||
|  |         ++outIterator; | ||||||
|  |         ++numEmitted; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|     if (options.limitParts <= 1) |     if (options.limitParts <= 1) | ||||||
|     { |     { | ||||||
|         result.push_back(stringView); |         emit(stringView); | ||||||
|         return result; |         return; | ||||||
|     } |     } | ||||||
|     auto start = stringView.begin(); |     auto start = stringView.begin(); | ||||||
|     auto pos = start; |     auto pos = start; | ||||||
| @ -108,10 +116,10 @@ std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_ | |||||||
|         { |         { | ||||||
|             if (!options.ignoreEmpty || pos != start) |             if (!options.ignoreEmpty || pos != start) | ||||||
|             { |             { | ||||||
|                 result.emplace_back(start, pos); |                 emit(std::string_view(start, pos)); | ||||||
|             } |             } | ||||||
|             start = pos = (pos + separator.size()); |             start = pos = (pos + separator.size()); | ||||||
|             if (result.size() == options.limitParts - 1) |             if (numEmitted == options.limitParts - 1) | ||||||
|             { |             { | ||||||
|                 if (options.ignoreEmpty) |                 if (options.ignoreEmpty) | ||||||
|                 { |                 { | ||||||
| @ -120,14 +128,14 @@ std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_ | |||||||
|                         pos += separator.size(); |                         pos += separator.size(); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 result.emplace_back(pos, end); |                 emit(std::string_view(pos, end)); | ||||||
|                 return result; |                 return; | ||||||
|             } |             } | ||||||
|             if (!options.ignoreEmpty && pos == end) |             if (!options.ignoreEmpty && pos == end) | ||||||
|             { |             { | ||||||
|                 // skipped a separator at the very end, add an empty entry
 |                 // skipped a separator at the very end, add an empty entry
 | ||||||
|                 result.emplace_back(""); |                 emit(""); | ||||||
|                 return result; |                 return; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
| @ -138,9 +146,37 @@ std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_ | |||||||
| 
 | 
 | ||||||
|     if (start != end) |     if (start != end) | ||||||
|     { |     { | ||||||
|         result.emplace_back(start, end); |         emit(std::string_view(start, end)); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | template<typename TChar, typename TTraits> | ||||||
|  | std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_view<TChar, TTraits> stringView, | ||||||
|  |                                                               std::basic_string_view<TChar, TTraits> separator, | ||||||
|  |                                                               const SplitOptions& options) | ||||||
|  | { | ||||||
|  |     std::vector<std::basic_string_view<TChar, TTraits>> result; | ||||||
|  |     std::size_t numEmitted = 0; | ||||||
|  |     splitImpl(stringView, separator, options, std::back_inserter(result), numEmitted); | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | template<std::size_t count, typename TChar, typename TTraits> | ||||||
|  | std::array<std::basic_string_view<TChar, TTraits>, count> splitFixedImpl(std::basic_string_view<TChar, TTraits> stringView, | ||||||
|  |                                                                          std::basic_string_view<TChar, TTraits> separator, | ||||||
|  |                                                                          SplitOptions options, | ||||||
|  |                                                                          std::size_t* outNumResults) | ||||||
|  | { | ||||||
|  |     options.limitParts = count; | ||||||
|  | 
 | ||||||
|  |     std::array<std::basic_string_view<TChar, TTraits>, count> result; | ||||||
|  |     std::size_t numEmitted = 0; | ||||||
|  |     splitImpl(stringView, separator, options, result.begin(), numEmitted); | ||||||
|  |     if (outNumResults != nullptr) | ||||||
|  |     { | ||||||
|  |         *outNumResults = numEmitted; | ||||||
|  |     } | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -201,6 +237,13 @@ template<typename TLeft, typename TRight> | |||||||
|                              std::basic_string_view(std::forward<TRight>(separator)), options); |                              std::basic_string_view(std::forward<TRight>(separator)), options); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | template<std::size_t count, typename TLeft, typename TRight> | ||||||
|  | [[nodiscard]] auto splitFixed(TLeft&& stringView, TRight&& separator, SplitOptions options = {}, std::size_t* outNumResults = nullptr) | ||||||
|  | { | ||||||
|  |     return detail::splitFixedImpl<count>(std::basic_string_view(std::forward<TLeft>(stringView)), | ||||||
|  |                                          std::basic_string_view(std::forward<TRight>(separator)), options, outNumResults); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| template<typename TString, typename TChars> | template<typename TString, typename TChars> | ||||||
| [[nodiscard]] | [[nodiscard]] | ||||||
| auto trimPrefix(TString&& string, TChars&& chars) | auto trimPrefix(TString&& string, TChars&& chars) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user