I need to iterate over folder either recursively or not (given the boolean parameter). I have discovered there is fs::recursive_directory_iterator() and also fs::directory_iterator(). In Java, I would expect them to implement the same interface or share the common ancestor so that I could substitute the needed one. But for some reason the two iterators do not share the common ancestor, forcing the to write the code like:
if (recursive_) {
path = recursive_iterator_->path();
recursive_iterator_++;
} else {
path = plain_iterator_->path();
plain_iterator_++;
}
I cannot believe this is how it is supposed to work. I also initially assumed there are some options to turn off recursion for recursive_directory_iterator but seems no any between std::filesystem::directory_options.
The value is not known at the compile time. I think it should be possible to use something like a closure or even subclass with virtual method but looks a bit like overkill.
Should I simply use conditionals switching between the two iterators as needed, or there are better approaches?
implement the same interface
They do. They are both InputIterators, that dereference to const std::filesystem::directory_entry&.
C++ avoids virtual by default.
You can use boost::any_range to type erase the recursiveness.
template <typename... Args>
auto make_directory_range(bool recursive, Args... args) {
return recursive
? boost::make_iterator_range(fs::recursive_directory_iterator(args...), fs::recursive_directory_iterator()) | boost::adaptors::type_erased()
: boost::make_iterator_range(fs::directory_iterator(args...), fs::directory_iterator());
}
using iterator_t = decltype(make_directory_range(true).begin());
auto range = make_directory_range(recursive_, args...);
iterator_t iterator = range.begin();
iterator_t end = range.end();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With