summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rspamd.com>2023-06-24 14:55:55 +0100
committerVsevolod Stakhov <vsevolod@rspamd.com>2023-06-24 14:55:55 +0100
commit8c1c1ddd88a2ea84ca937fce536553cc4b8cd3da (patch)
tree346cc7bbd28d6d36440ef81738b3b7fadcd6bb53 /src
parentf89a5b762d489e9b0dd2a5302b02002cff7f351b (diff)
downloadrspamd-8c1c1ddd88a2ea84ca937fce536553cc4b8cd3da.tar.gz
rspamd-8c1c1ddd88a2ea84ca937fce536553cc4b8cd3da.zip
[Minor] Add utility to iterate over a list of newline separated strings
Diffstat (limited to 'src')
-rw-r--r--src/libutil/cxx/util.hxx29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/libutil/cxx/util.hxx b/src/libutil/cxx/util.hxx
index 88a022954..6faba9277 100644
--- a/src/libutil/cxx/util.hxx
+++ b/src/libutil/cxx/util.hxx
@@ -66,6 +66,35 @@ inline constexpr auto make_string_view_from_it(_It begin, _It end)
}
/**
+ * Iterate over lines in a string, newline characters are dropped
+ * @tparam S
+ * @tparam F
+ * @param input
+ * @param functor
+ * @return
+ */
+template<class S, class F, typename std::enable_if_t<std::is_invocable_v<F, std::string_view> &&
+ std::is_constructible_v<std::string_view, S>, bool> = true>
+inline auto string_foreach_line(const S &input, const F &functor)
+{
+ auto it = input.begin();
+ auto end = input.end();
+
+ while (it != end) {
+ auto next = std::find(it, end, '\n');
+ while (next >= it && (*next == '\n' || *next == '\r')) {
+ --next;
+ }
+ functor(make_string_view_from_it(it, next));
+ it = next;
+
+ if (it != end) {
+ ++it;
+ }
+ }
+}
+
+/**
* Enumerate for range loop
*/
template <typename T,