30 Input/output library [input.output]

30.6 Stream buffers [stream.buffers]

30.6.1 Header <streambuf> synopsis [streambuf.syn]

namespace std {
  template <class charT, class traits = char_traits<charT>>
    class basic_streambuf;
  using streambuf  = basic_streambuf<char>;
  using wstreambuf = basic_streambuf<wchar_t>;
}

Заголовок <streambuf> определяет типы, которые управляют вводом и выводом character последовательностей.

30.6.2 Stream buffer requirements [streambuf.reqts]

Буферы потоков могут накладывать различные ограничения на последовательности, которыми они управляют. Некоторые ограничения:

  • Управляемая входная последовательность не читается.

  • Управляемая выходная последовательность не может быть записана.

  • Управляемые последовательности могут быть связаны с содержимым других представлений для последовательностей символов, таких как внешние файлы.

  • Управляемые последовательности могут поддерживать операции directly с ассоциированными последовательностями или из них.

  • Управляемые последовательности могут налагать ограничения на то, как программа может читать символы из последовательности, записывать символы в последовательность, возвращать символы во входную последовательность или изменять положение потока.

Каждая последовательность характеризуется тремя указателями, которые, если они не равны нулю, все указывают на один и тот же charT объект массива. Объект массива представляет в любой момент (под) последовательность символов из этой последовательности. Операции, выполняемые над последовательностью, изменяют значения, хранящиеся в этих указателях, выполняют чтение и запись непосредственно в или из связанных последовательностей, а также изменяют «позицию потока» и состояние преобразования по мере необходимости для поддержания этой взаимосвязи подпоследовательностей. Три указателя:

  • адрес beginning pointer, или наименьший адрес элемента в массиве (называемый xbeg здесь);

  • адрес next pointer, или следующий элемент, который является текущим кандидатом на чтение или запись ( xnext здесь называется );

  • end pointerили первый элемент адрес за концом массива ( так называемый xend здесь).

Следующие семантические ограничения всегда должны применяться к любому набору из трех указателей для последовательности, используя имена указателей, указанные непосредственно выше:

  • Если xnext не является нулевым указателем, то xbeg и xend также должны быть ненулевыми указателями на тот же charT массив, как описано выше; в противном случае xbeg и xend также должно быть недействительным.

  • Если xnext это не нулевой указатель и xnext < xend для выходной последовательности, то write position доступен. В этом случае *xnext должен быть назначен в качестве следующего элемента для записи (для помещения или сохранения символьного значения в последовательность).

  • Если xnext это не нулевой указатель и xbeg < xnext для входной последовательности, то putback position доступен. В этом случае xnext[-1] должен иметь определенное значение и быть следующим (предыдущим) элементом для хранения символа, который возвращается во входную последовательность.

  • Если xnext это не нулевой указатель и xnext < xend для входной последовательности, то read position доступен. В этом случае *xnext должен иметь определенное значение и быть следующим элементом для чтения (для получения или для получения символьного значения из последовательности).

30.6.3 Class template basic_­streambuf [streambuf]

namespace std {
  template <class charT, class traits = char_traits<charT>>
  class basic_streambuf {
  public:
    using char_type   = charT;
    using int_type    = typename traits::int_type;
    using pos_type    = typename traits::pos_type;
    using off_type    = typename traits::off_type;
    using traits_type = traits;

    virtual ~basic_streambuf();

    // [streambuf.locales], locales
    locale   pubimbue(const locale& loc);
    locale   getloc() const;

    // [streambuf.buffer], buffer and positioning
    basic_streambuf* pubsetbuf(char_type* s, streamsize n);
    pos_type pubseekoff(off_type off, ios_base::seekdir way,
                        ios_base::openmode which
                          = ios_base::in | ios_base::out);
    pos_type pubseekpos(pos_type sp,
                        ios_base::openmode which
                          = ios_base::in | ios_base::out);
    int      pubsync();

    // Get and put areas
    // [streambuf.pub.get], get area
    streamsize in_avail();
    int_type snextc();
    int_type sbumpc();
    int_type sgetc();
    streamsize sgetn(char_type* s, streamsize n);

    // [streambuf.pub.pback], putback
    int_type sputbackc(char_type c);
    int_type sungetc();

    // [streambuf.pub.put], put area
    int_type   sputc(char_type c);
    streamsize sputn(const char_type* s, streamsize n);

  protected:
    basic_streambuf();
    basic_streambuf(const basic_streambuf& rhs);
    basic_streambuf& operator=(const basic_streambuf& rhs);

    void swap(basic_streambuf& rhs);

    // [streambuf.get.area], get area access
    char_type* eback() const;
    char_type* gptr()  const;
    char_type* egptr() const;
    void       gbump(int n);
    void       setg(char_type* gbeg, char_type* gnext, char_type* gend);

    // [streambuf.put.area], put area access
    char_type* pbase() const;
    char_type* pptr() const;
    char_type* epptr() const;
    void       pbump(int n);
    void       setp(char_type* pbeg, char_type* pend);

    // [streambuf.virtuals], virtual functions
    // [streambuf.virt.locales], locales
    virtual void imbue(const locale& loc);

    // [streambuf.virt.buffer], buffer management and positioning
    virtual basic_streambuf* setbuf(char_type* s, streamsize n);
    virtual pos_type seekoff(off_type off, ios_base::seekdir way,
                             ios_base::openmode which
                               = ios_base::in | ios_base::out);
    virtual pos_type seekpos(pos_type sp,
                             ios_base::openmode which
                               = ios_base::in | ios_base::out);
    virtual int      sync();

    // [streambuf.virt.get], get area
    virtual streamsize showmanyc();
    virtual streamsize xsgetn(char_type* s, streamsize n);
    virtual int_type   underflow();
    virtual int_type   uflow();

    // [streambuf.virt.pback], putback
    virtual int_type   pbackfail(int_type c = traits::eof());

    // [streambuf.virt.put], put area
    virtual streamsize xsputn(const char_type* s, streamsize n);
    virtual int_type   overflow(int_type c = traits::eof());
  };
}

Шаблон класса basic_­streambuf служит абстрактным базовым классом для получения различных stream buffers объектов, каждый из которых контролирует два character sequences:

  • персонаж input sequence;

  • персонаж output sequence.

30.6.3.1 basic_­streambuf constructors [streambuf.cons]

basic_streambuf();

Effects: Создает объект класса basic_­streambuf<charT, traits> и инициализирует:299

  • все его объекты-члены-указатели на нулевые указатели,

  • getloc() член в копию глобальной локали locale(), во время строительства.

Remarks: После getloc() инициализации члена результаты вызова функций-членов локали и полученных таким образом элементов фасетов можно безопасно кэшировать до следующего вызова этого члена imbue .

basic_streambuf(const basic_streambuf& rhs);

Effects: Создает копию rhs.

Postconditions:

  • eback() == rhs.eback()

  • gptr() == rhs.gptr()

  • egptr() == rhs.egptr()

  • pbase() == rhs.pbase()

  • pptr() == rhs.pptr()

  • epptr() == rhs.epptr()

  • getloc() == rhs.getloc()

~basic_streambuf();

Effects: Никто.

Конструктор по умолчанию защищен для класса, basic_­streambuf чтобы гарантировать, что могут быть созданы только объекты для классов, производных от этого класса.

30.6.3.2 basic_­streambuf public member functions [streambuf.members]

30.6.3.2.1 Locales [streambuf.locales]

locale pubimbue(const locale& loc);

Postconditions: loc == getloc().

Effects: Звонки imbue(loc).

Returns: Предыдущее значение getloc().

locale getloc() const;

Returns: Если pubimbue() когда-либо вызывалась, то последнее значение loc предоставлено, в противном случае - текущая глобальная локаль, locale()действующая на момент создания. Если вызван после того, pubimbue() как был вызван, но перед возвратомpubimbue (т. Е. Изнутри вызова imbue()), то он возвращает предыдущее значение.

30.6.3.2.2 Buffer management and positioning [streambuf.buffer]

basic_streambuf* pubsetbuf(char_type* s, streamsize n);

Returns: setbuf(s, n).

pos_type pubseekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out);

Returns: seekoff(off, way, which).

pos_type pubseekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out);

Returns: seekpos(sp, which).

int pubsync();

Returns: sync().

30.6.3.2.3 Get area [streambuf.pub.get]

streamsize in_avail();

Returns: Если позиция чтения доступна, возвращается egptr() - gptr(). В противном случае возвращается showmanyc().

int_type snextc();

Effects: Звонки sbumpc().

Returns: Если эта функция возвращается traits​::​eof(), возвращается traits​::​eof(). В противном случае возвращается sgetc().

int_type sbumpc();

Returns: Если позиция чтения входной последовательности недоступна, возвращается uflow(). В противном случае возвращает traits​::​to_­int_­type(*gptr()) и увеличивает следующий указатель для входной последовательности.

int_type sgetc();

Returns: Если позиция чтения входной последовательности недоступна, возвращается underflow(). В противном случае возвращается traits​::​to_­int_­type(*gptr()).

streamsize sgetn(char_type* s, streamsize n);

Returns: xsgetn(s, n).

30.6.3.2.4 Putback [streambuf.pub.pback]

int_type sputbackc(char_type c);

Returns: Если позиция возврата входной последовательности недоступна, или если traits​::​eq(c, gptr()[-1]) есть false, возвращается pbackfail(traits​::​to_­int_­type(c)). В противном случае уменьшает следующий указатель входной последовательности и возвращается traits​::​to_­int_­type(*gptr()).

int_type sungetc();

Returns: Если позиция возврата входной последовательности недоступна, возвращается pbackfail(). В противном случае уменьшает следующий указатель входной последовательности и возвращается traits​::​to_­int_­type(*gptr()).

30.6.3.2.5 Put area [streambuf.pub.put]

int_type sputc(char_type c);

Returns: Если позиция записи выходной последовательности недоступна, возвращается overflow(traits​::​to_­int_­type(c)). В противном случае сохраняет c в следующем указателе выходной последовательности, увеличивает указатель на единицу и возвращается traits​::​to_­int_­type(c).

streamsize sputn(const char_type* s, streamsize n);

Returns: xsputn(s, n).

30.6.3.3 basic_­streambuf protected member functions [streambuf.protected]

30.6.3.3.1 Assignment [streambuf.assign]

basic_streambuf& operator=(const basic_streambuf& rhs);

Effects: Назначает элементы данных rhs для *this.

Postconditions:

  • eback() == rhs.eback()

  • gptr() == rhs.gptr()

  • egptr() == rhs.egptr()

  • pbase() == rhs.pbase()

  • pptr() == rhs.pptr()

  • epptr() == rhs.epptr()

  • getloc() == rhs.getloc()

Returns: *this.

void swap(basic_streambuf& rhs);

Effects: Меняет местами элементы данных rhs и *this.

30.6.3.3.2 Get area access [streambuf.get.area]

char_type* eback() const;

Returns: Начальный указатель входной последовательности.

char_type* gptr() const;

Returns: Следующий указатель входной последовательности.

char_type* egptr() const;

Returns: Конечный указатель входной последовательности.

void gbump(int n);

Effects: Добавляет n к следующему указателю входной последовательности.

void setg(char_type* gbeg, char_type* gnext, char_type* gend);

Postconditions: gbeg == eback(),, gnext == gptr()и gend == egptr().

30.6.3.3.3 Put area access [streambuf.put.area]

char_type* pbase() const;

Returns: Начальный указатель выходной последовательности.

char_type* pptr() const;

Returns: Следующий указатель выходной последовательности.

char_type* epptr() const;

Returns: Конечный указатель выходной последовательности.

void pbump(int n);

Effects: Добавляет n к следующему указателю выходной последовательности.

void setp(char_type* pbeg, char_type* pend);

Postconditions: pbeg == pbase(),, pbeg == pptr()и pend == epptr().

30.6.3.4 basic_­streambuf virtual functions [streambuf.virtuals]

30.6.3.4.1 Locales [streambuf.virt.locales]

void imbue(const locale&);

Effects: Измените любые переводы в зависимости от языкового стандарта.

Remarks: Позволяет производному классу получать информацию об изменениях в локали в момент их возникновения. Между вызовами этой функции класс, производный от streambuf, может безопасно кэшировать результаты вызовов функций локали и членов полученных таким образом фасетов.

Default behavior: Ничего не делает.

30.6.3.4.2 Buffer management and positioning [streambuf.virt.buffer]

basic_streambuf* setbuf(char_type* s, streamsize n);

Effects: Влияет на буферизацию потока способом, который определяется отдельно для каждого класса, производного от basic_­streambuf этого пункта ([stringbuf.virtuals], [filebuf.virtuals]).

Default behavior: Ничего не делает. Возврат this.

pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out);

Effects: Изменяет позиции потока в одной или нескольких управляемых последовательностях способом, который определяется отдельно для каждого класса, производного от basic_­streambuf этого пункта ([stringbuf.virtuals], [filebuf.virtuals]).

Default behavior: Возврат pos_­type(off_­type(-1)).

pos_type seekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out);

Effects: Изменяет позиции потока в одной или нескольких управляемых последовательностях способом, который определяется отдельно для каждого класса, производного от basic_­streambuf этого пункта ([stringbuf], [filebuf]).

Default behavior: Возврат pos_­type(off_­type(-1)).

int sync();

Effects: Синхронизирует контролируемые последовательности с массивами. То есть, если не pbase() равно нулю, символы между pbase() и pptr() записываются в управляемую последовательность. Затем указатели могут быть при необходимости сброшены.

Returns: -1 при неудаче. Что составляет отказ, определяется каждым производным классом ([filebuf.virtuals]).

Default behavior: Возвращает ноль.

30.6.3.4.3 Get area [streambuf.virt.get]

streamsize showmanyc();300

Returns: Оценка количества символов, доступных в последовательности, или -1. Если он возвращает положительное значение, то последовательные вызовы underflow() не будут возвращаться traits​::​eof() до тех пор, пока из потока не будет извлечено хотя бы это количество символов. Если showmanyc() возвращается -1, вызовы underflow() или uflow() завершатся ошибкой.301

Default behavior: Возвращает ноль.

Remarks: Использует traits​::​eof().

streamsize xsgetn(char_type* s, streamsize n);

Effects: Присваивает до n символов последовательным элементам массива, первый элемент которого обозначен s. Назначенные символы считываются из входной последовательности, как если бы при повторных вызовах sbumpc(). Назначение прекращается, когда либо n были назначены символы, либоsbumpc() возвращался вызов traits​::​eof().

Returns: Количество присвоенных символов.302

Remarks: Использует traits​::​eof().

int_type underflow();

Remarks: Открытые члены basic_­streambuf вызывают эту виртуальную функцию только в том случае, если она gptr() равна нулю или gptr() >= egptr()

Returns: traits​::​to_­int_­type(c), где c является первым character из pending sequence, без перемещения позиции входной последовательности за ним. Если ожидающая последовательность пуста, функция возвращается, traits​::​eof() чтобы указать на сбой.

pending sequence Символов определяется как конкатенация

  • пустая последовательность, если она gptr() равна нулю, в противном случае символы в [gptr(), egptr()), за которыми следует

  • некоторая (возможно, пустая) последовательность символов, прочитанная из входной последовательности.

Это result character первый символ ожидающей последовательности, если он не пуст, в противном случае - следующий символ, который будет считан из входной последовательности.

Это backup sequence пустая последовательность, если она eback() равна нулю, в противном случае символы в [eback(), gptr()).

Effects: Функция устанавливает gptr() и так egptr() , что если ожидающая последовательность непуста, то не egptr() является нулевой, а символы в [gptr(), egptr()) являются символами в ожидающей последовательности, в противном случае либо gptr() имеет значение null, либо gptr() == egptr().

Если eback() и не gptr() равны нулю, функция не ограничена в отношении их содержимого, но «обычное условие резервного копирования» состоит в том, что либо

  • резервная последовательность содержит как минимум gptr() - eback() символы, и в этом случае символы [eback(), gptr()) соответствуют последним gptr() - eback() символам резервной последовательности, или

  • символы [gptr() - n, gptr()) соответствуют резервной последовательности (где n - длина резервной последовательности).

Default behavior: Возврат traits​::​eof().

int_type uflow();

Requires: Ограничения те же, что и для underflow(), за исключением того, что символ результата должен быть перенесен из ожидающей последовательности в резервную последовательность, а ожидающая последовательность не должна быть пустой перед передачей.

Default behavior: Звонки underflow(). Если underflow() возвращается traits​::​eof(), возвращается traits​::​eof(). В противном случае возвращает значение traits​::​to_­int_­type(*gptr()) и увеличивает значение следующего указателя для входной последовательности.

Returns: traits​::​eof() для обозначения отказа.

Морфемы слова showmanyc «es-how-many-see», а не «show-manic».

underflow или uflow может потерпеть неудачу из-за преждевременного создания исключения. Намерение состоит не только в том, чтобы звонки не возвращались, eof() но и в том, чтобы они вернулись «немедленно».

Классы, производные от, basic_­streambuf могут предоставить более эффективные способы реализации xsgetn() и xsputn() переопределения этих определений из базового класса.

30.6.3.4.4 Putback [streambuf.virt.pback]

int_type pbackfail(int_type c = traits::eof());

Remarks: Общедоступные функции basic_­streambuf вызывают эту виртуальную функцию только тогда, когда возвращается значение gptr() null gptr() == eback(), или . Другие вызовы также должны удовлетворять этому ограничению.traits​::​eq(traits​::​to_­char_­type(c), gptr()[-1])false

pending sequence Определяется как для underflow(), с изменениями , которые

  • Если traits​::​eq_­int_­type(c, traits​::​eof()) возвращается true, то входная последовательность копируется на один символ до того, как будет определена ожидающая последовательность.

  • Если traits​::​eq_­int_­type(c, traits​::​eof()) возвращается false, то c добавляется. Не указано, выполняется ли резервная копия входной последовательности или изменяется каким-либо иным образом.

Postconditions: В свою очередь, ограничения gptr(), eback()и pptr() такие же , как для underflow().

Returns: traits​::​eof() для обозначения отказа. Сбой может произойти из-за невозможности резервного копирования входной последовательности или из-за того, что по какой-либо другой причине указатели не могут быть установлены в соответствии с ограничениями. pbackfail() вызывается только тогда, когда возвращение действительно не удалось.

Возвращает какое-то значение, отличное от traits​::​eof() успешного.

Default behavior: Возврат traits​::​eof().

30.6.3.4.5 Put area [streambuf.virt.put]

streamsize xsputn(const char_type* s, streamsize n);

Effects: Записывает до n символов в выходную последовательность, как если бы при повторных вызовах sputc(c). Записанные символы получаются из последовательных элементов массива, первый элемент которого обозначен знаком s. Запись останавливается, когда либо n символы были написаны, либоsputc(c) возвращался вызов traits​::​eof(). Не указано, вызывает ли функция, overflow() когда pptr() == epptr() становится, true или она достигает тех же результатов другими способами.

Returns: Количество написанных символов.

int_type overflow(int_type c = traits::eof());

Effects: Использует некоторую начальную подпоследовательность символов pending sequence. Ожидающая последовательность определяется как конкатенация

  • пустая последовательность, если pbase() не равна нулю, в противном случае pptr() - pbase() символы, начинающиеся с pbase(), за которыми следует

  • пустая последовательность, если traits​::​eq_­int_­type(c, traits​::​eof()) возвращается true, в противном случае последовательность, состоящая из c.

Remarks: Функции-члены sputc() и sputn() вызывают эту функцию в случае, если в буфере размещения нет места, достаточного для размещения последовательности символов аргумента.

Requires: Каждое преобладающее определение этой виртуальной функции должно подчиняться следующим ограничениям:

  1. 1.Указывается влияние употребления символа на связанную выходную последовательность.303

  2. 2.Позвольте r быть количеством символов в ожидающей последовательности, которые не используются. Если неr равно нулю , то pbase() и pptr() должен быть установлен таким образом, чтобы: pptr() - pbase() == r а r символы , начинающиеся на pbase() это соответствующий выходной поток. В случае, если он r равен нулю (все символы ожидающей последовательности были израсходованы), то либо pbase() устанавливается nullptr, либо pbase() и pptr() оба установлены на одно и то же ненулевое значение.

  3. 3.Функция может завершиться ошибкой, если не удается добавить какой-либо символ в связанный выходной поток или если он не может быть установлен pbase() и в pptr() соответствии с вышеуказанными правилами.

Returns: traits​::​eof() или выдает исключение, если функция не работает.

В противном случае возвращает какое-либо значение, отличное от traits​::​eof() указания успеха.304

Default behavior: Возврат traits​::​eof().

То есть для каждого класса, производного от экземпляра basic_­streambuf в этом разделе ([stringbuf], [filebuf]), дается спецификация того, как потребление символа влияет на связанную выходную последовательность. Нет требований к программному классу.

Обычно overflow возвращается, c чтобы указать на успех, за исключением тех случаев, когда traits​::​eq_­int_­type(c, traits​::​eof()) возвращается true, и в этом случае он возвращается traits​::​not_­eof(c).