<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

<title>fpos requirements</title>

<style type="text/css">
  p {text-align:justify}
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  blockquote.note
  {
   background-color:#E0E0E0;
   padding-left: 15px;
   padding-right: 15px;
   padding-top: 1px;
   padding-bottom: 1px;
  }
</style>
</head><body>
<address style="text-align: left;">
Document number: P0759R0<br>
Date: 2017-07-28<br>
Audience: Library Working Group<br>
Author: Daniel Kr&uuml;gler<br>
Reply-to: <a href="mailto:daniel.kruegler@gmail.com">Daniel Kr&uuml;gler</a>
</address>
<hr>
<h1 style="text-align: center;"><tt>fpos</tt> Requirements</h1>

<ul>
<li><a href="#Intro">Introduction</a></li>
<li><a href="#Discussion">Discussion</a></li>
<li><a href="#Issues_Resolved">Resolved Issues</a></li>
<li><a href="#Proposed_resolution">Proposed Resolution</a></li>
<li><a href="#Bibliography">Bibliography</a></li>
<li><a href="#Akn">Acknowledgements</a></li>
</ul>

<h2><a name="Intro"></a>Introduction</h2>
<p>
This is a plain wording fixing proposal for the table-based requirement set of class template <tt>fpos</tt>. A paper 
is provided instead of drafting wording in the referenced issues, to have more room available for presentation and 
explanation.
<p/>
The wording changes suggested by this paper <em>should not</em> 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 <em>might</em> lead to decisions to change existing implementations, but the author has tried to be as 
conservative as possible in regard to such suggestions.
</p>

<h2><a name="Discussion"></a>Discussion</h2>
<p>
The <tt>fpos</tt> type family is one of the rarely and sparely explicitly mentioned templates of the 
Standard Library specified in 30.5.4.2 [fpos.operations] including Table 112 &mdash; "Position type requirements" 
(all references within this proposal to the C++ working draft are based on <sup><a href="#bib-n4659">1</a></sup>).
Specializations of that template are used in the IO Library to denote file positions and to allow
some arithmetic operations and to store/retrieve a rather opaque "state"; furthermore it connects 
<tt>std::char_traits</tt> with the IO streams due to its <tt>pos_type</tt> member which is an <tt>fpos</tt> 
instantiation whose state type is equal to <tt>char_traits&lt;CharT&gt;::state_type</tt>.
The latter property is not a strict requirement, since the specification leaves it implementation-defined what
happens when <tt>traits::pos_type</tt> differs from <tt>fpos&lt;char_traits&lt;CharT&gt;::state_type&gt;</tt>. 
The current wording also says (30.9.2 [filebuf] p4) that the behaviour is undefined, if <tt>traits::pos_type</tt> of 
<tt>basic_filebuf</tt> is different from <tt>fpos&lt;traits::state_type&gt;</tt>. For the pre-defined 
<tt>char_traits</tt>, <tt>traits::state_type</tt> is equal to <tt>mbstate_t</tt>, just another sparely-specified 
type inherited from the <tt>&lt;cwchar&gt;</tt> header. The C specification tells us, that
<tt>mbstate_t</tt> is a complete, non-array object type that can be default-initialized and value-initialized
(freely translated into C++ language terms) and "can hold the conversion state information necessary to convert 
between sequences of multibyte characters and wide characters". In C++ (see 24.2.2 [char.traits.typedefs] p4) the 
requirements imposed on <tt>char_traits&lt;&gt;::state_type</tt> are <tt>CopyAssignable</tt>, 
<tt>CopyConstructible</tt>, and <tt>DefaultConstructible</tt>. Associated with both <tt>char_traits</tt> 
and <tt>fpos</tt> are also the types <tt>streamoff</tt> and <tt>streamsize</tt> which are both signed basic 
integral types (30.5.2 [stream.types] p1+2). An alias for <tt>std::fpos&lt;std::mbstate_t&gt;</tt> is
<tt>std::streampos</tt>.
</p>

<h3><a name="Discussion.facts"></a>1. Specification Facts</h3>
<p>
Summarizing the essence of 30.5.4.1 [fpos.members] and 30.5.4.2 [fpos.operations], we can conclude the following:
</p>
<ul>
<li><p><tt>fpos&lt;stateT&gt;</tt> holds a single object of type <tt>stateT</tt>, 
that can be read from and written to via a <tt>state</tt> attribute.</p></li>
<li><p><tt>fpos&lt;stateT&gt;</tt> objects are <tt>EqualityComparable</tt> (This is not explicitly said but it can be 
indirectly deduced from the definition of <tt>EqualityComparable</tt> in Table 20 and the imposed requirements of 
<tt>fpos</tt> in regard to <tt>==</tt> in Table 112).</p></li>
<li><p><tt>fpos&lt;stateT&gt;</tt> objects can be direct-initialized or copy-initialized from <tt>int</tt> values.</p></li>
<li><p><tt>fpos&lt;stateT&gt;</tt> objects <tt>p</tt> can be direct-initialized from <tt>streamoff</tt> objects <tt>o</tt> 
and <tt>streamoff</tt> objects can be direct-initialized from <tt>fpos&lt;stateT&gt;</tt> objects, such that the
conversion sequence <tt>p<sub>1</sub></tt> &rarr; <tt>o</tt> &rarr; <tt>p<sub>2</sub></tt> ensures that 
<tt>p<sub>1</sub> == p<sub>2</sub></tt>.</p></li>
<li><p><tt>streamoff</tt> values can be added to and subtracted from <tt>fpos</tt> and the difference of two
<tt>fpos</tt> values returns a <tt>streamoff</tt>.</p></li>
</ul>

<h3><a name="Discussion.problems"></a>2. Specification Problems</h3>
<p>
The following bullets list some concrete unclear points. To simplify the descriptions below, <tt>P</tt> denotes a 
class type that is an instance of the <tt>std::fpos</tt> template and <tt>O</tt> denotes the type <tt>std::streamoff</tt>.
</p>
<ol>
<li><p>What is the semantics of initializing an <tt>fpos</tt> from an <tt>int</tt> value? (see 
<a href="http://wg21.link/lwg2832">LWG 2832</a>). Note that contrary to the construction from <tt>streamoff</tt>
there exists no similar conversion sequence cycle guarantee for <tt>int</tt> values. In theory, an (insane) implementation
could provide different constructors of <tt>fpos</tt> for <tt>int</tt> and for <tt>streamoff</tt>, both having
different semantics. Or, the constructor taking an <tt>int</tt> could be non-<tt>explicit</tt> and the
constructor taking an <tt>streamoff</tt> could be <tt>explicit</tt>. The author is convinced that this interpretation 
is not intended and recommends to specify the semantics of <tt>fpos</tt> initialization from <tt>int</tt> to be equivalent 
to the semantics of <tt>fpos</tt> initialization from <tt>streamoff</tt>, where the <tt>streamoff</tt> value has been 
initialized from <tt>int</tt> before (Note that due to the type nature of <tt>streamoff</tt> this conversion 
is statically possible, and it should always be dynamically be well-defined if the conversion of <tt>int</tt> to 
<tt>streamoff</tt> is well-defined). The indirect effect of doing that is that
the specification would now relax the direct-initialization requirement from <tt>O</tt> to <tt>P</tt> to an
implicit conversion from <tt>O</tt> to <tt>P</tt>, which is in sync with what existing implementations do anyway.
</p></li>
<li><p>
Related to the previous item, some entries in Table 112 are very likely debris of the last cleanup paper in this
area, specifically by <a href="http://wg21.link/n2884">N2884</a>. Before that paper, type <tt>streamoff</tt> was an 
implementation-defined type, not necessarily a built-in type. With the resolution of that paper <tt>streamoff</tt> 
became a guaranteed alias for a signed integral type. Since all integer types can be implicitly converted into each 
other, there is not much reason to provide the <em>additional</em> guarantee that <tt>fpos</tt> instances can be 
initialized by <tt>int</tt> values, because relying on the initialization by <tt>streamoff</tt> should be sufficient 
(This assumes the absence of implementations that used SFINAE-constrained constructors to accept <em>exactly</em> type
<tt>streamoff</tt> for one constructor and <em>exactly</em> type <tt>int</tt> for another constructor). For similar
reasons is the last row in Table 112 obsolete, which specifies the validity to convert between <tt>streamsize</tt> and
<tt>streamoff</tt>, because <tt>streamsize</tt> is (and was) also a synonym for a signed integral type. This proposal
therefore recommends to remove this last row as well as the explicit initialization specification of <tt>fpos</tt>
by <tt>int</tt> values.
</p></li>
<li><p>What requirements are imposed on the template type parameter <tt>stateT</tt>? 
(see <a href="http://wg21.link/lwg2808">LWG 2808</a>).
The current specification allows to conclude that <tt>stateT</tt> is required to be <tt>DefaultConstructible</tt>, because
there exists no portable way to initialize <tt>fpos</tt> with <tt>stateT</tt>, assuming that an implementation is 
not required to in-place construct <tt>stateT</tt>. The semantics of the <tt>state</tt> attribute functions
allows the assumption that <tt>stateT</tt> needs to be also <tt>CopyConstructible</tt>, <tt>CopyAssignable</tt>, and 
<tt>Destructible</tt>. This overlaps nicely with the requirements that come from 24.2.2 [char.traits.typedefs] p4, but
adds a missing <tt>Destructible</tt> requirement.
<p/>
A related open question is that the current specification doesn't tell whether the specified <tt>fpos&lt;stateT&gt;</tt> 
constructors will default-initialize or value-initialize the exposition-only <tt>stateT</tt> member, because this has 
impact on conforming programs that attempt to read the state before calling the setter. After inspection 
of existing implementations it turns out that all do the same thing, they <em>value-initialize</em> the state member.
The author therefore recommends to specify this existing practice. If the committee would consider this as an unwanted
strong specification, the wording should at least emphasize that the <tt>stateT</tt> member may be default-initialized
after construction and may thus have an indeterminate value, which implies that an initial call of the 
<tt>stateT state() const</tt> signature would be undefined behaviour.
</p></li>
<li><p>Are <tt>fpos</tt> instances <tt>DefaultConstructible</tt>, <tt>CopyConstructible</tt>, <tt>CopyAssignable</tt>, 
and <tt>Destructible</tt>? The requirements for <tt>CopyConstructible</tt> and <tt>Destructible</tt> follow indirectly 
from the usage of <tt>fpos</tt> in return types and function arguments from a pre-C++11 era, where every move was a 
copy. There is currently clearly no <tt>DefaultConstructible</tt> requirement, but existing 
implementations such as from Visual Studio 2017/Dinkumware, clang/libc++, and gcc/libstd++ provide default-constructible 
<tt>fpos</tt> types. In all cases the default-constructed <tt>fpos</tt> is equivalent to an <tt>fpos</tt> initialized by
<tt>streamoff(0)</tt>. Therefore this proposal suggests to require that <tt>fpos</tt> instances are <tt>CopyAssignable</tt> 
and <tt>DefaultConstructible</tt>.</p></li>
<li><p>Existing implementations of <tt>fpos</tt> provide implicit conversion to <tt>streamoff</tt>, the specification 
requires only <tt>explicit</tt> conversions. The current implementation state can be explained by the pre-C++11
existence of that type, where no explicit conversion functions where available. Nonetheless the author believes that
the currently stricter specification is reasonable for now and doesn't recommend any change. The author is open
to be requested to weaken the specification, therefore points this characteristics out here, asking for feedback from
the committee.</p></li>
<li><p>Are there any trivial type guarantees of <tt>fpos</tt>, conditionally depending on triviallity characteristics
of <tt>stateT</tt>? Albeit current implementations provide a default-constructor for <tt>fpos</tt>, this one is never
<em>trivial</em>. So regardless whether our recommendation is accepted to require the existence of an <tt>fpos</tt> 
default constructor, we can't give trivial type guarantees. But all implementations available to the author meet the 
following characteristics:</p>
<blockquote><pre>
static_assert(std::is_trivially_copyable_v&lt;std::streampos&gt;);
static_assert(!std::is_trivial_v&lt;std::streampos&gt;);
</pre></blockquote>
<p>
and thus are <em>trivially copyable</em> if <tt>stateT</tt> is also trivially copyable. The author of this proposal
suggest to provide individual trivial special member guarantees depending on corresponding <tt>is_trivially_xxx&lt;stateT&gt;</tt>
properties, similar to the special member specifications of <tt>std::istream_iterator</tt>.
</p>
</li>
<li><p>The mixed additions of <tt>fpos</tt> and <tt>streamoff</tt> are not symmetric (<tt>fpos</tt> on the right side is
not specified), is this intended?
<p/>
Let <tt>p</tt> denote a (possibly <tt>const</tt>) value of <tt>P</tt> and <tt>o</tt> denote a (possibly <tt>const</tt>) value 
of <tt>O</tt>, the existing requirements support the following expression
</p>
<blockquote><pre>
p + o;
</pre></blockquote>
<p>
but <em>not</em> the other way around:
</p>
<blockquote><pre>
o + p;
</pre></blockquote>
<p>
The observation that <tt>o + p</tt> is undefined by the letters of the Standard is unexpected for users and according to
the author's opinion user code uses either form obviously unaware of that fact. The interesting point is that all implementations
seem to behave the same way as follows:
</p>
<blockquote><pre>
P p(0);
O o(0);

using add1 = decltype(p + o);
using add2 = decltype(o + p);

static_assert(std::is_same_v&lt;add1, P&gt;);
static_assert(std::is_same_v&lt;add2, O&gt;);
</pre></blockquote>
<p>
This program is well-formed for all tested implementations, which means that <tt>p + o</tt> and <tt>o + p</tt> do have different
result types: The first one has type <tt>P</tt>, the second one has type <tt>O</tt>. The technical reason for this is that existing
implementations only define a member signature <tt>fpos operator+(streamoff offs) const</tt> but also always a conversion function
<tt>operator streamoff() const</tt>, the net result being that the expression <tt>o + p</tt> is well-formed, because it finds the
conversion function and after the conversion of <tt>p</tt> to <tt>streamoff</tt> it just adds two <tt>streamoff</tt> values.
<p/>
The author of this proposal believes that the binary plus operation of <tt>P</tt> and <tt>O</tt> should be well-defined to reduce
user surprises. Unfortunately existing implementations behave non-symmetric in regard to the semantics and result type. It is
unclear how to proceed here:
</p>
<ol>
<li><p>Keep the current state and leave <tt>o + p</tt> undefined. User-code cannot call that
combination of this binary operator at all in conforming code.</p></li>
<li><p>Change the specification to make <tt>o + p</tt> well-defined, allow one of <tt>P</tt> or
<tt>O</tt> to be valid. User-code could thus either use <tt>auto</tt> for the result or rely on an 
implicit conversion to <tt>P</tt> in conforming code.</p></li>
<li><p>Change the specification to make <tt>o + p</tt> well-defined, and say the the return type
is <em>convertible</em> to <tt>P</tt>. User-code could thus either use <tt>auto</tt> for the result or rely on an 
implicit conversion to <tt>P</tt> in conforming code.</p></li>
<li><p>Change the specification to make <tt>o + p</tt> well-defined, but specify what existing
implementations do. User-code could thus either use <tt>O</tt> for the result or rely on
implicit conversion to <tt>P</tt> in conforming code.</p></li>
<li><p>Change the specification to make <tt>o + p</tt> well-defined and require that all existing 
implementations change so that the return type is <tt>P</tt> instead of <tt>O</tt>. User-code could 
thus either use <tt>P</tt> for the result or rely on direct initialization to <tt>O</tt> in 
conforming code.</p></li>
</ol>
<p>
Some short observations to some of the suggested variants: Variant (2) would be a very unusual specification, because
we typically don't say that the result is one of several choices. In diffuse cases we typically make an implicit
conversion to some other type part of the spec (See for example the result of <tt>==</tt> or <tt>!=</tt> in most
requirement sets). Interestingly, all variants have in common that the result is convertible to <tt>P</tt>,
which is appealing because it emphasizes the "right" type. Variant (3) uses this commonality as the specification
directly.
<p/>
The author would like to gather feedback from the committee in regard to the preferred outcome, but suggests
to use the non-breaking variant (3), which has the following advantages: First, its specification emphasizes the
intuitively "correct" result type. Second, if the committee is in fond of that idea, existing implementations 
could decide in the future to <em>add</em> the missing <tt>P operator+(O, P)</tt>. Then, in a later future, if
a new survey of existing practice would be performed again and when now all existing implementations have added this
member, we could now strengthen the specification to impose that the return value of <tt>o + p</tt> is <tt>P</tt>.
<p/>
The author would also express his recommendation <em>not</em> to standardize the behaviour of existing 
implementations (variant (4)). This seems an unusual recommendation at first, but in this particular case, the 
author suspects that the status quo of implementations doesn't exist because of an intentional design, but 
due to an <em>unintended</em> artifact of strictly implementing what Table 112 describes. The author would
like to get feedback from existing implementations whether this assumption is correct or wrong.
</p>
</li>
<li><p>
According to Table 112 it looks as if the return types of assignment operator and compound assignment operator of <tt>fpos</tt>
have type <tt>fpos</tt> and not <tt>fpos&amp;</tt> (similar for <tt>streamoff</tt>). The presumable intend is to specify the
return types of the pure binary arithmetic expressions and not of the denoted assignments (except for the compound assignments). 
This paper proposes to isolate the different expressions and fix the wrong compound assignment return types.
</p></li>
<li><p>
Some rows in Table 112 specify a return type <tt>fpos</tt> for expressions such as <tt>P(o)</tt>. This is invalid, because
<tt>fpos</tt> is a class template, but the return type for an expression <tt>P(o)</tt> needs to be <tt>P</tt>, which is the 
same <em>specialization</em> of <tt>fpos</tt> that has been used to form the actual expression. The recommended resolution
is to replace such uses of <tt>fpos</tt> in Table 112 by <tt>P</tt> instead.
</p></li>
</ol>

<h2><a name="Issues_Resolved"></a>Resolved Issues</h2>
<p>
If the proposed resolution will be accepted, the following library issues will be resolved:
</p>
<table border="1">
  <tr>
    <th>Number</th>
    <th>Description</th>
    <th>C++17 NB comment</th>
  </tr>
  <tr>
    <td><a href="http://wg21.link/lwg2808">2808</a></td>
    <td>Requirements for <tt>fpos</tt> and <tt>stateT</tt></td>
    <td><a href="http://wg21.link/p0488r0">GB 60</a></td>
  </tr>
  <tr>
    <td><a href="http://wg21.link/lwg2832">2832</a></td>
    <td>&sect;[fpos.operations] strange requirement for <tt>P(i)</tt></td>
    <td>&mdash;</td>
  </tr>
</table> 

<h2><a name="Proposed_resolution"></a>Proposed resolution</h2>

<p>
At some places below, additional markup of the form
</p>
<blockquote class="note">
<p>
[<i>Drafting notes</i>: whatever &mdash; <i>end drafting notes</i>]
</p>
</blockquote>
<p>
is provided, which is <em>not</em> part of the normative wording, but is solely shown to provide additional information 
to the reader about the rationale of the concrete wording.
</p>

<p>
The proposed wording changes refer in all cases to <a href="http://wg21.link/n4659">N4659</a>.
</p>

<ol>
<li><p>Change 30.5.4.2 [fpos.operations] as indicated:</p>

<blockquote>
<p>
-1- <del>Operations specified in Table 112 are permitted.</del> <ins>An <tt>fpos</tt> type specifies file position 
information. It holds a state object whose type is equal to the template parameter <tt>stateT</tt>. Type <tt>stateT</tt>
shall meet the <tt>DefaultConstructible</tt> (Table 22), <tt>CopyConstructible</tt> (Table 24), 
<tt>CopyAssignable</tt> (Table 26), and <tt>Destructible</tt> (Table 27) requirements. If 
<tt>is_trivially_copy_constructible_v&lt;stateT&gt;</tt> is <tt>true</tt>, then <tt>fpos&lt;stateT&gt;</tt> has a 
trivial copy constructor. If <tt>is_trivially_copy_assignable&lt;stateT&gt;</tt> is <tt>true</tt>, then 
<tt>fpos&lt;stateT&gt;</tt> has a trivial copy assignment operator. If <tt>is_trivially_destructible_v&lt;stateT&gt;</tt> 
is <tt>true</tt>, then <tt>fpos&lt;stateT&gt;</tt> has a trivial destructor. All specializations of
<tt>fpos</tt> satisfy the <tt>DefaultConstructible</tt>, <tt>CopyConstructible</tt>, <tt>CopyAssignable</tt>, 
<tt>Destructible</tt>, and <tt>EqualityComparable</tt> (Table 20) requirements. 
In addition, the expressions shown in Table 112 are valid and have the indicated semantics.</ins>
In that table,
</p>
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; <tt>P</tt> refers to an instance of <tt>fpos</tt>,</p></li>
<li><p>(1.2) &mdash; <tt>p</tt> and <tt>q</tt> refer to values of type <tt>P</tt> <ins>or <tt>const P</tt></ins>,</p></li>
<li><p><ins>(1.?) &mdash; <tt>pl</tt> and <tt>ql</tt> refer to modifiable lvalues of type <tt>P</tt>,</ins></p></li>
<li><p>(1.3) &mdash; <tt>O</tt> refers to type <tt>streamoff</tt>,</p></li>
<li><p>(1.4) &mdash; <tt>o</tt> refers to a value of type <tt>streamoff</tt> <ins>or <tt>const streamoff</tt></ins>, 
<ins>and</ins></p></li>
<li><p><ins>(1.?) &mdash; <tt>ol</tt> refers to a modifiable lvalue of type <tt>streamoff</tt>.</ins></p></li>
<li><p><del>(1.5) &mdash; <tt>sz</tt> refers to a value of type <tt>streamsize</tt> and</del></p></li>
<li><p><del>(1.6) &mdash; <tt>i</tt> refers to a value of type <tt>int</tt>.</del></p></li>
</ol>

<blockquote class="note">
<p>
[<i>Drafting notes</i>: 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 20.4.1.3 [structure.requirements], in particular in p3+p4 &mdash; 
<i>end drafting notes</i>]
</p>
</blockquote>

<p>
<del>-2- [<i>Note:</i> Every implementation is required to supply overloaded operators on <tt>fpos</tt> objects to satisfy the
requirements of 30.5.4.2 [fpos.operations]. It is unspecified whether these operators are members of <tt>fpos</tt>, 
global operators, or provided in some other way. &mdash; <i>end note</i>]</del>
<p/>
-3- Stream operations that return a value of type <tt>traits::pos_type</tt> return <tt>P(O(-1))</tt> as an invalid value to
signal an error. If this value is used as an argument to any <tt>istream</tt>, <tt>ostream</tt>, or <tt>streambuf</tt> member that
accepts a value of type <tt>traits::pos_type</tt> then the behavior of that function is undefined.
</p>
</blockquote>
</li>

<li><p>Change Table 112 &mdash; "Position type requirements", as indicated:</p>

<blockquote class="note">
<p>
[<i>Drafting notes</i>: We can strike the wording about the destructor and <tt>==</tt>, because we
have now the <tt>EqualityComparable</tt> and <tt>Destructible</tt> requirements 
specified in 30.5.4.2 [fpos.operations] &mdash; <i>end drafting notes</i>]
</p>
</blockquote>

<blockquote>
<table border="1">
<caption>Table 112 &mdash; Position type requirements</caption>

<tr>
<th>Expression</th>
<th>Return type</th>
<th>Operational semantics</th>
<th>Assertion/note<br/>pre-/post-condition</th>
</tr>

<tr>
<td><del><tt>P(i)</tt></del></td> 
<td><del>&emsp;</del></td>
<td><del>&emsp;</del></td>
<td>
<del><tt>p == P(i)</tt><br/>
note: a destructor is assumed.</del>
</td>
</tr>

<tr>
<td>
<del><tt>P p(i);<br/>
P p = i;</tt></del>
</td>
<td><del>&emsp;</del></td>
<td><del>&emsp;</del></td>
<td><del>Postconditions: <tt>p == P(i)</tt>.</del></td>
</tr>

<tr>
<td><tt>P(o)</tt></td>
<td><tt><del>fpos</del><ins>P</ins></tt></td>
<td>converts from <tt>offset</tt></td>
<td><ins><i>Effects:</i> Value-initializes the state object.</ins></td>
</tr>

<tr>
<td>
<ins><tt>P p(o);<br/>
P p = o;</tt></ins>
</td>
<td></td>
<td></td>
<td>
<ins><i>Effects:</i> Value-initializes the state object.</ins><br/>
<ins><i>Postconditions:</i> <tt>p == P(o)</tt></ins>
</td>
</tr>

<tr>
<td>
<ins><tt>P()</tt></ins></td>
<td><ins><tt>P</tt></ins></td>
<td><ins><tt>P(0)</tt></ins></td>
<td>
</td>
</tr>

<tr>
<td>
<ins><tt>P p;</tt></ins></td>
<td></td>
<td><ins><tt>P p(0);</tt></ins></td>
<td></td>
</tr>

<tr>
<td><tt>O(p)</tt></td>
<td><tt>streamoff</tt></td>
<td>converts to <tt>offset</tt></td>
<td><tt>P(O(p)) == p</tt></td>
</tr>

<tr>
<td><del><tt>p == q</tt></del></td>
<td><del>convertible to <tt>bool</tt></del></td>
<td><del>&emsp;</del></td>
<td><del><tt>==</tt> is an equivalence relation</del></td>
</tr>

<tr>
<td><tt>p != q</tt></td>
<td>convertible to <tt>bool</tt></td>
<td><tt>!(p == q)</tt></td>
<td></td>
</tr>

<tr>
<td><tt><del>q =</del> p + o<br/>
<del>p += o</del></tt></td>
<td><tt><del>fpos</del><ins>P</ins></tt></td>
<td><tt>+</tt> offset</td>
<td><ins><i>Remarks:</i> With <tt>ql = p + o;</tt>, then:<br/></ins> 
<tt>q<ins>l</ins> - o == p</tt></td>
</tr>

<tr>
<td><ins><tt>pl += o</tt></ins></td>
<td><ins><tt>P&amp;</tt></ins></td>
<td><ins><tt>+=</tt> offset</ins></td>
<td><ins><i>Remarks:</i> With <tt>ql = pl;</tt> before the <tt>+=</tt>, then:<br/>
<tt>pl - o == ql</tt></ins></td>
</tr>

<tr>
<td><tt><del>q =</del> p - o<br/>
<del>p -= o</del></tt></td>
<td><tt><del>fpos</del><ins>P</ins></tt></td>
<td><tt>-</tt> offset</td>
<td><ins><i>Remarks:</i> With <tt>ql = p - o;</tt>, then:<br/></ins> <tt>q<ins>l</ins> + o == p</tt></td>
</tr>

<tr>
<td><ins><tt>pl -= o</tt></ins></td>
<td><ins><tt>P&amp;</tt></ins></td>
<td><ins><tt>-=</tt> offset</ins></td>
<td><ins><i>Remarks:</i> With <tt>ql = pl;</tt> before the <tt>-=</tt>, then:<br/>
<tt>pl + o == ql</tt></ins></td>
</tr>

<tr>
<td><ins><tt>o + p</tt></ins></td> 
<td><ins>convertible to <tt>P</tt></ins></td>
<td></td>
<td><ins><tt>P(o + p) == p + o</tt></ins></td>
</tr>

<tr>
<td><tt><del>o =</del> p - q</tt></td>
<td><tt>streamoff</tt></td>
<td>distance</td>
<td>
<ins><tt>p == q + (p - q)</tt></ins><br/>
<ins><i>Remarks:</i> With <tt>ol = p - q;</tt>, then:<br/></ins><tt>q + o<ins>l</ins> == p</tt>
</td>
</tr>

<tr>
<td><del><tt>streamsize(o)<br/>
O(sz)</tt></del></td>
<td><del><tt>streamsize<br/>
streamoff</tt></del></td>
<td><del>converts<br/>
converts</del></td>
<td><del><tt>streamsize(O(sz)) == sz<br/>
streamsize(O(sz)) == sz</tt></del></td>
</tr>

</table>

</blockquote>
</li>

</ol>

<h2><a name="Bibliography"></a>Bibliography</h2>
<p>
<a name="bib-n4659"></a><a href="http://wg21.link/n4659">N4659 Richard Smith: "Working Draft, Standard for Programming Language C++"</a>
</p>

<h2><a name="Akn"></a>Acknowledgements</h2>
<p>
Thanks to Jonathan Wakely and Billy Robert O'Neal III for a review of this proposal and for encouragement to make a little more
changes as I originally believed I should make.
</p>

</body></html>