Why entry
is empty inside boost::adaptors::transformed()
?
I tried without filter, but it does not help.
#include <boost/range/adaptors.hpp>
#include <boost/static_string/static_string.hpp>
#include <boost/utility/string_view.hpp>
#include <filesystem>
int main() {
std::filesystem::path root = ".";
const auto names =
boost::make_iterator_range(std::filesystem::directory_iterator(root),
std::filesystem::directory_iterator{}) |
boost::adaptors::filtered([](const std::filesystem::directory_entry& entry) {
const auto name = entry.path().stem().string();
const auto suff = entry.path().extension().string();
return suff == ".cfg" && !boost::string_view(name).starts_with("__");
}) |
boost::adaptors::transformed([](const std::filesystem::directory_entry& entry) {
auto result = boost::static_string<64>{};
result = entry.path().stem().string();
return result;
});
}
CodePudding user response:
I have copied your image into a self-contained program an cannot see your issue:
#include <boost/range/adaptors.hpp>
#include <boost/static_string/static_string.hpp>
#include <boost/utility/string_view.hpp>
#include <filesystem>
#include <iostream>
int main() {
std::filesystem::path root = ".";
const auto names =
boost::make_iterator_range(std::filesystem::directory_iterator(root),
std::filesystem::directory_iterator{}) |
boost::adaptors::filtered([](const std::filesystem::directory_entry& entry) {
const auto name = entry.path().stem().string();
const auto suff = entry.path().extension().string();
return suff == ".cfg" && !boost::string_view(name).starts_with("__");
}) |
boost::adaptors::transformed([](const std::filesystem::directory_entry& entry) {
auto result = boost::static_string<64>{};
result = entry.path().stem().string();
return result;
});
for (auto&& name : names) {
std::cout << " - " << name << "\n";
}
}
Creating some files like:
touch test{001..022}.cfg
touch __hidden.cfg
Prints
- test001
- test006
- test013
- test017
- test015
- test021
- test008
- test012
- test016
- test002
- test007
- test005
- test010
- test009
- test020
- test014
- test019
- test022
- test018
- test011
- test004
- test003
BONUS
Simplification and style:
#include <boost/range/adaptors.hpp>
#include <boost/static_string/static_string.hpp>
#include <boost/utility/string_view.hpp>
#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
bool is_config(fs::path const& p) {
auto name = p.stem().string();
return p.extension() == ".cfg" &&
!boost::string_view(name).starts_with("__");
};
auto stem(fs::path const& p) { return boost::static_string<64>{p.stem().string()}; }
auto cfgs(fs::path root) {
using namespace boost::adaptors;
auto files = boost::make_iterator_range(fs::directory_iterator(root), {});
return files | filtered(is_config) | transformed(stem);
}
int main() {
for (auto cfg : cfgs("."))
std::cout << " - " << cfg << "\n";
}
Same output, obviously.
CodePudding user response:
UPDATE
const auto root = std::filesystem::path(".");
const auto names = boost::make_iterator_range(
std::filesystem::directory_iterator(root),
std::filesystem::directory_iterator {}
) |
boost::adaptors::filtered([](const std::filesystem::directory_entry& entry)
{
const auto name = entry.path().stem().string();
const auto suff = entry.path().extension().string();
return suff == ".cfg" && !boost::string_view(name).starts_with("__");
}) |
boost::adaptors::transformed([](const std::filesystem::directory_entry& entry)
{
auto result = boost::static_string<64>{};
result = entry.path().stem().string();
std::cout << result << std::endl;
return result;
});
// NEW LINES !!!
std::cout << boost::size(names) << std::endl;
std::cout << boost::size(names) << std::endl;
First call of boost::size()
returns right count of names, but second returns 1. I think this is a special behavior of the std::filesystem::directory_iterator