aboutsummaryrefslogtreecommitdiffstats
path: root/liblfjail/words.hh
diff options
context:
space:
mode:
Diffstat (limited to 'liblfjail/words.hh')
-rw-r--r--liblfjail/words.hh94
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