diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2023-11-02 10:18:50 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2023-11-02 10:18:50 +0200 |
commit | 1c6096e53a906d7821a401d91b32ca02df3d715f (patch) | |
tree | 380d7d9acc6fc186c7c7d18da025613e71526c71 /libbuild2 | |
parent | 2a09b60a4169c151fa89e1d4c979a4b5c40a0252 (diff) |
Add $first()/$second() pair functions
Diffstat (limited to 'libbuild2')
-rw-r--r-- | libbuild2/functions-builtin.cxx | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/libbuild2/functions-builtin.cxx b/libbuild2/functions-builtin.cxx index 13b315c..e24ff8e 100644 --- a/libbuild2/functions-builtin.cxx +++ b/libbuild2/functions-builtin.cxx @@ -101,6 +101,64 @@ namespace build2 // f["empty"] += [](value* v) {return v->null || v->empty ();}; + + // $first(<value>[, <not_pair>]) + // $second(<value>[, <not_pair>]) + // + // Return the first or the second half of a pair, respectively. If a value + // is not a pair, then return `null` unless the <not_pair> argument is + // `true`, in which case return the non-pair value. + // + // If multiple pairs are specified, then return the list of first/second + // halfs. If an element is not a pair, then omit it from the resulting + // list unless the <not_pair> argument is `true`, in which case add the + // non-pair element to the list. + // + f["first"] += [] (names ns, optional<value> not_pair) + { + // @@ TODO: would be nice to return typed half if passed typed value. + + bool np (not_pair && convert<bool> (move (*not_pair))); + + names r; + for (auto i (ns.begin ()), e (ns.end ()); i != e; ) + { + name& f (*i++); + name* s (f.pair ? &*i++ : nullptr); + + if (s != nullptr || np) + { + f.pair = '\0'; + r.push_back (move (f)); + } + else if (ns.size () == 1) + return value (nullptr); // Single non-pair. + } + + return value (move (r)); + }; + + f["second"] += [] (names ns, optional<value> not_pair) + { + bool np (not_pair && convert<bool> (move (*not_pair))); + + names r; + for (auto i (ns.begin ()), e (ns.end ()); i != e; ) + { + name& f (*i++); + name* s (f.pair ? &*i++ : nullptr); + + if (s != nullptr) + r.push_back (move (*s)); + else if (np) + r.push_back (move (f)); + else if (ns.size () == 1) + return value (nullptr); // Single non-pair. + } + + return value (move (r)); + }; + // Leave this one undocumented for now since it's unclear why would anyone // want to use it currently (we don't yet have any function composition // facilities). @@ -110,7 +168,7 @@ namespace build2 // $quote(<value>[, <escape>]) // // Quote the value returning its string representation. If <escape> is - // true, then also escape (with a backslash) the quote characters being + // `true`, then also escape (with a backslash) the quote characters being // added (this is useful if the result will be re-parsed, for example as a // script command line). // |