diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6a0e1e05..0b57e2a0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1072,7 +1072,7 @@ foreach(tgt dwarfs_common dwarfs_reader dwarfs_writer dwarfs_extractor dwarfs_to
set_target_properties(${tgt} PROPERTIES EXPORT_COMPILE_COMMANDS ON)
target_link_libraries(${tgt} PUBLIC Boost::boost)
- target_link_libraries(${tgt} PRIVATE dwarfs_folly_lite dwarfs_thrift_lite)
+ target_link_libraries(${tgt} PRIVATE dwarfs_folly_lite dwarfs_thrift_lite range-v3::range-v3)
if(USE_JEMALLOC)
target_link_libraries(${tgt} PRIVATE PkgConfig::JEMALLOC)
diff --git a/include/dwarfs/string.h b/include/dwarfs/string.h
new file mode 100644
index 00000000..1ceb7552
--- /dev/null
+++ b/include/dwarfs/string.h
@@ -0,0 +1,73 @@
+/* vim:set ts=2 sw=2 sts=2 et: */
+/**
+ * \author Marcus Holland-Moritz (github@mhxnet.de)
+ * \copyright Copyright (c) Marcus Holland-Moritz
+ *
+ * This file is part of dwarfs.
+ *
+ * dwarfs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * dwarfs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with dwarfs. If not, see .
+ */
+
+#pragma once
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+namespace dwarfs {
+
+template
+auto split_view(Input&& input, Delim&& delim) {
+ return std::forward(input) |
+ ranges::views::split(std::forward(delim)) |
+ ranges::views::transform([](auto&& rng) {
+ return T(&*rng.begin(), ranges::distance(rng));
+ });
+}
+
+template
+auto split_view(char const* input, Delim&& delim) {
+ return split_view(std::string_view(input), std::forward(delim));
+}
+
+template
+R split_to(Input&& input, Delim&& delim) {
+ return split_view(std::forward(input),
+ std::forward(delim)) |
+ ranges::to;
+}
+
+template
+R split_to(char const* input, Delim&& delim) {
+ return split_to(std::string_view(input), std::forward(delim));
+}
+
+template
+void split_to(Input&& input, Delim&& delim, Container& container) {
+ ranges::copy(split_view(
+ std::forward(input), std::forward(delim)),
+ std::inserter(container, container.end()));
+}
+
+template
+void split_to(char const* input, Delim&& delim, Container& container) {
+ split_to(std::string_view(input), std::forward(delim), container);
+}
+
+} // namespace dwarfs
diff --git a/src/dwarfs/options.cpp b/src/dwarfs/options.cpp
index 0bfb8f8e..df9a2d5b 100644
--- a/src/dwarfs/options.cpp
+++ b/src/dwarfs/options.cpp
@@ -26,10 +26,9 @@
#include
-#include
-
#include
#include
+#include
namespace dwarfs {
@@ -147,15 +146,13 @@ fsinfo_features fsinfo_features::for_level(int level) {
fsinfo_features fsinfo_features::parse(std::string_view features) {
fsinfo_features result;
- for (auto const& f : features | ranges::views::split(',')) {
- // TODO: This should be much simpler with C++23
- std::string_view fsv(&*f.begin(), ranges::distance(f));
+ for (auto const& f : split_view(features, ',')) {
auto const it =
std::find_if(fsinfo_feature_names.begin(), fsinfo_feature_names.end(),
- [&fsv](auto const& p) { return fsv == p.second; });
+ [&f](auto const& p) { return f == p.second; });
if (it == fsinfo_feature_names.end()) {
- DWARFS_THROW(runtime_error, fmt::format("invalid feature: \"{}\"", fsv));
+ DWARFS_THROW(runtime_error, fmt::format("invalid feature: \"{}\"", f));
}
result |= it->first;
diff --git a/src/dwarfs_main.cpp b/src/dwarfs_main.cpp
index 0c582dc0..bc3a1503 100644
--- a/src/dwarfs_main.cpp
+++ b/src/dwarfs_main.cpp
@@ -45,7 +45,6 @@
#include
-#include
#include
#include
@@ -95,6 +94,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -1431,9 +1431,7 @@ void load_filesystem(dwarfs_userdata& userdata) {
std::optional perfmon_trace_file;
#if DWARFS_PERFMON_ENABLED
if (opts.perfmon_enabled_str) {
- folly::splitTo(
- '+', opts.perfmon_enabled_str,
- std::inserter(perfmon_enabled, perfmon_enabled.begin()));
+ split_to(opts.perfmon_enabled_str, '+', perfmon_enabled);
}
if (opts.perfmon_trace_file_str) {
perfmon_trace_file = userdata.iol.os->canonical(std::filesystem::path(
diff --git a/src/dwarfsextract_main.cpp b/src/dwarfsextract_main.cpp
index afa15a6a..cddcc721 100644
--- a/src/dwarfsextract_main.cpp
+++ b/src/dwarfsextract_main.cpp
@@ -26,8 +26,6 @@
#include
-#include
-
#include
#include
#include
@@ -38,6 +36,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -156,9 +155,7 @@ int dwarfsextract_main(int argc, sys_char** argv, iolayer const& iol) {
std::optional perfmon_trace_file;
#if DWARFS_PERFMON_ENABLED
if (!perfmon_str.empty()) {
- folly::splitTo(
- ',', perfmon_str,
- std::inserter(perfmon_enabled, perfmon_enabled.begin()));
+ split_to(perfmon_str, ',', perfmon_enabled);
}
if (!trace_file.empty()) {
perfmon_trace_file = iol.os->canonical(trace_file);
diff --git a/src/mkdwarfs_main.cpp b/src/mkdwarfs_main.cpp
index 7ab802e2..4e31bc25 100644
--- a/src/mkdwarfs_main.cpp
+++ b/src/mkdwarfs_main.cpp
@@ -46,15 +46,12 @@
#include
#include
-#include
-
#include
#if FMT_VERSION >= 110000
#include
#endif
#include
-#include
#include
#include
@@ -84,6 +81,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -865,10 +863,8 @@ int mkdwarfs_main(int argc, sys_char** argv, iolayer const& iol) {
rw_opts.recompress_categories_exclude = true;
input.remove_prefix(1);
}
- folly::splitTo(
- ',', input,
- std::inserter(rw_opts.recompress_categories,
- rw_opts.recompress_categories.end()));
+ rw_opts.recompress_categories =
+ split_to>(input, ',');
}
}
@@ -956,8 +952,8 @@ int mkdwarfs_main(int argc, sys_char** argv, iolayer const& iol) {
chmod_str = "ug-st,=Xr";
}
- std::vector chmod_exprs;
- folly::split(',', chmod_str, chmod_exprs);
+ auto chmod_exprs =
+ split_to>(chmod_str, ',');
auto mask = get_current_umask();
@@ -1021,8 +1017,8 @@ int mkdwarfs_main(int argc, sys_char** argv, iolayer const& iol) {
options.pack_symlinks = true;
options.pack_symlinks_index = false;
} else {
- std::vector pack_opts;
- folly::split(',', pack_metadata, pack_opts);
+ auto pack_opts =
+ split_to>(pack_metadata, ',');
for (auto const& opt : pack_opts) {
if (opt == "chunk_table") {
options.pack_chunk_table = true;
@@ -1156,8 +1152,8 @@ int mkdwarfs_main(int argc, sys_char** argv, iolayer const& iol) {
}
if (!categorizer_list.value.empty()) {
- std::vector categorizers;
- folly::split(',', categorizer_list.value, categorizers);
+ auto categorizers =
+ split_to>(categorizer_list.value, ',');
options.inode.categorizer_mgr = std::make_shared(lgr);