diff --git a/include/ircd/js/for_each.h b/include/ircd/js/for_each.h index 8b1514cbe..efe3afba6 100644 --- a/include/ircd/js/for_each.h +++ b/include/ircd/js/for_each.h @@ -25,50 +25,32 @@ namespace ircd { namespace js { -using closure_id = std::function; -using closure_key_val = std::function; -using closure_mutable_key_val = std::function; - -void for_each(object::handle, const closure_id &); -void for_each(object::handle, const closure_key_val &); -void for_each(object::handle_mutable, const closure_mutable_key_val &); - - -inline void -for_each(object::handle_mutable obj, - const closure_mutable_key_val &closure) +enum class iter { - for_each(obj, [&obj, &closure] - (const id &hid) - { - value val(get(obj, hid)); - const value key(hid); - closure(key, val); - }); -} + none = 0, + enumerate = JSITER_ENUMERATE, + for_each = JSITER_FOREACH, + key_val = JSITER_KEYVALUE, + own_only = JSITER_OWNONLY, + hidden = JSITER_HIDDEN, + symbols = JSITER_SYMBOLS, + symbols_only = JSITER_SYMBOLSONLY, +}; -inline void -for_each(object::handle obj, - const closure_key_val &closure) -{ - for_each(obj, [&obj, &closure] - (const id &hid) - { - const value val(get(obj, hid)); - const value key(hid); - closure(key, val); - }); -} +// Key iteration (as id type) +using each_id = std::function; +void for_each(object::handle, const iter &flags, const each_id &); +void for_each(object::handle, const each_id &); -inline void -for_each(object::handle obj, - const closure_id &closure) -{ - JS::Rooted props(*cx, JS::IdVector(cx->ptr())); - if(JS_Enumerate(*cx, obj, &props)) - for(size_t i(0); i < props.length(); ++i) - closure(props[i]); -} +// Key iteration (as value) +using each_key = std::function; +void for_each(object::handle, const each_key &); +void for_each(object::handle, const iter &flags, const each_key &); + +// Key/Value iteration (as value => value) +using each_key_val = std::function; +void for_each(object::handle, const each_key_val &); +void for_each(object::handle, const iter &flags, const each_key_val &); } // namespace js } // namespace ircd diff --git a/ircd/js.cc b/ircd/js.cc index 232c0f51f..fa41067b8 100644 --- a/ircd/js.cc +++ b/ircd/js.cc @@ -1328,6 +1328,70 @@ noexcept // ircd/js/function.h // +/////////////////////////////////////////////////////////////////////////////// +// +// ircd/js/for_each.h +// + +void +ircd::js::for_each(object::handle obj, + const each_key_val &closure) +{ + for_each(obj, iter::none, closure); +} + +void +ircd::js::for_each(object::handle obj, + const iter &flags, + const each_key_val &closure) +{ + for_each(obj, flags, each_id([&obj, &closure] + (const id &hid) + { + const value val(get(obj, hid)); + const value key(hid); + closure(key, val); + })); +} + +void +ircd::js::for_each(object::handle obj, + const each_key &closure) +{ + for_each(obj, iter::none, closure); +} + +void +ircd::js::for_each(object::handle obj, + const iter &flags, + const each_key &closure) +{ + for_each(obj, flags, each_id([&obj, &closure] + (const id &id) + { + const value key(id); + closure(key); + })); +} + +void +ircd::js::for_each(object::handle obj, + const each_id &closure) +{ + for_each(obj, iter::none, closure); +} + +void +ircd::js::for_each(object::handle obj, + const iter &flags, + const each_id &closure) +{ + vector props; + if(::js::GetPropertyKeys(*cx, obj, uint(flags), &props)) + for(size_t i(0); i < props.length(); ++i) + closure(props[i]); +} + /////////////////////////////////////////////////////////////////////////////// // // ircd/js/call.h