#include "operators.hpp" #include "fn_utils.hpp" #include "fn_maps.hpp" namespace Sass { namespace Functions { ///////////////// // MAP FUNCTIONS ///////////////// Signature map_get_sig = "map-get($map, $key)"; BUILT_IN(map_get) { // leaks for "map-get((), foo)" if not Obj // investigate why this is (unexpected) Map_Obj m = ARGM("$map", Map); Expression_Obj v = ARG("$key", Expression); try { Value_Obj val = m->at(v); if (!val) return SASS_MEMORY_NEW(Null, pstate); val->set_delayed(false); return val.detach(); } catch (const std::out_of_range&) { return SASS_MEMORY_NEW(Null, pstate); } catch (...) { throw; } } Signature map_has_key_sig = "map-has-key($map, $key)"; BUILT_IN(map_has_key) { Map_Obj m = ARGM("$map", Map); Expression_Obj v = ARG("$key", Expression); return SASS_MEMORY_NEW(Boolean, pstate, m->has(v)); } Signature map_keys_sig = "map-keys($map)"; BUILT_IN(map_keys) { Map_Obj m = ARGM("$map", Map); List* result = SASS_MEMORY_NEW(List, pstate, m->length(), SASS_COMMA); for ( auto key : m->keys()) { result->append(key); } return result; } Signature map_values_sig = "map-values($map)"; BUILT_IN(map_values) { Map_Obj m = ARGM("$map", Map); List* result = SASS_MEMORY_NEW(List, pstate, m->length(), SASS_COMMA); for ( auto key : m->keys()) { result->append(m->at(key)); } return result; } Signature map_merge_sig = "map-merge($map1, $map2)"; BUILT_IN(map_merge) { Map_Obj m1 = ARGM("$map1", Map); Map_Obj m2 = ARGM("$map2", Map); size_t len = m1->length() + m2->length(); Map* result = SASS_MEMORY_NEW(Map, pstate, len); // concat not implemented for maps *result += m1; *result += m2; return result; } Signature map_remove_sig = "map-remove($map, $keys...)"; BUILT_IN(map_remove) { bool remove; Map_Obj m = ARGM("$map", Map); List_Obj arglist = ARG("$keys", List); Map* result = SASS_MEMORY_NEW(Map, pstate, 1); for (auto key : m->keys()) { remove = false; for (size_t j = 0, K = arglist->length(); j < K && !remove; ++j) { remove = Operators::eq(key, arglist->value_at_index(j)); } if (!remove) *result << std::make_pair(key, m->at(key)); } return result; } } }