C++ Logo

std-proposals

Advanced search

Re: [std-proposals] istream_iterator_limited

From: Keenan Horrigan <friedkeenan_at_[hidden]>
Date: Mon, 18 Apr 2022 19:22:23 +0000
std::counted_iterator already exists, does it not fulfill your needs?
------- Original Message -------
On Monday, April 18th, 2022 at 3:19 PM, Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]> wrote:

> We can read from "cin" or any file (fstream) as though it were a container in volatile memory, using istream_iterator. But we can't put a limit on how many char's to take from the istream.
>
> Sometimes there is an alternative function available to use, e.g. 'copy_n' instead of 'copy', but sometimes there isn't.
>
> I propose a new template class istream_iterator_limited(N) that will stop reading from the istream after N characters.
>
> - - - - WHY I NEEDED THIS:
>
> I wanted to open a file using "ifstream", and then I wanted to read 32 bytes from the file and feed them directly into the function 'boost::algorithm::hex'.
> Unfortunately I couldn't do this because 'hex' takes two iterators [begin,end), and there's no alternative function called "hex_n". So I had to read the file into a string object first with 'copy_n', and then pass the string into the 'hex' function.
>
> - - - - THE IDEA I CAME UP WITH:
>
> Open the file using "ifstream", and then use a special iterator that will stop reading from the file after 32 bytes, with syntax like this:
>
> ifstream logfile("log.txt");
>
> hex( istream_iterator_limited<char>(logfile,32u),
> istream_iterator_limited<char>(), g_some_global_container.begin() );
>
> - - - - HOW I CODED IT:
>
> #include <cstddef> /* size_t */
> #include <iterator> /* istream_iterator */
>
> template <typename 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)
> : Base(obj_stream), m_limit(arg_limit), m_current_count(1u)
> {
> /* The initialiser list above does all the construction work */
> }
>
> istream_iterator_limited(void) /* This gives the End-Of-Stream iterator */
> : Base() , m_limit(0u), m_current_count(1u)
> {
> /* 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;
> }
> };
>
> - - - - HOW I TESTED IT:
>
> #include <algorithm> /* copy */
> #include <string> /* string */
> #include <sstream> /* istringstream */
> #include <iostream> /* cout, endl */
> #include <iterator> /* back_inserter */
>
> 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;
>
> str.clear();
>
> /* Get another 3 */
> std::copy( istream_iterator_limited<char>(iss,3),
> istream_iterator_limited<char>(), std::back_inserter(str) );
>
> std::cout << str << std::endl;
> }

Received on 2022-04-18 19:22:30