diff options
Diffstat (limited to 'liblfjail/words.hh')
| -rw-r--r-- | liblfjail/words.hh | 94 |
1 files changed, 34 insertions, 60 deletions
diff --git a/liblfjail/words.hh b/liblfjail/words.hh index a9f7114..4b1209b 100644 --- a/liblfjail/words.hh +++ b/liblfjail/words.hh @@ -17,15 +17,13 @@ namespace lfjail { * words: take a string-like object and split it into words using the given * predicate. Empty values are discarded (i.e., repeated separators are * ignored). - * - * words() returns std::strings, while wordsv() return std::string_views - * which refer to the original string. */ namespace detail { -template<typename R, typename Pred> -auto split(std::string_view text, Pred &&pred) -> std::generator<R> +template<std::ranges::range Range, + std::indirect_unary_predicate<std::ranges::iterator_t<Range>> Pred> +auto split(Range &&text, Pred pred) -> std::generator<std::string> { auto pos = std::ranges::begin(text); auto end = std::ranges::end(text); @@ -42,86 +40,62 @@ auto split(std::string_view text, Pred &&pred) -> std::generator<R> auto split_pos = std::find_if(pos, end, pred); // Yield this word. - co_yield R(pos, split_pos); + co_yield std::string(pos, split_pos); pos = split_pos; } } +template<typename Pred> +struct words_fn : std::ranges::range_adaptor_closure<words_fn<Pred>> { + words_fn(Pred p) : _pred(std::move(p)) {} -template<typename ValueType, - std::ranges::viewable_range Range, - std::indirect_unary_predicate<std::ranges::iterator_t<Range>> Pred> -requires (std::ranges::contiguous_range<Range>) -struct words_view : - std::ranges::view_interface<words_view<ValueType, Range, Pred>> -{ - words_view(auto &&base, auto &&pred) - : _base(std::forward<decltype(base)>(base)) - , _pred(std::forward<decltype(pred)>(pred)) - , _generator(detail::split<ValueType>( - std::string_view(_base), _pred)) - {} - - auto begin(this auto const &self) { - return self._generator.begin(); - } - - auto end(this auto const &self) { - return self._generator.end(); + template<std::ranges::range Range> + constexpr auto operator()(Range &&range) const { + return detail::split(std::forward<Range>(range), + std::move(_pred)); } private: - Range _base; Pred _pred; - - mutable std::generator<ValueType> _generator; -}; - -template<typename R> -struct words_impl : std::ranges::range_adaptor_closure<words_impl<R>> { - template<std::ranges::range Range, typename Pred> - constexpr auto operator()(Range &&range, Pred &&pred) const { - return words_view<R, Range, Pred>( - std::forward<decltype(range)>(range), - std::forward<decltype(pred)>(pred)); - } }; } // namespace detail template<std::ranges::range Range, std::indirect_unary_predicate<std::ranges::iterator_t<Range>> Pred> -auto words(Range &&range, Pred &&pred) - requires (std::ranges::borrowed_range<Range>) -{ - return detail::words_impl<std::string_view>{}( - std::forward<Range>(range), - std::forward<Pred>(pred)); -} - -template<std::ranges::range Range, - std::indirect_unary_predicate<std::ranges::iterator_t<Range>> Pred> -auto words(Range &&range, Pred &&pred) - requires (!std::ranges::borrowed_range<Range>) +auto words(Range &&range, Pred pred) { - return detail::words_impl<std::string>{}( - std::forward<Range>(range), - std::forward<Pred>(pred)); + return detail::split(std::forward<Range>(range), std::move(pred)); } -template<std::ranges::range Range> -auto words(Range &&range, std::ranges::range_value_t<Range> ch) -{ +template<std::ranges::viewable_range Range, std::integral Char> +auto words(Range &&range, Char ch) { return words(std::forward<Range>(range), [ch](auto c) { return c == ch; }); } -template<std::ranges::range Range> -auto words(Range &&range) -{ +template<std::ranges::viewable_range Range> +auto words(Range &&range) { return words(std::forward<Range>(range), is_c_space); } +template<typename Pred> +requires(!std::integral<Pred> && !std::ranges::range<Pred>) +auto words(Pred pred) { + return detail::words_fn(std::move(pred)); +} + +auto words() { + return words(is_c_space); +} + +template<std::integral Char> +auto words(Char ch) { + return words([ch](auto c) { return c == ch; }); +} + +//constexpr words_impl words{}; + } // namespace lfjail #endif // LIBLFJAIL_WORDS_HH |
