Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Putting a limit on an IO iterator

33 views
Skip to first unread message

Frederick Gotham

unread,
Oct 25, 2019, 5:34:14 AM10/25/19
to

Here's what I'm going right now:


ifstream logfile("/etc/log.txt");

string hex_str;

copy_n( istream_iterator<char>(logfile), sizeof(my_POD_object) * 2u, std::back_inserter(hex_str) );

boost::algorithm::unhex( hex_str.begin(), hex_str.end(), reinterpret_cast<uint8_t*>(&my_POD_object) );


. . .when really I would just prefer to do this:


ifstream logfile("/etc/log.txt");

boost::algorithm::unhex( istream_iterator<char>(logfile), istream_iterator<char>(logfile) + (sizeof(my_POD_object) * 2u), reinterpret_cast<uint8_t*>(&my_POD_object) );

but of course you can't add to an input iterator like that.

Is there some sort of trickery I can do here?


Frederick Gotham

unread,
Oct 26, 2019, 7:09:57 AM10/26/19
to
On Friday, October 25, 2019 at 10:34:14 AM UTC+1, Frederick Gotham wrote:

> but of course you can't add to an input iterator like that.
>
> Is there some sort of trickery I can do here?


Here's what I've got so far for istream_iterator_limited:

#include <cassert>
#include <cstddef> /* size_t */
#include <iterator> /* istream_iterator, back_inserter */
#include <limits> /* numeric_limits */

#include <algorithm> /* copy */
#include <string> /* string */

#include <sstream> /* istringstream */
#include <iostream> /* cout, endl */

template <class T>
class istream_iterator_limited : public std::istream_iterator<T> {
protected:
std::size_t const m_limit;
std::size_t m_current_count;

public:
/* Shorter names */
typedef std::istream_iterator<T> Base;
typedef istream_iterator_limited<T> This;

istream_iterator_limited(typename Base::istream_type &obj_stream, size_t const arg_limit)
: m_current_count(1), m_limit(arg_limit), Base(obj_stream)
{
/* The initialiser list above does all the construction work */

assert(0 != arg_limit);
}

istream_iterator_limited(void) /* This gives the End-Of-Stream iterator */
: m_current_count(1), m_limit(0), Base()
{
/* The initialiser list above does all the construction work */
}

This &operator++(void)
{
if ( m_limit <= m_current_count )
{
Base::operator=( Base() ); /* Becomes End-Of-Stream iterator */
}
else
{
++m_current_count;
Base::operator++();
}

return *this;
}
};

auto main(void) -> int
{
std::istringstream iss("123456789");

std::string str;

/* Let's use copy to read 5 char's into our string */
std::copy( istream_iterator_limited<char>(iss,5), istream_iterator_limited<char>(), std::back_inserter(str) );

std::cout << str << std::endl;
}
0 new messages