1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
#include <iostream>
#include <iterator>
#include <type_traits>
#include <fstream>
#include <algorithm>
namespace binary_io
{
template < typename T > // use needlessly deprecated std::iterator for brevity
struct istream_iterator : std::iterator< std::input_iterator_tag, T, T >
{
static_assert( std::is_trivially_copyable<T>::value, "T must be a TriviallyCopyable type" ) ;
static_assert( std::is_default_constructible<T>::value, "T must be a DefaultConstructible type" ) ;
istream_iterator() : stm(nullptr) {}
explicit istream_iterator( std::istream& stm ) : stm( std::addressof(stm) ) { ++*this ; }
T operator* () const { return value ; }
const T* operator->() const { return std::addressof(**this) ; }
istream_iterator& operator++()
{
stm->read( reinterpret_cast<char*>( std::addressof(value) ), sizeof(value) ) ;
return *this ;
}
istream_iterator& operator++(int) { return ++*this ; }
bool operator== ( const istream_iterator& that ) const { return bool(*this) == bool(that) ; }
bool operator!= ( const istream_iterator& that ) const { return !( *this == that) ; }
std::istream* stm ;
T value {} ;
explicit operator bool() const { return stm && *stm ; }
};
template < typename T > // use needlessly deprecated std::iterator for brevity
struct ostream_iterator : std::iterator< std::output_iterator_tag, T, T >
{
static_assert( std::is_trivially_copyable<T>::value, "T must be a TriviallyCopyable type" ) ;
explicit ostream_iterator( std::ostream& stm ) : stm(stm) {}
ostream_iterator& operator* () { return *this ; }
ostream_iterator& operator++() { return *this ; }
ostream_iterator& operator++(int) { return ++*this ; }
ostream_iterator& operator= ( const T& value )
{
stm.write( reinterpret_cast< const char* >( std::addressof(value) ), sizeof(value) ) ;
return *this ;
}
std::ostream& stm ;
};
}
int main()
{
const long long test[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ;
const char* const file_name = "test.bin" ;
{
std::ofstream file( file_name, std::ios::binary ) ;
std::copy( std::begin(test), std::end(test), binary_io::ostream_iterator<long long>(file) ) ;
// sanity check
std::cout << "bytes written: " << file.tellp() << " array size: " << sizeof(test)
<< " #items: " << sizeof(test) / sizeof(*test) << '\n' ;
}
{
std::ifstream file( file_name, std::ios::binary ) ;
binary_io::istream_iterator<long long> begin(file), end ;
std::copy( begin, end, std::ostream_iterator<long long>( std::cout, " " ) ) ;
// sanity check
file.clear() ;
const auto pos = file.tellg() ;
std::cout << "\nbytes read: " << pos << " #items: " << pos / sizeof(long long) << '\n' ;
}
}
|