camper schrieb:
Arcoth schrieb:
@ProfiProgrammierer: Künftig bitte in Final Drafts schaun, für C++11 wäre das N3797.
Das wäre genau genommen N3291 welches geschützt ist, und die beste Annäherung dafür ist zweifellos N3337 (nur textliche Änderungen gegenüber dem Standard, siehe N3338).
Für C++14 ist es N3936 - ebenfalls geschützt. Dafür wäre gegenwärtig N3797 zusammen mit N3938 zu Rate zu ziehen.
Ich dachte es wäre lediglich ein älterer Draft, danke für die Aufklärung.
N3797 war natürlich ein Tippfehler, ich meine N3337. Das ist meines Wissens nach (wie du ja bestätigt hast) die beste Annäherung, "the latest publicly available draft".
leider eben nur für container mit zusammenhängendem speicher.
Willst du etwa mehrere Gigabyte in einer verketteten Liste speichern?
Ganz grob heruntergetippt:
#include <streambuf>
#include <iterator>
#include <type_traits>
template <typename Iterator,
typename CharT,
typename Traits = std::char_traits<CharT>>
class basic_iterator_streambuf : public std::basic_streambuf<CharT, Traits>
{
Iterator first, current, last;
using char_type = CharT;
using traits_type = Traits;
using int_type = typename traits_type::int_type;
virtual int_type underflow() override
{
if (current != last)
return *current;
return traits_type::eof();
}
virtual int_type uflow() override
{
auto c = underflow();
if (traits_type::eq_int_type(c, traits_type::eof()))
return c;
++current;
return c;
}
int_type pbackfail_noneof_impl( char_type c, std::true_type )
{
traits_type::assign(*current, c);
return traits_type::not_eof( traits_type::eof() );
}
int_type pbackfail_noneof_impl( char_type, std::false_type )
{
return traits_type::eof();
}
int_type pbackfail_impl( std::true_type, int_type c )
{
if (first == current)
return traits_type::eof();
--current;
if (not traits_type::eq_int_type(c, traits_type::eof()))
return pbackfail_noneof_impl( traits_type::to_char_type(c),
std::integral_constant<bool, std::is_convertible<char_type, typename std::iterator_traits<Iterator>::value_type>::value // Grober Indikator!
&& !std::is_const<typename std::remove_reference<decltype(*current)>::type>::value>{} );
return traits_type::not_eof( traits_type::eof() );
}
int_type pbackfail_impl( std::false_type, int_type )
{
return traits_type::eof();
}
virtual int_type pbackfail( int_type c = traits_type::eof() ) override
{
return pbackfail_impl(std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<Iterator>::iterator_category>{}, c);
}
virtual std::streamsize showmanyc() override
{
return std::distance(current, last);
}
public:
basic_iterator_streambuf( Iterator first, Iterator last ) :
first(first), current(first), last(last) {}
};
template <typename I>
using iterator_streambuf = basic_iterator_streambuf<I, char>;
#include <iostream>
int main()
{
std::string const str = "Hallo Welt!";
iterator_streambuf<std::string::const_iterator> buf(str.begin(), str.end());
std::istream stream(&buf);
std::string outstr;
stream >> outstr;
std::cout << outstr;
}
Werner kann das sicher vollständig und richtig machen.