From dc9f129060d44f6af4c2c0abe267ee410f826171 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Mon, 15 May 2017 15:59:44 +0200 Subject: [PATCH] Implement the Array#any and Array#all protoype functions --- doc/18-library-reference.md | 18 +++++++++++++++++ lib/base/array-script.cpp | 39 +++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/doc/18-library-reference.md b/doc/18-library-reference.md index 9d8cbc0ca..2dd41d69f 100644 --- a/doc/18-library-reference.md +++ b/doc/18-library-reference.md @@ -1148,6 +1148,24 @@ Signature: Returns a copy of the array containing only the elements for which `func(element)` is true. +### Array#any + +Signature: + + function any(func); + +Returns true if the array contains at least one element for which `func(element)` +is true, false otherwise. + +### Array#all + +Signature: + + function all(func); + +Returns true if the array contains only elements for which `func(element)` +is true, false otherwise. + ### Array#unique Signature: diff --git a/lib/base/array-script.cpp b/lib/base/array-script.cpp index 03ae2cae8..568037d9e 100644 --- a/lib/base/array-script.cpp +++ b/lib/base/array-script.cpp @@ -207,6 +207,43 @@ static Array::Ptr ArrayFilter(const Function::Ptr& function) return result; } +static bool ArrayAny(const Function::Ptr& function) +{ + ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); + Array::Ptr self = static_cast(vframe->Self); + + if (vframe->Sandboxed && !function->IsSideEffectFree()) + BOOST_THROW_EXCEPTION(ScriptError("Filter function must be side-effect free.")); + + ObjectLock olock(self); + for (const Value& item : self) { + std::vector args; + args.push_back(item); + if (function->Invoke(args)) + return true; + } + + return false; +} + +static bool ArrayAll(const Function::Ptr& function) +{ + ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); + Array::Ptr self = static_cast(vframe->Self); + + if (vframe->Sandboxed && !function->IsSideEffectFree()) + BOOST_THROW_EXCEPTION(ScriptError("Filter function must be side-effect free.")); + + ObjectLock olock(self); + for (const Value& item : self) { + std::vector args; + args.push_back(item); + if (!function->Invoke(args)) + return false; + } + + return true; +} static Array::Ptr ArrayUnique(void) { ScriptFrame *vframe = ScriptFrame::GetCurrentFrame(); @@ -242,6 +279,8 @@ Object::Ptr Array::GetPrototype(void) prototype->Set("map", new Function("Array#map", WrapFunction(ArrayMap), { "func" }, true)); prototype->Set("reduce", new Function("Array#reduce", WrapFunction(ArrayReduce), { "reduce" }, true)); prototype->Set("filter", new Function("Array#filter", WrapFunction(ArrayFilter), { "func" }, true)); + prototype->Set("any", new Function("Array#any", WrapFunction(ArrayAny), { "func" }, true)); + prototype->Set("all", new Function("Array#all", WrapFunction(ArrayAll), { "func" }, true)); prototype->Set("unique", new Function("Array#unique", WrapFunction(ArrayUnique), {}, true)); }