This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of CD1 status.

654. Missing IO roundtrip for random number engines

Section: 29.5.3.4 [rand.req.eng] Status: CD1 Submitter: Daniel Krügler Opened: 2007-03-08 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [rand.req.eng].

View all issues with CD1 status.

Discussion:

Table 98 and para 5 in 29.5.3.4 [rand.req.eng] specify the IO insertion and extraction semantic of random number engines. It can be shown, v.i., that the specification of the extractor cannot guarantee to fulfill the requirement from para 5:

If a textual representation written via os << x was subsequently read via is >> v, then x == v provided that there have been no intervening invocations of x or of v.

The problem is, that the extraction process described in table 98 misses to specify that it will initially set the if.fmtflags to ios_base::dec, see table 104:

dec: converts integer input or generates integer output in decimal base

Proof: The following small program demonstrates the violation of requirements (exception safety not fulfilled):

#include <cassert>
#include <ostream>
#include <iostream>
#include <iomanip>
#include <sstream>

class RanNumEngine {
  int state;
public:
  RanNumEngine() : state(42) {}

  bool operator==(RanNumEngine other) const {
      return state == other.state;
  }

  template <typename Ch, typename Tr>
  friend std::basic_ostream<Ch, Tr>& operator<<(std::basic_ostream<Ch, Tr>& os, RanNumEngine engine) {
    Ch old = os.fill(os.widen(' ')); // Sets space character
    std::ios_base::fmtflags f = os.flags();
    os << std::dec << std::left << engine.state; // Adds ios_base::dec|ios_base::left
    os.fill(old); // Undo
    os.flags(f);
    return os;
  }

  template <typename Ch, typename Tr>
  friend std::basic_istream<Ch, Tr>& operator>>(std::basic_istream<Ch, Tr>& is, RanNumEngine& engine) {
       // Uncomment only for the fix.

    //std::ios_base::fmtflags f = is.flags();
    //is >> std::dec;
    is >> engine.state;
    //is.flags(f);
    return is;
  }
};

int main() {
    std::stringstream s;
    s << std::setfill('#'); // No problem
        s << std::oct; // Yikes!
        // Here starts para 5 requirements:
    RanNumEngine x;
    s << x;
    RanNumEngine v;
    s >> v;
    assert(x == v); // Fails: 42 == 34
}

A second, minor issue seems to be, that the insertion description from table 98 unnecessarily requires the addition of ios_base::fixed (which only influences floating-point numbers). Its not entirely clear to me whether the proposed standard does require that the state of random number engines is stored in integral types or not, but I have the impression that this is the indent, see e.g. p. 3

The specification of each random number engine defines the size of its state in multiples of the size of its result_type.

If other types than integrals are supported, then I wonder why no requirements are specified for the precision of the stream.

See N2391 and N2423 for some further discussion.

Proposed resolution:

Adopt the proposed resolution in N2423.

[ Kona (2007): The LWG adopted the proposed resolution of N2423 for this issue. The LWG voted to accelerate this issue to Ready status to be voted into the WP at Kona. ]

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy