|
Packit Service |
7770af |
#include "sass.hpp"
|
|
Packit Service |
7770af |
#include "node.hpp"
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
namespace Sass {
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/*
|
|
Packit Service |
7770af |
# This is the equivalent of ruby's Sass::Util.paths.
|
|
Packit Service |
7770af |
#
|
|
Packit Service |
7770af |
# Return an array of all possible paths through the given arrays.
|
|
Packit Service |
7770af |
#
|
|
Packit Service |
7770af |
# @param arrs [NodeCollection<NodeCollection<Node>>]
|
|
Packit Service |
7770af |
# @return [NodeCollection<NodeCollection<Node>>]
|
|
Packit Service |
7770af |
#
|
|
Packit Service |
7770af |
# @example
|
|
Packit Service |
7770af |
# paths([[1, 2], [3, 4], [5]]) #=>
|
|
Packit Service |
7770af |
# # [[1, 3, 5],
|
|
Packit Service |
7770af |
# # [2, 3, 5],
|
|
Packit Service |
7770af |
# # [1, 4, 5],
|
|
Packit Service |
7770af |
# # [2, 4, 5]]
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
The following is the modified version of the ruby code that was more portable to C++. You
|
|
Packit Service |
7770af |
should be able to drop it into ruby 3.2.19 and get the same results from ruby sass.
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
def paths(arrs)
|
|
Packit Service |
7770af |
// I changed the inject and maps to an iterative approach to make it easier to implement in C++
|
|
Packit Service |
7770af |
loopStart = [[]]
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
for arr in arrs do
|
|
Packit Service |
7770af |
permutations = []
|
|
Packit Service |
7770af |
for e in arr do
|
|
Packit Service |
7770af |
for path in loopStart do
|
|
Packit Service |
7770af |
permutations.push(path + [e])
|
|
Packit Service |
7770af |
end
|
|
Packit Service |
7770af |
end
|
|
Packit Service |
7770af |
loopStart = permutations
|
|
Packit Service |
7770af |
end
|
|
Packit Service |
7770af |
end
|
|
Packit Service |
7770af |
*/
|
|
Packit Service |
7770af |
Node paths(const Node& arrs) {
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Node loopStart = Node::createCollection();
|
|
Packit Service |
7770af |
loopStart.collection()->push_back(Node::createCollection());
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
for (NodeDeque::iterator arrsIter = arrs.collection()->begin(), arrsEndIter = arrs.collection()->end();
|
|
Packit Service |
7770af |
arrsIter != arrsEndIter; ++arrsIter) {
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Node& arr = *arrsIter;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Node permutations = Node::createCollection();
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
for (NodeDeque::iterator arrIter = arr.collection()->begin(), arrIterEnd = arr.collection()->end();
|
|
Packit Service |
7770af |
arrIter != arrIterEnd; ++arrIter) {
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Node& e = *arrIter;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
for (NodeDeque::iterator loopStartIter = loopStart.collection()->begin(), loopStartIterEnd = loopStart.collection()->end();
|
|
Packit Service |
7770af |
loopStartIter != loopStartIterEnd; ++loopStartIter) {
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Node& path = *loopStartIter;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Node newPermutation = Node::createCollection();
|
|
Packit Service |
7770af |
newPermutation.got_line_feed = arr.got_line_feed;
|
|
Packit Service |
7770af |
newPermutation.plus(path);
|
|
Packit Service |
7770af |
newPermutation.collection()->push_back(e);
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
permutations.collection()->push_back(newPermutation);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
loopStart = permutations;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
return loopStart;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/*
|
|
Packit Service |
7770af |
This is the equivalent of ruby sass' Sass::Util.flatten and [].flatten.
|
|
Packit Service |
7770af |
Sass::Util.flatten requires the number of levels to flatten, while
|
|
Packit Service |
7770af |
[].flatten doesn't and will flatten the entire array. This function
|
|
Packit Service |
7770af |
supports both.
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
# Flattens the first `n` nested arrays. If n == -1, all arrays will be flattened
|
|
Packit Service |
7770af |
#
|
|
Packit Service |
7770af |
# @param arr [NodeCollection] The array to flatten
|
|
Packit Service |
7770af |
# @param n [int] The number of levels to flatten
|
|
Packit Service |
7770af |
# @return [NodeCollection] The flattened array
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
The following is the modified version of the ruby code that was more portable to C++. You
|
|
Packit Service |
7770af |
should be able to drop it into ruby 3.2.19 and get the same results from ruby sass.
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
def flatten(arr, n = -1)
|
|
Packit Service |
7770af |
if n != -1 and n == 0 then
|
|
Packit Service |
7770af |
return arr
|
|
Packit Service |
7770af |
end
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
flattened = []
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
for e in arr do
|
|
Packit Service |
7770af |
if e.is_a?(Array) then
|
|
Packit Service |
7770af |
flattened.concat(flatten(e, n - 1))
|
|
Packit Service |
7770af |
else
|
|
Packit Service |
7770af |
flattened << e
|
|
Packit Service |
7770af |
end
|
|
Packit Service |
7770af |
end
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
return flattened
|
|
Packit Service |
7770af |
end
|
|
Packit Service |
7770af |
*/
|
|
Packit Service |
7770af |
Node flatten(Node& arr, int n) {
|
|
Packit Service |
7770af |
if (n != -1 && n == 0) {
|
|
Packit Service |
7770af |
return arr;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Node flattened = Node::createCollection();
|
|
Packit Service |
7770af |
if (arr.got_line_feed) flattened.got_line_feed = true;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
for (NodeDeque::iterator iter = arr.collection()->begin(), iterEnd = arr.collection()->end();
|
|
Packit Service |
7770af |
iter != iterEnd; iter++) {
|
|
Packit Service |
7770af |
Node& e = *iter;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// e has the lf set
|
|
Packit Service |
7770af |
if (e.isCollection()) {
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// e.collection().got_line_feed = e.got_line_feed;
|
|
Packit Service |
7770af |
Node recurseFlattened = flatten(e, n - 1);
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
if(e.got_line_feed) {
|
|
Packit Service |
7770af |
flattened.got_line_feed = e.got_line_feed;
|
|
Packit Service |
7770af |
recurseFlattened.got_line_feed = e.got_line_feed;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
for(auto i : (*recurseFlattened.collection())) {
|
|
Packit Service |
7770af |
if (recurseFlattened.got_line_feed) {
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
i.got_line_feed = true;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
flattened.collection()->push_back(i);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
} else {
|
|
Packit Service |
7770af |
flattened.collection()->push_back(e);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
return flattened;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|