cppitertools
cppitertools copied to clipboard
arguments for product
- in many use cases, the number of arguments for a function like this is known only at run time. is it possible for product to accept a vector object?
- or add something equivalent to Python's unpacking operator (*) to cppitertools?
Can you show me an example of how you'd like to call the function? So that I understand your intent
Toy example:
vector
vector<vector<vector
for(auto&& combo: combos){ for(auto&& prod: product(combo){ // combo would therefore vary in size per iteration // do something with each prod } }
I suppose an implementation of an unpacking operator (similar to Python's) would make product() work without modification (e.g., product(*vector)), if this is practically feasible.
On Fri, Oct 13, 2017 at 11:24 AM, Ryan Haining [email protected] wrote:
Can you show me an example of how you'd like to call the function? So that I understand your intent
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ryanhaining/cppitertools/issues/41#issuecomment-336340079, or mute the thread https://github.com/notifications/unsubscribe-auth/AfPVx0o796p8Sm2ajeCFBEWolDTQA9YYks5srtf_gaJpZM4P37DM .
You can do an "unpack" with a tuple, pair, even std::array, any time the size is known at compile time (see iter::starmap) but you can't send a variable number of arguments when you don't know the length until run time. Supporting what you want would require an entire new implementation, not saying I won't do it but it's not an easy modification.
Thanks for considering the suggestion. For whatever it's worth, here's some code I picked up from D Forum that might help. I believe this is a functor that implements a cartesian product function that accepts a variable number of items contained in an array.
D code posted by Era Scarecrow on D Forum:
struct MultiCart(T) { T[][] data; int iteration; int max;
this(T[][] _d, int iter=0) {
data = _d;
iteration = iter;
max = 1;
foreach(a; _d) {
if (a.length)
max *= a.length;
}
}
T[] front() {
int i = iteration;
T[] val;
foreach(d; data) {
if (d.length) {
val ~= d[i % d.length];
i /= d.length;
}
}
return val;
}
void popFront() {
iteration++;
}
bool empty() {
return iteration = max;
}
}
unittest { import std.stdio; alias CartInt = MultiCart!int;
int[] a=[1,2,3],b=[4,5],c=[6,7];
foreach(x; CartInt([a,b,c]))
writeln(x);
foreach(x; CartInt([a,b]))
writeln(x);
}
It could probably use some minor cleanup, documentation and proper unittests and constraints, moving to unsigned size_t; If front is used more than once than there's inefficiency with memory and remaking the array it builds (among other things). Could even make an opIndex for creating specific iterations of the results.
On Sun, Oct 15, 2017 at 8:08 AM, Ryan Haining [email protected] wrote:
You can do an "unpack" with a tuple, pair, even std::array, any time the size is known at compile time (see iter::starmap but you can't send a variable number of arguments when you don't know the length until run time. Supporting what you want would require an entire new implementation, not saying I won't do it but it's not an easy modification.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ryanhaining/cppitertools/issues/41#issuecomment-336676241, or mute the thread https://github.com/notifications/unsubscribe-auth/AfPVx3CVU1r4tvK0-DdgicqlqBeQ96zCks5ssUzlgaJpZM4P37DM .
I used boost lexical_cast to read the tuple elements into a string. Very efficient.