Add concatStringsSep as a primop

This fixes the quadratic behaviour of concatStrings/concatStringsSep
in Nixpkgs.
This commit is contained in:
Eelco Dolstra 2015-07-24 02:31:58 +02:00
parent cb4320c1a0
commit 2e8fd4c5cd
3 changed files with 30 additions and 0 deletions

View file

@ -1514,6 +1514,26 @@ static void prim_match(EvalState & state, const Pos & pos, Value * * args, Value
} }
static void prim_concatStringSep(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
PathSet context;
auto sep = state.forceString(*args[0], context, pos);
state.forceList(*args[1]);
string res;
res.reserve((args[1]->listSize() + 32) * sep.size());
bool first = true;
for (unsigned int n = 0; n < args[1]->listSize(); ++n) {
if (first) first = false; else res += sep;
res += state.coerceToString(pos, *args[1]->listElems()[n], context);
}
mkString(v, res, context);
}
/************************************************************* /*************************************************************
* Versions * Versions
*************************************************************/ *************************************************************/
@ -1720,6 +1740,7 @@ void EvalState::createBaseEnv()
addPrimOp("__unsafeDiscardOutputDependency", 1, prim_unsafeDiscardOutputDependency); addPrimOp("__unsafeDiscardOutputDependency", 1, prim_unsafeDiscardOutputDependency);
addPrimOp("__hashString", 2, prim_hashString); addPrimOp("__hashString", 2, prim_hashString);
addPrimOp("__match", 2, prim_match); addPrimOp("__match", 2, prim_match);
addPrimOp("__concatStringsSep", 2, prim_concatStringSep);
// Versions // Versions
addPrimOp("__parseDrvName", 1, prim_parseDrvName); addPrimOp("__parseDrvName", 1, prim_parseDrvName);

View file

@ -0,0 +1 @@
[ "" "foobarxyzzy" "foo, bar, xyzzy" "foo" "" ]

View file

@ -0,0 +1,8 @@
with builtins;
[ (concatStringsSep "" [])
(concatStringsSep "" ["foo" "bar" "xyzzy"])
(concatStringsSep ", " ["foo" "bar" "xyzzy"])
(concatStringsSep ", " ["foo"])
(concatStringsSep ", " [])
]