#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);
ExpressionObj v = ARG("$key", Expression);
try {
ValueObj 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);
ExpressionObj 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;
}
}
}