allow split_args to take a lambda

master
Daniel Kolesa 2017-05-11 23:49:51 +02:00
parent d4edafa350
commit 5fc674e4d3
2 changed files with 17 additions and 15 deletions

View File

@ -125,9 +125,9 @@ static std::string get_command(strvec const &args) {
} }
static void add_args(strvec &args, std::string const &cmdl) { static void add_args(strvec &args, std::string const &cmdl) {
auto app = ostd::appender(std::move(args)); ostd::split_args([&args](ostd::string_range arg) {
ostd::split_args(app, cmdl); args.emplace_back(arg);
args = std::move(app.get()); }, cmdl);
} }
static fs::path path_with_ext(fs::path const &p, fs::path const &ext) { static fs::path path_with_ext(fs::path const &p, fs::path const &ext) {

View File

@ -54,12 +54,12 @@ namespace detail {
* is assumed to be UTF-8 and the output strings are always UTF-8, on POSIX * is assumed to be UTF-8 and the output strings are always UTF-8, on POSIX
* the wordexp implementation is followed (so it's locale specific). * the wordexp implementation is followed (so it's locale specific).
* *
* The `out` argument is an output range that takes a single argument at * The `out` argument can be an output range that takes a single argument
* a time. The value type is any that can be explicitly constructed from * at a time. The value type is an ostd::string_range. If it's not an output
* an ostd::string_range. However, the string range that is used internally * range, it has to be a function that takes the ostd::string_range. However,
* during the conversions is just temporary and freed at the end of this * the string range that is used internally during the conversions is just
* function, so it's important that the string type holds its own memory; * temporary and freed at the end of this function, so it's important that
* an std::string will usually suffice. * it's copied in the range or the lambda.
* *
* The ostd::word_error exception is used to handle failures of this * The ostd::word_error exception is used to handle failures of this
* function itself. It may also throw other exceptions though, particularly * function itself. It may also throw other exceptions though, particularly
@ -71,14 +71,16 @@ namespace detail {
* @throws ostd::word_error on failure or anything thrown by `out`. * @throws ostd::word_error on failure or anything thrown by `out`.
* @throws std::bad_alloc on alloation failures. * @throws std::bad_alloc on alloation failures.
*/ */
template<typename OutputRange> template<typename Sink>
OutputRange &&split_args(OutputRange &&out, string_range str) { Sink &&split_args(Sink &&out, string_range str) {
detail::split_args_impl(str, [](string_range val, void *outp) { detail::split_args_impl(str, [](string_range val, void *outp) {
static_cast<std::decay_t<OutputRange> *>(outp)->put( if constexpr(is_output_range<std::decay_t<Sink>>) {
range_value_t<std::decay_t<OutputRange>>{val} static_cast<std::decay_t<Sink> *>(outp)->put(val);
); } else {
(*static_cast<std::decay_t<Sink> *>(outp))(val);
}
}, &out); }, &out);
return std::forward<OutputRange>(out); return std::forward<Sink>(out);
} }
/** @brief Thrown on errors in ostd::subprocess. */ /** @brief Thrown on errors in ostd::subprocess. */