______________________________________________________________________ 27 Input/output library [lib.input.output] ______________________________________________________________________ 1 This clause describes components that C++ programs may use to perform input/output operations. 2 The following subclauses describe components for all iostreams (_lib.iostreams_), base stream buffer and streams classes (_lib.default.iostreams_), stream manipulators (_lib.manipulators_), string streams (_lib.string.streams_), and file streams (_lib.file.streams_). 27.1 Iostreams [lib.iostreams] 1 Headers: --<ios> --<iostream> 2 Table 1: Table 1--Header <ios> synopsis +--------------------------------------------------------------------+ | Type Name(s) | +--------------------------------------------------------------------+ |Template basic_ios | |class: | +--------------------------------------------------------------------+ |Template ios_baggage ios_char_baggage ios_pos_baggage | |structs: | +--------------------------------------------------------------------+ |Template functions: | |basic_dec basic_noshowbase basic_oct basic_showpos | |basic_fixed basic_noshowpoint basic_right basic_skipws | |basic_hex basic_noskipws basic_scientific basic_uppercase | |basic_internal basic_nouppercase basic_showbase | |basic_left basic_nowshowpos basic_showpoint | +--------------------------------------------------------------------+ |Classes: basic_ios<char> basic_ios<wchar_t> ios | +--------------------------------------------------------------------+ |Structs: | |ios_baggage<char> ios_pos_baggage<streampos> | |ios_baggage<wchar_t> ios_pos_baggage<wstreampos> | |ios_char_baggage<char> | |ios_char_baggage<wchar_t> | +--------------------------------------------------------------------+ |Functions: | |dec noshowbase oct showpos | |fixed noshowpoint right skipws | |hex noshowpos scientific uppercase | |internal noskipws showbase | |left nouppercase showpoint | +--------------------------------------------------------------------+ 3 Table 2: Table 2--Header <iostream> synopsis +------------------------------------+ | Type Name(s) | +------------------------------------+ |Objects: cerr cin clog cout | +------------------------------------+ +------- BEGIN BOX 1 -------+ Is it clear that these can be declared using incomplete types? I'm a little unhappy about this name because people are going to assume that iostream is essentially the same as iostream.h. +------- END BOX 1 -------+ 4 Additional definitions: --Character In this clause, the term ``character'' means the general ized element of text data. Each text data consist of a sequence of character. So the term does not only means the char type object, and the wchar_t type object, but also any sort of classes which pro vides the definitions specified in (_lib.TBD_). --Character container type Character container type is a class or a type which represent a character. It is used for one of the tem plate parameter of the template IOStream classes. --The template IOStream classes The template IOStream classes are the template classes which takes two template parameters: charT and bag gage. The class, charT, represents the character container class and the class, baggage, represents the baggage structure which pro vides the definition of the functionality necessary to implement the template IOStream classes. --Narrow-oriented IOStream classes The narrow-oriented IOStream classes are the versions of the template IOStream classes special ized with the character container class, char. The traditional IOStream classes aree regarded as the narrow-oriented IOStream classes. --Wide-oriented IOStream classes The wide-oriented IOStream classes are the versions of the template IOStream classes specialized with the character container class, wchar_t. 27.1.1 Iostream character traits [lib.iostream.traits] 27.1.1.1 Template struct ios_baggage [lib.ios.baggage] +------- BEGIN BOX 2 -------+ At the Kitchener meeting, the Library WG decided to change the names used from ``baggage'' to ``traits''. However, Tom Plum objected to doing this without a formal proposal and vote. These names are there fore unresolved, and subject to change. +------- END BOX 2 -------+ +------- BEGIN BOX 3 -------+ I don't find the two level approach of ios_baggage useful. I think it will simplify everyone's (i.e. both our and programmer's) life and shorten the working paper if we combine all the baggages (or traits) needed by any class in the standard into a single template. Using multiple inheritance we can arrange for everything to be specified exactly once, and only the wchar_t version needs to be specialized. The char version is generic. 1 Proposal: Combine the following two into one template <class charT> struct char_traits<charT> { typedef char char_type; typedef int int_type; static char_type to_char_type(int_type c) { return c; } // etc. +------- END BOX 3 -------+ template <class charT> struct ios_baggage {}; struct ios_baggage<char> { typedef ios_char_baggage<char> char_bag; typedef ios_pos_baggage<streampos> pos_bag; }; struct ios_baggage<wchar_t> { typedef ios_char_baggage<wchar_t> char_bag; typedef ios_pos_baggage<wstreampos> pos_bag; }; 2 The template struct ios_baggage<charT> is an baggage class which main tains the definitions of the types and functions necessary to imple ment the template IOStream classes. The template parameter charT rep resents the character container type and each specialized version pro vides the default definitions corresponding to the specialized charac ter container type. 3 All of the types and functions provided in this struct can be classi fied into two categories, character-container-type-related and posi tional-information-related. Each of the specialized struct, ios_baggage<CHAR_T>, in which CHAR_T represents the specialized type of the character container type, typedefs two specialized template structs, ios_char_baggage<CHAR_T> and ios_pos_baggage<POS_T>, in which POS_T represents a specialized version of the repositioning informa tion class. 27.1.1.2 Template struct ios_char_baggage [lib.ios.char.baggage] template <class charT> struct ios_char_baggage : public string_char_baggage<charT> {}; 1 Every implementation shall provide the following two specialization versions of the ios_char_baggage1): struct ios_char_baggage<char> { typedef char char_type; typedef int int_type; _________________________ 1) The two types wchar_t and wint_t are declared in <cwchar>. static char_type to_char_type(int_type c) { return c; } static int_type to_int_type (char_type c) { return c; } static bool eq_char_type(char_type c1, char_type c2) { return c1 == c2; } static bool eq_int_type (int_type c1, int_type c2) { return c1 == c2; } static int_type eof() { return EOF; } static int_type not_eof() { return ~EOF; } static bool is_eof(int_type c) { return c == EOF; } static char_type newline() { return '\n'; } static bool is_whitespace(char_type c, locale::ctype<char> ctype) { return ctype.isspace<char>(c); } static char_type eos() { return 0; } static size_t length(const char_type* s) { return strlen(s); } static char_type* copy(char_type* dst, const char_type* src, size_t n) { return strcpy(dst,src,size); } }; struct ios_char_baggage<wchar_t> { typedef wchar_t char_type; typedef wint_t int_type; static char_type to_char_type(int_type c) { return c; } static int_type to_int_type (char_type c) { return c; } static bool eq_char_type(char_type c1, char_type c2) { return c1 == c2; } static bool eq_int_type (int_type c1, int_type c2) { return c1 == c2; } static int_type eof() { return WEOF; } static int_type not_eof() { return ~WEOF; } static bool is_eof(int_type c) { return c == WEOF; } static char_type newline() { return L'\n'; } static bool is_whitespace(char_type c, locale::ctype<char_type> ctype) { return ctype.isspace<char_type>(c); } static char_type eos() { return 0; } +------- BEGIN BOX 4 -------+ The following two functions were not defined in the proposal. They should be give the generic definitions. Is that clear? +------- END BOX 4 -------+ static size_t length(const char_type* s); static char_type* copy(char_type* dst, const char_type* src, size_t n); }; +------- BEGIN BOX 5 -------+ There are several types and functions needed for implementing the tem plate IOStream classes. Some of these types and functions depend on the definition of the character container type. The collection of these functions describes the behavior which the implementation of the template IOStream class expects to the character container class. Those who provide a character container class as the template parame ter have to provide all of these functions as well as the container class itself. The collection of these functions can be regarded as the collection of the common definitions for the implementation of the character container class. No special definition/declaration is provided here. The base class (or struct), string_char_baggage provides the common definitions common between the template string classes and the template IOStream classes. +------- END BOX 5 -------+ 2 The template struct ios_char_baggage<charT> is a struct derived from the class string_char_baggage<charT>. For each of the character con tainer classes, CHAR_T, the corresponding specialized struct ios_char_baggage<CHAR_T> prepares the definitions related to the char acter container type so that it provides all the functionality neces sary to implement the template IOStream classes. 3 Each of the specialization of the struct ios_char_baggage shall have the following definitions: struct ios_char_baggage<CHAR_T> { typedef CHAR_T char_type; typedef INT_T int_type; static char_type to_char_type (int_type); static int_type to_int_type (char_type); static bool eq_char_type (char_type, char_type); static bool eq_int_type (int_type, int_type); static int_type eof(); static int_type not_eof(); +------- BEGIN BOX 6 -------+ Jerry Schwarz proposal: Change the declaration of not_eof to static int_type not_eof(char_type c); with a generic description that it returns a value other than eof(). 4 This is the way the function is used by implementations. It can be implemented efficiently in many cases and it provides an easy way for me to specify return values in the working paper. +------- END BOX 6 -------+ static bool is_eof(int_type); static char_type newline(); static bool is_whitespace(locale::ctype<char_type> ctype, char_type c); static char_type eos(); static size_t length(const char_type* s); static char_type* copy(char_type* dst, const char_type* src, size_t n) ; }; +------- BEGIN BOX 7 -------+ If the proposal for flattening the baggage classes is accepted, these classes will also need to be flattened. A reasonable structure would be class std_pos_traits { // note that this is not a template typedef streampos pos_t; typedef streamoff off_t; } template <class charT> struct std_traits<charT> : public std_char_traits<charT>, public std_pos_traits { } struct std_traits<wchar_t> : public std_char_traits<wchar_t> { typedef wstreampos pos_t; typedef wstreamoff off_t; // implementations are free to replace any other function provided // it satisfies the generic constraints for the given trait. } +------- END BOX 7 -------+ 27.1.1.2.1 Type [lib.ios.char.baggage::int.t] ios_char_baggage::INT_T INT_T 1 Another character container type which can also hold an end-of-file value. It is used as the return type of some of the IOStream class member functions. If CHAR_T is either char or wchar_t, INT_T shall be int or wint_t, respectively. 27.1.1.2.2 Type [lib.ios.char.baggage::char.type] ios_char_baggage::char_type char_type 1 A synonym of the character container type, CHAR_T. 27.1.1.2.3 Type [lib.ios.char.baggage::int.type] ios_char_baggage::int_type int_type 1 A synonym of the character container type, INT_T. 27.1.1.2.4 [lib.ios.char.baggage::to.char.type] ios_char_baggage::to_char_type char_type to_char_type(int_type c); 1 Converts a valid character value represented in the int_type to the corresponding char_type value. If c is the end-of-file value, the return value is unspecified. 27.1.1.2.5 [lib.ios.char.baggage::to.int.type] ios_char_baggage::to_int_type int_type to_int_type(char_type c); 1 Converts a valid character value represented in the char_type to the corresponding int_type value. 27.1.1.2.6 [lib.ios.char.baggage::eq.char.type] ios_char_baggage::eq_char_type bool eq_char_type(char_type c1, char_type c2); 1 Returns true if c1 and c2 represent the same character. 27.1.1.2.7 [lib.ios.char.baggage::eq.int.type] ios_char_baggage::eq_int_type bool eq_int_type(int_type c1, int_type c2); 1 Returns true if c1 and c2 represent the same character. 27.1.1.2.8 ios_char_baggage::eof [lib.ios.char.baggage::eof] int_type eof(); 1 Returns an int_type value which represents the end-of-file. It is returned by several functions to indicate end-of-file state (no more input from an input sequence or no more output permitted to an output sequence), or to indicate an invalid return value. 27.1.1.2.9 [lib.ios.char.baggage::not.eof] ios_char_baggage::not_eof int_type not_eof(); 1 Returns a certain int_type value other than the end-of-file. It is used in basic_streambuf<charT,baggage>::overflow(). 27.1.1.2.10 [lib.ios.char.baggage::is.eof] ios_char_baggage::is_eof bool is_eof(int_type c); 1 Returns true if c represent the end-of-file. 27.1.1.2.11 [lib.ios.char.baggage::newline] ios_char_baggage::newline char_type newline(); 1 Returns a character value which represent the newline character of the basic character set. It appears as the default parameter of basic_istream<charT,baggage>::getline(). 27.1.1.2.12 [lib.ios.char.baggage::is.whitespace] ios_char_baggage::is_whitespace bool is_whitespace(char_type c, locale::ctype<char_type> ctype); 1 Returns true if c represents one of the white space characters. The default definition is as if it returns ctype.isspace(c). 2 An implementation of the template IOStream classes may use all of the above static member functions in addition to the following three func tions provided from the base struct string_char_baggage<CHAR_T>. 27.1.1.2.13 ios_char_baggage::eos [lib.ios.char.baggage::eos] char_type eos(); 1 Returns the null character which is used for the terminator of null terminated character strings. The default constructor for the charac ter container type provides the value. 27.1.1.2.14 [lib.ios.char.baggage::length] ios_char_baggage::length size_t length(const char_type* s); 1 Determines the length of a null terminated character string pointed to by s. 27.1.1.2.15 ios_char_baggage::copy [lib.ios.char.baggage::copy] char_type* copy(char_type* dest, const char_type* src, size_t n); 1 Copies n characters from the object pointed to by src into the object pointed to by dest. If copying takes place between objects that over lap, the behavior is undefined. +------- BEGIN BOX 8 -------+ The reason that these two member functions, length and copy, are pre pared is to achive efficiency for char and wchar_t specialized ver sions. If the character container type require no special construc tion/destruction operations (or it is a immutable class), the memory copy operation leads us to avoid inefficiency which an explicit copy loop in the implementation of the template IOStream classes give rise to. +------- END BOX 8 -------+ 27.1.2 Positional information [lib.positional] +------- BEGIN BOX 9 -------+ The description of the following member functions is incomplete. The behavior and specification of the streampos/streamoff should need more discussion. +------- END BOX 9 -------+ 27.1.2.1 Template struct ios_pos_baggage [lib.ios.pos.baggage] template <class posT> struct ios_pos_baggage {}; struct ios_pos_baggage<streampos> { typedef streampos pos_type; typedef streamoff off_type; }; struct ios_pos_baggage<wstreampos> { typedef wstreampos pos_type; typedef wstreamoff off_type; }; 1 The template struct ios_pos_baggage<posT> is a struct. For each of the repositional information class, POS_T, the corresponding special ized struct ios_pos_baggage<POS_T> prepares the typedefs related to the POS_T. 2 +------- BEGIN BOX 10 -------+ Jerry Schwarz proposal: Rewrite the following sections to clarify that we are talking about generic requirements for members of a user supplied baggage::pos_bag and not only ios_char_baggage specializa tions. +------- END BOX 10 -------+ Each of the specialization of the struct ios_pos_baggage shall have the following definitions: struct ios_pos_baggage<POS_T> { typedef POS_T pos_type; typedef OFF_T off_type; }; 27.1.2.1.1 Type [lib.ios.pos.baggage::off.t] ios_pos_baggage::OFF_T OFF_T; 1 A synonym for one of the signed integral types whose representation has at least as many bits as type long. 27.1.2.1.2 Type [lib.ios.pos.baggage::off.type] ios_pos_baggage::off_type off_type; 1 A synonym of the OFF_T and is used for declaring/implementing the tem plate IOStream class. 27.1.2.1.3 Type [lib.ios.pos.baggage::pos.t] ios_pos_baggage::POS_T POS_T; 1 An implementation-defined class for seek operations which describes an object that can store all the information necessary to restore to the position. 27.1.2.1.4 Type [lib.ios.pos.baggage::pos.type] ios_pos_baggage::pos_type pos_type; 1 A synonym for the class POS_T which is used for declaring/implementing the template IOStream classes. 27.1.2.2 Type OFF_T requirements [lib.off.t.reqmts] 1 The type OFF_T is a synonym for one if the signed basic integral types T1 whose representation at least as many bits as type long. It is used to represent: --a signed displacement, measured in characters, from a specified position within a sequence. --an absolute position within a sequence. +------- BEGIN BOX 11 -------+ Jerry Schwarz proposal: Revrite the following so that it is clear that certain operations are possible on baggage::char_bag::pos_type but that it need not be a class. One of the advantages of the templatiz ing approach is that implementations can make ios_pos_baggage<char>::pos_type the same as their current streampos. +------- END BOX 11 -------+ 27.1.2.3 Type POS_T requirements [lib.pos.t.reqmts] 1 Every class that can apply to the template parameter posT in the tem plate struct ios_pos_baggage shall have following definitions: typedef T1 OFF_T; +------- BEGIN BOX 12 -------+ Jerry Schwarz proposal: Replace POS_T::offset by fPOS_T::operator OFF_T. The point is to allow POS_T to be a non-class. +------- END BOX 12 -------+ class POS_T { public: POS_T(int off); POS_T(OFF_T off = 0); OFF_T offset() const; OFF_T operator- (POS_T& rhs); POS_T& operator+=(OFF_T off); POS_T& operator-=(OFF_T off); POS_T operator+ (OFF_T off); POS_T operator- (OFF_T off); bool operator==(POS_T& rhs) const; bool operator!=(POS_T& rhs) const; }; +------- BEGIN BOX 13 -------+ The asymmetries implied by making operator+, operator-, operator== and operator!= members rather than global operators are unpleasant. +------- END BOX 13 -------+ +------- BEGIN BOX 14 -------+ This subclause need more discussion. How do we treat the case if the external source/sink stream does not ensure to accept POS_T, OFF_T object to which some arithmetic operations performed? +------- END BOX 14 -------+ 2 The class POS_T describes an object that can store all the information necessary to restore one or more types of sequences to a previous stream position. Every POS_T class has the corresponding OFF_T type and the set of applicable stream classes. --Repositional Streams and Arbitrary-positional Streams There are two types of stream: repositional and arbitrary-positional. +------- BEGIN BOX 15 -------+ There are also non-positional streams in which no seeking is possible. +------- END BOX 15 -------+ 3 With a repositional stream, we can seek to only the position where we previously encountered. On the other hand, with an arbitrary- positional stream, we can seek to any integral position within the length of the stream. 4 For a stream buffer which is corresponding to a repositional stream (but not a arbitrary-positional stream), all we can do is either to fetch the current position of the stream buffer or to specify the pre vious position which we have already fetched from the stream buffer. 5 Every arbitrary-positional stream is a repositional. 6 If a repositional stream returns a POS_T object, and some arithmetic operations (operator+=, operator-, operator+=, operator-=) are applied, the behavior of the stream after restoring the position with the modified POS_T object is undefined. It means that a POS_T object whose parent stream is repositional shall not apply any arithmetic operations. 7 It is not ensured that in case the validity of a certain POS_T object is broken, the error shall be informed. Or there is no way to check the validity of a certain POS_T object. --Invalid POS_T value The stream operations whose return type is POS_T may return POS_T((OFF_T)(-1)) as signal to some error occurs. This return value is called the invalid POS_T value. The constructor POS_T::POS_T((OFF_T)(-1)) constructs the invalid POS_T value, which is available only for comparing to the return value of such member functions. 27.1.2.3.1 POS_T constructors [lib.pos.t.cons] POS_T(int off); POS_T(OFF_T off = 0); 1 [Almost same as _lib.streampos.cons_] 2 Constructs an object of type POS_T, initializing pos to zero and fp to the stream position at the beginning of the sequence, with the conver sion state at the beginning of a new multibyte sequence in the initial shift state.2) The constructor then evaluates the expression *this += off. 27.1.2.3.2 POS_T::offset [lib.ios.pos.t.offset] OFF_T offset() const; 1 [Almost same as _lib.streampos.offset_] _________________________ 2) The next character to read or write is the first character in the sequence. 2 Determines the value of type OFF_T that represents the stream position stored in pos and fp, if possible, and returns that value. Otherwise, returns (OFF_T)(-1). For a sequence requiring a conversion state, even a representable value of type OFF_T need not supply sufficient information to restore the stored stream position. 27.1.2.3.3 POS_T::operator- [lib.ios.pos.t.op-.pos.t] OFF_T operator- (POS_T& rhs); 1 [Almost same as _lib.streampos.op-_] 2 Determines the value of type POS_T that represents the difference in stream positions between *this and rhs, if possible, and returns that value. (If *this is a stream position nearer the beginning of the sequence than rhs, the difference is negative.) Otherwise, returns (streamoff)(-1). For a sequence that does not represent stream posi tions in uniform units, even a representable value need not be mean ingful. 3 If the parent stream is not arbitrary-positional, the value of the operation becomes invalid so it may not apply the parent stream. 27.1.2.3.4 POS_T::operator+= [lib.ios.pos.t.op+=] POS_T& operator+=(OFF_T off); 1 [Almost same as _lib.streampos.op+=_] 2 Adds off to the stream position stored in pos and fp, if possible, and replaces the stored values. Otherwise, the function stores an invalid stream position in pos and fp. For a sequence that does not represent stream positions in uniform units, the resulting stream position need not be meaningful. 3 Returns *this. 4 If the parent stream is not arbitrary-positional, the value of the operation becomes invalid so it may not apply the parent stream. 27.1.2.3.5 POS_T::operator-= [lib.ios.pos.t.op-=] POS_T& operator-=(OFF_T off); 1 [Almost same as _lib.streampos.op-=_] 2 Subtracts off from the stream position stored in pos and fp, if possi ble, and replaces the stored value. Otherwise, the function stores an invalid stream position in pos and fp. For a sequence that does not represent stream positions in uniform units, the resulting stream position need not be meaningful. 3 Returns *this. 4 If the parent stream is not arbitrary-positional, the value of the operation becomes invalid so it may not apply the parent stream. 27.1.2.3.6 POS_T::operator+ [lib.ios.pos.t.op+] POS_T operator+ (OFF_T off); 1 [Almost same as _lib.streampos.op+_] 2 Returns POS_T(*this) += off. 27.1.2.3.7 POS_T::operator- [lib.ios.pos.t.op-.off.t] POS_T operator- (OFF_T off); 1 [Almost same as _lib.streampos.op-_] 2 Returns POS_T(*this) -= off. 27.1.2.3.8 POS_T::operator== [lib.ios.pos.t.op==] bool operator==(POS_T& rhs) const; 1 [Almost same as _lib.streampos.op==_] 2 Compares the stream position stored in *this to the stream position stored in rhs, and returns true if the two correspond to the same position within a file or if both store an invalid stream position. 27.1.2.3.9 POS_T::operator!= [lib.ios.pos.t.op!=] bool operator!=(POS_T& rhs) const; 1 [Almost same as _lib.streampos.op!=_] 2 Returns true if !(*this == rhs). 27.1.2.4 Type streamoff [lib.streamoff] typedef T2 streamoff; 1 The type streamoff is a synonym for one of the signed basic integral types T1 whose representation has at least as many bits as type long. The corresponding POS_T class is the class, streampos. It is used to represent: --a signed displacement, measured in bytes, from a specified position within a sequence; 2 If a streamoff object has a value other than the parent stream returns (for example, assigned an arbitrary integer), the value may not apply any streams. 3 Any streamoff object can be converted to a streampos object is ensured. But no validity of the result streampos object is ensured, whether the streamoff object is valid or else. 27.1.2.5 Type streamsize [lib.streamsize] typedef T3 streamsize; 1 The type streamsize is a synonym for one of the signed basic integral types. It is used to represent the number of characters transferred in an I/O operation, or the size of I/O buffers.3) 27.1.2.6 Class wstreamoff [lib.wstreamoff] 1 [Almost the same description as in streamoff] 27.1.2.7 Class streampos [lib.streampos] 1 In this subclause, the type name fpos_t is a synonym for the type fpos_t defined in <cstdio> (_lib.file.streams_). class streampos { public: streampos(streamoff off = 0); streamoff offset() const; streamoff operator-(streampos& rhs) const; streampos& operator+=(streamoff off); streampos& operator-=(streamoff off); streampos operator+(streamoff off) const; streampos operator-(streamoff off) const; bool operator==(const streampos& rhs) const; bool operator!=(const streampos& rhs) const; private: // streamoff pos; exposition only // fpos_t fp; exposition only }; 27.1.2.8 Class wstreampos [lib.wstreampos] 1 [Almost the same description as in streampos] 2 The class streampos describes an object that can store all the infor mation necessary to restore an arbitrary sequence, controlled by the Standard C++ library, to a previous stream position and conversion state.4) For the sake of exposition, the data it stores is presented here as: --streamoff pos, specifies the absolute position within the sequence; --fpos_t fp, specifies the stream position and conversion state in the implementation-dependent form required by functions declared in <cstdio>. _________________________ 3) streamsize is used in most places where ISO C would use size_t. Most of the uses of streamsize could use size_t, except for the strstreambuf constructors, which require negative values. The streamsize type should probably be the signed type corresponding to size_t (which is what Posix.2 calls ssize_t). 4) The conversion state is used for sequences that translate between wide-character and generalized multibyte encoding, as described in Amendment 1 to the C Standard. 3 It is unspecified how these two member objects combine to represent a stream position. 27.1.2.8.1 streampos constructor [lib.streampos.cons] +------- BEGIN BOX 16 -------+ One of the advantages of the template approach is that streampos can does not have to hold the state information required for wide oriented streams. 1 Jerry Schwarz proposal: Replace this section with: streaampos satis fies the generic constraints on a POS_T. +------- END BOX 16 -------+ streampos(streamoff off = 0); 2 Constructs an object of class streampos, initializing pos to zero and fp to the stream position at the beginning of the sequence, with the conversion state at the beginning of a new multibyte sequence in the initial shift state.5) The constructor then evaluates the expression *this += off. 27.1.2.8.2 streampos::offset [lib.streampos::offset] streamoff offset() const; 1 Determines the value of type streamoff that represents the stream position stored in pos and fp, if possible, and returns that value. Otherwise, returns (streamoff)(-1). 2 For a sequence requiring a conversion state, even a representable value of type streamoff need not supply sufficient information to restore the stored stream position. 27.1.2.8.3 streampos::operator- [lib.streampos::op-.sp] streamoff operator-(streampos& rhs) const; 1 Determines the value of type streamoff that represents the difference in stream positions between *this and rhs, if possible, and returns that value. (If *this is a stream position nearer the beginning of the sequence than rhs, the difference is negative.) Otherwise, returns (streamoff)(-1). 2 For a sequence that does not represent stream positions in uniform units, even a representable value need not be meaningful. 27.1.2.8.4 streampos::operator+= [lib.streampos::op+=] streampos& operator+=(streamoff off); 1 Adds off to the stream position stored in pos and fp, if possible, and replaces the stored values. Otherwise, the function stores an invalid _________________________ 5) The next character to read or write is the first character in the sequence. stream position in pos and fp. 2 For a sequence that does not represent stream positions in uniform units, the resulting stream position need not be meaningful. 3 Returns *this. 27.1.2.8.5 streampos::operator-= [lib.streamos::op-=] streampos& operator-=(streamoff off); 1 Subtracts off from the stream position stored in pos and fp, if possi ble, and replaces the stored value. Otherwise, the function stores an invalid stream position in pos and fp. 2 For a sequence that does not represent stream positions in uniform units, the resulting stream position need not be meaningful. 3 Returns *this. 27.1.2.8.6 streampos::operator+ [lib.streampos::op+] streampos operator+(streamoff off) const; 1 Returns streampos(*this) += off. 27.1.2.8.7 streampos::operator- [lib.streampos::op-.off] streampos operator-(streamoff off) const; 1 Returns streampos(*this) -= off. 27.1.2.8.8 streampos::operator== [lib.streampos::op==] bool operator==(const streampos& rhs) const; 1 Compares the stream position stored in *this to the stream position stored in rhs, and returns true if the two correspond to the same position within a file or if both store an invalid stream position. 27.1.2.8.9 streampos::operator!= [lib.op!=.streampos] bool operator!=(const streampos& rhs) const; 1 Returns true if !(*this == rhs). 27.1.3 Base class ios and manipulators [lib.ios.base] 1 The header <ios> defines three types that controls input from and out put to character sequence. 27.1.3.1 Template class basic_ios [lib.ios] template<class charT, class baggage = ios_baggage<charT> > class basic_ios { typedef basic_ios<charT,baggage> ios_type; public: typedef charT char_type; typedef baggage::char_bag::int_type int_type; typedef baggage::pos_bag::pos_type pos_type; typedef baggage::pos_bag::off_type off_type; int_type eof() { return baggage::char_bag::eof(); } char_type newline() { return baggage::char_bag::newline(); } +------- BEGIN BOX 17 -------+ Note: An idea to declare eof as a constant, that is, static const IEOF = baggage::char_bag::eof(), is rejected because it cause a constraint that charT and int_type should be integral types. +------- END BOX 17 -------+ class failure : public exception { public: failure(const string& what_arg); virtual ~failure(); // virtual string what() const; inherited protected: }; typedef T1 fmtflags; static const fmtflags boolalpha; static const fmtflags dec; static const fmtflags fixed; static const fmtflags hex; static const fmtflags internal; static const fmtflags left; static const fmtflags oct; static const fmtflags right; static const fmtflags scientific; static const fmtflags showbase; static const fmtflags showpoint; static const fmtflags showpos; static const fmtflags skipws; static const fmtflags unitbuf; static const fmtflags uppercase; static const fmtflags adjustfield; static const fmtflags basefield; static const fmtflags floatfield; typedef T2 iostate; static const iostate badbit; static const iostate eofbit; static const iostate failbit; static const iostate goodbit; typedef T3 openmode; static const openmode app; static const openmode ate; static const openmode binary; static const openmode in; static const openmode out; static const openmode trunc; typedef T4 seekdir; static const seekdir beg; static const seekdir cur; static const seekdir end; class Init { public: Init(); ~Init(); private: // static int init_cnt; exposition only }; basic_ios(basic_streambuf<charT,baggage>* sb_arg); virtual ~basic_ios(); operator bool() const bool operator!() const ios_type& copyfmt(const ios_type& rhs); basic_ostream<charT,baggage>* tie() const; basic_ostream<charT,baggage>* tie(basic_ostream<charT,baggage>* tiestr_arg); basic_streambuf<charT,baggage>* rdbuf() const; basic_streambuf<charT,baggage>* rdbuf(basic_streambuf<charT,baggage>* sb_arg); +------- BEGIN BOX 18 -------+ Note: template parameter coupling between basic_ios and basic_streambuf: Both basic_ios and basic_streambuf corresponding to it should take the same template parameter <charT,baggage>. We need not allow to make a couple of basic_ios<wchar_t> and basic_streambuf<char>. +------- END BOX 18 -------+ iostate rdstate() const; void clear(iostate state_arg = goodbit); void setstate(iostate state_arg); bool good() const; bool eof() const; bool fail() const; bool bad() const; iostate exceptions() const; void exceptions(iostate except_arg); fmtflags flags() const; fmtflags flags(fmtflags fmtfl_arg); fmtflags setf(fmtflags fmtfl_arg); fmtflags setf(fmtflags fmtfl_arg, fmtflags mask); void unsetf(fmtflags mask); +------- BEGIN BOX 19 -------+ Specifying fill character. It is represented as int_type. +------- END BOX 19 -------+ int_type fill() const; int_type fill(int_type ch); int precision() const; int precision(int prec_arg); int width() const; int width(int wide_arg); locale imbue(const locale& loc_arg); locale getloc() const; static int xalloc(); long& iword(int index_arg); void*& pword(int index_arg); protected: basic_ios(); void init(basic_streambuf<charT,baggage>* sb_arg); private: // basic_streambuf<charT,baggage>* sb; exposition only // basic_ostream<charT,baggage>* tiestr; exposition only // iostate state; exposition only // iostate except; exposition only // fmtflags fmtfl; exposition only // int prec; exposition only // int wide; exposition only // char fillch; exposition only // locale loc; exposition only // static int index; exposition only // int* iarray; exposition only // void** parray; exposition only }; +------- BEGIN BOX 20 -------+ Lots of things that should be the same in all instantiations of basic_ios are made members. In particular it seems that failure, fmt flags, iostate, openmode, seekdir, and all the constants of these types should be the same in different instances. Jerry Schwarz proposal: class ios_constants { class failure .... ; typedef T1 fmtflags; ....; // bits of fmtflags; typedef T2 iostate; ....; // bits of iostate typedef T3 openmode; ....; // bits of openmode typedef T4 seekdir; ....; // bits of seekdir }; template<class charT, class traits = std_traits<charT> > class basic_ios : public ios_constants { .... }; +------- END BOX 20 -------+ class ios : public basic_ios<char> {} class wios : public basic_ios<wchar_t> {} +------- BEGIN BOX 21 -------+ Jerry Schwarz proposal: Replace with typedef basic_ios<char> ios ; typedef basic_ios<wchar_t> wios; +------- END BOX 21 -------+ 1 The template class basic_ios<charT,baggage> serves as a base class for the classes basic_istream<charT,baggage> and basic_ostream<charT,baggage>. 2 The class ios is an instance of the template class basic_ios, special ized by the type char. 3 The class wios is a version of the template class basic_ios special ized by the type wchar_t. 4 basic_ios defines several member types: --a class failure derived from exception; --a class Init; +------- BEGIN BOX 22 -------+ Jerry Schwarz proposal: Eliminate basic_ios::Init and replace it by a requirement (in _lib.iostreams_) that the standard streams should be initialized before startup. We had a discussion of this in San Diego and I think this was the consensus. The "nifty counter" trick is gen erally regarded as a bad way to cause initialization of the standard streams because of the overheads. +------- END BOX 22 -------+ --three bitmask types, fmtflags, iostate, and openmode; --an enumerated type, seekdir. 5 It maintains several kinds of data: --a pointer to a stream buffer, an object of class basic_streambuf<charT,baggage>, that controls sources (input) and sinks (output) of character sequences; the parameter charT specifies the type of character; --state information that reflects the integrity of the stream buffer; --control information that influences how to interpret (format) input sequences and how to generate (format) output sequences; --additional information that is stored by the program for its private use. 6 For the sake of exposition, the maintained data is presented here as: --basic_streambuf<charT,baggage>* sb, points to the stream buffer; --basic_ostream<charT,baggage>* tiestr, points to an output sequence that is tied to (synchronized with) an input sequence controlled by the stream buffer; --iostate state, holds the control state of the stream buffer; --iostate except, holds a mask that determines what elements set in state cause exceptions to be thrown; --fmtflags fmtfl, holds format control information for both input and output; --int wide, specifies the field width (number of characters) to gener ate on certain output conversions; --int prec, specifies the precision (number of digits after the deci mal point) to generate on certain output conversions; --char fillch, specifies the character to use to pad (fill) an output conversion to the specified field width; --locale loc, specifies the locale in which to perform locale- dependent input and output operations; --static int index, specifies the next available unique index for the integer or pointer arrays maintained for the private use of the pro gram, initialized to an unspecified value; --int* iarray, points to the first element of an arbitrary-length integer array maintained for the private use of the program; --void** parray, points to the first element of an arbitrary-length pointer array maintained for the private use of the program. 27.1.3.1.1 Class basic_ios::failure [lib.ios::failure] class failure : public exception { public: failure(const string& what_arg); virtual ~failure(); // virtual string what() const; inherited }; 1 The class failure defines the base class for the types of all objects thrown as exceptions, by functions in the iostreams library, to report errors detected during stream buffer operations. 27.1.3.1.1.1 basic_ios::failure [lib.basic.ios::failure.cons] constructor failure(const char* what_arg = 0); 1 Constructs an object of class failure, initializing the base class with exception(what_arg). +------- BEGIN BOX 23 -------+ Jerry Schwarz proposal: Allow an implementation defined default value. +------- END BOX 23 -------+ 27.1.3.1.1.2 [lib.basic.ios::failure.des] basic_ios::failure::~failure destructor virtual ~failure(); 1 Destroys an object of class failure. 27.1.3.1.1.3 basic_ios::failure::what [lib.ios::failure::what] // virtual string what() const; inherited 1 Behaves the same as exception::what(). 27.1.3.1.2 Type basic_ios::fmtflags [lib.ios::fmtflags] typedef T1 fmtflags; 1 The type fmtflags is a bitmask type (indicated here as T1). Setting its elements has the effects indicated in Table 3: Table 3--fmtflags effects ----------------------------------------------------------------------- Element Effect(s) if set ----------------------------------------------------------------------- boolalpha insert and extract bool type in alphabetic for mat dec converts integer input or generates integer output in decimal base fixed generate floating-point output in fixed-point notation; hex converts integer input or generates integer output in hexadecimal base; internal adds fill characters at a designated internal point in certain gener ated output; left adds fill characters on the left (initial posi tions) of certain gen erated output; oct converts integer input or generates integer output in octal base; right adds fill characters on the right (final posi tions) of certain gen erated output; scientific generates floating- point output in scien tific notation; showbase generates a prefix in dicating the numeric base of generated inte ger output; showpoint generates a decimal- point character uncon ditionally in generated floating-point output; showpos generates a + sign in non-negative generated numeric output; skipws skips leading white space before certain input operations; | | | | | | | | | unitbuf flushes output after | | each output operation; | | uppercase replaces certain lower | | case letters with their | | uppercase equivalents | | in generated output. | +---------------------------------------------------------------------+ 2 Type fmtflags also defines the constants indicated in Table 4: Table 4--fmtflags constants +--------------------------------------+ | Constant Allowable values | +--------------------------------------+ |adjustfield left | right | internal | |basefield dec | oct | hex | |floatfield scientific | fixed | +--------------------------------------+ 27.1.3.1.3 Type basic_ios::iostate [lib.ios::iostate] typedef T2 iostate; 1 The type iostate is a bitmask type (indicated here as T2). It con tains the elements indicated in Table 5: Table 5--iostate effects +---------------------------------------------------------------------+ | Element Effect(s) if set | +---------------------------------------------------------------------+ | badbit indicates a loss of in | | tegrity in an input or | | output sequence (such | | as an irrecoverable | | read error from a | | file); | | eofbit indicates that an input | | operation reached the | | end of an input se | | quence; | | failbit indicates that an input | | operation failed to | | read the expected char | | acters, or that an out | | put operation failed to | | generate the desired | | characters. | +---------------------------------------------------------------------+ 2 Type iostate also defines the constant: --goodbit, the value zero. 27.1.3.1.4 Type basic_ios::openmode [lib.ios::openmode] typedef T3 openmode; 1 The type openmode is a bitmask type (indicated here as T3). It con tains the elements indicated in Table 6: Table 6--openmode effects +---------------------------------------------------------------------+ | Element Effect(s) if set | +---------------------------------------------------------------------+ | app seek to end-of-file be | | fore each write to the | | file | | ate open a file and seek to | | end-of-file immediately | | after opening the file | | binary perform input and out | | put in binary mode (as | | opposed to text mode) | | in open a file for input | | out open a file for output | | trunc truncate an existing | | file when opening it | +---------------------------------------------------------------------+ 27.1.3.1.5 Type basic_ios::seekdir [lib.ios::seekdir] typedef T4 seekdir; 1 The type seekdir is an enumerated type (indicated here as T4). It contains the elements indicated in Table 7: Table 7--seekdir effects +---------------------------------------------------------------------+ | Element Meaning | +---------------------------------------------------------------------+ | beg request a seek (posi | | tioning for subsequent | | input or output within | | a sequence) relative to | | the beginning of the | | stream | | cur request a seek relative | | to the current position | | within the sequence | | end request a seek relative | | to the current end of | | the sequence | +---------------------------------------------------------------------+ 27.1.3.1.6 Class basic_ios::Init [lib.ios::Init] +------- BEGIN BOX 24 -------+ Jerry Schwarz proposal: Eliminate basic_ios::Init and replace it by a requirement (in _lib.iostreams_) that the standard streams should be initialized before startup. We had a discussion of this in San Diego and I think this was the consensus. The "nifty counter" trick is gen erally regarded as a bad way to cause initialization of the standard streams because of the overheads. +------- END BOX 24 -------+ class Init { public: Init(); ~Init(); private: // static int init_cnt; exposition only }; 1 The class Init describes an object whose construction ensures the con struction of the four objects declared in <iostream> that associate file stream buffers with the standard C streams provided for by the functions declared in <cstdio> (_lib.file.streams_). 2 For the sake of exposition, the maintained data is presented here as: --static int init_cnt, counts the number of constructor and destructor calls for class Init, initialized to zero. 27.1.3.1.6.1 basic_ios::Init [lib.basic.ios::init.cons] constructor Init(); 1 Constructs an object of class Init. If init_cnt is zero, the function stores the value one in init_cnt, then constructs and initializes the four objects cin (_lib.cin_), cout (_lib.cout_), cerr (_lib.cerr_), and clog (_lib.clog_). In any case, the function then adds one to the value stored in init_cnt. 27.1.3.1.6.2 basic_ios::Init [lib.basic.ios::init.des] destructor ~Init(); 1 Destroys an object of class Init. The function subtracts one from the value stored in init_cnt and, if the resulting stored value is one, calls cout.flush(), cerr.flush(), and clog.flush(). 27.1.3.1.7 basic_ios::basic_ios [lib.basic.ios.sb.cons] constructor basic_ios(basic_streambuf<charT,baggage>* sb_arg); 1 Constructs an object of class basic_ios, assigning initial values to its member objects by calling init(sb_arg). 27.1.3.1.8 basic_ios destructor [lib.basic.ios.des] virtual ~basic_ios(); 1 Destroys an object of class basic_ios. 27.1.3.1.9 basic_ios::operator bool [lib.ios::operator.bool] operator bool() const 1 Returns a non-null pointer (whose value is otherwise unspecified) if failbit | badbit is set in state. 27.1.3.1.10 basic_ios::operator! [lib.ios::operator!] bool operator!() const 1 Returns true if failbit | badbit is set in state. 27.1.3.1.11 basic_ios::copyfmt [lib.ios::copyfmt] basic_ios<charT,baggage>& copyfmt(const basic_ios<charT,baggage>& rhs); 1 Assigns to the member objects of *this the corresponding member objects of rhs, except that: --sb and state are left unchanged; --except is altered last by calling exception(rhs.except). --The contents of arrays pointed at by pword and iword are copied not the pointers themselves.6) _________________________ 2 If any newly stored pointer values in *this point at objects stored outside the object rhs, and those objects are destroyed when rhs is destroyed, the newly stored pointer values are altered to point at newly constructed copies of the objects. 3 Returns *this. 27.1.3.1.12 basic_ios::tie [lib.ios::tie] basic_ostream<charT,baggage>* tie() const; 1 Returns tiestr. basic_ostream<charT,baggage>* tie(basic_ostream<charT,baggage>* tiestr_arg); 2 Assigns tiestr_arg to tiestr and then returns the previous value stored in tiestr. 27.1.3.1.13 basic_ios::rdbuf [lib.ios::rdbuf] basic_streambuf<charT,baggage>* rdbuf() const; 1 Returns sb. basic_streambuf<charT,baggage>* rdbuf(basic_streambuf<charT,baggage>* sb_arg); 2 Assigns sb_arg to sb, then calls clear(). +------- BEGIN BOX 25 -------+ Note: need to modify so as to describe the occurence of imbueing loc::codecnv into the argument stream buffer. +------- END BOX 25 -------+ 3 Returns the previous value stored in sb. 27.1.3.1.14 basic_ios::rdstate [lib.ios::rdstate] iostate rdstate() const; 1 Returns state. 27.1.3.1.15 basic_ios::clear(iostate) [lib.ios::clear.basic.ios] void clear(iostate state_arg = goodbit); 1 Assigns state_arg to state. If sb is a null pointer, the function then sets badbit in state. If state & except is zero, returns. Oth erwise, the function throws an object fail of class failure, con structed with argument values that are implementation-defined. 27.1.3.1.16 [lib.ios::setstate.basic.ios] basic_ios::setstate(iostate) void setstate(iostate state_arg); _________________________ 6) This suggests an infinite amount of copying, but the implementation can keep track of the maximum element of the arrays that is non-zero. 1 Calls clear(state | state_arg). 27.1.3.1.17 basic_ios::good [lib.ios::good] bool good() const; 1 Returns true if state is zero. 27.1.3.1.18 basic_ios::eof [lib.ios::eof] bool eof() const; 1 Returns true if eofbit is set in state. 27.1.3.1.19 basic_ios::fail [lib.ios::fail] bool fail() const; 1 Returns true if failbit or badbit is set in state.7) 27.1.3.1.20 basic_ios::bad [lib.ios::bad] bool bad() const; 1 Returns true if badbit is set in state. 27.1.3.1.21 basic_ios::exceptions [lib.ios::exceptions] iostate exceptions() const; 1 Returns except. void exceptions(iostate except_arg); 2 Assigns except_arg to except, then calls clear(state). 27.1.3.1.22 basic_ios::flags [lib.ios::flags] fmtflags flags() const; 1 Returns fmtfl. fmtflags flags(fmtflags fmtfl_arg); 2 Assigns fmtfl_arg to fmtfl and then returns the previous value stored in fmtfl. 27.1.3.1.23 basic_ios::setf(fmtflags) [lib.ios::setf] fmtflags setf(fmtflags fmtfl_arg); 1 Sets fmtfl_arg in fmtfl and then returns the previous value stored in fmtfl. fmtflags setf(fmtflags fmtfl_arg, fmtflags mask); 2 Clears mask in fmtfl, sets fmtfl_arg & mask in fmtfl, and then returns the previous value stored in fmtfl. _________________________ 7) Checking badbit also for fail() is historical practice. 27.1.3.1.24 basic_ios::unsetf(fmtflags) [lib.ios::unsetf] void unsetf(fmtflags mask); 1 Clears mask in fmtfl. 27.1.3.1.25 basic_ios::fill [lib.ios::fill] int_type fill() const; 1 Returns fillch. int_type fill(int_type fillch_arg); 2 Assigns fillch_arg to fillch and then returns the previous value stored in fillch. 27.1.3.1.26 basic_ios::precision [lib.ios::precision] int precision() const; 1 Returns prec. int precision(int prec_arg); 2 Assigns prec_arg to prec and then returns the previous value stored in prec. 27.1.3.1.27 basic_ios::width [lib.ios::width] int width() const; 1 Returns wide. int width(int wide_arg); 2 Assigns wide_arg to wide and then returns the previous value stored in wide. 27.1.3.1.28 basic_ios::imbue [lib.ios::imbue] locale imbue(const locale loc_arg); 1 Imbues the basic_ios with the locale object, loc. In case the member pointer sb of the basic_streambuf<charT,ICB> has already initialized, the function also imbues the object pointed to by sb. 2 Assigns loc_arg to loc and then returns the previous value stored in loc. 27.1.3.1.29 basic_ios::getloc [lib.ios::getloc] locale getloc() const; 1 Returns the classic "C" locale if no locale has been imbued. Other wise, returns loc. 27.1.3.1.30 basic_ios::xalloc [lib.ios::xalloc] static int xalloc(); 1 Returns index++. 27.1.3.1.31 basic_ios::iword [lib.ios::iword] long& iword(int idx); 1 If iarray is a null pointer, allocates an array of int of unspecified size and stores a pointer to its first element in iarray. The func tion then extends the array pointed at by iarray as necessary to include the element iarray[idx]. Each newly allocated element of the array is initialized to zero. 2 Returns iarray[idx]. After a subsequent call to iword(int) for the same object, the earlier return value may no longer be valid.8) 27.1.3.1.32 basic_ios::pword [lib.ios::pword] void* & pword(int idx); 1 If parray is a null pointer, allocates an array of pointers to void of unspecified size and stores a pointer to its first element in parray. The function then extends the array pointed at by parray as necessary to include the element parray[idx]. Each newly allocated element of the array is initialized to a null pointer. 2 Returns parray[idx]. After a subsequent call to pword(int) for the same object, the earlier return value may no longer be valid. 27.1.3.1.33 basic_ios constructor [lib.basic.ios.cons] basic_ios(); 1 Constructs an object of class basic_ios, assigning initial values to its member objects by calling init(0). 27.1.3.1.34 basic_ios::init [lib.basic.ios::init] void init(basic_streambuf<charT,baggage>* sb_arg); 1 The postconditions of this function are indicated in Table 8: _________________________ 8) An implementation is free to implement both the integer array pointed at by iarray and the pointer array pointed at by parray as sparse data structures, possibly with a one-element cache for each. Table 8--init effects +----------------------------------+ |Element Value | +----------------------------------+ |sb sb_arg | |tiestr a null pointer | |state goodbit if sb_arg is | | not a null pointer, | | otherwise badbit. | |except goodbit | |fmtfl skipws | dec | |wide zero | |prec 6 | |fillch the space character | |loc new locale(), which | | means the default value | | is the current global | | locale;9) | |iarray a null pointer | |parray a null pointer | +----------------------------------+ +------- BEGIN BOX 26 -------+ Note: the default locale value shall be global but not transparent because the locality of the stream buffer will be unchanged between its lifetime. +------- END BOX 26 -------+ 27.1.3.2 Standard basic_ios manipulators [lib.std.ios.manip] 27.1.3.2.1 fmtflags manipulators [lib.fmtflags.manip] template<class charT, class baggage> basic_boolalpha<charT,baggage>& boolalpha(basic_ios<charT,baggage>& str); 1 Calls str.setf(basic_ios::boolalpha) and then returns str.10) template<class charT, class baggage> basic_ios<charT,baggage>& noboolalpha(basic_ios<charT,baggage>& str); 2 Calls str.unsetf(basic_ios::boolalpha) and then returns str. template<class charT, class baggage> basic_ios<charT,baggage>& showbase(basic_ios<charT,baggage>& str); 3 Calls str.setf(basic_ios::showbase) and then returns str. template<class charT, class baggage> basic_ios<charT,baggage>& noshowbase(basic_ios<charT,baggage>& str); _________________________ 9) Usually, locale::classic(). 4 Calls str.unsetf(basic_ios::showbase) and then returns str. 27.1.3.2.2 basic_showpoint [lib.basic.showpoint] template<class charT, class baggage> basic_ios<charT,baggage>& showpoint(basic_ios<charT,baggage>& str); 1 Calls str.setf(basic_ios::showpoint) and then returns str. template<class charT, class baggage> basic_ios<charT,baggage>& noshowpoint(basic_ios<charT,baggage>& str); 2 Calls str.unsetf(basic_ios::showpoint) and then returns str. template<class charT, class baggage> basic_ios<charT,baggage>& showpos(basic_ios<charT,baggage>& str); 3 Calls str.setf(basic_ios::showpos) and then returns str. template<class charT, class baggage> basic_ios<charT,baggage>& noshowpos(basic_ios<charT,baggage>& str); 4 Calls str.unsetf(basic_ios::showpos) and then returns str. template<class charT, class baggage> basic_ios<charT,baggage>& skipws(basic_ios<charT,baggage>& str); 5 Calls str.setf(basic_ios::skipws) and then returns str. template<class charT, class baggage> basic_ios<charT,baggage>& noskipws(basic_ios<charT,baggage>& str); 6 Calls str.unsetf(basic_ios::skipws) and then returns str. template<class charT, class baggage> basic_ios<charT,baggage>& uppercase(basic_ios<charT,baggage>& str); 7 Calls str.setf(basic_ios::uppercase) and then returns str. template<class charT, class baggage> basic_ios<charT,baggage>& nouppercase(basic_ios<charT,baggage>& str); 8 Calls str.unsetf(basic_ios::uppercase) and then returns str. 27.1.3.2.3 adjustfield manipulators [lib.adjustfield.manip] template<class charT, class baggage> basic_ios<charT,baggage>& internal(basic_ios<charT,baggage>& str); 1 Calls str.setf(basic_ios::internal, basic_ios::adjustfield) and then returns str. template<class charT, class baggage> basic_ios<charT,baggage>& left(basic_ios<charT,baggage>& str); 2 Calls str.setf(basic_ios::left, basic_ios::adjustfield) and then returns str. template<class charT, class baggage> basic_ios<charT,baggage>& right(basic_ios<charT,baggage>& str); 3 Calls str.setf(basic_ios::right, basic_ios::adjustfield) and then returns str. 27.1.3.2.4 basefield manipulators [lib.basefield.manip] template<class charT, class baggage> basic_ios<charT,baggage>& dec(basic_ios<charT,baggage>& str); 1 Calls str.setf(basic_ios::dec, basic_ios::basefield) and then returns str.10) template<class charT, class baggage> basic_ios<charT,baggage>& hex(basic_ios<charT,baggage>& str); 2 Calls str.setf(basic_ios::hex, basic_ios::basefield) and then returns str. template<class charT, class baggage> basic_ios<charT,baggage>& oct(basic_ios<charT,baggage>& str); 3 Calls str.setf(basic_ios::oct, basic_ios::basefield) and then returns str. 27.1.3.2.5 floatfield manipulators [lib.floatfield.manip] template<class charT, class baggage> basic_ios<charT,baggage>& fixed(basic_ios<charT,baggage>& str); 1 Calls str.setf(basic_ios::fixed, basic_ios::floatfield) and then returns str. template<class charT, class baggage> basic_ios<charT,baggage>& scientific(basic_ios<charT,baggage>& str); 2 Calls str.setf(basic_ios::scientific, basic_ios::floatfield) and then returns str. 27.1.4 Standard iostream objects [lib.iostream.objects] 1 The header <iostream> declares four objects that associate objects of class basic_stdiobuf with the standard C streams provided for by the functions declared in <cstdio> (_lib.file.streams_). +------- BEGIN BOX 27 -------+ Jerry Schwarz proposal: Replace the following paragraph by: The four objects are constructed and associations are established before dynamic initialization of file scope variables is begun. +------- END BOX 27 -------+ The four objects are constructed, and the associations are estab lished, the first time an object of class basic_ios<charT,baggage>::Init is constructed. The four objects are not destroyed during program execution.11) _________________________ 10) The function signature dec(basic_ios<charT,baggage>&) can be called by the function signature basic_ostream& stream::operator<<(basic_ostream& (*)(basic_ostream&)) to permit ex pressions of the form cout << dec to change the format flags stored in cout. 11) Constructors and destructors for static objects can access these objects to read input from stdin or write output to stdout or stderr. +------- BEGIN BOX 28 -------+ Note: Need to determine whether we treat cin, cout, cerr, and clog as wide-oriented or not. We can allow to change narrow-wide if only no I/O operations occurs. So the default is wide-oriented and easily modify narrow-oriented? -- mjv +------- END BOX 28 -------+ +------- BEGIN BOX 29 -------+ They can't be wide-oriented. They have the wrong type. -- jss +------- END BOX 29 -------+ +------- BEGIN BOX 30 -------+ Jerry Schwarz proposal: Add wcin, wcout, werr and wclog. +------- END BOX 30 -------+ +------- BEGIN BOX 31 -------+ Jerry Schwarz proposal: Except as noted below the state of the format state of the iostream objects after initialization is the default state established by ios::init(). +------- END BOX 31 -------+ 27.1.4.1 Object cin [lib.cin] istream cin; 1 The object cin controls input from an unbuffered stream buffer associ ated with the object stdin, declared in <cstdio>. 2 After the object cin is initialized, cin.tie() returns cout. 27.1.4.2 Object cout [lib.cout] ostream cout; 1 The object cout controls output to an unbuffered stream buffer associ ated with the object stdout, declared in <cstdio> (_lib.file.streams_). 27.1.4.3 Object cerr [lib.cerr] ostream cerr; 1 The object cerr controls output to an unbuffered stream buffer associ ated with the object stderr, declared in <cstdio> (_lib.file.streams_). 2 After the object cerr is initialized, cerr.flags() & unitbuf is nonzero. 27.1.4.4 Object clog [lib.clog] ostream clog; 1 The object clog controls output to a stream buffer associated with the object stderr, declared in <cstdio> (_lib.file.streams_). +------- BEGIN BOX 32 -------+ I think this is overspecification. The destination of clog ought to be implementation defined. --jss +------- END BOX 32 -------+ 27.2 Default stream buffers and streams [lib.default.iostreams] 1 Headers: --<streambuf> --<istream> --<ostream> 2 Table 9: Table 9--Header <streambuf> synopsis +--------------------------------------------------------+ | Type Name(s) | +--------------------------------------------------------+ |Type: streamoff | +--------------------------------------------------------+ |Template class: basic_streambuf | +--------------------------------------------------------+ |Classes: | |basic_streambuf<char> streambuf wstreambuf | |basic_streambuf<wchar_t> streampos wstreampos | +--------------------------------------------------------+ 3 Table 10: Table 10--Header <istream> synopsis +-----------------------------------------------------------------------+ | Type Name(s) | +-----------------------------------------------------------------------+ |Template classes: | |basic_istream istreambuf_iterator | +-----------------------------------------------------------------------+ |Template operators: | |operator!= (istreambuf_iterator) operator== (istreambuf_iterator) | +-----------------------------------------------------------------------+ |Template functions: | |basic_ws value_type (istreambuf_iterator) | |distance_type (istreambuf_iterator) | |iterator_category (istreambuf_iter) | +-----------------------------------------------------------------------+ |Classes: | |basic_istream<char> istream | |basic_istream<wchar_t> wistream | +-----------------------------------------------------------------------+ |Function: ws | +-----------------------------------------------------------------------+ 4 Table 11: Table 11--Header <ostream> synopsis +-----------------------------------------------------------------------+ | Type Name(s) | +-----------------------------------------------------------------------+ |Template classes: | |basic_ostream ostreambuf_iterator | +-----------------------------------------------------------------------+ |Template operators: | |operator!= (ostreambuf_iterator) operator== (ostreambuf_iterator) | +-----------------------------------------------------------------------+ |Template functions: | |basic_ends value_type (ostreambuf_iterator) | |basic_flush iterator_category (ostreambuf_iter) | +-----------------------------------------------------------------------+ |Classes: | |basic_ostream<char> ostream | |basic_ostream<wchar_t> wostream | +-----------------------------------------------------------------------+ |Functions: endl ends flush | +-----------------------------------------------------------------------+ 27.2.1 Stream buffers [lib.stream.buffers] 1 The header <streambuf> defines types that control input from and out put to character sequences. 27.2.1.1 Stream buffer requirements [lib.streambuf.reqts] 1 The following templates defined in the header <streambuf> have already been specified in subclause _lib.ios.baggage_: template class ios_baggage, template class ios_char_baggage, template class ios_pos_baggage; 2 The following defined in the header <streambuf> have already been specified in subclauses _lib.ios.char.baggage_ and _lib.ios.pos.baggage_: class ios_char_baggage<char>, class ios_char_baggage<wchar_t>, class ios_pos_baggage<streampos>, class ios_pos_baggage<wstreampos>, Type streamoff, Type streampos, Type wstreamoff, Class wstreampos. 27.2.1.2 Template class [lib.streambuf] basic_streambuf<charT,baggage> template<class charT, class baggage = ios_baggage<charT> > class basic_streambuf { public: typedef charT char_type; typedef baggage::char_bag::int_type int_type; typedef baggage::pos_bag::pos_type pos_type; typedef baggage::pos_bag::off_type off_type; +------- BEGIN BOX 33 -------+ In order to simplify descriptions and as a convenience for program mers. 1 Jerry Schwarz proposal: typedef basic_ios<char> ios; and use of the defined type as appropriate elsewhere in the working paper. +------- END BOX 33 -------+ int_type eof() { return baggage::char_bag::eof(); } char_type newline() { return baggage::char_bag::newline(); } public: virtual ~basic_streambuf(); pos_type pubseekoff(off_type off, basic_ios<charT,baggage>::seekdir way, basic_ios<charT,baggage>::openmode which = basic_ios<charT,baggage>::in | basic_ios<charT,baggage>::out); pos_type pubseekpos(pos_type sp, basic_ios<charT,baggage>::openmode which = basic_ios<charT,baggage>::in | basic_ios<charT,baggage>::out); basic_streambuf<char_type,baggage>* pubsetbuf(char_type* s, streamsize n); +------- BEGIN BOX 34 -------+ The following was not part of the proposal. Should we keep it? -- mjv +------- END BOX 34 -------+ +------- BEGIN BOX 35 -------+ Yes. I believe this was an inadvertant omission due to the proposal being based on a draft that did not contain in_avail. -- jss. +------- END BOX 35 -------+ int in_avail(); int pubsync(); int_type sbumpc(); int_type sgetc(); int sgetn(char_type* s, streamsize n); int_type snextc(); int_type sputbackc(char_type c); +------- BEGIN BOX 36 -------+ The following two were not part of the proposal. Should we keep them? -- mjv +------- END BOX 36 -------+ +------- BEGIN BOX 37 -------+ Yes. I believe this was an inadvertant omission due to the proposal being based on a draft that did not contain sungetc . -- jss. +------- END BOX 37 -------+ int sungetc(); int sputc(int c); int_type sputn(const char_type* s, streamsize n); protected: basic_streambuf(); char_type* eback() const; char_type* gptr() const; char_type* egptr() const; void gbump(int n); void setg(char_type* gbeg_arg, char_type* gnext_arg, char_type* gend_arg); char_type* pbase() const; char_type* pptr() const; char_type* epptr() const; void pbump(int n); void setp(char_type* pbeg_arg, char_type* pend_arg); virtual int_type overflow (int_type c = eof()); virtual int_type pbackfail(int_type c = eof()); +------- BEGIN BOX 38 -------+ The following was not part of the proposal. Should we keep it? -- mjv +------- END BOX 38 -------+ +------- BEGIN BOX 39 -------+ Yes. It is the public interface to in_avail. -- jss +------- END BOX 39 -------+ virtual int showmany(); virtual int_type underflow(); virtual int_type uflow(); virtual streamsize xsgetn(char_type* s, streamsize n); virtual streamsize xsputn(const char_type* s, streamsize n); virtual pos_type seekoff(off_type off, basic_ios<charT,baggage>::seekdir way, basic_ios<charT,baggage>::openmode which = in | out); virtual pos_type seekpos(pos_type sp, basic_ios<charT,baggage>::openmode which = in | out); virtual basic_streambuf<char_type,baggage>* setbuf(char_type* s, streamsize n); virtual int sync(); +------- BEGIN BOX 40 -------+ The following two member functions are introduced to support raw byte I/O, whose behaviors are implementation-defined. +------- END BOX 40 -------+ +------- BEGIN BOX 41 -------+ Private discussions in Kitchener concluded that these functions cannot be implemented in any generic fashion and that their usefulness is doubtful. 2 Jerry Schwarz proposal: Remove write_byte and read_byte here and throughout the working paper. +------- END BOX 41 -------+ virtual streamsize write_byte(const char* buf, streamsize len); virtual streamsize read_byte (char* buf, streamsize len); private: // char_type* gbeg; exposition only // char_type* gnext; exposition only // char_type* gend; exposition only // char_type* pbeg; exposition only // char_type* pnext; exposition only // char_type* pend; exposition only }; class streambuf : public basic_streambuf<char> {}; class wstreambuf : public basic_streambuf<wchar_t> {}; 3 The class template basic_streambuf<charT,baggage> serves as an abstract base class for deriving various stream buffers whose objects each control two character sequences: --a character input sequence; --a character output sequence. 4 The class streambuf is an instantiation of the template class basic_streambuf specialized by the type char. 5 The class wstreambuf is an instantiation of the template class basic_streambuf specialized by the type wchar_t. 6 Stream buffers can impose various constraints on the sequences they control. Some constraints are: --The controlled input sequence can be not readable. --The controlled output sequence can be not writable. --The controlled sequences can be associated with the contents of other representations for character sequences, such as external files. --The controlled sequences can support operations directly to or from associated sequences. --The controlled sequences can impose limitations on how the program can read characters from a sequence, write characters to a sequence, put characters back into an input sequence, or alter the stream position. 7 Each sequence is characterized by three pointers which, if non-null, all point into the same charT array object. The array object repre sents, at any moment, a (sub)sequence of characters from the sequence. Operations performed on a sequence alter the values stored in these pointers, perform reads and writes directly to or from associated sequences, and alter "the stream position" and conversion state as needed to maintain this subsequence relationship. The three pointers are: --the beginning pointer, or lowest element address in the array (called xbeg here); --the next pointer, or next element address that is a current candi date for reading or writing (called xnext here); --the end pointer, or first element address beyond the end of the array (called xend here). 8 The following semantic constraints shall always apply for any set of three pointers for a sequence, using the pointer names given immedi ately above: --If xnext is not a null pointer, then xbeg and xend shall also be non-null pointers into the same charT array, as described above. --If xnext is not a null pointer and xnext < xend for an output sequence, then a write position is available. In this case, *xnext shall be assignable as the next element to write (to put, or to store a character value, into the sequence). --If xnext is not a null pointer and xbeg < xnext for an input sequence, then a putback position is available. In this case, xnext[-1] shall have a defined value and is the next (preceding) element to store a character that is put back into the input sequence. --If xnext is not a null pointer and xnext < xend for an input sequence, then a read position is available. In this case, *xnext shall have a defined value and is the next element to read (to get, or to obtain a character value, from the sequence). 9 For the sake of exposition, the maintained data is presented here as: --char_type* gbeg, the beginning pointer for the input sequence; --char_type* gnext, the next pointer for the input sequence; --char_type* gend, the end pointer for the input sequence; --char_type* pbeg, the beginning pointer for the output sequence; --char_type* pnext, the next pointer for the output sequence; --char_type* pend, the end pointer for the output sequence. 27.2.1.2.1 basic_streambuf destructor [lib.basic.streambuf.des] virtual ~basic_streambuf(); 1 Destroys an object of class basic_streambuf. 27.2.1.2.2 [lib.streambuf::pubseekoff] basic_streambuf::pubseekoff pos_type pubseekoff(off_type off, basic_ios<charT,baggage>::seekdir way, basic_ios<charT,baggage>::openmode which = basic_ios<charT,baggage>::in | basic_ios<charT,baggage>::out); 1 Returns seekoff(off, way, which). 27.2.1.2.3 [lib.streambuf::pubseekpos] basic_streambuf::pubseekpos pos_type pubseekpos(pos_type sp, basic_ios<charT,baggage>::openmode which = basic_ios<charT,baggage>::in | basic_ios<charT,baggage>::out); 1 Returns seekpos(sp, which). 27.2.1.2.4 basic_streambuf::pubsetbuf [lib.streambuf::pubsetbuf] basic_streambuf<char_type,baggage>* pubsetbuf(char_type* s, streamsize n); 1 Returns setbuf(s, n). +------- BEGIN BOX 42 -------+ The following was not part of the proposal. Should we keep it? +------- END BOX 42 -------+ 27.2.1.2.5 basic_streambuf::in_avail [lib.streambuf::in.avail] int in_avail(); 1 If the input sequence does not have a read position available, returns showmany(). Otherwise, returns gend - gnext. 27.2.1.2.6 basic_streambuf::pubsync [lib.streambuf::pubsync] int pubsync(); 1 Returns sync(). 27.2.1.2.7 basic_streambuf::sbumpc [lib.streambuf::sbumpc] int_type sbumpc(); 1 If the input sequence does not have a read position available, returns uflow(). Otherwise, returns (char_type)*gnext++. 27.2.1.2.8 basic_streambuf::sgetc [lib.streambuf::sgetc] int_type sgetc(); 1 If the input sequence does not have a read position available, returns underflow(). Otherwise, returns (char_type)*gnext. 27.2.1.2.9 basic_streambuf::sgetn [lib.streambuf::sgetn] int sgetn(char_type* s, streamsize n); 1 Returns xsgetn(s, n). 27.2.1.2.10 basic_streambuf::snextc [lib.streambuf::snextc] int_type snextc(); 1 Calls sbumpc() and, if that function returns eof(), returns eof(). Otherwise, returns sgetc(). +------- BEGIN BOX 43 -------+ Note: baggage::eos() ... the definition of EOF +------- END BOX 43 -------+ 27.2.1.2.11 [lib.streambuf::sputbackc] basic_streambuf::sputbackc int_type sputbackc(char_type c); 1 If the input sequence does not have a putback position available, or if c != gnext[-1], returns pbackfail(c). Otherwise, returns (char_type)*--gnext. +------- BEGIN BOX 44 -------+ The following was not part of the proposal. Should we keep it? +------- END BOX 44 -------+ 27.2.1.2.12 basic_streambuf::sungetc [lib.streambuf::sungetc] int sungetc(); 1 If the input sequence does not have a putback position available, returns pbackfail(). Otherwise, returns (char_type)*--gnext. +------- BEGIN BOX 45 -------+ The following was not part of the proposal. Should we keep it? --mjv +------- END BOX 45 -------+ +------- BEGIN BOX 46 -------+ Absolutely sputc is a fundamental member of the interface -- jss +------- END BOX 46 -------+ 27.2.1.2.13 basic_streambuf::sputc [lib.streambuf::sputc] int sputc(int c); 1 If the output sequence does not have a write position available, returns overflow(c). Otherwise, returns (*pnext++ = c). 27.2.1.2.14 basic_streambuf::sputn [lib.streambuf::sputn] int_type sputn(const char_type* s, streamsize n); 1 Returns xsputn(s, n). 27.2.1.2.15 basic_streambuf [lib.basic.streambuf.cons] constructor basic_streambuf(); 1 Constructs an object of class basic_streambuf<charT,baggage> and ini tializes: 12) --all its pointer member objects to null pointers, --the loc member object to the return value of locale::global(). +------- BEGIN BOX 47 -------+ Once the loc member is initialized its locale-dependent behavior does not change until the next imbueing of the locale. +------- END BOX 47 -------+ 27.2.1.2.16 basic_streambuf::eback [lib.streambuf::eback] char_type* eback() const; 1 Returns gbeg. 27.2.1.2.17 basic_streambuf::gptr [lib.streambuf::gptr] char_type* gptr() const; 1 Returns gnext. 27.2.1.2.18 basic_streambuf::egptr [lib.streambuf::egptr] char_type* egptr() const; 1 Returns gend. 27.2.1.2.19 basic_streambuf::gbump [lib.streambuf::gbump] void gbump(int n); 1 Assigns gnext + n to gnext. _________________________ 12) The default constructor is protected for class basic_streambuf to assure that only objects for classes derived from this class may be constructed. 27.2.1.2.20 basic_streambuf::setg [lib.streambuf::setg] void setg(char_type* gbeg_arg, char_type* gnext_arg, char_type* gend_arg); 1 Assigns gbeg_arg to gbeg, gnext_arg to gnext, and gend_arg to gend. 27.2.1.2.21 basic_streambuf::pbase [lib.streambuf::pbase] char_type* pbase() const; 1 Returns pbeg. 27.2.1.2.22 basic_streambuf::pptr [lib.streambuf::pptr] char_type* pptr() const; 1 Returns pnext. 27.2.1.2.23 basic_streambuf::epptr [lib.streambuf::epptr] char_type* epptr() const; 1 Returns pend. 27.2.1.2.24 basic_streambuf::pbump [lib.streambuf::pbump] void pbump(int n); 1 Assigns pnext + n to pnext. 27.2.1.2.25 basic_streambuf::setp [lib.streambuf::setp] void setp(char_type* pbeg_arg, char_type* pend_arg); 1 Assigns pbeg_arg to pbeg, pbeg_arg to pnext, and pend_arg to pend. 27.2.1.2.26 basic_streambuf::overflow [lib.streambuf::overflow] virtual int_type overflow(int_type c = eof()); 1 Consumes some initial subsequence of the characters of the pending sequence. The pending sequence is defined as the concatenation of a)if pbeg is NULL then the empty sequence otherwise, pnext - pbeg characters beginning at pbeg. b)if c == eof() then the empty sequence otherwise, the sequence con sisting of c. 2 The member functions sputc and sputn call this function in case that no room can be found in the put buffer enough to accomodate the argu ment character sequence. 3 Every overiding definition of this virtual function shall obey the following constraints: 1)The effect of consuming a character on the associated output sequence is specified13) _________________________ 2)Let r be the number of characters in the pending sequence not con sumed. If r is non-zerof then pbeg and pnext must be set so that: pnext - pbeg == r and the r characters starting at pbeg are the associated output stream. In case r is zero (all characters of the pending sequence have been consumed) then either pbeg is set to NULL, or pbeg and pnext are both set to the same non-NULL value. 3)The function may fail if either appending some character to the associated output stream fails or if it is unable to establish pbeg and pnext according to the above rules. 4 Returns eof() or throws an exception if the function fails. 5 Otherwise, returns some value other than eof()14) to indicate success. 6 Default behavior: returns eof(). +------- BEGIN BOX 48 -------+ Should be pure virtual. -- mjv +------- END BOX 48 -------+ +------- BEGIN BOX 49 -------+ I disagree. Accidental attempts to create a streambuf are eliminated by making the constructors protected. By giving definitions to all the virtuals in streambuf we make it possible to derive from it by only supplying definitions for the virtuals that are needed. For example, you do not have to define overflow in a streambuf that is only intended for input. I have a similar response to all the other places where there is a box asking this question although IUm only making this response in one place. -- jss +------- END BOX 49 -------+ 27.2.1.2.27 [lib.streambuf::pbackfail] basic_streambuf::pbackfail virtual int_type pbackfail(int c = eof()); +------- BEGIN BOX 50 -------+ Check vs. _lib.basic.filebuf::pbackfail_ +------- END BOX 50 -------+ +------- BEGIN BOX 51 -------+ Jerry Schwarz proposal: Replace this section by the following and make corresponding changes to descriptions of the overriding functions _________________________ 13) That is, for each class derived from an instance of ba sic_streambuf in this clause, a specification of how consume a charac ter effects the associated output sequence is given. There is no re quirement on a user defined class. 14) Typically, c. defined elsewhere in the working paper. 1 The public functions of basic_streambuf call this virtual only when gnext is null, gnext==gbeg or *gnext!=c. Other calls shall also sat isfy that constraint. 2 The pending sequence is defined as for underflow (in _lib.streambuf::underflow_) with the modifications that --If c==eof() then the input sequence is backed up one character before the pending sequence is determined. --If c!=eof() then c is prepended. Whether the input sequence is backed up or modified in any other way is unspecified. 3 On return, the constraints of gnext, gbeg, and pnext are the same as for underflow (in _lib.streambuf::underflow_) 4 Returns eof() to indicate failure. Failure may occur because the input sequence could not be backed up, or if for some other reason the pointers could not be set consistent with the constraints. 5 Returns some value other than eof() to indicate success. 6 Default behavior: returns eof() +------- END BOX 51 -------+ 7 Puts back the character designated by c to the input sequence, if pos sible, in one of five ways: --If c != eof(), if either the input sequence has a putback position available or the function makes a putback position available, and if (charT)c == (charT)gnext[-1], assigns gnext - 1 to gnext. Returns (char_type)c. --If c != eof(), if either the input sequence has a putback position available or the function makes a putback position available, and if the function is permitted to assign to the putback position, assigns c to *--gnext. Returns (char_type)c. --If c != eof(), if no putback position is available, and if the func tion can put back a character directly to the associated input sequence, puts back c directly to the associated input sequence. Returns (char_type)c. --If c == eof() and if either the input sequence has a putback posi tion available or the function makes a putback position available, assigns gnext - 1 to gnext. Returns (char_type)c. --If c == eof(), if no putback position is available, if the function can put back a character directly to the associated input sequence, and if the function can determine the character x immediately before the current position in the associated input sequence, puts back x directly to the associated input sequence. Returns a value other than eof(). 8 Returns eof() to indicate failure. 9 Default behavior: returns eof(). +------- BEGIN BOX 52 -------+ Should be pure virtual. +------- END BOX 52 -------+ 10Notes: 11If the function can succeed in more than one of these ways, it is unspecified which way is chosen. The function can alter the number of putback positions available as a result of any call. How (or whether) the function makes a putback position available, puts back a character directly to the input sequence, or determines the character immedi ately before the current position in the associated input sequence is defined separately for each class derived from basic_streambuf in this clause. +------- BEGIN BOX 53 -------+ The following was not part of the proposal. Should we keep it? +------- END BOX 53 -------+ 27.2.1.2.28 [lib.streambuf::showmany] basic_streambuf::showmany15) virtual int showmany(); 1 Returns a count of the guaranteed number of characters that can be read from the input sequence before a call to uflow() or underflow() returns eof(). A positive return value of indicates that the next such call will not return eof().16) 2 Default behavior: returns zero. _________________________ 15) The morphemes of showmany are "es-how-manyS, not "show-many". 16) The next such call might fail by throwing an exception. The in tention is that the next call will return ``immediately.'' 27.2.1.2.29 [lib.streambuf::underflow] basic_streambuf::underflow virtual int_type underflow(); 1 The public members of basic_streambuf call this virtual only if gnext is null or gnext >= gend 2 Returns the first character of the pending sequence, if possible, without moving the input sequence position past it. If the pending sequence is null then the function fails. 3 The pending sequence of characters is defined as the concatenation of: a)If gnext is non-NULL, then the gend - gnext characters starting at gnext, otherwise the empty sequence. b)Some sequence (possibly empty) of characters read from the input sequence. 4 The result character is a)If the pending sequence is non-empty, the first character of the sequence. b)If the pending sequence empty then the next character that would be read from the input sequence. 5 The backup sequence is defined as the concatenation of: a)If gbeg is null then empty, b)Otherwise the gnext - gbeg characters beginning at gbeg. 6 The function sets up the gnext and gend satisfying one of: a)If the pending sequence is non-empty, gend is non-null and gend - gnext characters starting at gnext are the characters in the pending sequence b)If the pending sequence is empty, either gnext is null or gnext and gend are set to the same non-NULL pointer. 7 If gbeg and gnext are non-null then the function is not constrained as to their contents, but the ``usual backup condition'' is that either: a)If the backup sequence contains at least gnext - gbeg characters, then the gnext - gbeg characters starting at gbeg agree with the last gnext - gbeg characters of the backup sequence. b)Or the n characters starting at gnext - n agree with the backup sequence (where n is the length of the backup sequence) 8 Returns eof() to indicate failure. 9 Default behavior: returns eof(). +------- BEGIN BOX 54 -------+ Should be pure virtual. +------- END BOX 54 -------+ 27.2.1.2.30 basic_streambuf::uflow [lib.streambuf::uflow] virtual int_type uflow(); 1 The constraints are the same as for underflow (_lib.streambuf::underflow_) except that the result character is transfered from the pending sequence to the backup sequence, and the pending sequence may not be empty before the transfer. 2 Default behavior: Calls underflow(eof()). If underflow returns eof(), returns eof(). Otherwise, do gbump(-1) and returns (char_type)*gnext. +------- BEGIN BOX 55 -------+ Jerry Schwarz proposal: Returns not_eof(c). +------- END BOX 55 -------+ 27.2.1.2.31 basic_streambuf::xsgetn [lib.streambuf::xsgetn] virtual streamsize xsgetn(char_type* s, streamsize n); 1 Assigns up to n characters to successive elements of the array whose first element is designated by s. The characters assigned are read from the input sequence as if by repeated calls to sbumpc(). Assign ing stops when either n characters have been assigned or a call to sbumpc() would return eof(). 2 Returns the number of characters assigned.17) 27.2.1.2.32 basic_streambuf::xsputn [lib.streambuf::xsputn] virtual streamsize xsputn(const char_type* s, streamsize n); 1 Writes up to n characters to the output sequence as if by repeated calls to sputc(c). The characters written are obtained from succes sive elements of the array whose first element is designated by s. Writing stops when either n characters have been written or a call to sputc(c) would return eof(). 2 Returns the number of characters written. _________________________ 17) Classes derived from basic_streambuf can provide more efficient ways to implement xsgetn and xsputn by overriding these definitions in the base class. 27.2.1.2.33 basic_streambuf::seekoff [lib.streambuf::seekoff] virtual pos_type seekoff(off_type off, basic_ios<charT,baggage>::seekdir way, basic_ios<charT,baggage>::openmode which = basic_ios<charT,baggage>::in | basic_ios<charT,baggage>::out); 1 Alters the stream positions within one or more of the controlled sequences in a way that is defined separately for each class derived from basic_streambuf in this clause. 2 Default behavior: returns an object of class pos_type that stores an invalid stream position. +------- BEGIN BOX 56 -------+ Should be pure virtual. +------- END BOX 56 -------+ 27.2.1.2.34 basic_streambuf::seekpos [lib.streambuf::seekpos] virtual pos_type seekpos(pos_type sp, basic_ios<charT,baggage>::openmode which = in | out); 1 Alters the stream positions within one or more of the controlled sequences in a way that is defined separately for each class derived from basic_streambuf in this clause. 2 Default behavior: returns an object of class pos_type that stores an invalid stream position. +------- BEGIN BOX 57 -------+ Should be pure virtual. +------- END BOX 57 -------+ 27.2.1.2.35 basic_streambuf::setbuf [lib.streambuf::setbuf] virtual basic_streambuf* setbuf(char_type* s, streamsize n); 1 Performs an operation that is defined separately for each class derived from basic_streambuf in this clause. +------- BEGIN BOX 58 -------+ Should be pure virtual. +------- END BOX 58 -------+ 2 Default behavior: returns this. 27.2.1.2.36 basic_streambuf::sync [lib.streambuf::sync] virtual int sync(); 1 Synchronizes the controlled sequences with the arrays. That is, if pbeg is non-null the characters between pbeg and pnext are written to the controlled sequence, and if gnext is non-null the characters between gnext and gend are restored to the input sequence. The point ers may then be reset as appropriate. 2 Returns -1 on failure. What constitutes failure is determined by each derived class. 3 Default behavior: returns zero. 27.2.1.2.37 [lib.streambuf::read.byte] basic_streambuf::read_byte +------- BEGIN BOX 59 -------+ Jerry Schwarz proposal: Delete read_byte. It cannot be given any generic definition. +------- END BOX 59 -------+ streamsize read_byte(char* s, streamsize n); Assigns up to n bytes to successive elements of an array whose first element is designated by s. How the characters written are obtained is the implementation-defined. Assigning stops when either n charac ters have been assigned or end-of-file occurs on the input sequence. 1 Returns the number of characters assigned. +------- BEGIN BOX 60 -------+ The reason that the behavior of read_byte is unspecified (or implemen tation-defined) is because we cannot assume the nature of the external source/sink stream. If the external source/sink stream is a byte stream, we have a chance to specify more clear description about the behavior. However, there is no insurance that the external stream be a byte sequence. In case the stream is a wide character stream. How we should convert it to a byte sequence, use ``narrow'' functions, every wide character breaks an element of bytes, or converted into a multibyte character sequence? Because even library users can cus tomize the C++ iostream, any kind of external source/sink stream may be applied and any kind of conversion will be challenged. So, the Standard should not provide any specification about the nature of the conversion. +------- END BOX 60 -------+ 27.2.1.2.38 [lib.streambuf::write.byte] basic_streambuf::write_byte +------- BEGIN BOX 61 -------+ Jerry Schwarz proposal: Delete write_byte. It cannot be given any generic definition. +------- END BOX 61 -------+ streamsize write_byte(const char* s, streamsize n); 1 Writes up to n bytes to the output sequences. The bytes written are obtained from successive elements of the array whose first element is designated by s. How the bytes written are converted to the external source/sink stream is implementation-defined. Writing stops when either n characters have been written or a write fails. 2 Returns the number of characters written. 27.2.2 Input streams [lib.input.streams] 1 The header <istream> defines a type and a function signature that con trol input from a stream buffer. 27.2.2.1 Template class basic_istream [lib.istream] template <class charT, class baggage = ios_baggage<charT> > class basic_istream : virtual public basic_ios<charT,baggage> { public: typedef charT char_type; typedef baggage::char_bag::int_type int_type; typedef baggage::pos_bag::pos_type pos_type; typedef baggage::pos_bag::off_type off_type; int_type eof() { return baggage::char_bag::eof(); } char_type newline() { return baggage::char_bag::newline(); } private: // for abbreviation: typedef basic_istream<char_type,baggage> istream_type; typedef basic_ios<charT,baggage> ios_type; public: basic_istream(basic_streambuf<charT,baggage>* sb); virtual ~basic_istream(); bool ipfx(bool noskipws = 0); void isfx(); istream_type& operator>>(istream_type& (*pf)(istream_type&)) istream_type& operator>>(ios_type& (*pf)(ios_type&)) istream_type& operator>>(char_type* s); +------- BEGIN BOX 62 -------+ The following two were not part of the proposal. Should we keep them? -- mjv +------- END BOX 62 -------+ +------- BEGIN BOX 63 -------+ They cannot be kept because their types are not legal. You can't make an arbitrary char_type signed or unsigned. However they are very much a part of the current iostream interface, and I suspect are used extensively, so they must be supported. The only way I can see to deal with this is to make basic_iostream<char> a specialization. I'm not making this an "Jerry Schwarz proposal" because I am not convinced that this is the best solution. -- jss +------- END BOX 63 -------+ istream_type& operator>>(unsigned char_type* s) istream_type& operator>>(signed char_type* s); istream_type& operator>>(char_type& c); +------- BEGIN BOX 64 -------+ The following two were not part of the proposal. Should we keep them? -- mjv +------- END BOX 64 -------+ +------- BEGIN BOX 65 -------+ The same considerations as applied to operator>> apply here. -- jss +------- END BOX 65 -------+ istream_type& operator>>(unsigned char_type& c) istream_type& operator>>(signed char_type& c) istream_type& operator>>(bool& n); istream_type& operator>>(short& n); istream_type& operator>>(unsigned short& n); istream_type& operator>>(int& n); istream_type& operator>>(unsigned int& n); istream_type& operator>>(long& n); istream_type& operator>>(unsigned long& n); istream_type& operator>>(float& f); istream_type& operator>>(double& f); istream_type& operator>>(long double& f); istream_type& operator>>(void*& p); istream_type& operator>>(basic_streambuf<char_type,baggage>& sb); int_type get(); istream_type& get(char_type* s, streamsize n, char_type delim = newline()); +------- BEGIN BOX 66 -------+ The following two were not part of the proposal. Should we keep them? +------- END BOX 66 -------+ +------- BEGIN BOX 67 -------+ The same considerations as applied to operator>> apply here. -- jss +------- END BOX 67 -------+ istream_type& get(unsigned char_type* s, streamsize n, char_type delim = newline()) +------- BEGIN BOX 68 -------+ The following two were not part of the proposal. Should we keep them? +------- END BOX 68 -------+ istream_type& get(signed char_type* s, streamsize n, char_type delim = newline()) istream_type& get(char_type& c); istream_type& get(unsigned char_type& c); istream_type& get(signed char_type& c); istream_type& get(basic_streambuf<char_type,baggage>& sb, char_type delim = newline()); istream_type& getline(char_type* s, streamsize n, char_type delim = newline()); +------- BEGIN BOX 69 -------+ The following two were not part of the proposal. Should we keep them? +------- END BOX 69 -------+ +------- BEGIN BOX 70 -------+ The same considerations as applied to operator>> apply here. -- jss +------- END BOX 70 -------+ istream_type& getline(unsigned char_type* s, streamsize n, char_type delim = newline()) istream_type& getline(signed char_type* s, streamsize n, char_type delim = newline()) istream_type& ignore(streamsize n = 1, int_type delim = eof()); istream_type& read(char_type* s, streamsize n); +------- BEGIN BOX 71 -------+ The following two were not part of the proposal. Should we keep them? +------- END BOX 71 -------+ +------- BEGIN BOX 72 -------+ The same considerations as applied to operator>> apply here. -- jss +------- END BOX 72 -------+ istream_type& read(unsigned char_type* s, streamsize n) istream_type& read(signed char_type* s, streamsize n) +------- BEGIN BOX 73 -------+ A new member function for supporting the raw byte I/O in which it per forms rdbuf().read_byte(s,n) +------- END BOX 73 -------+ istream_type& read_byte(char* s, streamsize n); +------- BEGIN BOX 74 -------+ The following was not part of the proposal. Should we keep it? -- mjv +------- END BOX 74 -------+ +------- BEGIN BOX 75 -------+ Yes, it is the interface to in_avail -- jss +------- END BOX 75 -------+ int readsome(char_type* s, int n); int peek(); istream_type& putback(char_type c); istream_type& unget(); streamsize gcount() const; int sync(); private: // streamsize chcount; exposition only }; +------- BEGIN BOX 76 -------+ We talked about this in Kitchener and it seems that deriving istream from an instance of basic_istream<char> doesn't work unless it dupli cates all the members with return type modified to istream rather than basic_istream<char>. Rather than do that we could "bite the bullet" and make them typedefs. The consequence of that any existing code that declares them to be (incomplete) classes without including <iostream.h> will break. Both of these are unpleasant. But some change is required, so as a placeholder Jerry Schwarz proposal: typedef basic_istream<char> istream; typedef basic_istream<wchar_t> wistream; +------- END BOX 76 -------+ class istream : public basic_istream<char> {}; class wistream : public basic_istream<wchar_t> {}; 1 The class basic_istream defines a number of member function signatures that assist in reading and interpreting input from sequences con trolled by a stream buffer. +------- BEGIN BOX 77 -------+ [To Be Filled] +------- END BOX 77 -------+ 2 For the sake of exposition, the data maintained by an object of class basic_istream is presented here as: --int chcount, stores the number of characters extracted by the last unformatted input member function called for the object. 3 Two groups of member function signatures share common properties: the formatted input functions (or extractors) and the unformatted input functions. Both groups of input functions are described as if they obtain (or extract) input characters by calling sb.sbumpc() or sb.sgetc(). They may use other public members of istream except that they do not invoke any tuals members of sb except uflow. 4 If sb.sbumpc() or sb.sgetc() returns eof(), then the input function, except as explicitly noted otherwise, completes its actions and does setstate(eofbit) before returning. 5 If one of these called functions throws an exception, then unless explicitly noted otherwise the input function calls setstate(badbit) and if badbit is on in sb.exception() rethrows the exception without completing its actions. 27.2.2.1.1 basic_istream constructor [lib.basic.istream.cons] basic_istream(basic_streambuf<charT,baggage>* sb); 1 Constructs an object of class basic_istream, assigning initial values to the base class by calling basic_ios::init(sb), then assigning zero to chcount. 27.2.2.1.2 basic_istream destructor [lib.basic.istream.des] virtual ~basic_istream(); 1 Destroys an object of class basic_istream. Does not perform any oper ations of sb. 27.2.2.1.3 basic_istream::ipfx [lib.istream::ipfx] bool ipfx(bool noskipws = 0); 1 If good() is true, prepares for formatted or unformatted input. First, if tie() is not a null pointer, the function calls tie()->flush() to synchronize the output sequence with any associated external C stream.18) If noskipws is zero and flags() & skipws is nonzero, the function extracts and discards each character as long as the next available input character c is a whitespace character. 2 To decide if the character c is a whitespace character, the function performs as if it executes the following code fragment: locale::ctype<charT> ctype = getloc().use<locale::ctype<charT> >(); if (baggage::char_bag::is_whitespace (c, ctype)!=0) // c is a whitespace character. 3 If, after any preparation is completed, good() is true, returns true. Otherwise, it calls setstate(failbit) and returns false.19) +------- BEGIN BOX 78 -------+ The proposal will say as follows: The function basic_istream<charT,baggage>::ipfx() uses the function, bool baggage::char_bag::is_whitespace(charT, const locale*) in the baggage structure to determine whether the next input character is whitespace or not. A typical implementation of the ipfx function may be as follows: _________________________ 18) The call tie()->flush() does not necessarily occur if the function can determine that no synchronization is necessary. 19) The function signatures ipfx(int) and isfx() can also perform ad ditional implementation-dependent operations. template <class charT, class baggage = ios_baggage<charT> > int basic_istream<charT,baggage>::ipfx() { ... // skipping whitespace according to a constraint function, // is_whitespace intT c; typedef locale::ctype<charT> ctype_type; ctype_type& ctype = getloc().use<ctype_type>(); while ((c = rdbuf()->snextc()) != eof()) { if (!baggage::char_bag::is_whitespace (c,ctype)==0) { rdbuf()->sputbackc (c); break; } } ... } In case we use ios_baggage<char> or ios_baggage<wchar_t>, the behavior of the constraint function baggage::char_bag::is_whitespace() is as if it invokes: locale::ctype<charT>& ctype = getloc().use<locale::ctype<charT> >(); ctype.is(locale::ctype<charT>::SPACE, c); otherwise, the behavior of the function bag gage::char_bag::is_whitespace() is unspecified. Those who want to use locale-independent whitespace predicate can specify their definition of is_whitespace in their new ios_char_baggage as follows: struct my_baggage : public ios_baggage<char> { typedef my_char_baggage char_bag; }; struct my_char_baggage : public ios_char_baggage<char> { static bool is_whitespace (char c, const locale::ctype<charT>& ctype) { ....(my own implementation)... } }; +------- END BOX 78 -------+ 27.2.2.1.4 basic_istream::isfx [lib.istream::isfx] void isfx(); 1 Returns. 27.2.2.1.5 basic_istream::sync [lib.istream::sync] int sync(); 1 If rdbuf() is a null pointer, returns eof(). Otherwise, calls rdbuf()->pubsync() and, if that function returns eof(), calls set state(badbit) and returns eof(). Otherwise, returns zero. 27.2.2.2 Formatted input functions [lib.istream.formatted] 27.2.2.2.1 Common requirements [lib.istream.formatted.reqmts] 1 Each formatted input function begins execution by calling ipfx(). If that function returns true, the function endeavors to obtain the requested input. In any case, the formatted input function ends by calling isfx(), then returns *this 2 Some formatted input functions endeavor to obtain the requested input by parsing characters extracted from the input sequence, converting the result to a value of some scalar data type, and storing the con verted value in an object of that scalar data type. +------- BEGIN BOX 79 -------+ The numeric conversion behaviors of the following extractors are locale-dependent. istream_type::operator>>(short& val); istream_type::operator>>(unsigned short& val); istream_type::operator>>(int& val); istream_type::operator>>(unsigned int& val); istream_type::operator>>(long& val); istream_type::operator>>(unsigned long& val); istream_type::operator>>(float& val); istream_type::operator>>(double& val); istream_type::operator>>(long double& val); As in the case of the inserters, these extractors depend on the Nathan Myers's locale::num_get<> object to perform parsing the input stream data. The conversion occurs as if it performed the following code fragment: HOLDTYPE tmp; locale::num_get<charT>& fmt = loc.use< locale::num_get<charT> >(); fmt.get (iter, *this, loc, tmp); if ((val = (TYPE)tmp) != tmp) // set fail bit... In the above fragment, loc stands for the private member of the basic_ios class, TYPE stands for the type of the argument of the extractor, and HOLDTYPE is as follows; --for short, int and long, HOLDTYPE is long; --for unsigned short, unsigned int and unsigned long, HOLDTYPE is unsigned long. --for float, double, HOLDTYPE is double. --for long double, HOLDTYPE is long double. The first argument provides an object of the istream_iterator class which is an iterator pointed to an input stream. It bypasses istreams and uses streambufs directly. Class locale relies on this type as its interface to istream, since the flexibility it has been abstracted away from direct dependence on istream. +------- END BOX 79 -------+ 3 In case the converting result is a value of either an integral type (short, unsigned short, int, unsigned int, long, unsigned long) or a float type (float, double, long double), performing to parse and con vert the result depend on the imbued locale object. So the behavior of the above type extractors are locale-dependent. The imbued locale object uses an istreambuf_iterator to access the input character sequence. 4 The behavior of such functions is described in terms of the conversion specification for an equivalent call to the function fscanf()20) oper ating with the global locale set to loc, with the following alter ations: --The formatted input function extracts characters from a stream buffer, rather than reading them from an input file.21) --If flags() & skipws is zero, the function does not skip any leading white space. In that case, if the next input character is white space, the scan fails. --If the converted data value cannot be represented as a value of the specified scalar data type, a scan failure occurs. +------- BEGIN BOX 80 -------+ Can the current locale::num_put/num_get facet handle basefield speci fication? Needs more discussion. +------- END BOX 80 -------+ 5 If the scan fails for any reason, the formatted input function calls setstate(failbit). 6 For conversion to an integral type other than a character type, the function determines the integral conversion specifier as indicated in Table 12: _________________________ 20) The signature fscanf(FILE*, const char*, ...) is declared in <cst dio> (_lib.file.streams_) 21) The stream buffer can, of course, be associated with an input file, but it need not be. Table 12--Integer conversions +------------------------------------------------+ | State stdio equivalent | +------------------------------------------------+ |(flags() & basefield) == oct %o | +------------------------------------------------+ |(flags() & basefield) == hex %x | |(flags() & uppercase) != 0 %X | +------------------------------------------------+ |(flags() & basefield) == 0 %i | | | |Otherwise, | +------------------------------------------------+ |signed integral type %d | +------------------------------------------------+ |unsigned integral type %u | +------------------------------------------------+ +------- BEGIN BOX 81 -------+ Is this table clear with regards to f5%x vs. %X ? -- jss +------- END BOX 81 -------+ 27.2.2.2.2 basic_istream::operator>> [lib.istream::extractors] istream_type& operator>>(istream_type& (*pf)(istream_type&)) 1 Returns (*pf)(*this).22) istream_type& operator>>(ios_type& (*pf)(ios_type&)) 2 Calls (*pf)(*this), then returns *this.23) istream_type& operator>>(char_type* s); 3 Extracts characters and stores them into successive locations of an array whose first element is designated by s. If width() is greater than zero, the maximum number of characters stored n is width(); oth erwise it is INT_MAX.24) 4 Characters are extracted and stored until any of the following occurs: --n - 1 characters are stored; --end-of-file occurs on the input sequence; _________________________ 22) See, for example, the function signature ws(basic_istream&). 23) See, for example, the function signature dec(basic_ios<charT,baggage>&). 24) MAX_INT is defined in <climits> (_lib.file.streams_). --baggage::char_bag::is_whitespace(c,ctype) is nonzero for the next available input character c. In the above code fragment, the argu ment ctype is acquired by getloc().use<locale::ctype<charT> >(). 5 If the function stores no characters, it calls setstate(failbit). In any case, it then stores a null character into the next successive location of the array and calls width(0). 6 Returns *this. +------- BEGIN BOX 82 -------+ The following two were not part of the proposal. Should we keep them? +------- END BOX 82 -------+ istream_type& operator>>(unsigned char_type* s) 7 Returns operator>>((char_type*)s). istream_type& operator>>(signed char_type* s); 8 Returns operator>>((char_type*)s). istream_type& operator>>(char_type& c); 9 Extracts a character, if one is available, and stores it in c. Other wise, the function calls setstate(failbit). 10Returns *this. +------- BEGIN BOX 83 -------+ The following two were not part of the proposal. Should we keep them? +------- END BOX 83 -------+ istream_type& operator>>(unsigned char_type& c) 11Returns operator>>((char&)c). istream_type& operator>>(signed char_type& c) 12Returns operator>>((char&)c). istream_type& operator>>(bool& n); 13Converts a signed short integer, if one is available, and stores it in x. Behaves as if: if (flags() & ios::boolalpha) { getloc().extract(*this, n); } else { int x; *this >> x; if (x == 0) n = false; else if (x == 1) n = true; else ; // indicate failure } return *this; +------- BEGIN BOX 84 -------+ Locale extraction (getloc().extract()) of the string is something like: istream i; string bool_false = ...; // locale dependent string bool_true = ...; string s; i >> s; if (s == bool_false) n = false; else if (s == bool_true) n = true; else ; // indicate failure The strings for the default locale are "false" and "true". +------- END BOX 84 -------+ 14Returns *this. istream_type& operator>>(short& n); 15Converts a signed short integer, if one is available, and stores it in n. 16Returns *this. istream_type& operator>>(unsigned short& n); 17Converts an unsigned short integer, if one is available, and stores it in n. 18Returns *this. istream_type& operator>>(int& n); 19Converts a signed integer, if one is available, and stores it in n. 20Returns *this. istream_type& operator>>(unsigned int& n); 21Converts an unsigned integer, if one is available, and stores it in n. 22Returns *this. istream_type& operator>>(long& n); 23Converts a signed long integer, if one is available, and stores it in n. 24Returns *this. istream_type& operator>>(unsigned long& n); 25Converts an unsigned long integer, if one is available, and stores it in n. 26Returns *this. istream_type& operator>>(float& f); 27Converts a float, if one is available, and stores it in f. 28Returns *this. istream_type& operator>>(double& f); 29Converts a double, if one is available, and stores it in f. 30Returns *this. istream_type& operator>>(long double& f); 31Converts a long double, if one is available, and stores it in f. 32Returns *this. istream_type& operator>>(void*& p); 33Converts a pointer to void, if one is available, and stores it in p. 34Returns *this. istream_type& operator>>(basic_streambuf<charT,baggage>& sb); 35Extracts characters from *this and inserts them in the output sequence controlled by sb. Characters are extracted and inserted until any of the following occurs: --end-of-file occurs on the input sequence; --inserting in the output sequence fails (in which case the character to be inserted is not extracted); --an exception occurs (in which case the exception is caught). set state(badbit) is not called 36If the function inserts no characters, it calls setstate(failbit). If failure was due to catching an exception thrown while extracting char acters from sb and failbit is on in except then the caught exception is rethrown. 37Returns *this. 27.2.2.3 Unformatted input functions [lib.istream.unformatted] 1 Each unformatted input function begins execution by calling ipfx(1). If that function returns nonzero, the function endeavors to extract the requested input. It also counts the number of characters extracted. In any case, the unformatted input function ends by stor ing the count in a member object and calling isfx(), then returning the value specified for the unformatted input function. 27.2.2.3.1 basic_istream::get [lib.istream::get] int get(); 1 Extracts a character c, if one is available. The function then returns (unsigned char)c. Otherwise, the function calls set state(failbit) and then returns eof(). istream_type& get(char_type* s, streamsize n, char_type delim = newline()); 2 Extracts characters and stores them into successive locations of an array whose first element is designated by s. Characters are extracted and stored until any of the following occurs: --n - 1 characters are stored; --end-of-file occurs on the input sequence (in which case the function calls setstate(eofbit)); --c == delim for the next available input character c (in which case c is not extracted). 3 If the function stores no characters, it calls setstate(failbit). In any case, it then stores a null character into the next successive location of the array. 4 Returns *this. +------- BEGIN BOX 85 -------+ The following two were not part of the proposal. Should we keep them? +------- END BOX 85 -------+ istream_type& get(unsigned char_type* s, streamsize n, char_type delim = newline()) 5 Returns get((char_type*)s, n, delim). istream_type& get(signed char_type* s, streamsize n, char_type delim = newline()) 6 Returns get((char_type*)s, n, delim). istream_type& get(char_type& c); 7 Extracts a character, if one is available, and assigns it to c. Oth erwise, the function calls setstate(failbit). 8 Returns *this. istream_type& get(unsigned char_type& c); 9 Returns get((char&)c). +------- BEGIN BOX 86 -------+ The following two were not part of the proposal. Should we keep them? +------- END BOX 86 -------+ istream_type& get(signed char_type& c); 10Returns basic_istream::get((char&)c). istream_type& get(basic_streambuf<char_type,baggage>& sb, char_type delim = newline()); 11Extracts characters and inserts them in the output sequence controlled by sb. Characters are extracted and inserted until any of the follow ing occurs: --end-of-file occurs on the input sequence; --inserting in the output sequence fails (in which case the character to be inserted is not extracted); --c == delim for the next available input character c (in which case c is not extracted); --an exception occurs (in which case, the exception is caught but not rethrown). 12If the function inserts no characters, it calls setstate(failbit). 13Returns *this. 27.2.2.3.2 basic_istream::getline [lib.istream::getline] istream_type& getline(char_type* s, streamsize n, char_type delim = newline()); 1 Extracts characters and stores them into successive locations of an array whose first element is designated by s. Characters are extracted and stored until one of the following occurs: 1)end-of-file occurs on the input sequence (in which case the function calls setstate(eofbit)); 2)c == delim for the next available input character c (in which case the input character is extracted but not stored);25) 3)n - 1 characters are stored (in which case the function calls set state(failbit)). 2 These conditions are tested in the order shown.26) 3 If the function extracts no characters, it calls setstate(failbit).27) 4 In any case, it then stores a null character into the next successive location of the array. 5 Returns *this. _________________________ 25) Since the final input character is ``extracted,'' it is counted in the gcount(), even though it is not stored. 26) This allows an input line which exactly fills the buffer, without setting failbit. This is different behavior than the historical AT&T implementation. 27) This implies an empty input line will not cause failbit to be set. 6 Example: #include <iostream> using std; const int line_buffer_size = 100; int main() { char buffer[line_buffer_size]; int line_number = 0; while (cin.getline(buffer, line_buffer_size) || cin.gcount()) { int count = cin.gcount(); if (cin.eof()) cout << "Partial final line"; // cin.fail() is false else if (cin.fail()) { cout << "Partial long line"; cin.clear(cin.rdstate() & ~ios::failbit); } else { count--; // Don't include '\n' in count cout << "Line " << ++line_number; } cout << " (" << count << " chars): " << buffer << endl; } } +------- BEGIN BOX 87 -------+ The following two were not part of the proposal. Should we keep them? +------- END BOX 87 -------+ istream_type& getline(unsigned char_type* s, streamsize n, char_type delim = newline()) 7 Returns getline((char_type*)s, n, delim). istream_type& getline(signed char_type* s, streamsize n, char_type delim = newline()) 8 Returns getline((char_type*)s, n, delim). 27.2.2.3.3 basic_istream::ignore [lib.istream::ignore] istream_type& ignore(int n = 1, int_type delim = eof()); 1 Extracts characters and discards them. Characters are extracted until any of the following occurs: --if n != INT_MAX, n characters are extracted --end-of-file occurs on the input sequence (in which case the function calls setstate(eofbit)); --c == delim for the next available input character c (in which case c is extracted). 28) _________________________ 28) The macro INT_MAX is defined in <climits>. 2 The last condition will never occur if delim == eof(). 3 Returns *this. 27.2.2.3.4 basic_istream::read [lib.istream::read] istream_type& read(char_type* s, streamsize n); 1 Extracts characters and stores them into successive locations of an array whose first element is designated by s. Characters are extracted and stored until either of the following occurs: --n characters are stored; --end-of-file occurs on the input sequence (in which case the function calls setstate(failbit)). 2 Returns *this. +------- BEGIN BOX 88 -------+ The following two were not part of the proposal. Should we keep them? +------- END BOX 88 -------+ istream_type& read(unsigned char_type* s, streamsize n) 3 Returns read((char_type*)s, n). istream_type& read(signed char_type* s, streamsize n) 4 Returns read((char_type*)s, n). 27.2.2.3.5 basic_istream::read_byte [lib.istream::read.byte] istream_type<charT,baggage>& read_byte(char* s, streamsize n); 1 Extracts bytes by invoking: rdbuf()->read_byte(s,n); 2 In case end-of-file occurs on the input character sequence, the func tion calls setstate(failbit). 3 Returns *this. +------- BEGIN BOX 89 -------+ The following was not part of the proposal. Should we keep it? +------- END BOX 89 -------+ 27.2.2.3.6 basic_istream::readsome [lib.istream::readsome] int readsome(char_type* s, int n); 1 Extracts characters and stores them into successive locations of an array whose first element is designated by s. The function first determines navail, the value returned by calling in_avail(). If navail is 1, the function calls setstate(eofbit) and returns zero. 2 Otherwise, the function determines the number of characters to extract m as the smaller of n and navail, and returns read(s, m). 27.2.2.3.7 basic_istream::peek [lib.istream::peek] int peek(); 1 Returns eof() if good() is false. Otherwise, returns rdbuf()->sgetc(). 27.2.2.3.8 basic_istream::putback [lib.istream::putback] istream_type& putback(char_type c); 1 Calls rdbuf->sputbackc(c). If that function returns eof(), calls set state(badbit). 2 Returns *this. 27.2.2.3.9 basic_istream::unget [lib.istream::unget] istream_type& unget(); 1 Calls rdbuf->sungetc(). If that function returns eof(), calls set state(badbit). 2 Returns *this. 27.2.2.3.10 basic_istream::gcount [lib.istream::gcount] streamsize gcount() const; 1 Returns chcount. 27.2.2.4 Standard basic_istream [lib.basic.istream.manip] manipulators template<class charT, class baggage> basic_istream<charT,baggage>& ws(basic_istream<charT,baggage>& is); 1 Saves a copy of is.fmtflags, then clears is.skipws in is.fmtflags. Then calls is.ipfx() and is.isfx(), and restores is.fmtflags to its saved value.29) 2 Returns is. 27.2.3 Template class [lib.istreambuf.iterator] istreambuf_iterator +------- BEGIN BOX 90 -------+ As part of the original proposals, the class istreambuf_iterator is defined in the header <istream>. It really should be defined as part of Clause _lib.streambuf.iterators_. _________________________ 29) The effect of cin >> ws is to skip any white space in the input sequence controlled by cin. +------- END BOX 90 -------+ template<class charT, class baggage = ios_baggage<charT> > class istreambuf_iterator { public: typedef charT char_type; typedef baggage baggage_type; typedef baggage::int_type int_type; typedef basic_streambuf<charT,baggage> streambuf; typedef basic_istream<charT,baggage> istream; class proxy { charT keep_; streambuf* sbuf_; proxy (charT c, streambuf* sbuf) : keep_(c), sbuf_(sbuf) {} public: charT operator*() { return keep_; } friend class istreambuf_iterator; }; public: istreambuf_iterator(); istreambuf_iterator(istream& s); istreambuf_iterator(streambuf* s); istreambuf_iterator(const proxy& p); charT operator*(); istreambuf_iterator<charT,baggage>& operator++(); proxy operator++(int); bool equal(istreambuf_iterator& b); private: // streambuf* sbuf_; exposition only }; 1 The template class istreambuf_iterator reads successive characters from the streambuf for which it was constructed. 2 After it is constructed, and every time operator++ is used, the itera tor reads and stores a value of character. If the end of stream is reached (streambuf::sgetc() returns baggage::char_bag::eof()), the iterator becomes equal to the end of stream iterator value. The default constructor istreambuf_iterator() and the constructor istream buf_iterator(0) always construct an end of stream iterator object, which is the only legitimate iterator to be used for the end condi tion. 3 The result of operator*() on an end of stream is undefined. For any other iterator value a const char_type& is returned. It is impossible to store things into input iterators. 4 Note that in the input iterators, ++ operators are not equality pre serving, that is, i == j does not guarantee at all that ++i == ++j. Every time ++ is used a new value is used. 5 The practical consequence of this fact is that an istreambuf_iterator object can be used only for one-pass algorithms, which actually makes perfect sense, since for multi-pass algorithms it is always more appropriate to use in-memory data structures. Two end of stream iter ators are always equal. An end of stream iterator is not equal to a non-end of stream iterator. Two non-end of stream iterators are equal when they are constructed from the same stream. 27.2.3.1 Template class [lib.istreambuf.iterator::proxy] istreambuf_iterator::proxy template <class charT, class baggage = ios_baggage<charT> > class istream_iterator::proxy { charT keep_; streambuf* sbuf_; proxy(charT c, streambuf* sbuf) : keep_(c), sbuf_(sbuf) {} public: charT operator*() { return keep_; } friend class istreambuf_iterator; }; 1 Class istream_iterator<charT,baggage>::proxy provides a temporal placeholder as the return value of the post-increment operator (opera tor++). It keeps the character pointed to by the previous value of the iterator for some possible future access to get the character. 27.2.3.2 istreambuf_iterator [lib.istreambuf.iterator.cons] constructors istreambuf_iterator(); 1 Constructs the end-of-stream iterator. istreambuf_iterator(basic_istream<charT,baggage>& s); 2 Constructs the istream_iterator pointing to the basic_streambuf object *(s.rdbuf()). istreambuf_iterator(const proxy& p); 3 Constructs the istreambuf_iterator pointing to the basic_streambuf object related to the proxy object p. 27.2.3.3 [lib.istreambuf.iterator::op*] istreambuf_iterator::operator* charT operator*() 1 Extract one character pointed to by the streambuf *sbuf_. 27.2.3.4 [lib.istreambuf.iterator::op++] istreambuf_iterator::operator++ istreambuf_iterator<charT,baggage>& istreambuf_iterator<charT,baggage>::operator++(); 1 Advances the iterator and returns the result proxy istreambuf_iterator<charT,baggage>::operator++(int); 2 Advances the iterator and returns the proxy object keeping the charac ter pointed to by the previous iterator. 27.2.3.5 [lib.istreambuf.iterator::equal] istreambuf_iterator::equal bool equal(istreambuf_iterator<charT,baggage>& b); 1 Returns true if the iterators are equal. Equality is defined as fol lows: --If both a and b are end-of-stream iterators, a == b. --If either a or b is an end-of-stream iterator, if the other points end-of-file, a == b, otherwise a != b. --If both a and b are not end-of-stream, the two streambuf pointed to by the both iterators are compared. 27.2.3.6 iterator_category [lib.iterator.category.i] input_iterator iterator_category(const istreambuf_iterator& s); 1 Returns the category of the iterator s. 27.2.3.7 operator== [lib.istreambuf.iterator::op==] template <class charT, class baggage = ios_baggage<charT> > bool operator==(istreambuf_iterator<charT, baggage>& a, istreambuf_iterator<charT, baggage>& b); 1 Returns a.equal(b). 27.2.3.8 operator!= [lib.istreambuf.iterator::op!=] template <class charT, class baggage = ios_baggage<charT> > bool operator!=(istreambuf_iterator<charT, baggage>& a, istreambuf_iterator<charT, baggage>& b); 1 Returns !a.equal(b). 27.2.4 Output streams [lib.output.streams] 1 The header <ostream> defines a type and several function signatures that control output to a stream buffer. 27.2.4.1 Template class basic_ostream [lib.ostream] template <class charT, class baggage = ioc_baggage<charT> > class basic_ostream : virtual public basic_ios<charT,baggage> { public: typedef charT char_type; typedef baggage::char_bag::int_type int_type; typedef baggage::pos_bag::pos_type pos_type; typedef baggage::pos_bag::off_type off_type; int_type eof() { return baggage::char_bag::eof(); } char_type newline() { return baggage::char_bag::newline(); } private: typedef basic_ostream<charT,baggage> ostream_type; public: basic_ostream(basic_streambuf<char_type,baggage>* sb); virtual ~basic_ostream(); bool opfx(); void osfx(); ostream_type& operator<<(ostream_type& (*pf)(ostream_type&)); ostream_type& operator<<(ios_type& (*pf)(ios_type&)); ostream_type& operator<<(const char_type* s); ostream_type& operator<<(char_type c); +------- BEGIN BOX 91 -------+ The following two were not part of the proposal. Should we keep them? +------- END BOX 91 -------+ ostream_type& operator<<(unsigned char_type c); ostream_type& operator<<(signed char_type c); ostream_type& operator<<(bool n); ostream_type& operator<<(short n); ostream_type& operator<<(unsigned short n); ostream_type& operator<<(int n); ostream_type& operator<<(unsigned int n); ostream_type& operator<<(long n); ostream_type& operator<<(unsigned long n); ostream_type& operator<<(float f); ostream_type& operator<<(double f); ostream_type& operator<<(long double f); ostream_type& operator<<(void* p); ostream_type& operator<<(basic_streambuf<char_type,baggage>& sb); int put(char_type c); ostream_type& write(const char_type* s, streamsize n); +------- BEGIN BOX 92 -------+ The following two were not part of the proposal. Should we keep them? +------- END BOX 92 -------+ ostream_type& write(const unsigned char_type* s, streamsize n); ostream_type& write(const signed char_type* s, streamsize n); ostream_type& write_byte (const char* s, streamsize n); ostream_type& flush(); }; class ostream : public basic_ostream<char> {}; class wostream : public basic_ostream<wchar_t> {}; 1 The class basic_ostream defines a number of member function signatures that assist in formatting and writing output to output sequences con trolled by a stream buffer. +------- BEGIN BOX 93 -------+ [To Be Filled] +------- END BOX 93 -------+ 2 Two groups of member function signatures share common properties: the formatted output functions (or inserters) and the unformatted output functions. Both groups of output functions generate (or insert) output characters by actions equivalent to calling sb.sputc(int). They may use other public members of basic_ostream except that they do not invoke any tuals members of sb except overflow. If the called func tion throws an exception, the output function calls setstate(badbit) and if badbit is on in except rethrows the exception. 27.2.4.1.1 basic_ostream constructor [lib.basic.ostream.sb.cons] basic_ostream(basic_streambuf<charT,baggage>* sb); 1 Constructs an object of class basic_ostream, assigning initial values to the base class by calling basic_ios<charT,baggage>::init(sb). 27.2.4.1.2 basic_ostream destructor [lib.basic.ostream.des] virtual ~basic_ostream(); 1 Destroys an object of class basic_ostream. Does not perform any oper ations on sb. 27.2.4.1.3 basic_ostream::opfx [lib.ostream::opfx] bool opfx(); 1 If good() is nonzero, prepares for formatted or unformatted output. If tie() is not a null pointer, calls tie()->flush().30) +------- BEGIN BOX 94 -------+ Note: Need to append the locale dependency on appropriate extractors. +------- END BOX 94 -------+ 2 Returns good().31) 27.2.4.1.4 basic_ostream::osfx [lib.ostream::osfx] void osfx(); 1 If flags() & unitbuf is nonzero, calls flush(). _________________________ 30) The call tie()->flush() does not necessarily occur if the function can determine that no synchronization is necessary. 31) The function signatures opfx() and osfx() can also perform addi tional implementation-dependent operations. 27.2.4.1.5 basic_ostream::flush [lib.ostream::flush] basic_ostream& flush(); 1 If rdbuf() is not a null pointer, calls rdbuf()->pubsync(). If that function returns eof(), calls setstate(badbit). 2 Returns *this. 27.2.4.2 Formatted output functions [lib.ostream.formatted] 27.2.4.2.1 Common requirements [lib.ostream.formatted.reqmts] 1 Each formatted output function begins execution by calling opfx(). If that function returns nonzero, the function endeavors to generate the requested output. In any case, the formatted output function ends by calling osfx(), then returning the value specified for the formatted output function. +------- BEGIN BOX 95 -------+ The following specification description has not reflected locale- dependency of the behavior of the integral type/float type inserters. The numeric conversion behaviors of the following inserters are locale-dependent: basic_ostream<charT,baggage>::operator<<(short val); basic_ostream<charT,baggage>::operator<<(unsigned short val); basic_ostream<charT,baggage>::operator<<(int val); basic_ostream<charT,baggage>::operator<<(unsigned int val); basic_ostream<charT,baggage>::operator<<(long val); basic_ostream<charT,baggage>::operator<<(unsigned long val); basic_ostream<charT,baggage>::operator<<(float val); basic_ostream<charT,baggage>::operator<<(double val); basic_ostream<charT,baggage>::operator<<(long double val); According to the Nathan Myers's locale object draft [X3J16/94-0064R1,WG21/N0451R1], the class locale::num_get<> and locale::num_put<> handle locale-dependent numeric formatting and pars ing. The above inserter functions refers the imbued locale value to utilize these numeric formatting functionality. The formatting conversion occurs as if it performed the following code fragment: locale::num_put<charT>& fmt = loc.use< locale::num_put<charT> >(); fmt.put (ostreambuf_iterator(*this), *this, loc, val); In the above fragment, loc stands for the private member of the basic_ios class which maintains the imbued locale object. The first argument provides an object of the ostreambuf_iterator class which is an iterator for ostream class. It bypasses ostreams and uses stream bufs directly. Class locale relies on these types as its interface to iostreams, since for flexibility it has been abstracted away from direct dependence on ostream. +------- END BOX 95 -------+ 2 Some formatted output functions endeavor to generate the requested output by converting a value from some scalar or NTBS type to text form and inserting the converted text in the output sequence. +------- BEGIN BOX 96 -------+ Needs work: NTBS. +------- END BOX 96 -------+ The behavior of such functions is described in terms of the conversion specification for an equivalent call to the function fprintf,32) oper ating with the global locale set to loc, with the following alter ations: --The formatted output function inserts characters in a stream buffer, rather than writing them to an output file.33) --The formatted output function uses the fill character returned by fill() as the padding character (rather than the space character for left or right padding, or 0 for internal padding). 3 If the operation fails for any reason, the formatted output function calls setstate(badbit). 4 For conversion from an integral type other than a character type, the function determines the integral conversion specifier as indicated in Table 13: Table 13--Integer conversions +------------------------------------------------+ | State stdio equivalent | +------------------------------------------------+ |(flags() & basefield) == oct %o | +------------------------------------------------+ |(flags() & basefield) == hex %x | |(flags() & uppercase) != 0 %X | | | |Otherwise, | +------------------------------------------------+ |signed integral type %d | +------------------------------------------------+ |unsigned integral type %u | +------------------------------------------------+ +------- BEGIN BOX 97 -------+ _________________________ 32) The signature fprintf(FILE*, const char_type*, ...) is declared in <cstdio> (_lib.file.streams_). 33) The stream buffer can, of course, be associated with an output file, but it need not be. Is this table clear with regards to f5%x vs. f5%X ? -- jss +------- END BOX 97 -------+ 5 For conversion from a floating-point type, the function determines the floating-point conversion specifier as indicated in Table 14: +------- BEGIN BOX 98 -------+ Can the current locale::num_put/num_get facet handle basefield speci fication? Needs more discussion. +------- END BOX 98 -------+ Table 14--Floating-point conversions +--------------------------------------------------------+ | State stdio equivalent | +--------------------------------------------------------+ |(flags() & floatfield) == fixed %f | +--------------------------------------------------------+ |(flags() & floatfield) == scientific %e | |(flags() & uppercase) != 0 %E | | | |Otherwise, | +--------------------------------------------------------+ | %g | |(flags() & uppercase) != 0 %G | +--------------------------------------------------------+ +------- BEGIN BOX 99 -------+ Is this table clear with regards to f5%e vs. %E ? -- jss +------- END BOX 99 -------+ 6 The conversion specifier has the following additional qualifiers prepended as indicated in Table 15: Table 15--Floating-point conversions +----------------------------------------------------------------------+ | Type(s) State stdio equivalent | +----------------------------------------------------------------------+ |an integral type oth (flags() & showpos) != 0 + | |er than a character (flags() & showbase) != 0 # | |type | +----------------------------------------------------------------------+ |a floating-point type (flags() & showpos) != 0 + | | (flags() & showpoint) != 0 # | +----------------------------------------------------------------------+ --For any conversion, if width() is nonzero, then a field width is specified in the conversion specification. The value is width(). --For conversion from a floating-point type, if flags() & fixed is nonzero or if precision() is greater than zero, then a precision is specified in the conversion specification. The value is preci sion(). 7 Moreover, for any conversion, padding with the fill character returned by fill() behaves as follows: --If (flags() & adjustfield) == right, no flag is prepended to the conversion specification, indicating right justification (any padding occurs before the converted text). A fill character occurs wherever fprintf generates a space character as padding. --If (flags() & adjustfield) == internal, the flag 0 is prepended to the conversion specification, indicating internal justification (any padding occurs within the converted text). A fill character occurs wherever fprintf generates a 0 as padding.34) 8 Otherwise, the flag - is prepended to the conversion specification, indicating left justification (any padding occurs after the converted text). A fill character occurs wherever fprintf generates a space character as padding. 9 Unless explicitly stated otherwise for a particular inserter, each formatted output function calls width(0) after determining the field width. 27.2.4.2.2 basic_ostream::operator<< [lib.ostream.inserters] ostream_type& operator<<(ostream_type& (*pf)(ostream_type&)) 1 Returns (*pf)(*this).35) ostream_type& operator<<(ios_type& (*pf)(ios_type&)) 2 Calls (*(basic_ios<charT,baggage>*)pf)(*this), then returns *this.36) ostream_type& operator<<(const char_type* s); 3 Converts the NTBS s with the conversion specifier s. 4 Returns *this. ostream_type& operator<<(char_type c); 5 Converts the char_type c with the conversion specifier c and a field width of zero. The stored field width (basic_ios<charT,baggage>::wide) is not set to zero. _________________________ 34) The conversion specification #o generates a leading 0 which is not a padding character. 35) See, for example, the function signature endl(basic_ostream&). 36) See, for example, the function signature ::dec(basic_ios<charT,baggage>&). 6 Returns *this. +------- BEGIN BOX 100 -------+ The following two were not part of the proposal. Should we keep them? +------- END BOX 100 -------+ ostream_type& operator<<(unsigned char_type c) 7 Returns operator<<((char_type)c). ostream_type& operator<<(signed char_type c) 8 Returns operator<<((char_type)c). ostream_type& operator<<(bool n); 9 Behaves as if: { if (flags() & ios::boolalpha) { getloc().insert(*this, n); } else { *this << int(n); } } 10Returns *this. ostream_type& operator<<(short n); 11Converts the signed short integer n with the integral conversion spec ifier preceded by h. 12Returns *this. ostream_type& operator<<(unsigned short n); 13Converts the unsigned short integer n with the integral conversion specifier preceded by h. 14Returns *this. ostream_type& operator<<(int n); 15Converts the signed integer n with the integral conversion specifier. 16Returns *this. ostream_type& operator<<(unsigned int n); 17Converts the unsigned integer n with the integral conversion speci fier. 18Returns *this. ostream_type& operator<<(long n); 19Converts the signed long integer n with the integral conversion speci fier preceded by l. 20Returns *this. ostream_type& operator<<(unsigned long n); 21Converts the unsigned long integer n with the integral conversion specifier preceded by l. 22Returns *this. ostream_type& operator<<(float f); 23Converts the float f with the floating-point conversion specifier. 24Returns *this. ostream_type& operator<<(double f); 25Converts the double f with the floating-point conversion specifier. 26Returns *this. ostream_type& operator<<(long double f); 27Converts the long double f with the floating-point conversion speci fier preceded by L. 28Returns *this. ostream_type& operator<<(void* p); 29Converts the pointer to void p with the conversion specifier p. 30Returns *this. ostream_type& operator<<(basic_streambuf<charT,baggage>& sb); 31Gets characters from sb and inserts them in *this. Characters are read from sb and inserted until any of the following occurs: --end-of-file occurs on the input sequence; --inserting in the output sequence fails (in which case the character to be inserted is not extracted); LI an exception occurs while get ting a character from sb (in which case, the exception is rethrown). 32If the function inserts no characters or if it stopped because an exception was thrown while extracting a character, it calls set state(failbit). If an exception was thrown while extracting a charac ter and failbit is on in excedptions the caught exception is rethrown. 33Returns *this. 27.2.4.3 Unformatted output functions [lib.ostream.unformatted] 1 Each unformatted output function begins execution by calling opfx(). If that function returns nonzero, the function endeavors to generate the requested output. In any case, the unformatted output function ends by calling osfx(), then returning the value specified for the unformatted output function. 27.2.4.3.1 basic_ostream::put [lib.ostream::put] int put(char_type c); 1 Inserts the character c, if possible. Then returns (unsigned char)c. 2 Otherwise, calls setstate(badbit) and returns eof(). 27.2.4.3.2 basic_ostream::write [lib.ostream::write.str] basic_ostream& write(const char_type* s, streamsize n); 1 Obtains characters to insert from successive locations of an array whose first element is designated by s. Characters are inserted until either of the following occurs: --n characters are inserted; --inserting in the output sequence fails (in which case the function calls setstate(badbit)). 2 Returns *this. +------- BEGIN BOX 101 -------+ The following two were not part of the proposal. Should we keep them? +------- END BOX 101 -------+ basic_ostream& write(const unsigned char_type* s, streamsize n) 3 Returns write((const char_type*)s, n). basic_ostream& write(const signed char_type* s, streamsize n) 4 Returns write((const char_type*)s, n). 27.2.4.3.3 basic_ostream::write_byte [lib.ostream::write.byte] streamsize write_byte(const char* s, streamsize n); 1 Inserts bytes by invoking: rdbuf()->write_byte(s,n); 2 In case writing characters fails, calls setstate(failbit). 3 Returns the number of bytes written. 27.2.4.4 Standard basic_ostream [lib.basic.ostream.manip] manipulators 27.2.4.4.1 endl [lib.endl] basic_ostream<charT,baggage>& endl(basic_ostream<charT,baggage>& os); 1 Calls os.put(baggage::newline()), then os.flush(). 2 Returns os.37) _________________________ 37) The effect of executing cout << endl is to insert a newline char acter in the output sequence controlled by cout, then synchronize it 27.2.4.4.2 ends [lib.ends] basic_ostream<charT,baggage>& ends(basic_ostream<charT,baggage>& os); 1 +------- BEGIN BOX 102 -------+ [To Be Filled] +------- END BOX 102 -------+ 2 Returns os.38) 27.2.4.4.3 flush [lib.flush] basic_ostream<charT,baggage>& flush(basic_ostream<charT,baggage>& os); 1 Calls os.flush(). +------- BEGIN BOX 103 -------+ [To Be Filled] +------- END BOX 103 -------+ 2 Returns os. 27.2.5 Template class [lib.ostreambuf.iterator] ostreambuf_iterator +------- BEGIN BOX 104 -------+ Because the class locale::num_put<> depends on the class, ostream buf_iterator as the fundamental access way to the output stream with some efficiency, the class ostreambuf_iterator is defined in the header <ostream>. It really should be defined as part of Clause _lib.streambuf.iterators_. +------- END BOX 104 -------+ template <class charT, class baggage = ios_char_baggage<charT> > class ostreambuf_iterator { public: typedef charT char_type; typedef baggage baggage_type; typedef basic_streambuf<charT,baggage> streambuf; typedef basic_ostream<charT,baggage> ostream; _________________________ with any external file with which it might be associated. 38) The effect of executing ostr << ends is to insert a null character in the output sequence controlled by ostr. If ostr is an object of class basic_strstreambuf, the null character can terminate an NTBS constructed in an array object. public: ostreambuf_iterator() : sbuf_(0) {} ostreambuf_iterator(ostream& s) : sbuf_(s.rdbuf()) {} ostreambuf_iterator(streambuf* s) : sbuf_(s) {} ostreambuf_iterator& operator*() { return *this; } ostreambuf_iterator& operator++() { return *this; } ostreambuf_iterator& operator++(int) { return *this; } ostreambuf_iterator& operator=(charT c) { sbuf_->sputc(baggage::to_int_type(c)); } bool equal(ostreambuf_iterator& b) { return sbuf_ == b.sbuf_; } private: // streambuf* sbuf_; exposition only }; 1 The template class ostreambuf_iterator writes successive characters onto the output stream from which it was constructed. It is not pos sible to get a value out of the output iterator. 2 Two output iterators are equal if they are constructed with the same output streambuf. output_iterator iterator_category (const ostreambuf_iterator&) { return output_iterator(); } template<class charT, class baggage = ios_char_baggage<charT> > bool operator==(ostreambuf_iterator<charT,baggage>& a, ostreambuf_iterator<charT,baggage>& b) { return a.equal (b); } template<class charT, class baggage = ios_char_baggage<charT> > bool operator!=(ostreambuf_iterator<charT,baggage>& a, ostreambuf_iterator<charT,baggage>& b) { return !a.equal (b); } 27.3 Stream manipulators [lib.manipulators] 1 Headers: --<iomanip> 2 Table 16: Table 16--Header <iomanip> synopsis +---------------------------------------------------------------+ | Type Name(s) | +---------------------------------------------------------------+ |Template classes: | |basic_imanip imanip wimanip | |basic_omanip omanip womanip | |basic_smanip smanip wsmanip | +---------------------------------------------------------------+ |Template operators: | |operator<< (omanip) operator>> (imanip) | |operator<< (smanip) operator>> (smanip) | +---------------------------------------------------------------+ |Template functions: | |basic_resetiosflags basic_setfill basic_setprecision | |basic_setbase basic_setiosflags | +---------------------------------------------------------------+ |Functions: | |resetiosflags setfill setprecision | |setbase setiosflags setw | +---------------------------------------------------------------+ 3 The header <iomanip> defines three template classes and several related functions that use these template classes to provide extrac tors and inserters that alter information maintained by class basic_ios and its derived classes. It also defines several instantia tions of these template classes and functions. 27.3.1 Input manipulators [lib.input.manip] +------- BEGIN BOX 105 -------+ Manipulators have gotten way out of hand. The standard mainpulators should be provided, but the general mechanism isn't needed and a sim pler way to define them should be possible. +------- END BOX 105 -------+ 27.3.1.1 Template class basic_imanip [lib.template.basic.imanip] template<class T, class charT, class baggage = ios_char_baggage<charT> > class basic_imanip { public: typedef charT char_type; typedef baggage::char_bag::int_type int_type; typedef baggage::pos_bag::pos_type pos_type; typedef baggage::pos_bag::off_type off_type; int_type eof() { return baggage::char_bag::eof(); } char_type newline() { return baggage::char_bag::newline(); } public: basic_imanip( basic_ios<charT,baggage>& (*pf_arg)(basic_ios<charT,baggage>&, T), T); // basic_ios<charT,baggage>& (*pf)(basic_ios<charT,baggage>&, T); exposition only // T manarg; exposition only }; template <class T> class imanip<T> : public basic_imanip<T,char> {}; template <class T> class wimanip<T> : public basic_imanip<T,wchar_t> {}; 1 The template class basic_imanip<T,charT,baggage> describes an object that can store a function pointer and an object of type T. The desig nated function accepts an argument of this type T. +------- BEGIN BOX 106 -------+ [To Be Filled] +------- END BOX 106 -------+ 2 For the sake of exposition, the maintained data is presented here as: --basic_ios<charT,baggage>& (*pf)(basic_ios<charT,baggage>&, T), the function pointer; --T manarg, the object of type T. 27.3.1.1.1 basic_imanip<T> [lib.basic.imanip.basic.ios.cons] constructor basic_imanip(basic_ios<charT,baggage>& (*pf_arg)(basic_ios<charT,baggage>&, T), T manarg_arg); 1 Constructs an object of class basic_imanip<T>, initializing pf to pf_arg and manarg to manarg_arg. 27.3.1.1.2 operator>> [lib.ext.basic.imanip] template<class T, class charT, class baggage> basic_istream<charT,baggage>& operator>>(basic_istream<charT,baggage>& is, const basic_imanip<T,charT,baggage>& a); 1 Calls (*a.pf)(is, a.manarg) and catches any exception the function call throws. If the function catches an exception, it calls is.setstate(basic_ios::failbit) (the exception is not rethrown). 2 Returns is. 27.3.2 Template class basic_omanip [lib.template.basic.omanip] template<class T, class charT, class baggage = ios_char_baggage<charT> > class basic_omanip { public: basic_omanip( basic_ios<charT,baggage>& (*pf_arg)(basic_ios<charT,baggage>&, T), T); // basic_ios<charT,baggage>& (*pf)(basic_ios<charT,baggage>&, T); exposition only // T manarg; exposition only }; template <class T> class omanip<T> : public basic_omanip<T,char> {}; template <class T> class womanip<T> : public basic_omanip<T,wchar_t> {}; 1 The template class basic_omanip<T> describes an object that can store a function pointer and an object of type T. The designated function accepts an argument of this type T. +------- BEGIN BOX 107 -------+ [To Be Filled] +------- END BOX 107 -------+ 2 For the sake of exposition, the maintained data is presented here as: --basic_ios<charT,baggage>& (*pf)(basic_ios<charT,baggage>&, T), the function pointer; --T manarg, the object of type T. 27.3.2.1 basic_omanip [lib.basic.omanip.basic.ios.cons] constructor basic_omanip( basic_ios<charT,baggage>& (*pf_arg)(basic_ios<charT,baggage>&,T), T manarg_arg); 1 Constructs an object of class basic_omanip<T>, initializing pf to pf_arg and manarg to manarg_arg. 27.3.2.2 operator<< [lib.ins.basic.omanip] template<class T, class charT, class baggage> basic_ostream<charT,baggage>& operator<<(basic_ostream<charT,baggage>& os, const basic_omanip<T,charT,baggage>& a); 1 Calls (*a.pf)(os, a.manarg) and catches any exception the function call throws. If the function catches an exception, it calls os.setstate(basic_ios::failbit) (the exception is not rethrown). 2 Returns os. 27.3.3 Template class basic_smanip [lib.template.basic.smanip] template<class T, class charT, class baggage = ios_baggage<charT> > class basic_smanip { public: typedef charT char_type; typedef baggage::char_bag::int_type int_type; typedef baggage::pos_bag::pos_type pos_type; typedef baggage::pos_bag::off_type off_type; int_type eof() { return baggage::char_bag::eof(); } char_type newline() { return baggage::char_bag::newline(); } public: basic_smanip( basic_ios<charT,baggage>& (*pf_arg)(basic_ios<charT,baggage>&, T), T); // basic_ios<charT,baggage>& (*pf)(basic_ios<charT,baggage>&, T); exposition only // T manarg; exposition only }; template <class T> class smanip<T> : public basic_smanip<T,char> {}; template <class T> class wsmanip<T> : public basic_smanip<T,wchar_t> {}; 1 The template class basic_smanip<T,charT,baggage> describes an object that can store a function pointer and an object of type T. The desig nated function accepts an argument of this type T. +------- BEGIN BOX 108 -------+ [To Be Filled] +------- END BOX 108 -------+ 2 For the sake of exposition, the maintained data is presented here as: --basic_ios<charT,baggage>& (*pf)(basic_ios<charT,baggage>&, T), the function pointer; --T manarg, the object of type T. 27.3.3.1 basic_smanip [lib.basic.smanip.basic.ios.cons] constructor basic_smanip( basic_ios<charT,baggage>& (*pf_arg)(basic_ios<charT,baggage>&, T), T manarg_arg); 1 Constructs an object of class basic_smanip<T>, initializing pf to pf_arg and manarg to manarg_arg. 27.3.3.2 operator>> [lib.ext.basic.smanip] template<class T, class charT, class baggage> basic_istream<charT,baggage>& operator>>(basic_istream<charT,baggage>& is, const basic_smanip<T,charT,baggage>& a); 1 Calls (*a.pf)(is, a.manarg) and catches any exception the function call throws. If the function catches an exception, it calls is.setstate(basic_ios::failbit) (the exception is not rethrown). 2 Returns is. 27.3.3.3 operator<< [lib.ins.basic.smanip] template<class T, class charT, class baggage> basic_ostream<charT,baggage>& operator<<(basic_ostream<charT,baggage>& os, const basic_smanip<T,charT,baggage>& a); 1 Calls (*a.pf)(os, a.manarg) and catches any exception the function call throws. If the function catches an exception, it calls os.setstate(basic_ios::failbit) (the exception is not rethrown). 2 Returns os. 27.3.4 Standard manipulators [lib.std.manip] 27.3.4.1 basic_resetiosflags [lib.basic.resetiosflags] template<class charT, class baggage> basic_smanip<basic_ios<charT,baggage>::fmtflags> basic_resetiosflags(basic_ios<charT,baggage>::fmtflags mask); 1 Returns basic_smanip<basic_ios<charT,baggage>::fmtflags>(&f, mask), where f can be defined as:39) template<class charT, class baggage> basic_ios<charT,baggage>& f(basic_ios<charT,baggage>& str, basic_ios<charT,baggage>::fmtflags mask) { // reset specified flags str.setf((basic_ios<charT,baggage>::fmtflags)0, mask); return str; } 27.3.4.2 basic_setiosflags [lib.basic.setiosflags] template<class charT, class baggage> basic_smanip<basic_ios<charT,baggage>::fmtflags> basic_setiosflags(basic_ios<charT,baggage>::fmtflags mask); 1 Returns basic_smanip<basic_ios<charT,baggage>::fmtflags>(&f,mask), where f can be defined as: template<class charT, class baggage> basic_ios<charT,baggage>& f(basic_ios<charT,baggage>& str, basic_ios<charT,baggage>::fmtflags mask) { // set specified flags str.setf(mask); return str; } _________________________ 39) The expression cin >> resetba sic_iosflags(basic_ios<charT,baggage>::skipws) clears ba sic_ios<charT,baggage>::skipws in the format flags stored in the ba sic_istream object cin (the same as cin >> noskipws), and the expres sion cout << resetbasic_iosflags(basic_ios<charT,baggage>::showbase) clears basic_ios<charT,baggage>::showbase in the format flags stored in the basic_ostream object cout (the same as cout << noshowbase). 27.3.4.3 basic_setbase [lib.basic.setbase] template<class charT, class baggage> basic_smanip<int> basic_setbase(int base); 1 Returns basic_smanip<int>(&f, base), where f can be defined as: template<class charT, class baggage> basic_ios<charT,baggage>& f(basic_ios<charT,baggage>& str, int base) { // set basefield str.setf(n == 8 ? basic_ios<charT,baggage>::oct : n == 10 ? basic_ios<charT,baggage>::dec : n == 16 ? basic_ios<charT,baggage>::hex : basic_ios<charT,baggage>::fmtflags(0), basic_ios<charT,baggage>::basefield); return str; } 27.3.4.4 basic_setfill [lib.basic.setfill] basic_smanip<int> basic_setfill(int c); 1 Returns basic_smanip<int>(&f, c), where f can be defined as: template<class charT, class baggage> basic_ios<charT,baggage>& f(basic_ios<charT,baggage>& str, int c) { // set fill character str.fill(c); return str; } 27.3.4.5 basic_setprecision [lib.basic.setprecision] template<class charT, class baggage> basic_smanip<int> basic_setprecision(int n); 1 Returns basic_smanip<int>(&f, n), where f can be defined as: template<class charT, class baggage> basic_ios<charT,baggage>& f(basic_ios<charT,baggage>& str, int n) { // set precision str.precision(n); return str; } 27.3.4.6 basic_setw [lib.basic.setw] template<class charT, class baggage> basic_smanip<int> basic_setw(int n); 1 Returns basic_smanip<int>(&f, n), where f can be defined as: template<class charT, class baggage> basic_ios<charT,baggage>& f(basic_ios<charT,baggage>& str, int n) { // set width str.width(n); return str; } +------- BEGIN BOX 109 -------+ [To Be Filled] +------- END BOX 109 -------+ 27.4 String-based streams [lib.string.streams] 1 Headers: --<sstream> --<strstream> --<cstdlib> ascii <-> numeric conversions 2 Table 17: Table 17--Header <sstream> synopsis +------------------------------------------------------------+ | Type Name(s) | +------------------------------------------------------------+ |Template classes: | |basic_istringstream basic_ostringstream basic_stringbuf | +------------------------------------------------------------+ |Classes: stringbuf wstringbuf | | istringstream wistringstream | | ostringstream wostringstream | +------------------------------------------------------------+ 3 Table 18: Table 18--Header <strstream> synopsis +------- BEGIN BOX 110 -------+ I believe that strstream is obsolete and should not be included in the standard. The interface is klunky (a "technical term" meaning the de scription is longer than it ought to be) and has been frequently crit icized for making memory management hard. sstream(or a class that us es a general STL iterator) should be a replacement for it, not an ad dition. I am not making an editorial proposal because I realize that this is likely to be controversial. -- jss +------- END BOX 110 -------+ +--------------------------------------------------------------------+ | Type Name(s) | +--------------------------------------------------------------------+ |Template basic_istrstream basic_ostrstream basic_strstreambuf | |classes: | +--------------------------------------------------------------------+ |Classes: istrstream ostrstream strstreambuf | +--------------------------------------------------------------------+ 4 Table 19: Table 19--Header <cstdlib> synopsis +---------------------+ |Type Name(s) | +---------------------+ |Functions: | | atoi strtod | | atol strtol | +---------------------+ 5 SEE ALSO: ISO C subclause 7.10.1. 27.4.1 char* streams [lib.str.strstreams] 1 The header <strstream> defines three types that associate stream buffers with character array objects and assist reading and writing such objects. 27.4.1.1 Template class basic_strstreambuf [lib.strstreambuf] template <class charT, class baggage = ios_baggage<charT> > class basic_strstreambuf : public basic_streambuf<charT,baggage> { public: typedef charT char_type; typedef baggage::char_bag::int_type int_type; typedef baggage::pos_bag::pos_type pos_type; typedef baggage::pos_bag::off_type off_type; int_type eof() { return baggage::char_bag::eof(); } char_type newline() { return baggage::char_bag::newline(); } +------- BEGIN BOX 111 -------+ Note: null character constraint is needed in ios_baggage. +------- END BOX 111 -------+ public: basic_strstreambuf(streamsize alsize_arg = 0); basic_strstreambuf(void* (*palloc_arg)(size_t), void (*pfree_arg)(void*)); basic_strstreambuf(char_type* gnext_arg, streamsize n, char_type* pbeg_arg = 0); +------- BEGIN BOX 112 -------+ The following two were not part of the proposal. Should we keep them? +------- END BOX 112 -------+ basic_strstreambuf(unsigned char_type* gnext_arg, streamsize n, unsigned char_type* pbeg_arg = 0); basic_strstreambuf(signed char_type* gnext_arg, streamsize n, signed char_type* pbeg_arg = 0); basic_strstreambuf(const char_type* gnext_arg, streamsize n); +------- BEGIN BOX 113 -------+ The following two were not part of the proposal. Should we keep them? +------- END BOX 113 -------+ basic_strstreambuf(const unsigned char_type* gnext_arg, streamsize n); basic_strstreambuf(const signed char_type* gnext_arg, streamsize n); virtual ~basic_strstreambuf(); void freeze(bool = 1); char_type* str(); int pcount(); protected: // virtual int_type overflow (int_type c = eof()); inherited // virtual int_type pbackfail(int_type c = eof()); inherited +------- BEGIN BOX 114 -------+ The following was not part of the proposal. Should we keep it? +------- END BOX 114 -------+ // virtual int showmany(); inherited // virtual int_type underflow(); inherited // virtual int_type uflow(); inherited // virtual streamsize xsgetn(char_type* s, streamsize n); inherited // virtual streamsize xsputn(const char_type* s, streamsize n); inherited // virtual pos_type seekoff(off_type off, // basic_ios<charT,baggage>::seekdir way, // basic_ios<charT,baggage>::openmode which // = basic_ios<charT,baggage>::in | basic_ios<charT,baggage>::out); inherited // virtual pos_type seekpos(pos_type sp, // basic_ios<charT,baggage>::openmode which // = basic_ios<charT,baggage>::in | basic_ios<charT,baggage>::out); inherited // virtual basic_streambuf<char_type,baggage>* // setbuf(char_type* s, streamsize n); inherited // virtual int sync(); inherited private: // typedef T1 strstate; exposition only // static const strstate allocated; exposition only // static const strstate constant; exposition only // static const strstate dynamic; exposition only // static const strstate frozen; exposition only // strstate strmode; exposition only // streamsize alsize; exposition only // void* (*palloc)(size_t); exposition only // void (*pfree)(void*); exposition only }; 1 The class basic_strstreambuf<charT,baggage> is derived from basic_streambuf<charT,baggage> to associate the input sequence and possibly the output sequence with an object of some character array type, whose elements store arbitrary values. The array object has several attributes. 2 For the sake of exposition, these are represented as elements of a bitmask type (indicated here as T1) called strstate. The elements are: --allocated, set when a dynamic array object has been allocated, and hence should be freed by the destructor for the basic_strstreambuf object; --constant, set when the array object has const elements, so the out put sequence cannot be written; --dynamic, set when the array object is allocated (or reallocated) as necessary to hold a character sequence that can change in length; --frozen, set when the program has requested that the array object not be altered, reallocated, or freed. 3 For the sake of exposition, the maintained data is presented here as: --strstate strmode, the attributes of the array object associated with the basic_strstreambuf object; --int alsize, the suggested minimum size for a dynamic array object; --void* (*palloc)(size_t), points to the function to call to allocate a dynamic array object; --void (*pfree)(void*), points to the function to call to free a dynamic array object. 4 Each object of class basic_strstreambuf<charT,baggage> has a seekable area, delimited by the pointers seeklow and seekhigh. If gnext is a null pointer, the seekable area is undefined. Otherwise, seeklow equals gbeg and seekhigh is either pend, if pend is not a null pointer, or gend. 27.4.1.1.1 basic_strstreambuf [lib.basic.strstreambuf.cons] constructors basic_strstreambuf(streamsize alsize_arg = 0); 1 Constructs an object of class basic_strstreambuf, initializing the base class with basic_streambuf(). The postconditions of this func tion are indicated in Table 20: Table 20--basic_strstreambuf(streamsize) effects +-------------------------+ |Element Value | +-------------------------+ |strmode dynamic | |alsize alsize_arg | |palloc a null pointer | |pfree a null pointer | +-------------------------+ basic_strstreambuf(void* (*palloc_arg)(size_t), void (*pfree_arg)(void*)); 2 Constructs an object of class basic_strstreambuf, initializing the base class with basic_streambuf(). The postconditions of this func tion are indicated in Table 21: Table 21--basic_strstreambuf(void* (*)(size_t),void (*)(void*) effects +-------------------------------+ |Element Value | +-------------------------------+ |strmode dynamic | |alsize an unspecified value | |palloc palloc_arg | |pfree pfree_arg | +-------------------------------+ basic_strstreambuf(char_type* gnext_arg, streamsize n, char_type *pbeg_arg = 0); 3 Constructs an object of class basic_strstreambuf, initializing the base class with basic_streambuf(). The postconditions of this func tion are indicated in Table 22: Table 22--basic_strstreambuf(charT*,streamsize,charT*) effects +-------------------------------+ |Element Value | +-------------------------------+ |strmode 0 | |alsize an unspecified value | |palloc a null pointer | |pfree a null pointer | +-------------------------------+ 4 gnext_arg shall point to the first element of an array object whose number of elements N is determined as follows: --If n > 0, N is n. --If n == 0, N is strlen(gnext_arg). +------- BEGIN BOX 115 -------+ Needs work, regarding charT length. +------- END BOX 115 -------+ --If n < 0, N is INT_MAX. 40) _________________________ 40) The function signature strlen(const char*) is declared in <cstring> (_lib.c.strings_). The macro INT_MAX is defined in 5 If pbeg_arg is a null pointer, the function executes: setg(gnext_arg, gnext_arg, gnext_arg + N); 6 Otherwise, the function executes: setg(gnext_arg, gnext_arg, pbeg_arg); setp(pbeg_arg, pbeg_arg + N); +------- BEGIN BOX 116 -------+ The following two were not part of the proposal. Should we keep them? +------- END BOX 116 -------+ basic_strstreambuf(unsigned char_type* gnext_arg, streamsize n, unsigned char_type* pbeg_arg = 0); 7 Behaves the same as basic_strstreambuf((char_type*)gnext_arg, n, (char_type*)pbeg_arg). basic_strstreambuf(signed char_type* gnext_arg, streamsize n, signed char_type* pbeg_arg = 0); 8 Behaves the same as basic_strstreambuf((char_type*)gnext_arg, n, (char_type*)pbeg_arg). basic_strstreambuf(const char_type* gnext_arg, streamsize n); 9 Behaves the same as basic_strstreambuf((char_type*)gnext_arg, n), except that the constructor also sets constant in strmode. +------- BEGIN BOX 117 -------+ The following two were not part of the proposal. Should we keep them? +------- END BOX 117 -------+ basic_strstreambuf(const unsigned char_type* gnext_arg, streamsize n); 10Behaves the same as basic_strstreambuf((const char_type*)gnext_arg,n). basic_strstreambuf(const signed char_type* gnext_arg, streamsize n); 11Behaves the same as basic_strstreambuf((const char_type*)gnext_arg,n). 27.4.1.1.2 basic_strstreambuf [lib.basic.strstreambuf.des] destructor virtual ~basic_strstreambuf(); 1 Destroys an object of class basic_strstreambuf. The function frees the dynamically allocated array object only if strmode & allocated is nonzero and strmode & frozen is zero. (Subclause _basic_strstreambuf::overflow_ describes how a dynamically allocated array object is freed.) _________________________ <climits> (_lib.support.limits_). 27.4.1.1.3 basic_strstreambuf::freeze [lib.strstreambuf::freeze] void freeze(bool freezefl = 1); 1 If strmode & dynamic is non-zero, alters the freeze status of the dynamic array object as follows: If freezefl is false, the function sets frozen in strmode. Otherwise, it clears frozen in strmode. 27.4.1.1.4 basic_strstreambuf::str [lib.strstreambuf::str] char_type* str(); 1 Calls freeze(), then returns the beginning pointer for the input sequence, gbeg.41) 27.4.1.1.5 basic_strstreambuf::pcount [lib.strstreambuf::pcount] int pcount() const; 1 If the next pointer for the output sequence, pnext, is a null pointer, returns zero. Otherwise, returns the current effective length of the array object as the next pointer minus the beginning pointer for the output sequence, pnext - pbeg. 27.4.1.1.6 [lib.strstreambuf::overflow] basic_strstreambuf::overflow // virtual int_type overflow(int_type c = eof()); inherited +------- BEGIN BOX 118 -------+ This needs to be rewritten in terms of consuming characters to be con sistent with the revised protocol for overflow. +------- END BOX 118 -------+ 1 Appends the character designated by c to the output sequence, if pos sible, in one of two ways: --If c != eof() and if either the output sequence has a write position available or the function makes a write position available (as described below), assigns c to *pnext++. Returns (char_type)c. --If c == eof(), there is no character to append. Returns a value other than eof(). 2 Returns eof() to indicate failure. 3 Notes: 4 The function can alter the number of write positions available as a result of any call. _________________________ 41) The return value can be a null pointer. 5 To make a write position available, the function reallocates (or ini tially allocates) an array object with a sufficient number of elements n to hold the current array object (if any), plus at least one addi tional write position. How many additional write positions are made available is otherwise unspecified.42) If palloc is not a null pointer, the function calls (*palloc)(n) to allocate the new dynamic array object. Otherwise, it evaluates the expression new charT[n]. In either case, if the allocation fails, the function returns eof(). Otherwise, it sets allocated in strmode. 6 To free a previously existing dynamic array object whose first element address is p: If pfree is not a null pointer, the function calls (*pfree)(p). Otherwise, it evaluates the expression delete[] p. 7 If strmode & dynamic is zero, or if strmode & frozen is nonzero, the function cannot extend the array (reallocate it with greater length) to make a write position available. 27.4.1.1.7 [lib.strstreambuf::pbackfail] basic_strstreambuf::pbackfail // virtual int_type pbackfail(int_type c = eof()); inherited +------- BEGIN BOX 119 -------+ This needs to be rewritten in terms of consuming characters to be con sistent with the revised protocol for pbackfail.. +------- END BOX 119 -------+ 1 Puts back the character designated by c to the input sequence, if pos sible, in one of three ways: --If c != eof(), if the input sequence has a putback position avail able, and if (char_type)c == char_type)gnext[-1], assigns gnext - 1 to gnext. Returns (char_type)c. --If c != eof(), if the input sequence has a putback position avail able, and if strmode & constant is zero, assigns c to *--gnext. Returns (char_type)c. --If c == eof() and if the input sequence has a putback position available, assigns gnext - 1 to gnext. Returns (char_type)c. 2 Returns eof() to indicate failure. 3 Notes: _________________________ 42) An implementation should consider alsize in making this decision. +------- BEGIN BOX 120 -------+ Cannot distinguish success and failure if c == EOF. +------- END BOX 120 -------+ 4 If the function can succeed in more than one of these ways, it is unspecified which way is chosen. The function can alter the number of putback positions available as a result of any call. +------- BEGIN BOX 121 -------+ The following was not part of the proposal. Should we keep it? +------- END BOX 121 -------+ 27.4.1.1.8 [lib.strstreambuf::showmany] basic_strstreambuf::showmany // virtual int showmany(); inherited 1 Behaves the same as basic_streambuf::showmany(int). 27.4.1.1.9 [lib.strstreambuf::underflow] basic_strstreambuf::underflow // virtual int_type underflow(); inherited +------- BEGIN BOX 122 -------+ This needs to be rewritten in terms of consuming characters to be con sistent with the revised protocol for underflow.. +------- END BOX 122 -------+ 1 Reads a character from the input sequence, if possible, without moving the stream position past it, as follows: --If the input sequence has a read position available the function signals success by returning (char_type)*gnext. --Otherwise, if the current write next pointer pnext is not a null pointer and is greater than the current read end pointer gend, makes a read position available by: assigning to gend a value greater than gnext and no greater than pnext. Returns (char_type)*gnext. 2 Returns eof() to indicate failure. 3 Notes: 4 The function can alter the number of read positions available as a result of any call. 27.4.1.1.10 basic_strstreambuf::uflow [lib.strstreambuf::uflow] // virtual int_type uflow(); inherited 1 Behaves the same as basic_streambuf::uflow(). 27.4.1.1.11 [lib.strstreambuf::xsgetn] basic_strstreambuf::xsgetn // virtual streamsize xsgetn(char_type* s, streamsize n); inherited 1 Behaves the same as basic_streambuf::xsgetn(s,n). 27.4.1.1.12 [lib.strstreambuf::xsputn] basic_strstreambuf::xsputn // virtual int xsputn(const char_type* s, streamsize n); inherited 1 Behaves the same as basic_streambuf::xsputn(s,n). 27.4.1.1.13 [lib.strstreambuf::seekoff] basic_strstreambuf::seekoff // virtual pos_type seekoff(off_type off, seekdir way, // openmode which = in | out); inherited +------- BEGIN BOX 123 -------+ Check vs. _lib.stringbuf::seekoff_ +------- END BOX 123 -------+ 1 Alters the stream position within one of the controlled sequences, if possible, as indicated in Table 23: Table 23--seekoff positioning +----------------------------------------------------------------------------+ | Conditions Result | +----------------------------------------------------------------------------+ (which & basic_ios::in) != 0positions the input sequence | +----------------------------------------------------------------------------+ (which& basic_ios::out) != 0positions the output sequence | +----------------------------------------------------------------------------+ |Otherwise, | (which & (basic_ios::in | positions both the input and the output sequences| basic_ios::out)) == (ba | sic_ios::in | ba | sic_ios::out)) | |and way == either ba | sic_ios::beg or ba | sic_ios::end | +----------------------------------------------------------------------------+ |Otherwise, the positioning operation fails. | +----------------------------------------------------------------------------+ +------- BEGIN BOX 124 -------+ Comment: this condition is unclear. If the 2nd condition is true, is the 1st condition always true? If so, the 2nd operation may occur, mayn't it? +------- END BOX 124 -------+ 2 For a sequence to be positioned, if its next pointer is a null pointer, the positioning operation fails. Otherwise, the function determines newoff as indicated in Table 24: Table 24--newoff values +---------------------------------------------------------+ | Condition newoff Value | +---------------------------------------------------------+ |way == basic_ios::beg 0 | +---------------------------------------------------------+ |way == basic_ios::cur the next pointer minus the be | | ginning pointer (xnext - xbeg) | +---------------------------------------------------------+ |way == basic_ios::end seekhigh minus the beginning | | pointer (seekhigh - xbeg) | +---------------------------------------------------------+ |If (newoff + off) < the positioning operation fails | |(seeklow - xbeg), | |or (seekhigh - xbeg) < | |(newoff + off) | +---------------------------------------------------------+ 3 Otherwise, the function assigns xbeg + newoff + off to the next pointer xnext. 4 Returns pos_type(newoff), constructed from the resultant offset newoff (of type off_type), that stores the resultant stream position, if pos sible. If the positioning operation fails, or if the constructed object cannot represent the resultant stream position, the object stores an invalid stream position. +------- BEGIN BOX 125 -------+ Note: Need posT object which stores an invalid stream position. Com ment: Not clear if the constructed object cannot represent the resul tant stream position +------- END BOX 125 -------+ 27.4.1.1.14 [lib.strstreambuf::seekpos] basic_strstreambuf::seekpos // virtual pos_type seekpos(pos_type sp, // basic_ios<charT,baggage>::openmode which // = basic_ios<charT,baggage>::in | basic_ios<charT,baggage>::out); inherited +------- BEGIN BOX 126 -------+ Check vs. _lib.stringbuf::seekpos_ +------- END BOX 126 -------+ 1 Alters the stream position within one of the controlled sequences, if possible, to correspond to the stream position stored in sp (as described below). --If (which & basic_ios::in) != 0, positions the input sequence. --If (which & basic_ios::out) != 0, positions the output sequence. --If the function positions neither sequence, the positioning opera tion fails. 2 For a sequence to be positioned, if its next pointer is a null pointer, the positioning operation fails. Otherwise, the function determines newoff from sp.offset(): --If newoff is an invalid stream position, has a negative value, or has a value greater than (seekhigh - seeklow), the positioning oper ation fails --Otherwise, the function adds newoff to the beginning pointer xbeg and stores the result in the next pointer xnext. 3 Returns pos_type(newoff), constructed from the resultant offset newoff (of type off_type), that stores the resultant stream position, if pos sible. If the positioning operation fails, or if the constructed object cannot represent the resultant stream position, the object stores an invalid stream position. 4 27.4.1.1.15 [lib.strstreambuf::setbuf] basic_strstreambuf::setbuf // virtual basic_streambuf<char_type,baggage>* // setbuf(char_type* s, streamsize n); inherited 1 Performs an operation that is defined separately for each class derived from basic_strstreambuf. +------- BEGIN BOX 127 -------+ Should be pure virtual. +------- END BOX 127 -------+ 2 Default behavior: the same as for basic_streambuf::setbuf(char_type*, streamsize). 27.4.1.1.16 basic_strstreambuf::sync [lib.strstreambuf::sync] // virtual int sync(); inherited 1 Behaves the same as basic_streambuf::sync(). 27.4.1.2 Template class basic_istrstream [lib.istrstream] template<class charT, class baggage = int_baggage<charT> > class basic_istrstream : public basic_istream<charT,baggage> { public: typedef charT char_type; typedef baggage::char_bag::int_type int_type; typedef baggage::pos_bag::pos_type pos_type; typedef baggage::pos_bag::off_type off_type; int_type eof() { return baggage::char_bag::eof(); } char_type newline() { return baggage::char_bag::newline(); } public: basic_istrstream(const char_type* s); basic_istrstream(const char_type* s, streamsize n); basic_istrstream(char_type* s); basic_istrstream(char_type* s, streamsize n); virtual ~basic_istrstream(); basic_strstreambuf<char_type,baggage>* rdbuf() const; char *str(); private: // basic_strstreambuf<char_type,baggage> sb; exposition only // typedef basic_strstreambuf<char_type,baggage> sb_type; exposition only }; 1 The class basic_istrstream is a derivative of basic_istream that assists in the reading of objects of class basic_strstreambuf. It supplies a basic_strstreambuf object to control the associated array object. 2 For the sake of exposition, the maintained data is presented here as: --sb, the basic_strstreambuf object. 27.4.1.2.1 basic_istrstream [lib.basic.istrstream.cons] constructors basic_istrstream(const char_type* s); 1 Constructs an object of class basic_istrstream, initializing the base class with basic_istream(&sb), and initializing sb with sb_type(s, 0). s shall designate the first element of an NTBS. +------- BEGIN BOX 128 -------+ Needs work, NTBS. +------- END BOX 128 -------+ basic_istrstream(const char_type* s, streamsize n); 2 Constructs an object of class basic_istrstream, initializing the base class with basic_istream(&sb), and initializing sb with sb_type(s, n). s shall designate the first element of an array whose length is n elements, and n shall be greater than zero. basic_istrstream(char_type* s); 3 Constructs an object of class basic_istrstream, initializing the base class with basic_istream(&sb), and initializing sb with sb_type((const char_type*)s,0). s shall designate the first element of an NTBS. +------- BEGIN BOX 129 -------+ Needs work, NTBS. +------- END BOX 129 -------+ basic_istrstream(char_type* s, streamsize n); 4 Constructs an object of class basic_istrstream, initializing the base class with basic_istream(&sb), and initializing sb with sb_type((const char_type*)s,n). s shall designate the first element of an array whose length is n elements, and n shall be greater than zero. 27.4.1.2.2 basic_istrstream [lib.basic.istrstream.des] destructor virtual ~basic_istrstream(); 1 Destroys an object of class basic_istrstream. 27.4.1.2.3 basic_istrstream::rdbuf [lib.istrstream::rdbuf] basic_strstreambuf* rdbuf() const; 1 Returns (basic_strstreambuf*)&sb. 27.4.1.2.4 basic_istrstream::str [lib.istrstream::str] char_type* str(); 1 Returns sb.str(). 27.4.1.3 Template class basic_ostrstream [lib.ostrstream] template <class charT, class baggage = int_baggage<charT> > class basic_ostrstream : public ostream<charT,baggage> { public: typedef charT char_type; typedef baggage::char_bag::int_type int_type; typedef baggage::pos_bag::pos_type pos_type; typedef baggage::pos_bag::off_type off_type; int_type eof() { return baggage::char_bag::eof(); } char_type newline() { return baggage::char_bag::newline(); } public: basic_ostrstream(); basic_ostrstream(char_type* s, int n, basic_ios<charT,baggage>::openmode mode = basic_ios<charT,baggage>::out); virtual ~basic_ostrstream(); basic_strstreambuf<char_type,baggage>* rdbuf() const; void freeze(int freezefl = 1); char_type* str(); int pcount() const; private: // basic_strstreambuf<char_type,baggage> sb; exposition only // typedef basic_strstreambuf<char_type,baggage> sb_type; exposition only }; 1 The class basic_ostrstream is a derivative of basic_ostream that assists in the writing of objects of class basic_strstreambuf. It supplies a basic_strstreambuf object to control the associated array object. 2 For the sake of exposition, the maintained data is presented here as: --sb, the basic_strstreambuf object. 27.4.1.3.1 basic_ostrstream [lib.basic.ostrstream.cons] constructors basic_ostrstream(); 1 Constructs an object of class basic_ostrstream, initializing the base class with basic_ostream(&sb), and initializing sb with sb_type(). basic_ostrstream(char_type* s, int n, basic_ios<charT,baggage>::openmode mode = basic_ios<charT,baggage>::out); 2 Constructs an object of class basic_ostrstream, initializing the base class with basic_ostream(&sb), and initializing sb with one of two constructors: --If mode & app is zero, then s shall designate the first element of an array of n elements. The constructor is sb_type(s, n, s). --If mode & app is nonzero, then s shall designate the first element of an array of n elements that contains an NTBS whose first element is designated by s. +------- BEGIN BOX 130 -------+ Needs work, NTBS and length(). +------- END BOX 130 -------+ The constructor is sb_type(s, n, s + ::strlen(s)). 43) _________________________ 43) The function signature strlen(const char_type*) is declared in <cstring> (_lib.file.streams_). 27.4.1.3.2 basic_ostrstream [lib.basic.ostrstream.des] destructor virtual ~basic_ostrstream(); 1 Destroys an object of class basic_ostrstream. 27.4.1.3.3 basic_ostrstream::rdbuf [lib.ostrstream::rdbuf] basic_strstreambuf* rdbuf() const; 1 Returns (basic_strstreambuf*)&sb. 27.4.1.3.4 basic_ostrstream::freeze [lib.ostrstream::freeze] void freeze(int freezefl = 1); 1 Calls sb.freeze(freezefl). 27.4.1.3.5 basic_ostrstream::str [lib.ostrstream::str] char_type* str(); 1 Returns sb.str(). 27.4.1.3.6 basic_ostrstream::pcount [lib.ostrstream::pcount] int pcount() const; 1 Returns sb.pcount(). 27.4.2 string streams [lib.string.strstreams] 1 The header <sstream> defines three types that associate stream buffers with objects of class string, as described in clause _lib.string_. 27.4.2.1 Template class basic_stringbuf [lib.stringbuf] +------- BEGIN BOX 131 -------+ When strings are rationalized with STL, that is when they become con tainers with iterators, this class ought to be replaced by a method that uses a general STL container. +------- END BOX 131 -------+ template <class charT, class baggage = int_charT_baggage<charT> > class basic_stringbuf : public basic_streambuf<charT,baggage> { public: typedef charT char_type; typedef baggage::char_bag::int_type int_type; typedef baggage::pos_bag::pos_type pos_type; typedef baggage::pos_bag::off_type off_type; int_type eof() { return baggage::char_bag::eof(); } char_type newline() { return baggage::char_bag::newline(); } public: basic_stringbuf(basic_ios<charT,baggage>::openmode which = basic_ios<charT,baggage>::in | basic_ios<charT,baggage>::out); basic_stringbuf(const basic_string<char_type>& str, basic_ios<charT,baggage>::openmode which = basic_ios<charT,baggage>::in | basic_ios<charT,baggage>::out); virtual ~basic_stringbuf(); basic_string<char_type> str() const; void str(const basic_string<char_type>& str_arg); protected: // virtual int_type overflow (int_type c = eof()); inherited // virtual int_type pbackfail(int_type c = eof()); inherited +------- BEGIN BOX 132 -------+ The following was not part of the proposal. Should we keep it? +------- END BOX 132 -------+ // virtual int showmany(); inherited // virtual int_type underflow(); inherited // virtual int_type uflow(); inherited // virtual streamsize xsgetn(char_type* s, streamsize n); inherited // virtual streamsize xsputn(const char_type* s, streamsize n); inherited // virtual pos_type seekoff(off_type off, // basic_ios<charT,baggage>::seekdir way, // basic_ios<charT,baggage>::openmode which // = basic_ios<charT,baggage>::in // | basic_ios<charT,baggage>::out); inherited // virtual pos_type seekpos(pos_type sp, // basic_ios<charT,baggage>::openmode which // = basic_ios<charT,baggage>::in // | basic_ios<charT,baggage>::out); inherited // virtual basic_streambuf<char_type,baggage>* // setbuf(char_type* s, streamsize n); inherited // virtual int sync(); inherited private: // basic_ios<charT,baggage>::openmode mode; exposition only }; +------- BEGIN BOX 133 -------+ The descriptions of the virtuals in this class need to be brought into agreement with the new descriptions of the generic protocols. As part of that we have 1 Jerry Schwarz proposal: // // string data ; exposition only +------- END BOX 133 -------+ class stringbuf : public basic_stringbuf<char> {}; class wstringbuf : public basic_stringbuf<wchar_t> {}; +------- BEGIN BOX 134 -------+ Note: same charT type string can be fed. +------- END BOX 134 -------+ 2 The class basic_stringbuf is derived from basic_streambuf to associate possibly the input sequence and possibly the output sequence with a sequence of arbitrary characters. The sequence can be initialized from, or made available as, an object of class basic_string. +------- BEGIN BOX 135 -------+ [To Be Filled] +------- END BOX 135 -------+ 3 For the sake of exposition, the maintained data is presented here as: --basic_ios<charT,baggage>::openmode mode, has in set if the input sequence can be read, and out set if the output sequence can be written. 4 For the sake of exposition, the stored character sequence is described here as an array object. 27.4.2.1.1 basic_stringbuf [lib.basic.stringbuf.cons] constructors basic_stringbuf(basic_ios<charT,baggage>::openmode which = basic_ios<charT,baggage>::in | basic_ios<charT,baggage>::out); 1 Constructs an object of class basic_stringbuf, initializing the base class with basic_streambuf(), and initializing mode with which. The function allocates no array object. basic_stringbuf(const basic_string<char_type>& str, basic_ios<charT,baggage>::openmode which = basic_ios<charT,baggage>::in | basic_ios<charT,baggage>::out); 2 Constructs an object of class basic_stringbuf, initializing the base class with basic_streambuf(), and initializing mode with which. 3 If str.length() is nonzero, the function allocates an array object x whose length n is str.length() and whose elements x[I] are initialized to str[I]. If which & basic_ios::in is nonzero, the function exe cutes: setg(x, x, x + n); 4 If which & basic_ios::out is nonzero, the function executes: setp(x, x + n); 27.4.2.1.2 basic_stringbuf destructor [lib.basic.stringbuf.des] virtual ~basic_stringbuf(); 1 Destroys an object of class basic_stringbuf. 27.4.2.1.3 basic_stringbuf::str [lib.stringbuf::str] basic_string<char_type> str() const; The return value of this function are indicated in Table 25: Table 25--str return values +---------------------------------------------------------------------+ | Condition Return Value | +---------------------------------------------------------------------+ |(mode & basic_ios::in) basic_string<char_type>(gbeg,gend - gbeg) | |!= 0 and (gnext != 0) | +---------------------------------------------------------------------+ |(mode & basic_ios::out) basic_string<char_type>(pbeg,pptr - pbeg) | |!= 0 and (pnext != 0 | +---------------------------------------------------------------------+ |Otherwise basic_string<char_type>() | +---------------------------------------------------------------------+ void str(const basic_string<char_type>& str_arg); 1 If str_arg.length() is zero, executes: setg(0, 0, 0); setp(0, 0); 2 and frees storage for any associated array object. Otherwise, the function allocates an array object x whose length n is str_arg.length() and whose elements x[I] are initialized to str_arg[I]. If which & basic_ios<charT,baggage>::in is nonzero, the function executes: setg(x, x, x + n); 3 If which & basic_ios<charT,baggage>::out is nonzero, the function exe cutes: setp(x, x + n); 27.4.2.1.4 basic_stringbuf::overflow [lib.stringbuf::overflow] // virtual int_type overflow(int_type c = eof()); inherited 1 Appends the character designated by c to the output sequence, if pos sible, in one of two ways: --If c != eof() and if either the output sequence has a write position available or the function makes a write position available (as described below), the function assigns c to *pnext++. The function signals success by returning (char_type)c. --If c == eof(), there is no character to append. The function sig nals success by returning a value other than eof(). 2 The function can alter the number of write positions available as a result of any call. 3 Returns eof() to indicate failure. 4 The function can make a write position available only if (mode & basic_ios<charT,baggage>::out) != 0. To make a write position avail able, the function reallocates (or initially allocates) an array object with a sufficient number of elements to hold the current array object (if any), plus one additional write position. If (mode & basic_ios<charT,baggage>::in) != 0, the function alters the read end pointer gend to point just past the new write position (as does the write end pointer pend). 27.4.2.1.5 basic_stringbuf::pbackfail [lib.stringbuf::pbackfail] // virtual int_type pbackfail(int_type c = eof()); inherited +------- BEGIN BOX 136 -------+ Check vs. _lib.streambuf::pbackfail_ and _lib.filebuf::pbackfail_ +------- END BOX 136 -------+ 1 Puts back the character designated by c to the input sequence, if pos sible, in one of three ways: --If c != eof(), if the input sequence has a putback position avail able, and if (char_type)c == (char_type)gnext[-1], assigns gnext - 1 to gnext. Returns (char_type)c. --If c != eof(), if the input sequence has a putback position avail able, and if mode & basic_ios<charT,baggage>::out is nonzero, assigns c to *--gnext. Returns (char_type)c. --If c == eof() and if the input sequence has a putback position available, assigns gnext - 1 to gnext. Returns (char_type)c. 2 Returns eof() to indicate failure. 3 Notes: 4 If the function can succeed in more than one of these ways, it is unspecified which way is chosen. +------- BEGIN BOX 137 -------+ The following was not part of the proposal. Should we keep it? +------- END BOX 137 -------+ 27.4.2.1.6 basic_stringbuf::showmany [lib.stringbuf::showmany] // virtual int showmany(); inherited 1 Behaves the same as basic_streambuf<charT,baggage>::showmany(). 27.4.2.1.7 basic_stringbuf::underflow [lib.stringbuf::underflow] // virtual int_type underflow(); inherited 1 If the input sequence has a read position available, returns (char_type)*gnext. Otherwise, returns eof(). 27.4.2.1.8 basic_stringbuf::uflow [lib.stringbuf::uflow] // virtual int_type uflow(); inherited 1 Behaves the same as basic_streambuf<charT,baggage>::uflow(). 27.4.2.1.9 basic_stringbuf::xsgetn [lib.stringbuf::xsgetn] // virtual streamsize xsgetn(char_type* s, streamsize n); inherited 1 Behaves the same as basic_streambuf<charT,baggage>::xsgetn(s,n). 27.4.2.1.10 basic_stringbuf::xsputn [lib.stringbuf::xsputn] // virtual streamsize xsputn(const char_type* s, streamsize n); inherited 1 Behaves the same as basic_streambuf<charT,baggage>::xsputn(s,n). 27.4.2.1.11 basic_stringbuf::seekoff [lib.stringbuf::seekoff] // virtual pos_type seekoff(off_type off, basic_ios<charT,baggage>::seekdir way, // basic_ios<charT,baggage>::openmode which // = basic_ios<charT,baggage>::in | basic_ios<charT,baggage>::out); inherited +------- BEGIN BOX 138 -------+ Check vs. _lib.strstreambuf::seekpos_ +------- END BOX 138 -------+ 1 Alters the stream position within one of the controlled sequences, if possible, as indicated in Table 26: Table 26--seekoff positioning +----------------------------------------------------------------------------+ | Conditions Result | +----------------------------------------------------------------------------+ (which & basic_ios::in) != 0positions the input sequence | +----------------------------------------------------------------------------+ (which& basic_ios::out) != 0positions the output sequence | +----------------------------------------------------------------------------+ |Otherwise, | (which & (basic_ios::in | positions both the input and the output sequences| basic_ios::out)) == (ba | sic_ios::in | ba | sic_ios::out)) | |and way == either ba | sic_ios::beg or ba | sic_ios::end | +----------------------------------------------------------------------------+ Otherwise, the positioning operation fails. | +----------------------------------------------------------------------------+ 2 For a sequence to be positioned, if its next pointer is a null pointer, the positioning operation fails. Otherwise, the function determines newoff as indicated in Table 27: Table 27--newoff values +--------------------------------------------------------+ | Condition newoff Value | +--------------------------------------------------------+ |way == basic_ios::beg 0 | +--------------------------------------------------------+ |way == basic_ios::cur the next pointer minus the be | | ginning pointer (xnext - xbeg). | +--------------------------------------------------------+ |way == basic_ios::end the end pointer minus the be | | ginning pointer (xend - xbeg) | +--------------------------------------------------------+ |If | |(newoff + off) < 0, | |or | |(xend - xbeg) < | |(newoff + off) | |T} the positioning operation fails | +--------------------------------------------------------+ 3 Otherwise, the function assigns xbeg + newoff + off to the next pointer xnext. 4 Returns pos_type(newoff), constructed from the resultant offset newoff (of type off_type), that stores the resultant stream position, if pos sible. If the positioning operation fails, or if the constructed object cannot represent the resultant stream position, the object stores an invalid stream position. 27.4.2.1.12 basic_stringbuf::seekpos [lib.stringbuf::seekpos] // virtual pos_type seekpos(pos_type sp, // basic_ios<charT,baggage>::openmode which // = basic_ios<charT,baggage>::in // | basic_ios<charT,baggage>::out); inherited +------- BEGIN BOX 139 -------+ Check vs. lib.strstreambuf::seekpos_ +------- END BOX 139 -------+ 1 Alters the stream position within one of the controlled sequences, if possible, to correspond to the stream position stored in sp (as described below). --If (which & basic_ios::in) != 0, positions the input sequence. --If (which & basic_ios::out) != 0, positions the output sequence. --If the function positions neither sequence, the positioning opera tion fails. 2 For a sequence to be positioned, if its next pointer is a null pointer, the positioning operation fails. Otherwise, the function determines newoff from sp.offset(): --If newoff is an invalid stream position, has a negative value, or has a value greater than (xend - xbeg), the positioning operation fails. --Otherwise, the function adds newoff to the beginning pointer xbeg and stores the result in the next pointer xnext. 3 Returns pos_type(newoff), constructed from the resultant offset newoff (of type off_type), that stores the resultant stream position, if pos sible. If the positioning operation fails, or if the constructed object cannot represent the resultant stream position, the object stores an invalid stream position. 27.4.2.1.13 basic_stringbuf::setbuf [lib.stringbuf::setbuf] // virtual basic_streambuf<charT,baggage>* // setbuf(char_type* s, streamsize n); inherited 1 Performs an operation that is defined separately for each class derived from basic_stringbuf<charT,baggage>. +------- BEGIN BOX 140 -------+ Should be pure virtual. +------- END BOX 140 -------+ 2 Default behavior: the same as for basic_streambuf<charT,baggage>::setbuf(char_type*, streamsize). 27.4.2.1.14 basic_stringbuf::sync [lib.stringbuf::sync] // virtual int sync(); inherited 1 Behaves the same as basic_streambuf<charT,baggage>::sync(). 27.4.2.2 Template class basic_istringstream [lib.istringstream] template <class charT, class baggage = ios_baggage<charT> > class basic_istringstream : public basic_istream<charT,baggage> { public: typedef charT char_type; typedef baggage::char_bag::int_type int_type; typedef baggage::pos_bag::pos_type pos_type; typedef baggage::pos_bag::off_type off_type; int_type eof() { return baggage::char_bag::eof(); } char_type newline() { return baggage::char_bag::newline(); } public: basic_istringstream(basic_ios<charT,baggage>::openmode which = basic_ios<charT,baggage>::in); basic_istringstream(const basic_string<charT>& str, basic_ios<charT,baggage>::openmode which = basic_ios<charT,baggage>::in); virtual ~basic_istringstream(); basic_stringbuf<charT,baggage>* rdbuf() const; basic_string<charT> str() const; void str(const basic_string<charT>& str); private: // basic_stringbuf<charT,baggage> sb; exposition only }; class istringstream : public basic_istringstream<char> {}; class wistringstream : public basic_istringstream<char> {}; 1 The class basic_istringstream<charT,baggage> is a derivative of basic_istream<charT,baggage> that assists in the reading of objects of class basic_stringbuf<charT,baggage>. It supplies a basic_stringbuf object to control the associated array object. +------- BEGIN BOX 141 -------+ [To Be Filled] +------- END BOX 141 -------+ 2 For the sake of exposition, the maintained data is presented here as: --sb, the basic_stringbuf object. 27.4.2.2.1 basic_istringstream [lib.basic.istringstream.m.cons] constructors basic_istringstream(basic_ios<charT,baggage>::openmode which = basic_ios<charT,baggage>::in); 1 Constructs an object of class basic_istringstream<charT,baggage>, ini tializing the base class with basic_istream<charT,baggage>(&sb), and initializing sb with sb(which). basic_istringstream(const basic_string<charT>& str, basic_ios<charT,baggage>::openmode which = basic_ios<charT,baggage>::in); 2 Constructs an object of class basic_istringstream<charT,baggage>, ini tializing the base class with basic_istream<charT,baggage>(&sb), and initializing sb with sb(str, which). 27.4.2.2.2 basic_istringstream [lib.basic.istringstream.des] destructor virtual ~basic_istringstream(); 1 Destroys an object of class basic_istringstream. 27.4.2.2.3 basic_istringstream::rdbuf [lib.istringstream::rdbuf] basic_stringbuf<charT,baggage>* rdbuf() const; 1 Returns (basic_stringbuf*)&sb. 27.4.2.2.4 basic_istringstream::str [lib.istringstream::str] basic_string<charT> str() const; 1 Returns sb.str(). void str(const basic_string<charT>& str_arg); 2 Calls sb.str(str_arg). 27.4.2.3 Class basic_ostringstream [lib.ostringstream] template <class charT, class baggage = ios_baggage<charT> > class basic_ostringstream : public basic_ostream<charT,baggage> { public: typedef charT char_type; typedef baggage::char_bag::int_type int_type; typedef baggage::pos_bag::pos_type pos_type; typedef baggage::pos_bag::off_type off_type; int_type eof() { return baggage::char_bag::eof(); } char_type newline() { return baggage::char_bag::newline(); } public: basic_ostringstream(basic_ios<charT,baggage>::openmode which = basic_ios<charT,baggage>::out); basic_ostringstream(const basic_string<charT>& str, basic_ios<charT,baggage>::openmode which = basic_ios<charT,baggage>::out); virtual ~basic_ostringstream(); basic_stringbuf<charT,baggage>* rdbuf() const; basic_string<charT> str() const; void str(const basic_string<charT>& str); private: // basic_stringbuf<charT,baggage> sb; exposition only }; class ostringstream : public basic_ostringstream<char> {}; class wostringstream : public basic_ostringstream<wchar_t> {}; 1 The class basic_ostringstream<charT,baggage> is a derivative of basic_ostream<charT,baggage> that assists in the writing of objects of class basic_stringbuf<charT,baggage>. It supplies a basic_stringbuf object to control the associated array object. +------- BEGIN BOX 142 -------+ [To Be Filled] +------- END BOX 142 -------+ 2 For the sake of exposition, the maintained data is presented here as: --sb, the basic_stringbuf<charT,baggage> object. 27.4.2.3.1 basic_ostringstream [lib.basic.ostringstream.cons] constructors basic_ostringstream(basic_ios<charT,baggage>::openmode which = basic_ios<charT,baggage>::out); 1 Constructs an object of class basic_ostringstream, initializing the base class with basic_ostream(&sb), and initializing sb with sb(which). basic_ostringstream(const basic_string<charT>& str, basic_ios<charT,baggage>::openmode which = basic_ios<charT,baggage>::out); 2 Constructs an object of class basic_ostringstream<charT,baggage>, ini tializing the base class with basic_ostream<charT,baggage>(&sb), and initializing sb with sb(str, which). 27.4.2.3.2 basic_ostringstream [lib.basic.ostringstream.des] destructor virtual ~basic_ostringstream(); 1 Destroys an object of class basic_ostringstream. 27.4.2.3.3 basic_ostringstream::rdbuf [lib.ostringstream::rdbuf] basic_stringbuf<charT,baggage>* rdbuf() const; 1 Returns (basic_stringbuf<charT,baggage>*)&sb. 27.4.2.3.4 basic_ostringstream::str [lib.ostringstream::str] basic_string<charT> str() const; 1 Returns sb.str(). void str(const basic_string<charT>& str_arg); 2 Calls sb.str(str_arg). 27.5 File-based streams [lib.file.streams] 1 Headers: --<cstream> --<fstream> --<stdiostream> --<cstdio> --<cwchar> 2 Table 28: 3 Table 29: Table 29--Header <cstream> synopsis +-------------------------------------------------------------------------+ | Type Name(s) | +-------------------------------------------------------------------------+ |Template class: basic_convbuf | +-------------------------------------------------------------------------+ |Template structs: conv_baggage ios_conv_baggage | +-------------------------------------------------------------------------+ |Structs: conv_baggage<wchar_t> ios_conv_baggage<wstreampos> | +-------------------------------------------------------------------------+ Table 29--Header <fstream> synopsis +-----------------------------------------------------------------+ | Type Name(s) | +-----------------------------------------------------------------+ |Template classes: | |basic_filebuf basic_ifstream basic_ofstream basic_stdiobuf | +-----------------------------------------------------------------+ |Classes: | |basic_filebuf<char> filebuf wfilebuf | |basic_filebuf<wchar_t> ifstream wifstream | |basic_ifstream<char> istdiostream wofstream | |basic_ifstream<wchar_t> ofstream | |basic_ofstream<char> ostdiostream | |basic_ofstream<wchar_t> stdiobuf | +-----------------------------------------------------------------+ 4 Table 30: Table 30--Header <cstdio> synopsis +-------------------------------------------------------------------------------+ | Type Name(s) | +-------------------------------------------------------------------------------+ |Macros: | |BUFSIZ L_tmpnam SEEK_SET TMP_MAX | |EOF NULL <cstdio> stderr _IOFBF | |FILENAME_MAX SEEK_CUR stdin _IOLBF | |FOPEN_MAX SEEK_END stdout _IONBF | +-------------------------------------------------------------------------------+ |Types: FILE fpos_t size_t <cstdio> | +-------------------------------------------------------------------------------+ |Functions: | |clearerr fgets fscanf gets rewind tmpfile | |fclose fopen fseek perror scanf tmpnam | |feof fprintf fsetpos printf setbuf ungetc | |ferror fputc ftell putc setvbuf vprintf | |fflush fputs fwrite puts sprintf vprintf | |fgetc fread getc remove sscanf vsprintf | |fgetpos freopen getchar rename tmpfile | +-------------------------------------------------------------------------------+ 5 Table 31: Table 31--Header <cwchar> synopsis +------------------------------------------------------------------------+ | Type Name(s) | +------------------------------------------------------------------------+ |Macros: NULL <cwchar> WCHAR_MAX WCHAR_MIN WEOF <cwchar> | +------------------------------------------------------------------------+ |Types: mbstate_t wint_t <cwchar> | +------------------------------------------------------------------------+ |Struct: tm <cwchar> | +------------------------------------------------------------------------+ |Functions: | |btowc getwchar ungetwc wcscpy wcsrtombs wmemchr | |fgetwc mbrlen vfwprintf wcscspn wcsspn wmemcmp | |fgetws mbrtowc vswprintf wcsftime wcsstr wmemcpy | |fputwc mbsinit vwprintf wcslen wcstod wmemmove | |fputws mbsrtowcs wcrtomb wcsncat wcstok wmemset | |fwide putwc wcscat wcsncmp wcstol wprintf | |fwprintf putwchar wcschr wcsncpy wcstoul wscanf | |fwscanf swprintf wcscmp wcspbrk wcsxfrm | |getwc swscanf wcscoll wcsrchr wctob | +------------------------------------------------------------------------+ SEE ALSO: ISO C subclause 7.9, Amendment 1 subclause 4.6.2. 27.5.1 Multi-byte conversions [lib.conv.fstreams] +------- BEGIN BOX 143 -------+ While this may be a useful class, its primary purpose is to allow implementation of wfilebuf. In the interest of simplicity I think it is better to specify wfilebuf directly and leave the details of imple mentations upto the system vendors. 1 Jerry Schwarz proposal: Delete this section. +------- END BOX 143 -------+ 2 The header <cstream> defines one type, basic_convbuf that associates its internal stream buffers holding a sequence of characters with the external source/sink stream representing a sequence of another type of characters. --Conversion There is a bidirectional conversion between the external source/sink stream and character sequences held in the basic_convbuf class object. --uchar_type: underlaid character container type The external source/sink stream can be regarded as a sequence of a character con tainer type, which may be different to charT. The character con tainer type on the external source/sink stream is called the underlaid character container type, or uchar_type. --Encoding rule Performing the conversion from a uchar_type character sequences to the corresponding character sequence, the basic_convbuf may parse the uchar_type sequence to extract the corresponding char acter represented on the uchar_type sequence. The rule how a cer tain character is to be represented on a sequence of uchar_type characters is called the encoding rule. The basic_convbuf can be regarded as having a (virtual) conversion machine which obeys the encoding rule to parse uchar_type sequences. --Conversion state The conversion machine has its internal state cor responding to a certain position of the external source/sink stream. If the basic_convbuf stops the conversion to resume later, it has to save its internal state, so a class or a type is prepared for saving the state onto it so that an user of the basic_convbuf class object can handle it. The class (or the type) is called the conversion state. -- +------- BEGIN BOX 144 -------+ Multibyte character I/O support The basic_convbuf can support multi byte character file I/O operations. Provided that the code conversion functions between multibyte characters and wide characters are pre pared, we may specify the conversion state, and the conversion func tions in the ios_conv_baggage so that the basic_convbuf can handle this multibyte characters. +------- END BOX 144 -------+ 27.5.1.1 Template class conv_baggage [lib.conv.baggage] template <class charT> struct conv_baggage {} struct conv_baggage<wchar_t> { typedef ios_char_baggage<wchar_t> char_bag; typedef ios_pos_baggage<wstreampos> pos_bag; typedef ios_conv_baggage<state_t> conv_bag; }; 1 The template struct conv_baggage<charT> is a baggage class which main tains the definitions of the types and functions necessary to imple ment the template class basic_convbuf. The template parameter charT reprsents the character container type and each specialized version of conv_baggage provides the default definitions corresponding to the specialized character container type. 2 The conv_baggage<charT> declaration has three members, ios_char_baggage, ios_pos_baggage, and ios_conv_baggage. 3 Although the former two of them are same as in the ios_baggage<charT>, the last baggage, ios_conv_baggage<charT> provides all the definitions about types and functions necessary to perform conversion. 27.5.1.2 Template class ios_conv_baggage [lib.ios.conv.baggage] template <class stateT> struct ios_conv_baggage {}; 1 As is the other baggage structs, there is no definition in the decla ration of the template struct, ios_conv_baggage. All of the defini tions related to the conversion and necessary to implement basic_convbuf class shall be provided in a template version, ios_conv_baggage<STATE_T> specialized for a conversion state STATE_T. 27.5.1.2.1 Struct [lib.ios.conv.baggage.state.t] ios_conv_baggage<STATE_T> struct ios_conv_baggage<STATE_T> { typedef CHAR_T char_type; typedef STATE_T conv_state; typedef UPOS_T conv_upos; typedef UCHAR_T uchar_type; typedef POS_T pos_type; typedef OFF_T off_type; typedef locale::codecnv<uchar_type,char_type,conv_state> codecvt_in; typedef locale::codecnv<char_type,uchar_type,conv_state> codecvt_out; locale::result convin(codecvt_in*, conv_state&, const uchar_type*, const uchar_type*, const uchar_type*&, char_type*, char_typeT*, char_type*&); locale::result convout(codecvt_out*, conv_state&, const char_type*, const char_type*, const char_type*&, uchar_type*, uchar_type*, uchar_type*&); pos_type get_pos(conv_state&, conv_upos&); off_type get_off(conv_state&, conv_upos&); conv_state get_posstate pos_type&); conv_state get_offstate(off_type&); conv_upos get_posupos (pos_type&); conv_upos get_offupos (off_type&); }; 1 A specialized version of the struct ios_conv_baggage<STATE_T> is nec essary to use the basic_convbuf class. In order to construct a spe cialized version of the struct, the following set of types and func tions shall be provided. --CHAR_T: is the character container type which shall be same as the template parameter of the class, conv_baggage. --STATE_T: is the conversion state type which also the template param eter type of this baggage. It is the parsing/tracing state which the function, convin and convout are taken. --Every type of conversion states have a state, called initial state, which corresponds to the state beginning to parse a new sequence. The constructor, STATE_T::STATE_T() or STATE_T::STATE_T(0) con structs the initial state. --UCHAR_T: is the underlaid character container type for the external source/sink stream handled by the basic_convbuf. --UPOS_T: is the repositional information type for the external source/sink stream. It is used to implement the seekpos/seekoff member functions in the basic_convbuf. --POS_T: is the repositional information which the basic_convbuf sup ports for the client of the object. It shall be the same as the template parameter type of the struct ios_pos_baggage in the same conv_baggage. --OFF_T: is an integral type which is used as the repositional infor mation which the basic_convbuf supports. 27.5.1.2.1.1 convin [lib.ios.conv.baggage.state.t::convin] locale::result convin(codecvt_in* ccvt, conv_state& stat, const uchar_type* from, const uchar_type* from_end, const uchar_type*& from_next, char_type* to, char_typeT* to_limit, char_type*& to_next); 1 The conversion state designated by stat represents the parsing state on the underlaid source sequence. According to the conversion state designated by stat, it begins to parse the source character sequence whose begining and end position designated by from and from_end to convert them. It stores the result sequence (if any) into the succes sive location of an array pointed to by to and to_limit. The conver sion stops when either of the following occurs: 1)parses all of the underlaid character sequences and stores the last character into the destination array. 2)fills all of the destination array and no more room to store. 3)encounters an invalid underlaid character in the source sequence. 2 In case (1), it returns ok. In case (2), it returns partial. In case (3), it returns error. 3 In all cases it leaves the from_next and to_next pointers pointing one beyond the last character successfully converted and leaves the con version state onto the stat for the next time conversion. If case (3) occurs, the conversion state on the stat becomes undefined value. No more conversion with the value is available. 4 If the locale-dependent conversion functions are needed, the nconver sion function which the locale::codecnv facet object, ccnv provides is available as the following invokation: ccnv.convert(stat, from, from_end, from_next, to, to_limit, to_next); 5 The default conversion function depends on the locale_codecvt facets. Users can customize the encoding scheme by specifying their own con version functions in a new conv_baggage class. 27.5.1.2.1.2 convout [lib.ios.conv.baggage.state.t::convout] locale::result convout(codecvt_out* ccvt, conv_state&, const char_type from*, const char_type* from_end, const char_type*& from_next., uchar_type*, uchar_type*, uchar_type*&); 1 The conversion state designated by stat represents the parsing state on the underlaid destination sequence. It begins to convert the source character sequence whose begining and end position designated by from and from_end. According to the conversion state designated by stat, it stores the result destination underlaid chracter sequence (if any) into the successive location of an array pointed to by to and to_limit. The conversion stops when either of the following occurs: 1)consumes all of the source character sequences and stores the last underlaid character into the destination array. 2)fills all of the destination array and no more room to store. 3)encounters an invalid character in the source sequence. 2 In case (1), it returns ok. In case (2), it returns partial. In case (3), it returns error. 3 In all cases it leaves the 5from_next and to_next pointers pointing one beyond the last character successfully converted and leaves the conversion state onto the stat for the next time conversion. If case (3) occurs, the conversion state on the stat becomes undefined value. No more conversion with the value is available. 4 If the locale-dependent conversion functions are needed, the conver sion function which the locale::codecnv facet object, ccnv provides is available as the following invocation; ccnv.convert(stat, from, from_end, from_next, to, to_limit, to_next); 5 The default conversion function is depends on the locale_codecvt facets. Users can customize the encoding scheme by specifying their own conversion functions in a new conv_baggage class. 27.5.1.2.1.3 get_pos and [lib.ios.conv.baggage.state.t::get.pos] get_off pos_type get_pos(conv_state& stat, conv_upos& upos); off_type get_off(conv_state&, conv_upos&); 1 Constructs the pos_type object or off_type object from the conversion state, stat and the repositional information for the underlaid stream, upos and returns it. These are used to make the return value of the basic_convbuf::seekpos/seekoff protected member function. 27.5.1.2.1.4 [lib.ios.conv.baggage.state.t::get.pos.state] get_posstate and get_offstate conv_state get_posstate(pos_type& pos); conv_state get_offstate(off_type& off); 1 Extract the conversion state held by the repositional information, pos or off. These are used to reset the conversion state maintained in the basic_convbuf class object when the basic_convbuf::seetpos/seekoff functions are performed. 27.5.1.2.1.5 [lib.ios.conv.baggage.state.t::get.pos.upos] ios_conv_baggage<STATE_T>::get_posupos and get_offupos conv_upos get_posupos(pos_type&); conv_upos get_offupos(off_type&); 1 Extract the repositioning information for the underlaid stream from the repositioning information on the basic_convbuf stream. These are used in the basic_convbuf::seekpos/seekoff protected member functions to reposition the external source/sink stream. 27.5.1.2.2 Struct [lib.ios.conv.baggage.wstreampos] ios_conv_baggage<wstreampos> struct ios_conv_baggage<wstreampos> { typedef wchar_t char_type; typedef STATE_T conv_state; typedef UPOS_T conv_upos; typedef char uchar_type; typedef wstreampos pos_type; typedef wstreamoff off_type; typedef locale::codecnv<char,wchar_t,STATE_T> codecnv_in; typedef locale::codecnv<wchar_t,char,STATE_T> codecnv_out; locale::result convin(codecvt_in* ccvt, conv_state& stat, const char *from, const char* from_end, const char*& from_next, wchar_t* to, wchar_t* to_limit, wchar_t*& to_next) { return ccvt->convert (stat, from, from_end, from_next, to, to_limit, to_next); } locale::result convout(codecvt_out* ccvt, conv_state& stat, const wchar_t* from, const wchar_t* from_end, const wchar_t*& from_next, char* to, char* to_limit, char* to_next) { return ccvt->convert (stat, from, from_end, from_next, to, to_limit, to_next); } pos_type get_pos(conv_state&, conv_upos&); off_type get_off(conv_state&, conv_upos&); conv_state get_posstate(pos_type&); conv_state get_offstate(off_type&); conv_upos get_posupos (pos_type&); conv_upos get_offupos (off_type&); }; 1 The specialized version of the struct, ios_conv_baggage<wstreampos> supports the wide-oriented basic_convbuf class and the conversion between wide characters and multibyte characters as the underlaid character sequence. The types, STATE_T and UPOS_T are implementation- defined types. The behavior of the conversion functions depend on those of the locale object. 2 The encoding rule of the multibyte characters is implementation- defined. 27.5.1.3 Template class basic_convbuf [lib.basic.convbuf] template <class charT, class baggage = conv_baggage<charT> > class basic_convbuf : public basic_streambuf<charT,baggage> { public: typedef charT char_type; typedef baggage::char_bag::int_type int_type; typedef baggage::pos_bag::pos_type pos_type; typedef baggage::pos_bag::off_type off_type; int_type eof() { return baggage::char_bag::eof(); } char_type newline() { return baggage::char_bag::newline(); } private: typedef baggage::conv_bag::conv_state state_type; typedef baggage::conv_bag::conv_upos upos_type ; public: basic_convbuf(); virtual ~basic_convbuf(); protected: // virtual int_type overflow (int_type c = eof()); inherited // virtual int_type pbackfail(int_type c = eof()); inherited // virtual int_type underflow(); inherited // virtual int_type uflow(); inherited // virtual streamsize xsgetn(charT* s, streamsize n); inherited // virtual streamsize xsputn(const charT* s, streamsize n); inherited // virtual pos_type seekoff(off_type, basic_ios<charT,baggage>::seekdir way, // basic_ios<charT,baggage>::openmode which // = basic_ios<charT,baggage>::in // | basic_ios<charT,baggage>::out); inherited // virtual pos_type seekpos(pos_type sp, basic_ios<charT,baggage>::openmode which // = basic_ios<charT,baggage>::in // | basic_ios<charT,baggage>::out); inherited // virtual basic_streambuf<charT,baggage>* // setbuf(charT* s, streamsize n); inherited // virtual int sync(); inherited private: // state_type state; exposition only }; 1 The template class basic_convbuf<charT,baggage> is derived from basic_streambuf<charT,baggage> to associate the character sequences and the underlaid character sequences. It performs the conversion between these two types of chracter sequences. 2 For the sake of exposition, the basic_convbuf maintains the conversion state to restart the conversion to read/write the character sequence from/to the underlaid stream. 27.5.1.3.1 basic_convbuf constructor [lib.basic.convbuf.cons] basic_convbuf(); 1 Constructs an object of template class basic_convbuf<charT,baggage>, initializing the base class with basic_streambuf<charT,baggage>(), and initializing; --state with state_type(0) as to specify initial state. 27.5.1.3.2 basic_convbuf destructor [lib.basic.convbuf.des] virtual ~basic_convbuf(); 1 Destroys an object of class basic_convbuf<charT,baggage>. 27.5.1.3.3 basic_convbuf::overflow [lib.basic.convbuf.overflow] virtual int_type overflow(int_type c = eof()); 1 Behaves the same as basic_streambuf<charT,baggage>::overflow(c), except that the behavior of ``consuming a character'' is as follows: --(1) Converting the characters to be consumed into the underlaid character sequence with the function baggage::conv_bag::convout(). --(2) The result underlaid character sequence is appended to the asso ciated output stream. 27.5.1.3.4 [lib.basic.convbuf::pbackfail] basic_convbuf::pbackfail virtual int_type pbackfail(int_type c); 1 Puts back the character designated by c to the input sequence, if pos sible, in one of three ways: +------- BEGIN BOX 145 -------+ Because the parsing on the underlaid character sequence generally can only go advance or most of parsing machined cannot go back, some of the basic_convbuf implementations cannot ``put back characters directly to the associated input sequence.'' So the behaviors related to putting back the associated input stream are removed. +------- END BOX 145 -------+ --If c != eof(), if either the input sequence has a putback position available or the function makes a putback position available, and if (charT)c == (charT)gnext[-1], assigns gnext - 1 to gnext. Returns (charT)c. --If c != eof(), if either the input sequence has a putback position available or the function makes a putback position available, and if the function is permitted to assign to the putback position, assigns c to *--gnext. Returns (charT)c. --If c == eof() and if either the input sequence has a putback posi tion available or the function makes a putback posotion available, assigns gnext - 1 to gnext. Returns (charT)c. 2 Returns eof() to signal the failure. 3 Notes: 4 The function does not put back a character directly to the input sequence. 5 If the function can succeed in more than one of these ways, it is unspecified which way is chosen. The function can alter the number of putback positions available as a result of any call. 6 Default behavior: returns baggage::char_bag::eof(). +------- BEGIN BOX 146 -------+ Should be pure virtual. +------- END BOX 146 -------+ 27.5.1.3.5 [lib.basic.convbuf::underflow] basic_convbuf::underflow // virtual int_type underflow(); inherited 1 Returns the first character of the pending sequence, if possible, without moving the stream position past it. If the pending sequence is null then the function fails. 2 The pending sequence of characters is defined as the concatenation of: a)If gnext is non-NULL, then the gend - gnext characters starting at gnext, otherwise the empty sequence. b)Some sequence (possibly empty) of characters read from the input stream. --These underlaid character sequence shall be converted by the func tion baggage::conv_bag::convin() before concatinating to construct the pending sequence. In case that there remains some underlaid characters which cannot be converted to any more characters, we treat it empty as the subsequence (b). 3 The result character is the first character of the pending sequence, if any. The backup sequence is defined as the concatenation of: a)If gbeg is non-NULL then empty, otherwise the gnext - gbeg charac ters beginning at gbeg. b)the result character. 4 The function sets up gnext and gend satisfying: a)In case the pending sequence has more than one character the gend - gnext characters starting at gnext are the characters in the pending sequence after the result character. b)If the pending sequence has exactly one character, then gnext and gend may be NULL or may both be set to the same non-NULL pointer. 5 If gbeg and gnext are non-NULL then the function is not constrained as to their contents, but the ``unusual backup condition'' is that either: a)If the backup sequence contains at least gnext - gbeg characters then the gnext - gbeg characters starting at gbeg agree with the last gnext - gbeg characters of the backup sequence. b)Or the n characters starting a gnext - n agree with the backup sequence (where n is the length of the backup sequence) 6 Returns eof() to indicate failure. 7 Default behavior: returns baggage::char_bag::eof(). +------- BEGIN BOX 147 -------+ Should be pure virtual. +------- END BOX 147 -------+ 27.5.1.3.6 basic_convbuf::uflow [lib.basic.convbuf::uflow] // virtual int_type uflow(); inherited 1 Behaves the same as basic_streambuf<charT,baggage>::uflow(). 27.5.1.3.7 basic_convbuf::xsgetn [lib.convbuf::xsgetn] // virtual streamsize xsgetn(char_type* s, streamsize n); inherited 1 Behaves the same as basic_streambuf<charT,baggage>::xsgetn(char_type*, streamsize). 27.5.1.3.8 basic_convbuf::xsputn [lib.convbuf::xsputn] // virtual streamsize xsputn(const char_type* s, streamsize n); inherited 1 Behaves the same as basic_streambuf<charT,baggage>::xsputn(char_type*, streamsize). 27.5.1.3.9 basic_convbuf::seekoff [lib.convbuf::seekoff] // virtual pos_type seekoff(off_type off, basic_ios<charT,baggage>::seekdir way, // basic_ios<charT,baggage>::openmode which // = basic_ios<charT,baggage>::in | basic_ios<charT,baggage>::out); inherited 1 Behaves the same as basic_streambuf<charT,baggage>::seekoff(off,way,which), except that the behavior ``alters the stream position'' means that: --(a) altering the underlaid character stream position which they get with the return value of the bag gage::conv_bag::get_posupos(off_type&); and, --(b) restoring the current conversion state by resetting the member, state with the return value of the bag gage::conv_bag::get_offstate(off_type&). 27.5.1.3.10 basic_convbuf::seekpos [lib.convbuf::seekpos] // virtual pos_type seekpos(pos_type sp, // basic_ios<charT,baggage>::openmode which // = basic_ios<charT,baggage>::in | basic_ios<charT,baggage>::out); inherited 1 At first do sync() to clear up the get buffer, and alters the stream position, as follows: --(a) altering the underlaid character stream position by which the function, baggage::conv_bag::get_posupos(pos), returns. and, --(b) restoring the member, state with the return value of the bag gage::conv_bag::get_posstate(pos). 2 Returns pos_type, newpos, constructed from the resultant upos and state if both (a) and (b) are successfully terminated. 3 If either or both (a) or/and (b) fail(s), or if the constructed object cannot represent the resultant stream position, the object stores an invalid stream position. 4 Whichever value is specified in the which parameters, the basic_convbuf handles only one external source/sink stream. 5 If (a) succeeds, returns a newly constructed streampos object returned by baggage::conv_bag::get_pos(state, upos) where upos is a UPOS_T type object which represent the current position of the underlaid stream. 6 Otherwise, the object stores an invalid stream position. 27.5.1.3.11 basic_convbuf::setbuf [lib.convbuf::setbuf] // virtual basic_streambuf<charT,baggage>* // setbuf(char_type* s, streamsize n); inherited 1 Makes the array of n (charT type) characters, whose first element is designated by s, available for use as a buffer area for the controlled sequences, if possible. +------- BEGIN BOX 148 -------+ The basic_convbuf does not fix the buffer management strategy. It remains alternatives for the derived class designers. +------- END BOX 148 -------+ 27.5.1.3.12 basic_convbuff::sync [lib.convbuf::sync] // virtual int sync(); inherited 1 Reflects the pending sequence to the external sink sequence and reset the get/put buffer pointers. It means that if there are some unread sequence on the get buffer and the external source sequense is not seekable, the unread sequence is perfectly lost. 2 The detailed behavior is as follows: a)Consumes all of the pending sequence of characters, (as pending sequence and ``consumes the sequence,'' see the description in the basic_streambuf<charT,baggage>::overflow() _lib.streambuf::overflow_) In case that consuming means appending characters to the associated output stream, the character sequense shall be converted to the cor responding underlaid character sequence by the bag gage::conv_bag::convout(). b)Clears all of the following pointers: pbeg, pnext, pend, gbeg, gnext, and gend. 3 Returns -1 if (a) fails, otherwise 0. 27.5.1.4 Examples of trait specialization [lib.examples.traits] class fstate_t { ... }; // Implementation-defined conversion state // object which is for file I/O. class wfstate_t { ... }; template <class charT> struct file_baggage {}; struct file_baggage<char> { typedef ios_char_baggage<char> char_bag; typedef ios_pos_baggage<streampos> char_pos; typedef ios_conv_baggage<fstate_t> conv_pos; }; struct file_baggage<wchar_t>{ typedef ios_char_baggage<char> char_bag; typedef ios_pos_baggage<wstreampos> char_pos; typedef ios_conv_baggage<wfstate_t> conv_pos; }; template <class stateT> struct ios_file_baggage {}; // // Specialized for the single-byte filebuf // struct ios_conv_baggage<fstate_t> { typedef char char_type; // char/wchar_t... typedef fstate_t conv_state; // key parameter(mainly depend on uchar_type) typedef streamoff conv_upos; // Physical file offset typedef char uchar_type; // Physical file I/O typedef streampos pos_type; // Enough to large typedef streamoff off_type; // Enough to large typedef locale::codecnv<char,wchar_t,fstate_t> codecnv_in; typedef locale::codecnv<wchar_t,char,fstate_t> codecnv_out; locale::result convin(codecvt_in* ccvt, conv_state& stat, const char *from, const char* from_end, const char*& from_next, char* to, char* to_limit, char*& to_next) { return ccvt->convert (stat, from, from_end, from_next, to, to_limit, to_next); } locale::result convout(codecvt_out* ccvt, conv_state& stat, const char* from, const char* from_end, const char*& from_next, char* to, char* to_limit, char* to_next) { return ccvt->convert (stat, from, from_end, from_next, to, to_limit, to_next); } pos_type get_pos(conv_state&, conv_upos&); off_type get_off(conv_state&, conv_upos&); conv_state get_posstate(pos_type&); conv_state get_offstate(off_type&); conv_upos get_posupos (pos_type&); conv_upos get_offupos (off_type&); }; // // Specialized for the wfilebuf // struct ios_conv_baggage<wfstate_t> { typedef wchar_t char_type; // char/wchar_t... typedef wfstate_t conv_state; // key parameter(mainly depend on uchar_type) typedef streamoff conv_upos; // Physical file offset typedef char uchar_type; // Physical file I/O typedef wstreampos pos_type; // Enough to large typedef wstreamoff off_type; // Enough to large typedef locale::codecnv<char,wchar_t,fstate_t> codecnv_in; typedef locale::codecnv<wchar_t,char,fstate_t> codecnv_out; locale::result convin (codecvt_in* ccvt, conv_state& stat, const char *from, const char* from_end, const char*& from_next, wchar_t* to, wchar_t* to_limit, wchar_t*& to_next) { return ccvt->convert (stat, from, from_end, from_next, to, to_limit, to_next); } locale::result convout (codecvt_out* ccvt, conv_state& stat, const wchar_t* from, const wchar_t* from_end, const wchar_t*& from_next, char* to, char* to_limit, char* to_next) { return ccvt->convert (stat, from, from_end, from_next, to, to_limit, to_next); } pos_type get_pos (conv_state&, conv_upos&); // wstreampos get_pos (wfstate_t&, streampos); off_type get_off (conv_state&, conv_upos&); // wstreamoff get_off (wfstate_t&, streampos); conv_state get_posstate (pos_type&); // wfstate_t get_posstate (wstreampos&); conv_state get_offstate (off_type&); // wfstate_t get_offstate (wstreamoff&); conv_upos get_posupos (pos_type&); // conv_upos get_offupos (off_type&); }; +------- BEGIN BOX 149 -------+ Need more description about these definitions +------- END BOX 149 -------+ 27.5.2 File streams [lib.fstreams] 1 The header <fstream> defines six types that associate stream buffers with files and assist reading and writing files. +------- BEGIN BOX 150 -------+ Note: Although filebuf object is templated, it accepts only type char as charT parameter and it continues to provide narrow-oriented file I/O operations. So this subclause remains unchanged. -- mjv +------- END BOX 150 -------+ +------- BEGIN BOX 151 -------+ Jerry Schwarz proposal: basic_filebuf<charT,baggage> should be speci fied so that it treats a file as a sequence of charT. Except for filebuf and wfilebuf that implies it treats the file as binary. +------- END BOX 151 -------+ 2 In this subclause, the type name FILE is a synonym for the type FILE.44) --File A File provides an external source/sink stream whose underlaid character type is char (byte). --Multibyte characters and Files Class basic_filebuf is derived from basic_convbuf to support multibyte character I/O. A File is a sequence of multibyte characters. In order to provide the contents as a wide character sequence, wfilebuf should convert between wide character sequences and multibyte character sequences. --basic_filebuf Derived from basic_convbuf. Even the single byte character version because single byte code conversion may be _________________________ 44) FILE is defined in <cstdio> (_lib.file.streams_). necessary... A basic_filebuf provide... file I/O, char/wchar_t par ity. fstate_t ... template parameter for ios_conv_baggage --Customize Mechanism Change name (conv_bag -> file_bag), customize ios_conv_baggage<fstate_t>. Modify the definition of ios_conv_baggage. --Multibyte character and Files A File provides byte sequences. So the streambuf (or its derived classes) treats a file as the external source/sink byte sequence. In a large character set environment, multibyte character sequences are held in files. In order to pro vide the contents of a file as wide character sequences, wide- oriented filebuf, namely wfilebuf should convert wide character sequences. Because of necessity of the conversion between the external source/sink streams and wide character sequences. 27.5.2.1 Template class basic_filebuf [lib.filebuf] template <class charT, class baggage = conv_baggage<charT> > class basic_filebuf : public basic_convbuf<charT,baggage> { public: typedef charT char_type; typedef baggage::char_bag::int_type int_type; typedef baggage::pos_bag::pos_type pos_type; typedef baggage::pos_bag::off_type off_type; int_type eof() { return baggage::char_bag::eof(); } char_type newline() { return baggage::char_bag::newline(); } public: basic_filebuf(); virtual ~basic_filebuf(); bool is_open() const; basic_filebuf<charT,baggage>* open(const char* s, basic_ios<charT,baggage>::openmode mode); // basic_filebuf<charT,baggage>* open(const char* s, ios::open_mode mode); basic_filebuf<charT,baggage>* close(); protected: // virtual int_type overflow (int_type c = eof()); inherited // virtual int_type pbackfail(int_type c = eof()); inherited +------- BEGIN BOX 152 -------+ The following was not part of the proposal. Should we keep it? +------- END BOX 152 -------+ // virtual int showmany(); inherited // virtual int_type underflow(); inherited // virtual int_type uflow(); inherited // virtual streamsize xsgetn(char_type* s streamsize n); inherited // virtual streamsize xsputn(const char_type* s, streamsize n); inherited // virtual pos_type seekoff(off_type off, // basic_ios<charT,baggage>::seekdir way, // basic_ios<charT,baggage>::openmode which // = basic_ios<charT,baggage>::in // | basic_ios<charT,baggage>::out); inherited // virtual pos_type seekpos(pos_type sp, // basic_ios<charT,baggage>::openmode which // = basic_ios<charT,baggage>::in // | basic_ios<charT,baggage>::out); inherited // virtual basic_streambuf<charT,baggage>* // setbuf(char_type* s, streamsize n); inherited // virtual int sync(); inherited private: // FILE* file; exposition only }; class filebuf : public basic_filebuf<char> {}; class wfilebuf : public basic_filebuf<wchar_t> {}; 1 The class basic_filebuf<charT,bagggage> is derived from basic_streambuf<charT,bagggage> to associate both the input sequence and the output sequence with an object of type FILE. 2 For the sake of exposition, the maintained data is presented here as: --FILE *file, points to the FILE associated with the object of class basic_filebuf<charT,bagggage>. 3 The restrictions on reading and writing a sequence controlled by an object of class basic_filebuf<charT,bagggage> are the same as for reading and writing its associated file. In particular: --If the file is not open for reading or for update, the input sequence cannot be read. --If the file is not open for writing or for update, the output sequence cannot be written. --A joint file position is maintained for both the input sequence and the output sequence. 4 In order to support file I/O and multibyte/wide character conversion, the following arrangement is applied to the baggage structures: --Specify char as the underlaid character type, uchar_type defined in the ios_conv_baggage<>. --Define state_t, the template parameter of the ios_conv_baggage<>, so that it can apply to the conversion function. In case the conver sion function provided by the locale::codecnv facet uses, we adopt a specialized template parameter stateT for the locale-oriented con version function suitable for the multibyte/wide character conver sion. Now we assume the name of the conversion state object is fstate_t. --Define streamoff (or streampos) as the repositional information for the underlaid byte sequence. --Define streamoff, wstreampos for the wide-oriented streambufs (or filebufs) so that some composite function in the ios_conv_baggage(), for example: wstreampos get_pos(fstate_t fs, streampos s); wstreamoff get_off(fstate_t fs, streampos s); 27.5.2.1.1 basic_filebuf constructor [lib.basic.filebuf.cons] basic_filebuf(); 1 Constructs an object of class basic_filebuf<charT,baggage>, initializ ing the base class with basic_streambuf<charT,baggage>(), and initial izing file to a null pointer. 27.5.2.1.2 basic_filebuf destructor [lib.basic.filebuf.des] virtual ~basic_filebuf(); 1 Destroys an object of class basic_filebuf<charT,baggage>. Calls close(). 27.5.2.1.3 basic_filebuf::is_open [lib.filebuf::is.open] bool is_open() const; 1 Returns true if file is not a null pointer. 27.5.2.1.4 basic_filebuf::open [lib.filebuf::open] basic_filebuf<charT,baggage>* open(const char* s, basic_ios<charT,baggage>::openmode mode); 1 If file is not a null pointer, returns a null pointer. Otherwise, calls basic_streambuf<charT,baggage>::basic_streambuf(). It then opens a file, if possible, whose name is the NTBS s, ``as if'' by calling fopen(s,modstr) and assigning the return value to file. 2 The NTBS modstr is determined from mode & ~basic_ios<charT,baggage>::ate as indicated in Table 32: Table 32--File open modes +---------------------------------------------+ |basic_ios<charT,baggage> stdio equivalent | | Value(s) | +---------------------------------------------+ |in "r" | |out | trunc "w" | |out | app "a" | |in | out "r+" | |in | binary "rb" | |out | trunc | binary "wb" | |out | app | binary "ab" | |in | out "r+ | |in | out | trunc "w+" | |in | out | app "a+" | |in | out | binary "r+b" | |in | out | trunc | binary "w+b" | |in | out | app | binary "a+b" | +---------------------------------------------+ 3 If the resulting file is not a null pointer and mode & basic_ios<charT,baggage>::ate is nonzero, calls fseek(file, 0, SEEK_END).45) 4 If fseek returns a null pointer, calls close() and returns a null pointer. Otherwise, returns this. basic_filebuf<charT,baggage>* open(const char* s, ios::open_mode mode); 5 Returns open(s, basic_ios<charT,baggage>::openmode(mode)). 27.5.2.1.5 basic_filebuf::close [lib.filebuf::close] basic_filebuf* close(); 1 If file is a null pointer, returns a null pointer. Otherwise, if the call fclose(file) returns zero, the function stores a null pointer in file and returns this.46) Otherwise, returns a null pointer. 27.5.2.1.6 basic_filebuf::overflow [lib.filebuf::overflow] // virtual int_type overflow(int_type c = eof()); inherited 1 Behaves the same as basic_streambuf<charT,baggage>::overflow(c), except that tThe behavior of ``consuming a character'' is as follows: _________________________ 45) The macro SEEK_END is defined, and the function signatures fopen(const char_type*, const char_type*) and fseek(FILE*, long, int) are declared, in <cstdio> (_lib.file.streams_). 46) The function signature fclose(FILE*) is declared, in <cstdio> (_lib.file.streams_). --(1) Converting the characters to be consumed into the underlaid character sequence with the function baggage::conv_bag::convout(). During the conversion, convout maintains the conversion state in the member state. At the end of execution of the conversion, the con version state is saved on it. --(2) The result underlaid character sequence is written to the file specified by file. At the consumption of the pending characters, none of them are dis carded. All of the characters are converted to be writted to the file. 2 Returns eof() to indicate failure. If file is a null pointer, the function always fails. 27.5.2.1.7 basic_filebuf::pbackfail [lib.filebuf::pbackfail] // virtual int_type pbackfail(int_type c = eof()); inherited +------- BEGIN BOX 153 -------+ Check vs. _lib.streambuf::pbackfail_ and _lib.strstreambuf::pbackfail_ and _lib.basic.convbuf::pbackfail_ +------- END BOX 153 -------+ 1 Puts back the character designated by c to the input sequence, if pos sible, in one of four ways: +------- BEGIN BOX 154 -------+ Because the parsing on the underlaid character sequence generally can only go advance or most of parsing machined cannot go back, some of the basic_convbuf implementations cannot ``put back characters directly to the associated input sequence.'' So the behaviors related to putting back the associated input stream are removed. +------- END BOX 154 -------+ --If c != eof() and if the function makes a putback position available and if (char_type)c == (char_type)gnext[-1], assigns gnext - 1 to gnext. Returns (char_type)c. --If c != eof() and if the function makes a putback position available and if the function is permitted to assign to the putback position, assigns c to *--gnext. Returns (char_type)c. --If c == eof() and if either the input sequence has a putback posi tion available or the function makes a putback position available, assigns gnext - 1 to gnext. Returns (char_type)c. 2 Returns eof() to indicate failure. 3 Notes: 4 If file is a null pointer, the function always fails. 5 The function does not put back a character directly to the input sequence. 6 If the function can succeed in more than one of these ways, it is unspecified which way is chosen. The function can alter the number of putback positions available as a result of any call. 7 Default behavior: returns baggage::char_bag::eof(). +------- BEGIN BOX 155 -------+ Should be pure virtual. +------- END BOX 155 -------+ +------- BEGIN BOX 156 -------+ Shall we impose Library uses onto performing sync()... make gbuffer/pbuffer empty every time they try to write after read or vice versa, as in the current MSE. -- mjv +------- END BOX 156 -------+ +------- BEGIN BOX 157 -------+ No. On systems where this is necessary the basic_filebuf virtuals should keep track of the last operation performed on the FILE and do whatever is neccessary (equivalent of an fseek?) in order to reverse the direction. -- jss +------- END BOX 157 -------+ +------- BEGIN BOX 158 -------+ The following was not part of the proposal. Should we keep it? +------- END BOX 158 -------+ 27.5.2.1.8 basic_filebuf::showmany [lib.filebuf::showmany] // virtual int showmany(); inherited 1 Behaves the same as basic_streambuf::showmany().47) _________________________ 47) An implementation might well provide an overriding definition for this function signature if it can determine that more characters can be read from the input sequence. 27.5.2.1.9 basic_filebuf::underflow [lib.filebuf::underflow] // virtual int_type underflow(); inherited 1 Behaves the same as basic_convbuf<charT,baggage>::underflow(), except that the underlaid input character sequence is the byte sequence in the file specified by file. +------- BEGIN BOX 159 -------+ Describing the behavior about maintaining the conversion state is needed. +------- END BOX 159 -------+ 27.5.2.1.10 basic_filebuf::uflow [lib.filebuf::uflow] // virtual int_type uflow(); inherited 1 Behaves the same as basic_convbuf<charT,baggage>::uflow(). 27.5.2.1.11 basic_filebuf::xsgetn [lib.filebuf::xsgetn] // virtual streamsize xsgetn(char_type* s, streamsize n); inherited 1 Behaves the same as basic_convbuf<charT,baggage>::xsgetn(s,n). 27.5.2.1.12 basic_filebuf::xsputn [lib.filebuf::xsputn] // virtual streamsize xsputn(const char_type* s, streamsize n); inherited 1 Behaves the same as basic_convbuf<charT,baggage>::xsputn(s,n). 27.5.2.1.13 basic_filebuf::seekoff [lib.filebuf::seekoff] // virtual pos_type seekoff(off_type off, basic_ios<charT,baggage>::seekdir way, // basic_ios<charT,baggage>::openmode which // = basic_ios<charT,baggage>::in // | basic_ios<charT,baggage>::out); inherited 1 Alters the stream position within the controlled sequences, if possi ble, as described below. 2 Returns a newly constructed pos_type object that stores the resultant stream position, if possible. If the positioning operation fails, or if the object cannot represent the resultant stream position, the object stores an invalid stream position. 3 If file is a null pointer, the positioning operation fails. Other wise, the function determines one of three values for the argument whence, of type int, as indicated in Table 33: Table 33--seekoff effects +----------------------------------+ | way Value stdio Equivalent | +----------------------------------+ |basic_ios::beg SEEK_SET | |basic_ios::cur SEEK_CUR | |basic_ios::end SEEK_END | +----------------------------------+ 4 The function then calls fseek(file, off, whence) and, if that function returns nonzero, the positioning operation fails.48) 5 The function extracts the conversion state from off by means of get_offstate() to reset the state member. 27.5.2.1.14 basic_filebuf::seekpos [lib.filebuf::seekpos] // virtual pos_type seekpos(pos_type sp, // basic_ios<charT,baggage>::openmode which // = basic_ios<charT,baggage>::in // | basic_ios<charT,baggage>::out); inherited +------- BEGIN BOX 160 -------+ [To Be Filled] +------- END BOX 160 -------+ 27.5.2.1.15 basic_filebuf::setbuf [lib.filebuf::setbuf] // virtual basic_streambuf* setbuf(char_type* s, int n); inherited +------- BEGIN BOX 161 -------+ [To Be Filled] +------- END BOX 161 -------+ 27.5.2.1.16 basic_filebuf::sync [lib.filebuf::sync] // virtual int sync(); inherited +------- BEGIN BOX 162 -------+ [To Be Filled] +------- END BOX 162 -------+ _________________________ 48) The macros SEEK_SET, SEEK_CUR, and SEEK_END are defined, and the function signature fseek(FILE*, long, int) is declared, in <cstdio> (_lib.file.streams_). 27.5.2.2 Template class basic_ifstream [lib.ifstream] template <class charT, class baggage = file_baggage<charT> > class basic_ifstream : public basic_istream<charT,baggage> { public: typedef charT char_type; typedef baggage::char_bag::int_type int_type; typedef baggage::pos_bag::pos_type pos_type; typedef baggage::pos_bag::off_type off_type; int_type eof() { return baggage::char_bag::eof(); } char_type newline() { return baggage::char_bag::newline(); } public: basic_ifstream(); basic_ifstream(const char* s, openmode mode = in); virtual ~basic_ifstream(); basic_filebuf<charT,baggage>* rdbuf() const; bool is_open(); void open(const char* s, openmode mode = in); // void open(const char* s, open_mode mode = in); optional void close(); private: // basic_filebuf<charT,baggage> fb; exposition only }; class ifstream : public basic_ifstream<char> {}; class wifstream : public basic_ifstream<wchar_t> {}; 1 The class basic_ifstream<charT,baggage> is a derivative of basic_istream<charT,baggage> that assists in the reading of named files. It supplies a basic_filebuf<charT,baggage> object to control the associated sequence. 2 For the sake of exposition, the maintained data is presented here as: --basic_filebuf<charT,baggage> fb, the basic_filebuf object. 27.5.2.2.1 basic_ifstream constructors [lib.basic.ifstream.cons] basic_ifstream(); 1 Constructs an object of class basic_ifstream<charT,baggage>, initial izing the base class with basic_istream<charT,baggage>(&fb). basic_ifstream(const char* s, openmode mode = in); 2 Constructs an object of class basic_ifstream, initializing the base class with basic_istream<charT,baggage>(&fb), then calls open(s, mode). 27.5.2.2.2 basic_ifstream destructor [lib.basic.ifstream.des] virtual ~basic_ifstream(); 1 Destroys an object of class basic_ifstream<charT,baggage>. 27.5.2.2.3 basic_ifstream::rdbuf [lib.ifstream::rdbuf] basic_filebuf<charT,baggage>* rdbuf() const; 1 Returns fb. 27.5.2.2.4 basic_ifstream::is_open [lib.ifstream::is.open] bool is_open(); 1 Returns fb.is_open(). 27.5.2.2.5 basic_ifstream::open [lib.ifstream::open] void open(const char* s, openmode mode = in); 1 Calls fb.open(s, mode). If is_open() returns zero, calls set state(failbit). 27.5.2.2.6 basic_ifstream::close [lib.ifstream::close] void close(); 1 Calls fb.close() and, if that function returns zero, calls set state(failbit). 27.5.2.3 Template class basic_ofstream [lib.ofstream] template <class charT, class baggage = file_baggage<charT> > class basic_ofstream : public basic_ostream<charT,baggage> { public: typedef charT char_type; typedef baggage::char_bag::int_type int_type; typedef baggage::pos_bag::pos_type pos_type; typedef baggage::pos_bag::off_type off_type; int_type eof() { return baggage::char_bag::eof(); } char_type newline() { return baggage::char_bag::newline(); } public: basic_ofstream(); basic_ofstream(const char* s, openmode mode = out); virtual ~basic_ofstream(); basic_filebuf<charT,baggage>* rdbuf() const; bool is_open(); void open(const char* s, openmode mode = out | trunc); // void open(const char* s, open_mode mode = out | trunc); optional void close(); private: // basic_filebuf<charT,baggage> fb; exposition only }; class ofstream : public basic_ofstream<char> {}; class wofstream : public basic_ofstream<wchar_t> {}; 1 The class basic_ofstream<charT,baggage> is a derivative of basic_ostream<charT,baggage> that assists in the writing of named files. It supplies a basic_filebuf<charT,baggage> object to control the associated sequence. 2 For the sake of exposition, the maintained data is presented here as: --basic_filebuf<charT,baggage> fb, the basic_filebuf object. 27.5.2.3.1 basic_ofstream constructors [lib.basic.ofstream.cons] basic_ofstream(); 1 Constructs an object of class basic_ofstream<charT,baggage>, initial izing the base class with basic_ostream<charT,baggage>(&fb). basic_ofstream(const char* s, openmode mode = out); 2 Constructs an object of class basic_ofstream<charT,baggage>, initial izing the base class with basic_ostream<charT,baggage>(&fb), then calls open(s, mode). 27.5.2.3.2 basic_ofstream destructor [lib.basic.ofstream.des] virtual ~basic_ofstream(); 1 Destroys an object of class basic_ofstream<charT,baggage>. 27.5.2.3.3 basic_ofstream::rdbuf [lib.ofstream::rdbuf] basic_filebuf<charT,baggage>* rdbuf() const; 1 Returns (basic_filebuf<charT,baggage>*)&fb. 27.5.2.3.4 basic_ofstream::is_open [lib.ofstream::is.open] bool is_open(); 1 Returns fb.is_open(). 27.5.2.3.5 basic_ofstream::open [lib.ofstream::open] void open(const char* s, openmode mode = out); 1 Calls fb.open(s, mode). If is_open() is then false, calls set state(failbit). 27.5.2.3.6 basic_ofstream::close [lib.ofstream::close] void close(); 1 Calls fb.close() and, if that function returns zero, calls set state(failbit). 27.5.3 stdio streams [lib.stdio.fstreams] 27.5.3.1 Template class basic_stdiobuf [lib.basic.stdiobuf] +------- BEGIN BOX 163 -------+ basic_stdiobuf may be useful, and it is based on (untemplatized) cur rent practice, but there is nothing fundamental in it (it can be defined by a user in a fully portable and efficient way) no other part of the workiing paper depends on it and it is used relatively little. So in the interests of keeping the working paper small 1 Jerry Schwarz proposal: Delete this section. +------- END BOX 163 -------+ template <class charT, class baggage = stdio_baggage<charT> > class basic_stdiobuf : public streambuf<charT,baggage> { public: typedef charT char_type; typedef baggage::char_bag::int_type int_type; typedef baggage::pos_bag::pos_type pos_type; typedef baggage::pos_bag::off_type off_type; int_type eof() { return baggage::char_bag::eof(); } char_type newline() { return baggage::char_bag::newline(); } public: basic_stdiobuf(FILE* file_arg = 0); virtual ~basic_stdiobuf(); bool buffered() const; void buffered(bool buf_fl); protected: // virtual int_type overflow (int_type c = eof()); inherited // virtual int_type pbackfail(int_type c = eof()); inherited +------- BEGIN BOX 164 -------+ The following was not part of the proposal. Should we keep it? +------- END BOX 164 -------+ // virtual int showmany(); inherited // virtual int_type underflow(); inherited // virtual int_type uflow(); inherited // virtual streamsize xsgetn(char_type* s, streamsize n); inherited // virtual streamsize xsputn(const char_type* s, streamsize n); inherited // virtual pos_type seekoff(off_type off, basic_ios<charT,baggage>::seekdir way, // basic_ios<charT,baggage>::openmode which // = basic_ios<charT,baggage>::in // | basic_ios<charT,baggage>::out); inherited // virtual pos_type seekpos(pos_type sp, // basic_ios<charT,baggage>::openmode which // = basic_ios<charT,baggage>::in // | basic_ios<charT,baggage>::out); inherited // virtual int sync(); inherited private: // FILE* file; exposition only // bool is_buffered; exposition only }; +------- BEGIN BOX 165 -------+ [To Be Filled] +------- END BOX 165 -------+ 2 The class basic_stdiobuf<charT,baggage> is derived from basic_streambuf<charT,baggage> to associate both the input sequence and the output sequence with an externally supplied object of type FILE.49) _________________________ 49) Type FILE is defined in <cstdio> (_lib.file.streams_). 3 For the sake of exposition, the maintained data is presented here as: --FILE *file, points to the FILE associated with the stream buffer; --bool is_buffered, nonzero if the basic_stdiobuf object is buffered, and hence need not be kept synchronized with the associated file (as described below). 4 The restrictions on reading and writing a sequence controlled by an object of class basic_stdiobuf are the same as for an object of class basic_filebuf. 5 If an basic_stdiobuf object is not buffered and file is not a null pointer, it is kept synchronized with the associated file, as follows: as indicated in Table 34:50) Table 34--stdiobuf synchronization +--------------------------------+ | stdiobuf stdio Equivalent | +--------------------------------+ |sputc(c) fputc(c,file) | |sputbackc(c) ungetc(c,file) | |sbumpc() fgetc(file) | +--------------------------------+ 27.5.3.1.1 [lib.basic.stdiobuf.cons] basic_stdiobuf::basic_stdiobuf constructor basic_stdiobuf(FILE* file_arg = 0); 1 Constructs an object of class basic_stdiobuf<charT,baggage>, initial izing the base class with basic_streambuf<charT,baggage>(), and ini tializing file to file_arg and is_buffered to zero. 27.5.3.1.2 basic_stdiobuf destructor [lib.basic.stdiobuf.des] virtual ~basic_stdiobuf(); 1 Destroys an object of class basic_stdiobuf<charT,baggage>. 27.5.3.1.3 [lib.basic.stdiobuf::buffered] basic_stdiobuf::buffered bool buffered() const; 1 Returns true if is_buffered is nonzero. void buffered(bool buf_fl); _________________________ 50) The functions fgetc(FILE*), fputc(int, FILE*), and ungetc(int, FILE*) are declared in <cstdio> (_lib.file.streams_). 2 Assigns buf_fl to is_buffered. 27.5.3.1.4 [lib.basic.stdiobuf::overflow] basic_stdiobuf::overflow // virtual int_type overflow(int_type c = eof()); inherited 1 Behaves the same as basic_filebuf<charT,baggage>::overflow(int), sub ject to the buffering requirements specified by is_buffered. 27.5.3.1.5 [lib.basic.stdiobuf::pbackfail] basic_stdiobuf::pbackfail // virtual int_type pbackfail(int_type c = eof()); inherited 1 Behaves the same as basic_filebuf<charT,baggage>::pbackfail(int), sub ject to the buffering requirements specified by is_buffered. +------- BEGIN BOX 166 -------+ The following was not part of the proposal. Should we keep it? +------- END BOX 166 -------+ 27.5.3.1.6 [lib.basic.stdiobuf::showmany] basic_stdiobuf::showmany // virtual int showmany(); inherited 1 Behaves the same as basic_streambuf<charT,baggage>::showmany().51) 27.5.3.1.7 [lib.basic.stdiobuf::underflow] basic_stdiobuf::underflow // virtual int_type underflow(); inherited 1 Behaves the same as basic_filebuf<charT,baggage>::underflow(), subject to the buffering requirements specified by is_buffered. 27.5.3.1.8 basic_stdiobuf::uflow [lib.basic.stdiobuf::uflow] // virtual int_type uflow(); inherited 1 Behaves the same as basic_filebuf<charT,baggage>::uflow(), subject to the buffering requirements specified by is_buffered. 27.5.3.1.9 basic_stdiobuf::xsgetn [lib.basic.stdiobuf::xsgetn] // virtual streamsize xsgetn(char_type* s, streamsize n); inherited 1 Behaves the same as basic_streambuf<charT,baggage>::xsgetn(s,n). _________________________ 51) An implementation might well provide an overriding definition for this function signature if it can determine that more characters can be read from the input sequence. 27.5.3.1.10 basic_stdiobuf::xsputn [lib.basic.stdiobuf::xsputn] // virtual streamsize xsputn(const char_type* s, streamsize n); inherited 1 Behaves the same as basic_streambuf<charT,baggage>::xsputn(s,n). 27.5.3.1.11 [lib.basic.stdiobuf::seekoff] basic_stdiobuf::seekoff // virtual pos_type seekoff(off_type off, basic_ios<charT,baggage>::seekdir way, // basic_ios<charT,baggage>::openmode which // = basic_ios<charT,baggage>::in // | basic_ios<charT,baggage>::out); inherited 1 Behaves the same as basic_filebuf<charT,baggage>::seekoff(off,way,which) 27.5.3.1.12 [lib.basic.stdiobuf::seekpos] basic_stdiobuf::seekpos // virtual pos_type seekpos(pos_type sp, // basic_ios<charT,baggage>::openmode which // = basic_ios<charT,baggage>::in // | basic_ios<charT,baggage>::out); inherited 1 Behaves the same as basic_filebuf<charT,baggage>::seekpos(sp,which) 27.5.3.1.13 basic_stdiobuf::setbuf [lib.basic.stdiobuf::setbuf] // virtual basic_streambuf<charT,baggage>* setbuf(char_type* s, int n); inherited 1 Behaves the same as basic_filebuf<charT,baggage>::setbuf(s,n) 27.5.3.1.14 basic_stdiobuf::sync [lib.basic.stdiobuf::sync] // virtual int sync(); inherited 1 Behaves the same as basic_filebufs,n::sync() 27.5.3.2 Class istdiostream [lib.istdiostream] class istdiostream : public basic_istream<char> { public: istdiostream(FILE* file_arg = 0); virtual ~istdiostream(); basic_stdiobuf<char>* rdbuf() const; bool buffered() const; void buffered(bool buf_fl); private: // basic_stdiobuf<char> fb; exposition only }; 1 The class istdiostream is a derivative of basic_istream<charT,baggage> that assists in the reading of files controlled by objects of type FILE. It supplies a basic_stdiobuf<charT,baggage> object to control the associated sequence. 2 For the sake of exposition, the maintained data is presented here as: --basic_stdiobuf fb, the basic_stdiobuf object. 27.5.3.2.1 istdiostream::istdiostream [lib.istdiostream.cons] constructor istdiostream(FILE* file_arg = 0); 1 Constructs an object of class istdiostream, initializing the base class with basic_istream(&fb) and initializing fb with basic_stdiobuf(file_arg). 27.5.3.2.2 istdiostream destructor [lib.istdiostream.des] virtual ~istdiostream(); 1 Destroys an object of class istdiostream. 27.5.3.2.3 istdiostream::rdbuf [lib.istdiostream::rdbuf] basic_stdiobuf<char>* rdbuf() const; 1 Returns fb. 27.5.3.2.4 istdiostream::buffered [lib.istdiostream::buffered] bool buffered() const; 1 Returns true if is_buffered is nonzero. 27.5.3.2.5 istdiostream::buffered [lib.istdiostream::buffered.b] void buffered(bool buf_fl); 1 Assigns buf_fl to is_buffered. 27.5.3.3 Class ostdiostream [lib.ostdiostream] class ostdiostream : public basic_ostream<char> { public: ostdiostream(FILE* file_arg = 0); virtual ~ostdiostream(); basic_stdiobuf<char>* rdbuf() const; bool buffered() const; void buffered(bool buf_fl); private: // basic_stdiobuf<char> fb; exposition only }; 1 The class ostdiostream is a derivative of basic_ostream that assists in the writing of files controlled by objects of type FILE. It sup plies a basic_stdiobuf object to control the associated sequence. 2 For the sake of exposition, the maintained data is presented here as: --basic_stdiobuf<char> fb, the basic_stdiobuf object. 27.5.3.3.1 ostdiostream constructor [lib.ostdiostream.cons] ostdiostream(FILE* file_arg = 0); 1 Constructs an object of class ostdiostream, initializing the base class with basic_ostream(&fb) and initializing fb with basic_stdiobuf(file_arg). 27.5.3.3.2 ostdiostream destructor [lib.ostdiostream.des] virtual ~ostdiostream(); 1 Destroys an object of class ostdiostream. 27.5.3.3.3 ostdiostream::rdbuf [lib.ostdiostream::rdbuf] basic_stdiobuf<char>* rdbuf() const; 1 Returns fb. 27.5.3.3.4 ostdiostream::buffered [lib.ostdiostream::buffered] bool buffered() const; 1 Returns true if is_buffered is nonzero. 27.5.3.3.5 ostdiostream::buffered [lib.ostdiostream::buffered.b] void buffered(bool buf_fl); 1 Assigns buf_fl to is_buffered.