Skip to content

Instantly share code, notes, and snippets.

@fabiogaluppo
Last active March 11, 2025 02:17
Show Gist options
  • Save fabiogaluppo/f8e15b531998658df081866f9dbbbcef to your computer and use it in GitHub Desktop.
Save fabiogaluppo/f8e15b531998658df081866f9dbbbcef to your computer and use it in GitHub Desktop.
Helper functions for manipulating istreams (file, stdin, cin)
//Source code by Fabio Galuppo
//C++ MasterClass - https://www.linkedin.com/company/cppmasterclass - https://cppmasterclass.com.br/
//Fabio Galuppo - http://member.acm.org/~fabiogaluppo - [email protected]
//March 2025
#ifndef ISTREAM_HELPER_UTIL_H
#define ISTREAM_HELPER_UTIL_H
#include <functional>
#include <istream>
#include <optional>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
namespace istream_helper
{
struct Util final
{
template<class CharT>
[[nodiscard]] static inline bool check_error(std::basic_istream<CharT>& is) noexcept
{
if (is.fail() || is.bad()) return false;
//else if (is.eof()) return true;
return true;
}
template<class CharT, class UnaryOp>
using result_type = std::optional<std::remove_reference_t<std::invoke_result_t<UnaryOp, std::basic_string<CharT>>>>;
template<class CharT, class UnaryOp>
[[nodiscard]] static inline result_type<CharT, UnaryOp> next(std::basic_istream<CharT>& is, UnaryOp&& unary_op) noexcept
{
std::basic_string<CharT> line;
if (check_error(std::getline(is, line)))
return std::forward<UnaryOp>(unary_op)(line);
return std::nullopt;
}
template<class CharT>
[[nodiscard]] static inline std::optional<std::basic_string<CharT>> next(std::basic_istream<CharT>& is) noexcept
{
return next<CharT>(is, std::identity{});
}
template<class CharT, class UnaryOp, class OutputIt>
static inline OutputIt drain(std::basic_istream<CharT>& is, UnaryOp&& unary_op, OutputIt first) noexcept
{
while (auto opt = next(is, unary_op))
*first++ = *opt;
return first;
}
template<class CharT, class OutputIt>
static inline OutputIt drain(std::basic_istream<CharT>& is, OutputIt first) noexcept
{
return drain<CharT>(is, std::identity{}, first);
}
template<class CharT, class UnaryOp>
[[nodiscard]] static inline std::vector<result_type<CharT, UnaryOp>> drain(std::basic_istream<CharT>& is, UnaryOp&& unary_op) noexcept
{
std::vector<std::basic_string<CharT>> temp;
drain(is, unary_op, std::back_inserter(temp));
return temp;
}
template<class CharT>
[[nodiscard]] static inline std::vector<std::basic_string<CharT>> drain(std::basic_istream<CharT>& is) noexcept
{
std::vector<std::basic_string<CharT>> temp;
drain(is, std::back_inserter(temp));
return temp;
}
};
}
#endif /* ISTREAM_HELPER_UTIL_H */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment