Document number: P0759R1
Date: 2018-06-04
Audience: Library Working Group
Author: Daniel Krügler
Reply-to: Daniel Krügler

fpos Requirements


This is a plain wording fixing proposal for the table-based requirement set of class template fpos. A paper is provided instead of drafting wording in the referenced issues, to have more room available for presentation and explanation.

The wording changes suggested by this paper should not have effects on any existing implementations, because it mainly intended to clearify several underspecified parts of the current specification. Nonetheless during the analysis of the paper there occurred some curiosities in the specification that caused to ask some questions to the committee which might lead to decisions to change existing implementations, but the author has tried to be as conservative as possible in regard to such suggestions.

Revision History

Changes since P0759R0:


This paper revision does not repeat the sections Discussion, 1. Specification Facts, and 2. Specification Problems of its predecessor P0759R0.

Please refer to the previous paper regarding general background and (extended) rationale.

Resolved Issues

If the proposed resolution will be accepted, the following library issues will be resolved:

Number Description C++17 NB comment
2808 Requirements for fpos and stateT GB 60
2832 §[fpos.operations] strange requirement for P(i)

Proposed resolution

At some places below, additional markup of the form

[Drafting notes: whatever — end drafting notes]

is provided, which is not part of the normative wording, but is solely shown to provide additional information to the reader about the rationale of the concrete wording.

The proposed wording changes refer in all cases to N4750.

  1. Change [fpos.operations] as indicated:

    -1- Operations specified in Table 112 are permitted. An fpos type specifies file position information. It holds a state object whose type is equal to the template parameter stateT. Type stateT shall meet the DefaultConstructible (Table 22), CopyConstructible (Table 24), CopyAssignable (Table 26), and Destructible (Table 27) requirements. If is_trivially_copy_constructible_v<stateT> is true, then fpos<stateT> has a trivial copy constructor. If is_trivially_copy_assignable<stateT> is true, then fpos<stateT> has a trivial copy assignment operator. If is_trivially_destructible_v<stateT> is true, then fpos<stateT> has a trivial destructor. All specializations of fpos satisfy the DefaultConstructible, CopyConstructible, CopyAssignable, Destructible, and EqualityComparable (Table 20) requirements. In addition, the expressions shown in Table 112 are valid and have the indicated semantics. In that table,

    1. (1.1) — P refers to an instance of fpos,

    2. (1.2) — p and q refer to values of type P or const P,

    3. (1.?) — pl and ql refer to modifiable lvalues of type P,

    4. (1.3) — O refers to type streamoff,and

    5. (1.4) — o refers to a value of type streamoff or const streamoff

    6. (1.5) — sz refers to a value of type streamsize and

    7. (1.6) — i refers to a value of type int.

    [Drafting notes: It is recommend to strike the non-normative note in p2 completely. This seems to be very out-dated wording and what is says is already said in [structure.requirements], in particular in p3+p4 — end drafting notes]

    -2- [Note: Every implementation is required to supply overloaded operators on fpos objects to satisfy the requirements of [fpos.operations]. It is unspecified whether these operators are members of fpos, global operators, or provided in some other way. — end note]

    -3- Stream operations that return a value of type traits::pos_type return P(O(-1)) as an invalid value to signal an error. If this value is used as an argument to any istream, ostream, or streambuf member that accepts a value of type traits::pos_type then the behavior of that function is undefined.

  2. Change Table 106 — "Position type requirements", as indicated:

    [Drafting notes: We can strike the wording about the destructor and ==, because we have now the EqualityComparable and Destructible requirements specified in [fpos.operations] — end drafting notes]

    Table 106 — Position type requirements
    Expression Return type Operational semantics Assertion/note
    P(i) p == P(i)
    note: a destructor is assumed.
    P p(i);
    P p = i;
    Postconditions: p == P(i).
    P(o) fposP converts from offset Effects: Value-initializes the state object.
    P p(o);
    P p = o;
    Effects: Value-initializes the state object.
    Postconditions: p == P(o)
    P() P P(0)
    P p; P p(0);
    O(p) streamoff converts to offset P(O(p)) == p
    p == q convertible to bool == is an equivalence relation
    p != q convertible to bool !(p == q)
    q = p + o
    p += o
    fposP + offset Remarks: With ql = p + o;, then:
    ql - o == p
    pl += o P& += offset Remarks: With ql = pl; before the +=, then:
    pl - o == ql
    q = p - o
    p -= o
    fposP - offset Remarks: With ql = p - o;, then:
    ql + o == p
    pl -= o P& -= offset Remarks: With ql = pl; before the -=, then:
    pl + o == ql
    o + p convertible to P p + o P(o + p) == p + o
    o = p - q streamoff distance p == q + (p - q)
    q + o == p
    streamsize(O(sz)) == sz
    streamsize(O(sz)) == sz


N4750 Richard Smith: "Working Draft, Standard for Programming Language C++"


Thanks to Jonathan Wakely, Billy Robert O'Neal III, and Axel Naumann for a review of this proposal and for encouragement to make a little more changes as I originally believed I should make.