I'm trying to create a function to generate the Cartesian product of a variable number of input ranges, using the style of the STL. My basic format is that the function accepts a fixed range and the start of an output range, then a variadic number of bidirectional input iterators.
template <
typename BidirectionalIterator,
typename OutputIterator,
typename... Args
>
void cartesian_product(
BidirectionalIterator first,
BidirectionalIterator last,
OutputIterator result,
Args&&... args
);
My idea for the args
is that I make a tuple
out of it, then I iterate through that tuple
to extract the elements. This would require me to follow a few basic steps:
- Make a
tuple
fromargs
- Dereference each iterator in the newly created
tuple
- Increment each iterator in the
tuple
I can do the first step like:
auto arg_tuple = std::make_tuple(std::forward<Args>(args)...);
The second step, I'm not too sure about. I think I will have somehow push_back
elements to a temporary tuple, then set *result
equal to that temporary tuple. I was a little inspired by the way that ostream
accomplishes this, so I think this could come in handy:
template <typename Tuple, typename T>
auto operator<<(const Tuple &lhs, const T &rhs)
-> decltype(std::tuple_cat(lhs, std::make_tuple(rhs)))
{
return std::tuple_cat(lhs, std::make_tuple(rhs));
}
The third step is probably pretty trivial. I could combine something like this:
template <typename T>
auto pre_increment(T &x) -> decltype(++x) {
return ++x;
}
with one of the 3,000 implementations of for_each
for a tuple
that are on here.
Odds are that I'm not correctly leveraging C++14 for this. My education has been entirely on the less-difficult parts of C++11 so far.
If you're tempted to recommend I use boost::fusion
for this, thanks, but I would prefer to not use it.
Aucun commentaire:
Enregistrer un commentaire