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 | ||||
| { | ||||
| template<typename TChar, typename TTraits> | ||||
| std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_view<TChar, TTraits> stringView, | ||||
| template<typename TChar, typename TTraits, typename TOutIterator> | ||||
| void splitImpl(std::basic_string_view<TChar, TTraits> stringView, | ||||
|                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>; | ||||
| 
 | ||||
| @ -84,14 +86,20 @@ std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_ | ||||
| 
 | ||||
|     if (separator.empty()) | ||||
|     { | ||||
|         return {}; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     std::vector<sv_t> result; | ||||
|     auto emit = [&](std::string_view result) | ||||
|     { | ||||
|         *outIterator = result; | ||||
|         ++outIterator; | ||||
|         ++numEmitted; | ||||
|     }; | ||||
| 
 | ||||
|     if (options.limitParts <= 1) | ||||
|     { | ||||
|         result.push_back(stringView); | ||||
|         return result; | ||||
|         emit(stringView); | ||||
|         return; | ||||
|     } | ||||
|     auto start = stringView.begin(); | ||||
|     auto pos = start; | ||||
| @ -108,10 +116,10 @@ std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_ | ||||
|         { | ||||
|             if (!options.ignoreEmpty || pos != start) | ||||
|             { | ||||
|                 result.emplace_back(start, pos); | ||||
|                 emit(std::string_view(start, pos)); | ||||
|             } | ||||
|             start = pos = (pos + separator.size()); | ||||
|             if (result.size() == options.limitParts - 1) | ||||
|             if (numEmitted == options.limitParts - 1) | ||||
|             { | ||||
|                 if (options.ignoreEmpty) | ||||
|                 { | ||||
| @ -120,14 +128,14 @@ std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_ | ||||
|                         pos += separator.size(); | ||||
|                     } | ||||
|                 } | ||||
|                 result.emplace_back(pos, end); | ||||
|                 return result; | ||||
|                 emit(std::string_view(pos, end)); | ||||
|                 return; | ||||
|             } | ||||
|             if (!options.ignoreEmpty && pos == end) | ||||
|             { | ||||
|                 // skipped a separator at the very end, add an empty entry
 | ||||
|                 result.emplace_back(""); | ||||
|                 return result; | ||||
|                 emit(""); | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|         else | ||||
| @ -138,9 +146,37 @@ std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_ | ||||
| 
 | ||||
|     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; | ||||
| } | ||||
| 
 | ||||
| @ -201,6 +237,13 @@ template<typename TLeft, typename TRight> | ||||
|                              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> | ||||
| [[nodiscard]] | ||||
| auto trimPrefix(TString&& string, TChars&& chars) | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user