I am trying to read/deserialize a list of elements from a file (and then filter out some of them). It is a useful approach to use an iterator for this purpose?
My current try is
#include <boost/iterator/iterator_adaptor.hpp>
class ReadIterator : public boost::iterator_adaptor<ReadIterator, Elem *, boost::single_pass_traversal_tag>
{
public:
explicit ReadIterator(const char *filename) : reader(filename) {}
private:
friend class boost::iterator_core_access;
void increment() {
this->base_reference() = reader.readNext();
}
Reader reader;
};
This does not properly deallocate memory (e.g., readNew returns a pointer to a new Elem), what is the right way to do this? Also, how would one actually use such an iterator, how can the end be determined? Or is there a better approach than using an iterator?
The easy way to do this is to use the std::istream_iterator
std::vector<YourObjectClass> data;
std::remove_copy_if(std::istream_iterator<YourObjectClass>(file),
std::istream_iterator<YourObjectClass>(),
std::back_inserter(data),
YourFilter
);
The standard algorithm copies objects (of type YourObjectClass) from the input file
and places them into the vector data
if the filter functor returns true.
The only conditions are:
Simple Working Example:
Exmpale:
#include <vector>
#include <string>
#include <fstream>
#include <iterator>
#include <algorithm>
struct Line
{
std::string data;
};
std::istream& operator>>(std::istream& stream, Line& line)
{
return std::getline(stream, line.data);
}
struct AFilter
{
bool operator()(Line const& line) const
{
return line.data.size() > 0 && line.data[0] == 'A';
}
};
int main()
{
std::ifstream file("Plop");
std::vector<Line> data;
std::remove_copy_if(std::istream_iterator<Line>(file),
std::istream_iterator<Line>(),
std::back_inserter(data),
AFilter()
);
}