Skip to content

Instantly share code, notes, and snippets.

@kazmura11
Last active June 28, 2020 08:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kazmura11/122d9bc79c8379c990d8 to your computer and use it in GitHub Desktop.
Save kazmura11/122d9bc79c8379c990d8 to your computer and use it in GitHub Desktop.
iotest.cpp streambuf_iterator simple implementation
#include <fstream>
#include <iostream>
#include <string>
#define USE_MY_LIB_
#ifdef USE_MY_LIB_
// 偽物ライブラリ
namespace MyLib
{
template
<
class charT = char,
class traits = std::char_traits<charT>
>
class istreambuf_iterator
: public std::iterator
<
std::input_iterator_tag,
charT,
typename traits::off_type,
charT*,
charT&
>
{
public:
typedef charT char_type;
typedef traits traits_type;
typedef typename traits::int_type int_type;
typedef std::basic_streambuf<charT, traits> streambuf_type;
typedef std::basic_istream<charT, traits> istream_type;
private:
streambuf_type *sbuf_;
int_type c_;
public:
// ctor
istreambuf_iterator()
: sbuf_(0), c_(traits::eof()) { }
istreambuf_iterator(istream_type& s)
// rdbuf() 格納されているストリームバッファのポインタを返す
: sbuf_(s.rdbuf()), c_(traits::eof()) { }
istreambuf_iterator(streambuf_type *s)
: sbuf_(s), c_(traits::eof()) { }
charT operator*() const
{
// sgetc() ストリームから1文字読込む
return sbuf_->sgetc();
}
istreambuf_iterator<charT, traits>& operator++()
{
// sbumpc() ストリームから 1 文字を読み取り、読み取り位置を進める
sbuf_->sbumpc();
return *this;
}
// istreambuf_iteratorの場合、初期構築時の状態か終端なのかだけを判断すればいい
// see: https://ja.cppreference.com/w/cpp/iterator/istreambuf_iterator/equal
bool equal(const istreambuf_iterator& b) const
{
if ((sbuf_ == 0 || *(*this) == traits::eof()) && (b.sbuf_ == 0 || *b == traits::eof())) {
return true;
}
return false;
}
};
template<class charT, class traits>
bool operator==(const istreambuf_iterator<charT, traits>& lhs,
const istreambuf_iterator<charT, traits>& rhs)
{
return lhs.equal(rhs);
}
template<class charT, class traits>
bool operator!=(const istreambuf_iterator<charT, traits>& lhs,
const istreambuf_iterator<charT, traits>& rhs)
{
return !lhs.equal(rhs);
}
}
#endif
int main()
{
#ifdef USE_MY_LIB_
// 偽物ライブラリ使います
std::cout << "USE DUMMY LIB!" << std::endl;
#else
// 本物ライブラリ使います
std::cout << "USE GENUINE LIB!" << std::endl;
#endif
// 標準ライブラリでファイルオープン
std::ifstream ifs("test.txt", std::ifstream::binary);
if (ifs.fail())
{
std::cerr << "failed." << std::endl;
return 1;
}
#ifdef USE_MY_LIB_
MyLib::istreambuf_iterator<char> start_of_stream(ifs);
MyLib::istreambuf_iterator<char> end_of_stream;
#else
std::istreambuf_iterator<char> start_of_stream(ifs);
std::istreambuf_iterator<char> end_of_stream;
#endif
// 変数にファイル丸読み
std::string str(start_of_stream, end_of_stream);
// 結果表示
std::cout << "[" << str << "]" << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment