Topic: The failures of iostreams


Author: Jason McKesson <jmckesson@gmail.com>
Date: Sat, 17 Nov 2012 11:36:34 -0800
Raw View
This is a multi-part message in MIME format.
--------------090300070501070807080901
Content-Type: text/plain; charset=ISO-8859-1; format=flowed

The Iostreams library in C++ has a problem. We have real, reasonable,
legitimate C++ professional, who like C++ and use modern C++ idioms,
telling people to not use iostreams. This is not due to differing ideas
on C++ or C-in-classes-style development, but the simple practical
realities of the situation.

This kind of thing is indicative of a real problem in iostreams. In
order to eventually solve that problem, we must first identify exactly
what the problems are. This discussion should be focused on exactly
that: identifying the problems with the library. Once we know what the
real problems are, we can be certain that any new system that is
proposed addresses them.

Note that this is about problems withiniostreams. This is not about a
list of things you /wish/ it could do. This is about what iostreams
actually tries to do but fails at in some way. So stuff like async file
IO doesn't go here, since iostreams doesn't try to provide that.

Feel free to add to this list other flaws you see in iostreams. Or if
you think that some of them are not real flaws, feel free to explain why.

Performance

This is the big one, generally the #1 reason why people suggest using
C-standard file IO rather than iostreams.

Oftentimes, when people defend iostreams performance, they will say
something to the effect of, "iostreams does far more than C-standard
file IO." And that's true. With iostreams, you have an extensible
mechanism for writing any type directly to a stream. You can "easily"
write new streambuf's that will allow you to (via runtime polymorphism)
be able to work with existing code, thus allowing you to leverage your
file IO for other forms of IO. You could even use a network pipe as an
input or output stream.

There's one real problem with this logic, and it is exactly why people
suggest C-standard file IO. Iostreams violates a fundamental precept of
C++: pay /only/ for what you use.

Consider this suite of benchmarks
<http://stackoverflow.com/questions/4340396/does-the-c-standard-mandate-poor-performance-for-iostreams-or-am-i-just-deali>.
This code doesn't do file IO; it writes directly to a string. All it's
doing is measuring the time it takes to append 4-characters to a string.
A lot. It uses a `char[]` as a useful control. It also tests the use of
`vector<char>` (presumably `basic_string` would have similar results).
Therefore, this is a solid test for the efficiency of the iostreams
codebase itself.

Obviously there will be some efficiency loss. But consider the numbers
in the results.

The ostringstream is more than full order of magnitudeslower than the
control. It's almost 100x in some cases. Note that it's not using << to
write to the stream; it's using `ostream::write()`.

Note that the vector<char> implementations are fairly comparable to the
control, usually being around 1x-4x the speed. So clearly this is
something in ostringstream.

Now, you might say that one could use the stringbuf directly. And that
was done. While it does improve performance over the ostringstream case
substantially (generally half to a quarter the performance), it's still
over 10x slower than the control or most vector<char> implementations.

Why? The stringbuf operations ought to be a thin wrapper over
std::string. After all, that's what was asked for.

Where does this inefficiency come from? I haven't done any extensive
profiling analysis, but my educated guesses are from two places: virtual
function overhead and an interface that does too much.

ostringstream is supposed to be able to be used as an ostream for
runtime-polymorphism. But here's where the C++ maxim comes into play.
Runtime-polymorphism is not being used here. Every function call should
be able to be statically dispatched. And it is, but all of the virtual
machinery comes from /within/ ostringstream.

This problem seems to come mostly from the fact that basic_ostream,
which does most of the leg-work for ostringstream, has no specific
knowledge of its stream type. Therefore it's always a virtual call. And
it may be doing many such virtual calls.

You can achieve the same runtime polymorphism (being able to overload
operator<< for any stream) by using a static set of stream classes,
tightly coupled to their specific streambufs, and a single "anystream"
type that those streams can be converted into. It would use
std::function-style type erasure to remember the original type and feed
function calls to it. It would use a single function call to initiate
each write operation, rather than what appears to be many virtual calls
within each write.

Then, there's the fact that streambuf itself is overdesigned. stringbuf
ought to be a simple interface wrapper around a std::string, but it's
not. It's a complex thing. It has locale supportof all things. Why?
Isn't that something that should be handled at the stream level?

This API has no way to get a low-level interface to a
file/string/whatever. There's no way to just open a filebuf and blast
the file into some memory, or to shove some memory out of a filebuf. It
will always employ the locale machinery even if you didn't ask for it.
It will always make these internal virtual calls, even if they are
completely statically dispatched.

With iostreams, you are paying for a lot of stuff that you don't
frequently use. At the stream level, it makes sense that you're paying
for certain machinery (though again, some way to say that you're not
using some of it would be nice). At the buffer level, it does not, since
that is the lowest level you're allowed to use.

Utility

While performance is the big issue, it's not the only one.

The biggest selling point for iostreams is the ability to extend its
formatted writing functionality. You can overload operator<< for various
types and simply use them. You can't do that with fprintf. And thanks to
ADL, it will work just fine for classes in namespaces. You can create
new streambuf types and even streams if you like. All relatively easily.

Here's the problem, and it is admittedly one that is subjective: printf
is really nice syntax.

It's very compact, for one. Once you understand the basic syntax of it,
it's very easy to see what's going on. Especially for complex
formatting. Just consider the physical size difference between these two:

snprintf(..., "0x%08x", integer);

stream << "0x" << std::right << std::hex << std::setw(8) << iVal << std::endl;

It may take a bit longer to become used to the printf version, but this
is something you can easily look up in a reference.

Plus, it makes it much easier to do translations on formatted strings.
You can look the pattern string up in a table that changes from language
to language. This is rather more difficult in iostreams, though not
impossible. Granted, pattern changes may not be enough, as some
languages have different subject/verb/object grammars that would require
reshuffling patterns around. However, there are printf-style systems
that do allow for reshuffling, whereas no such mechanism exists for
iostream-style.

C++ used the << method because the alternatives were less flexible.
Boost.Format and other systems show that C++03 did not really have to
use this mechanism to achieve the extensibility features that iostreams
provide.

What do you think? Are there other issues in iostreams that need to be
mentioned?

--




--------------090300070501070807080901
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<html>
  <head>

    <meta http-equiv=3D"content-type" content=3D"text/html; charset=3DISO-8=
859-1">
  </head>
  <body bgcolor=3D"#FFFFFF" text=3D"#000000">
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"
      id=3D"internal-source-marker_0.8014817711144224">The Iostreams
      library in C++ has a problem. We have real, reasonable, legitimate
      C++ professional, who like C++ and use modern C++ idioms, telling
      people to not use iostreams. This is not due to differing ideas on
      C++ or C-in-classes-style development, but the simple practical
      realities of the situation.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">This

      kind of thing is indicative of a real problem in iostreams. In
      order to eventually solve that problem, we must first identify
      exactly what the problems are. This discussion should be focused
      on exactly that: identifying the problems with the library. Once
      we know what the real problems are, we can be certain that any new
      system that is proposed addresses them.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">Note
      that this is about problems </span><span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:italic;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">within</span><span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">
      iostreams. This is not about a list of things you <i>wish</i> it
      could do. This is about what iostreams actually tries to do but
      fails at in some way. So stuff like async file IO doesn&#8217;t go he=
re,
      since iostreams doesn&#8217;t try to provide that.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">Feel

      free to add to this list other flaws you see in iostreams. Or if
      you think that some of them are not real flaws, feel free to
      explain why.</span><br>
    <p dir=3D"ltr"><span
style=3D"font-size:32px;font-family:Georgia;color:#666666;background-color:=
transparent;font-weight:normal;font-style:italic;font-variant:normal;text-d=
ecoration:none;vertical-align:baseline;">Performance</span></p>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">This
      is the big one, generally the #1 reason why people suggest using
      C-standard file IO rather than iostreams.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">Oftentimes,

      when people defend iostreams performance, they will say something
      to the effect of, &#8220;iostreams does far more than C-standard file
      IO.&#8221; And that&#8217;s true. With iostreams, you have an extensi=
ble
      mechanism for writing any type directly to a stream. You can
      &#8220;easily&#8221; write new streambuf&#8217;s that will allow you =
to (via runtime
      polymorphism) be able to work with existing code, thus allowing
      you to leverage your file IO for other forms of IO. You could even
      use a network pipe as an input or output stream.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">There&#8217;s

      one real problem with this logic, and it is exactly why people
      suggest C-standard file IO. Iostreams violates a fundamental
      precept of C++: pay <i>only</i> for what you </span><span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:italic;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">use</span><span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">Consider
    </span><a
href=3D"http://stackoverflow.com/questions/4340396/does-the-c-standard-mand=
ate-poor-performance-for-iostreams-or-am-i-just-deali"><span
style=3D"font-size:15px;font-family:Arial;color:#1155cc;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:underline;vertical-align:baseline;">this
        suite of benchmarks</span></a><span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">.
      This code doesn&#8217;t do file IO; it writes directly to a string. A=
ll
      it&#8217;s doing is measuring the time it takes to append 4-character=
s
      to a string. A lot. It uses a `char[]` as a useful control. It
      also tests the use of `vector&lt;char&gt;` (presumably
      `basic_string` would have similar results). Therefore, this is a
      solid test for the efficiency of the iostreams codebase itself.</span=
><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">Obviously
      there will be some efficiency loss. But consider the numbers in
      the results.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">The
      ostringstream is more than </span><span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:italic;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">full
      order of magnitude</span><span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">
      slower than the control. It&#8217;s almost 100x in some cases. Note t=
hat
      it&#8217;s not using &lt;&lt; to write to the stream; it&#8217;s usin=
g
      `ostream::write()`.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">Note

      that the vector&lt;char&gt; implementations are fairly comparable
      to the control, usually being around 1x-4x the speed. So clearly
      this is something in ostringstream.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">Now,

      you might say that one could use the stringbuf directly. And that
      was done. While it does improve performance over the ostringstream
      case substantially (generally half to a quarter the performance),
      it&#8217;s still over 10x slower than the control or most
      vector&lt;char&gt; implementations.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">Why?
      The stringbuf operations ought to be a thin wrapper over
      std::string. After all, that&#8217;s what was asked for.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">Where

      does this inefficiency come from? I haven&#8217;t done any extensive
      profiling analysis, but my educated guesses are from two places:
      virtual function overhead and an interface that does too much.</span>=
<br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">ostringstream

      is supposed to be able to be used as an ostream for
      runtime-polymorphism. But here&#8217;s where the C++ maxim comes into
      play. Runtime-polymorphism is </span><span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:italic;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">not
      being used here</span><span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">.
      Every function call should be able to be statically dispatched.
      And it is, but all of the virtual machinery comes from <i>within</i>
      ostringstream.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">This
      problem seems to come mostly from the fact that basic_ostream,
      which does most of the leg-work for ostringstream, has no specific
      knowledge of its stream type. Therefore it's always a virtual
      call. And it may be doing many such virtual calls.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">You

      can achieve the same runtime polymorphism (being able to overload
      operator&lt;&lt; for any stream) by using a static set of stream
      classes, tightly coupled to their specific streambufs, and a
      single &#8220;anystream&#8221; type that those streams can be convert=
ed into.
      It would use std::function-style type erasure to remember the
      original type and feed function calls to it. It would use a single
      function call to initiate each write operation, rather than what
      appears to be many virtual calls within each write.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">Then,

      there&#8217;s the fact that streambuf itself is overdesigned. stringb=
uf
      ought to be a simple interface wrapper around a std::string, but
      it&#8217;s not. It&#8217;s a complex thing. It has </span><span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:italic;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">locale
      support</span><span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">
      of all things. Why? Isn&#8217;t that something that should be handled=
 at
      the stream level?</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">This

      API has no way to get a low-level interface to a
      file/string/whatever. There&#8217;s no way to just open a filebuf and
      blast the file into some memory, or to shove some memory out of a
      filebuf. It will always employ the locale machinery even if you
      didn&#8217;t ask for it. It will always make these internal virtual
      calls, even if they are completely statically dispatched.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">With

      iostreams, you are paying for a lot of stuff that you don&#8217;t
      frequently use. At the stream level, it makes sense that you&#8217;re
      paying for certain machinery (though again, some way to say that
      you&#8217;re not using some of it would be nice). At the buffer level=
,
      it does not, since that is the lowest level you&#8217;re allowed to u=
se.</span><br>
    <p dir=3D"ltr"><span
style=3D"font-size:32px;font-family:Georgia;color:#666666;background-color:=
transparent;font-weight:normal;font-style:italic;font-variant:normal;text-d=
ecoration:none;vertical-align:baseline;">Utility</span></p>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">While
      performance is the big issue, it&#8217;s not the only one.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">The

      biggest selling point for iostreams is the ability to extend its
      formatted writing functionality. You can overload operator&lt;&lt;
      for various types and simply use them. You can&#8217;t do that with
      fprintf. And thanks to ADL, it will work just fine for classes in
      namespaces. You can create new streambuf types and even streams if
      you like. All relatively easily.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">Here&#8217;s
      the problem, and it is admittedly one that is subjective: printf
      is really nice syntax.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">It&#8217;s

      very compact, for one. Once you understand the basic syntax of it,
      it&#8217;s very easy to see what&#8217;s going on. Especially for com=
plex
      formatting. Just consider the physical size difference between
      these two:</span><br>
    <pre><tt><span style=3D"font-size: 15px; color: rgb(0, 0, 0); backgroun=
d-color: transparent; font-weight: normal; font-style: normal; font-variant=
: normal; text-decoration: none; vertical-align: baseline;">snprintf(..., &=
#8220;0x%08x&#8221;, integer);</span></tt></pre>
    <pre><tt><span style=3D"font-size: 15px; color: rgb(0, 0, 0); backgroun=
d-color: transparent; font-weight: normal; font-style: normal; font-variant=
: normal; text-decoration: none; vertical-align: baseline;"></span></tt></p=
re>
    <pre><tt><span style=3D"font-size: 15px; color: rgb(0, 0, 0); backgroun=
d-color: transparent; font-weight: normal; font-style: normal; font-variant=
: normal; text-decoration: none; vertical-align: baseline;">stream &lt;&lt;=
 "0x" &lt;&lt; std::right &lt;&lt; std::hex &lt;&lt; std::setw(8) &lt;&lt; =
iVal &lt;&lt; std::endl;</span></tt></pre>
    <pre><span style=3D"font-size:15px;font-family:Arial;color:#000000;back=
ground-color:transparent;font-weight:normal;font-style:normal;font-variant:=
normal;text-decoration:none;vertical-align:baseline;"></span></pre>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">It
      may take a bit longer to become used to the printf version, but
      this is something you can easily look up in a reference.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">Plus,

      it makes it much easier to do translations on formatted strings.
      You can look the pattern string up in a table that changes from
      language to language. This is rather more difficult in iostreams,
      though not impossible. Granted, pattern changes may not be enough,
      as some languages have different subject/verb/object grammars that
      would require reshuffling patterns around. However, there are
      printf-style systems that do allow for reshuffling, whereas no
      such mechanism exists for iostream-style.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">C++

      used the &lt;&lt; method because the alternatives were less
      flexible. Boost.Format and other systems show that C++03 did not
      really have to use this mechanism to achieve the extensibility
      features that iostreams provide.</span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><br>
    <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;"></span><span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tr=
ansparent;font-weight:normal;font-style:normal;font-variant:normal;text-dec=
oration:none;vertical-align:baseline;">What
      do you think? Are there other issues in iostreams that need to be
      mentioned?</span><br>
  </body>
</html>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--------------090300070501070807080901--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Sat, 17 Nov 2012 14:03:09 -0600
Raw View
--f46d0402dd78f5560f04ceb6618b
Content-Type: text/plain; charset=ISO-8859-1

On 17 November 2012 13:36, Jason McKesson <jmckesson@gmail.com> wrote:

> C++ used the << method because the alternatives were less flexible.
> Boost.Format and other systems show that C++03 did not really have to use
> this mechanism to achieve the extensibility features that iostreams provide.
>

Boost.Format came out in 2002.  C++03 (which is basically C++98) was
standardized in the 90s.  Short of building a time machine, I fail to see
how Boost.Format showed C++03 anything.


> What do you think? Are there other issues in iostreams that need to be
> mentioned?
>

Not really, no.  Ragging on iostreams is easy, and has been done plenty of
times already.  Coming up with a proposal to replace it is hard and time
consuming.  I don't see any proposal here.  Are you looking to write one?
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--




--f46d0402dd78f5560f04ceb6618b
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On 17 November 2012 13:36, Jason McKesson <span dir=3D"ltr">&lt;<a href=3D"=
mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>&gt;</=
span> wrote:<br><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote=
" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


 =20

   =20
 =20
  <div bgcolor=3D"#FFFFFF" text=3D"#000000"><span style=3D"vertical-align:b=
aseline;font-variant:normal;font-style:normal;font-size:15px;background-col=
or:transparent;text-decoration:none;font-family:Arial;font-weight:normal">C=
++

      used the &lt;&lt; method because the alternatives were less
      flexible. Boost.Format and other systems show that C++03 did not
      really have to use this mechanism to achieve the extensibility
      features that iostreams provide.</span></div></blockquote><div><br></=
div><div>Boost.Format came out in 2002. =A0C++03 (which is basically C++98)=
 was standardized in the 90s. =A0Short of building a time machine, I fail t=
o see how Boost.Format showed C++03 anything.=A0</div>

<div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div bgcolor=3D"#FFFFFF" text=
=3D"#000000">
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><span style=3D"vertical-align:base=
line;font-variant:normal;font-style:normal;font-size:15px;background-color:=
transparent;text-decoration:none;font-family:Arial;font-weight:normal">What
      do you think? Are there other issues in iostreams that need to be
      mentioned?</span></div></blockquote><div><br></div><div>Not really, n=
o. =A0Ragging on iostreams is easy, and has been done plenty of times alrea=
dy. =A0Coming up with a proposal to replace it is hard and time consuming. =
=A0I don&#39;t see any proposal here. =A0Are you looking to write one?</div=
>

</div>-- <br>=A0Nevin &quot;:-)&quot; Liber=A0 &lt;mailto:<a href=3D"mailto=
:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a>&gt;=
=A0 (847) 691-1404<br>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--f46d0402dd78f5560f04ceb6618b--

.


Author: =?ISO-8859-1?Q?Lo=EFc_Joly?= <loic.actarus.joly@numericable.fr>
Date: Sat, 17 Nov 2012 21:08:19 +0100
Raw View
Le 17/11/2012 20:36, Jason McKesson a =C3=A9crit :
> The Iostreams library in C++ has a problem. We have real, reasonable,=20
> legitimate C++ professional, who like C++ and use modern C++ idioms,=20
> telling people to not use iostreams. This is not due to differing=20
> ideas on C++ or C-in-classes-style development, but the simple=20
> practical realities of the situation.
>

There are mostly two points where I disagree with your analysis:
- Performance: I performances really matter, granted, I will not use=20
iostream, but I will not use C I/O facilities either. I will use=20
platform specific API that can deliver maximum performance.

- Usability: I find printf format really hard to use (and very error=20
prone). It's another language, and an obscure one. I genuinely have no=20
idea what 0x%08x meant in your message. I was not even sure if it=20
expected one argument or several. But this is not my main point. My main=20
point is that your comparison is unfair: Most of the time, when doing=20
I/O, I don't care about format (when I care, then I use a UI library=20
such as Qt, or I generate HTML, or LaTeX, or whatever, but I don't use=20
iostream). And in this case, iostream are not more verbose:

os << "Line " << line << ": Error(" << code << "): " << msg;
printf("Line %??: Error(%??): %??", line, code, msg);

The difference is not that big, even when using only basic types (and,=20
as you said, the difference is in the other direction when dealing with=20
user defined types).

For me, the biggest issue I have with iostream is localisation, and the=20
possibility to have a whole sentence in one block, and to be able to=20
swap arguments. And boost format really helps here.

--=20
Lo=C4=8Fc

--=20




.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 17 Nov 2012 12:13:07 -0800 (PST)
Raw View
------=_Part_563_23310816.1353183187169
Content-Type: text/plain; charset=ISO-8859-1



On Saturday, November 17, 2012 12:03:52 PM UTC-8, Nevin ":-)" Liber wrote:
>
> On 17 November 2012 13:36, Jason McKesson <jmck...@gmail.com <javascript:>
> > wrote:
>
>> C++ used the << method because the alternatives were less flexible.
>> Boost.Format and other systems show that C++03 did not really have to use
>> this mechanism to achieve the extensibility features that iostreams provide.
>>
>
> Boost.Format came out in 2002.  C++03 (which is basically C++98) was
> standardized in the 90s.  Short of building a time machine, I fail to see
> how Boost.Format showed C++03 anything.
>

My point being that Boost.Format was *possible*, so it could have been
done. That is, we didn't need variadic templates or other C++11 features to
be able to have this functionality.


>  What do you think? Are there other issues in iostreams that need to be
>> mentioned?
>>
>
> Not really, no.  Ragging on iostreams is easy, and has been done plenty of
> times already.  Coming up with a proposal to replace it is hard and time
> consuming.  I don't see any proposal here.  Are you looking to write one?
>

Did you read the intro section of the post, where I state that writing a
proposal first requires collecting the problems? You're kinda missing the
point here. You have to figure out what went wrong *before* you can fix it.
Otherwise, you're likely to create more problems by missing something
important.


> --
>  Nevin ":-)" Liber  <mailto:ne...@eviloverlord.com <javascript:>>  (847)
> 691-1404
>

--




------=_Part_563_23310816.1353183187169
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br>On Saturday, November 17, 2012 12:03:52 PM UTC-8, Nevin ":-)" Liber=
 wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 17 November 2012 13:=
36, Jason McKesson <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"=
_blank" gdf-obfuscated-mailto=3D"Q1kuCwBNFWMJ">jmck...@gmail.com</a>&gt;</s=
pan> wrote:<br><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote"=
 style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


 =20

   =20
 =20
  <div bgcolor=3D"#FFFFFF" text=3D"#000000"><span style=3D"vertical-align:b=
aseline;font-variant:normal;font-style:normal;font-size:15px;background-col=
or:transparent;text-decoration:none;font-family:Arial;font-weight:normal">C=
++

      used the &lt;&lt; method because the alternatives were less
      flexible. Boost.Format and other systems show that C++03 did not
      really have to use this mechanism to achieve the extensibility
      features that iostreams provide.</span></div></blockquote><div><br></=
div><div>Boost.Format came out in 2002. &nbsp;C++03 (which is basically C++=
98) was standardized in the 90s. &nbsp;Short of building a time machine, I =
fail to see how Boost.Format showed C++03 anything.&nbsp;</div></div></bloc=
kquote><div><br>My point being that Boost.Format was <i>possible</i>, so it=
 could have been done. That is, we didn't need variadic templates or other =
C++11 features to be able to have this functionality.<br>&nbsp;</div><block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><div class=3D"gmail_quote">

<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div bgcolor=3D"#FFFFFF" text=3D"#000000">
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><span style=3D"vertical-align:base=
line;font-variant:normal;font-style:normal;font-size:15px;background-color:=
transparent;text-decoration:none;font-family:Arial;font-weight:normal">What
      do you think? Are there other issues in iostreams that need to be
      mentioned?</span></div></blockquote><div><br></div><div>Not really, n=
o. &nbsp;Ragging on iostreams is easy, and has been done plenty of times al=
ready. &nbsp;Coming up with a proposal to replace it is hard and time consu=
ming. &nbsp;I don't see any proposal here. &nbsp;Are you looking to write o=
ne?</div></div></blockquote><div><br>Did you read the intro section of the =
post, where I state that writing a proposal first requires collecting the p=
roblems? You're kinda missing the point here. You have to figure out what w=
ent wrong <i>before</i> you can fix it. Otherwise, you're likely to create =
more problems by missing something important.<br>&nbsp;</div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px =
#ccc solid;padding-left: 1ex;"><div class=3D"gmail_quote">

</div>-- <br>&nbsp;Nevin ":-)" Liber&nbsp; &lt;mailto:<a href=3D"javascript=
:" target=3D"_blank" gdf-obfuscated-mailto=3D"Q1kuCwBNFWMJ">ne...@eviloverl=
ord.com</a><wbr>&gt;&nbsp; (847) 691-1404<br>
</blockquote>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_563_23310816.1353183187169--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 17 Nov 2012 12:50:26 -0800 (PST)
Raw View
------=_Part_259_646845.1353185426364
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable



On Saturday, November 17, 2012 12:08:20 PM UTC-8, Lo=EFc Joly wrote:
>
> Le 17/11/2012 20:36, Jason McKesson a =EF=BF=BDcrit :=20
> > The Iostreams library in C++ has a problem. We have real, reasonable,=
=20
> > legitimate C++ professional, who like C++ and use modern C++ idioms,=20
> > telling people to not use iostreams. This is not due to differing=20
> > ideas on C++ or C-in-classes-style development, but the simple=20
> > practical realities of the situation.=20
> >=20
>
> There are mostly two points where I disagree with your analysis:=20
> - Performance: I performances really matter, granted, I will not use=20
> iostream, but I will not use C I/O facilities either. I will use=20
> platform specific API that can deliver maximum performance.
>

I would consider this something of a non-sequitor. Yes, one can always run=
=20
to the OS facilities if one wants maximum performance. That is not an=20
excuse for iostream's performance however (and the fact that you do so is=
=20
indicative of the exact problem I state).

There's a big difference between "maximum performance", "reasonable=20
performance", and "iostreams performance". The difference between=20
vector<char> and writing to a char[] is "reasonable performance." It's an=
=20
abstraction, but it's a tight one that can work out well if your compiler=
=20
is good. The difference between iostreams (especially stringbuf) and=20
vector<char> is *utterly inexcusable*. There is no reason for such a=20
massive performance difference to exist between those cases.

I again remind you of the C++ maxim: pay only for what you use. You=20
shouldn't have to leave performance on the table unless you're doing=20
something that *requires* that loss of performance. C-standard file IO=20
offers *reasonable* performance relative to the OS facilities; why *
shouldn't* iostreams? Isn't that what one should expect from standard=20
library facilities, to offer a wrapper around the OS that is reasonably=20
thin?

You don't see people ditching operator new just to get reasonable=20
allocation performance. Even if they want to write their own allocation=20
system based on the OS specifics, they'll still hook it into operator new.

However, you rarely see people write a file IO system built on OS specifics=
=20
and then build a streambuf-derived class to use it with iostreams. There's=
=20
a reason for that.

Iostreams should be someone that people should *want* to use for=20
platform-neutral development. That's my point, and it's performance makes=
=20
people want to use other things.

- Usability: I find printf format really hard to use (and very error=20
> prone). It's another language, and an obscure one. I genuinely have no=20
> idea what 0x%08x meant in your message. I was not even sure if it=20
> expected one argument or several. But this is not my main point. My main=
=20
> point is that your comparison is unfair: Most of the time, when doing=20
> I/O, I don't care about format


That's nice that you don't have to. Some people do, a lot. Their use cases=
=20
should not be ignored.

My comparison came from actual use. There are plenty of times when I have=
=20
needed to look at a 32-bit integer output as a hexadecimal number. And=20
iostreams makes that incredibly difficult, while printf makes it incredibly=
=20
easy.
=20

> (when I care, then I use a UI library=20
> such as Qt, or I generate HTML, or LaTeX, or whatever, but I don't use=20
> iostream)


Isn't that indicative of a failure in iostreams? That if you need to write=
=20
hexadecimal numbers, you bring in Qt/HTML/LaTeX (I really don't know what=
=20
LaTeX is doing there), rather than using standard library features.=20
Remember: we're not talking about visual formatting; this is pure text=20
stuff. This is "I want the integer to be hexadecimal" or "I want the float=
=20
to only have 2 decimal digits."

You shouldn't have to run screaming to Qt whenever you want to do that in a=
=20
reasonable way.
=20

> . And in this case, iostream are not more verbose:=20
>
> os << "Line " << line << ": Error(" << code << "): " << msg;=20
> printf("Line %??: Error(%??): %??", line, code, msg);=20
>
> The difference is not that big, even when using only basic types (and,=20
> as you said, the difference is in the other direction when dealing with=
=20
> user defined types).=20
>
> For me, the biggest issue I have with iostream is localisation, and the=
=20
> possibility to have a whole sentence in one block, and to be able to=20
> swap arguments. And boost format really helps here.=20
>
> --=20
> Lo=EF=BF=BDc=20
>
>

--=20




------=_Part_259_646845.1353185426364
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br>On Saturday, November 17, 2012 12:08:20 PM UTC-8, Lo=EFc Joly wrote=
:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bo=
rder-left: 1px #ccc solid;padding-left: 1ex;">Le 17/11/2012 20:36, Jason Mc=
Kesson a =EF=BF=BDcrit :
<br>&gt; The Iostreams library in C++ has a problem. We have real, reasonab=
le,=20
<br>&gt; legitimate C++ professional, who like C++ and use modern C++ idiom=
s,=20
<br>&gt; telling people to not use iostreams. This is not due to differing=
=20
<br>&gt; ideas on C++ or C-in-classes-style development, but the simple=20
<br>&gt; practical realities of the situation.
<br>&gt;
<br>
<br>There are mostly two points where I disagree with your analysis:
<br>- Performance: I performances really matter, granted, I will not use=20
<br>iostream, but I will not use C I/O facilities either. I will use=20
<br>platform specific API that can deliver maximum performance.<br></blockq=
uote><div><br>I would consider this something of a non-sequitor. Yes, one c=
an always run to the OS facilities if one wants maximum performance. That i=
s not an excuse for iostream's performance however (and the fact that you d=
o so is indicative of the exact problem I state).<br><br>There's a big diff=
erence between "maximum performance", "reasonable performance", and "iostre=
ams performance". The difference between vector&lt;char&gt; and writing to =
a char[] is "reasonable performance." It's an abstraction, but it's a tight=
 one that can work out well if your compiler is good. The difference betwee=
n iostreams (especially stringbuf) and vector&lt;char&gt; is <i>utterly ine=
xcusable</i>. There is no reason for such a massive performance difference =
to exist between those cases.<br><br>I again remind you of the C++ maxim: p=
ay only for what you use. You shouldn't have to leave performance on the ta=
ble unless you're doing something that <i>requires</i> that loss of perform=
ance. C-standard file IO offers <i>reasonable</i> performance relative to t=
he OS facilities; why <i>shouldn't</i> iostreams? Isn't that what one shoul=
d expect from standard library facilities, to offer a wrapper around the OS=
 that is reasonably thin?<br><br>You don't see people ditching operator new=
 just to get reasonable allocation performance. Even if they want to write =
their own allocation system based on the OS specifics, they'll still hook i=
t into operator new.<br><br>However, you rarely see people write a file IO =
system built on OS specifics and then build a streambuf-derived class to us=
e it with iostreams. There's a reason for that.<br><br>Iostreams should be =
someone that people should <i>want</i> to use for platform-neutral developm=
ent. That's my point, and it's performance makes people want to use other t=
hings.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
- Usability: I find printf format really hard to use (and very error=20
<br>prone). It's another language, and an obscure one. I genuinely have no=
=20
<br>idea what 0x%08x meant in your message. I was not even sure if it=20
<br>expected one argument or several. But this is not my main point. My mai=
n=20
<br>point is that your comparison is unfair: Most of the time, when doing=
=20
<br>I/O, I don't care about format</blockquote><div><br>That's nice that yo=
u don't have to. Some people do, a lot. Their use cases should not be ignor=
ed.<br><br>My comparison came from actual use. There are plenty of times wh=
en I have needed to look at a 32-bit integer output as a hexadecimal number=
.. And iostreams makes that incredibly difficult, while printf makes it incr=
edibly easy.<br>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">(w=
hen I care, then I use a UI library=20
<br>such as Qt, or I generate HTML, or LaTeX, or whatever, but I don't use=
=20
<br>iostream)</blockquote><div><br>Isn't that indicative of a failure in io=
streams? That if you need to write hexadecimal numbers, you bring in Qt/HTM=
L/LaTeX (I really don't know what LaTeX is doing there), rather than using =
standard library features. Remember: we're not talking about visual formatt=
ing; this is pure text stuff. This is "I want the integer to be hexadecimal=
" or "I want the float to only have 2 decimal digits."<br><br>You shouldn't=
 have to run screaming to Qt whenever you want to do that in a reasonable w=
ay.<br>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">. And in th=
is case, iostream are not more verbose:
<br>
<br>os &lt;&lt; "Line " &lt;&lt; line &lt;&lt; ": Error(" &lt;&lt; code &lt=
;&lt; "): " &lt;&lt; msg;
<br>printf("Line %??: Error(%??): %??", line, code, msg);
<br>
<br>The difference is not that big, even when using only basic types (and,=
=20
<br>as you said, the difference is in the other direction when dealing with=
=20
<br>user defined types).
<br>
<br>For me, the biggest issue I have with iostream is localisation, and the=
=20
<br>possibility to have a whole sentence in one block, and to be able to=20
<br>swap arguments. And boost format really helps here.
<br>
<br>--=20
<br>Lo=EF=BF=BDc
<br>
<br></blockquote>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_259_646845.1353185426364--

.


Author: =?ISO-8859-1?Q?Lo=EFc_Joly?= <loic.actarus.joly@numericable.fr>
Date: Sat, 17 Nov 2012 22:32:22 +0100
Raw View
Le 17/11/2012 21:50, Nicol Bolas a =E9crit :
>
>
>     (when I care, then I use a UI library
>     such as Qt, or I generate HTML, or LaTeX, or whatever, but I don't
>     use
>     iostream)
>
>
> Isn't that indicative of a failure in iostreams? That if you need to=20
> write hexadecimal numbers, you bring in Qt/HTML/LaTeX (I really don't=20
> know what LaTeX is doing there), rather than using standard library=20
> features. Remember: we're not talking about visual formatting; this is=20
> pure text stuff. This is "I want the integer to be hexadecimal" or "I=20
> want the float to only have 2 decimal digits."
>
I may have been misunderstood here. What I was saying is that if I want=20
visual formatting, I will anyway use other libraries than iostream. And=20
if I don't want visual formatting, but pure text, then I usually don't=20
care if floats have 2, 6 or 12 decimal digits.

There is another point where I believe iostreams are weak, it's=20
encoding. There is the codecvt facet that can be used, but I find it not=20
really easy to use. Moreover, I'd like to open a file and let the system=20
automatically detect its format (using BOM, or maybe other heuristics)=20
and allow me to directly read from it into my internal format.

--=20
Lo=EFc



--=20




.


Author: =?ISO-8859-1?Q?V=E1clav_Zeman?= <vhaisman@gmail.com>
Date: Sat, 17 Nov 2012 23:34:03 +0100
Raw View
This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
--------------enig1B64C79C16F23B7D09F55C8E
Content-Type: multipart/alternative;
 boundary="------------000603040209040803000603"

This is a multi-part message in MIME format.
--------------000603040209040803000603
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On 11/17/2012 08:36 PM, Jason McKesson wrote:
> The Iostreams library in C++ has a problem. We have real, reasonable,
> legitimate C++ professional, who like C++ and use modern C++ idioms,
> telling people to not use iostreams. This is not due to differing
> ideas on C++ or C-in-classes-style development, but the simple
> practical realities of the situation.
>
> This kind of thing is indicative of a real problem in iostreams. In
> order to eventually solve that problem, we must first identify exactly
> what the problems are. This discussion should be focused on exactly
> that: identifying the problems with the library. Once we know what the
> real problems are, we can be certain that any new system that is
> proposed addresses them.
>
> Note that this is about problems withiniostreams. This is not about a
> list of things you /wish/ it could do. This is about what iostreams
> actually tries to do but fails at in some way. So stuff like async
> file IO doesn't go here, since iostreams doesn't try to provide that.
>
> Feel free to add to this list other flaws you see in iostreams. Or if
> you think that some of them are not real flaws, feel free to explain wh=
y.
[...]
> What do you think? Are there other issues in iostreams that need to be
> mentioned?

First, I do not consider myself C++ IO streams expert, rather an
advanced user. I agree that current C++ IO streams have some problems.

*Performance*
I have never needed that much performance that I would have to not use
C++ IO streams to get the performance. Thus, I do not consider
performance an issue with the current IO streams except for
std::stringstream et al. I think that it is a failure in design that
getting the string out of the stringstream is by value. Second, that the
only way to reset the stream easily is to call 'stream.str("")' or
'stream.str(std::string())'. There should be some sort of 'clear()' like
member function.

*Problematic cases*
Here are some use cases and experiences where I think the current C++ IO
streams are lacking or failing.

Recently, I have decided that I wanted to read (on Windows with MSVC)
UTF-16 or UTF-32 text files using wchar_t variants of file IO streams.
Now, to get that with C++11 I have to imbue the streams with one of
codecvt_utf{16,32} facets. So far that's ok and understandable. What I
consider a failure in design is that to actually get it working, I have
to open files in binary mode. Opening the file in binary mode means that
the stream will stop translating DOS/*NIX EOLs. Clearly, IMHO, the EOLs
and encoding are two separate issues, or should be. Maybe locale should
also have some sort of EOL facet to do this?

Second problem I consider important is that writing own streambufs is
exceptionally hard. This seems to be because both the semantics and
names of streambuf's member functions are bizarre.

*Possible solution?*
On few occasions, I have used Boost.IOStreams. Their abstractions and
categories of streams are richer than what standard C++ IO streams offer
and they have worked for me well enough, certainly better than raw
streams, in some situations. Especially the 'stream' and 'stream_buffer'
class templates are extremely useful. Implementing own stream and
stream_buf on to of Device concept using these two templates is rather
easy. Filtering stream with chain of filters is another very useful conce=
pt.

If Boost.IOStreams are not directly usable to be adopted as a standard
library, then at least they can server as an example of successful
library, IMHO, from which anybody who would like to improve existing C++
IO streams should learn.

If nothing else could be accepted from the library, just the stream and
the stream_buffer classes alone (with the necessary support
classes/code) would be a huge improvement to standard C++ IO streams.

HTH,

--=20
VZ


--------------000603040209040803000603
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<html>
  <head>
    <meta content=3D"text/html; charset=3DISO-8859-1"
      http-equiv=3D"Content-Type">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"moz-cite-prefix">On 11/17/2012 08:36 PM, Jason McKesson=

      wrote:<br>
    </div>
    <blockquote cite=3D"mid:50A7E742.7030702@gmail.com" type=3D"cite">
      <meta http-equiv=3D"content-type" content=3D"text/html;
        charset=3DISO-8859-1">
      <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:=
transparent;font-weight:normal;font-style:normal;font-variant:normal;text=
-decoration:none;vertical-align:baseline;"
        id=3D"internal-source-marker_0.8014817711144224">The Iostreams
        library in C++ has a problem. We have real, reasonable,
        legitimate C++ professional, who like C++ and use modern C++
        idioms, telling people to not use iostreams. This is not due to
        differing ideas on C++ or C-in-classes-style development, but
        the simple practical realities of the situation.</span><br>
      <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:=
transparent;font-weight:normal;font-style:normal;font-variant:normal;text=
-decoration:none;vertical-align:baseline;"></span><br>
      <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:=
transparent;font-weight:normal;font-style:normal;font-variant:normal;text=
-decoration:none;vertical-align:baseline;">This


        kind of thing is indicative of a real problem in iostreams. In
        order to eventually solve that problem, we must first identify
        exactly what the problems are. This discussion should be focused
        on exactly that: identifying the problems with the library. Once
        we know what the real problems are, we can be certain that any
        new system that is proposed addresses them.</span><br>
      <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:=
transparent;font-weight:normal;font-style:normal;font-variant:normal;text=
-decoration:none;vertical-align:baseline;"></span><br>
      <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:=
transparent;font-weight:normal;font-style:normal;font-variant:normal;text=
-decoration:none;vertical-align:baseline;">Note

        that this is about problems </span><span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:=
transparent;font-weight:normal;font-style:italic;font-variant:normal;text=
-decoration:none;vertical-align:baseline;">within</span><span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:=
transparent;font-weight:normal;font-style:normal;font-variant:normal;text=
-decoration:none;vertical-align:baseline;">
        iostreams. This is not about a list of things you <i>wish</i>
        it could do. This is about what iostreams actually tries to do
        but fails at in some way. So stuff like async file IO doesn&#8217=
;t go
        here, since iostreams doesn&#8217;t try to provide that.</span><b=
r>
      <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:=
transparent;font-weight:normal;font-style:normal;font-variant:normal;text=
-decoration:none;vertical-align:baseline;"></span><br>
      <span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:=
transparent;font-weight:normal;font-style:normal;font-variant:normal;text=
-decoration:none;vertical-align:baseline;">Feel


        free to add to this list other flaws you see in iostreams. Or if
        you think that some of them are not real flaws, feel free to
        explain why.</span><br>
    </blockquote>
    [...]<br>
    <blockquote cite=3D"mid:50A7E742.7030702@gmail.com" type=3D"cite"> <s=
pan
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:=
transparent;font-weight:normal;font-style:normal;font-variant:normal;text=
-decoration:none;vertical-align:baseline;"></span><span
style=3D"font-size:15px;font-family:Arial;color:#000000;background-color:=
transparent;font-weight:normal;font-style:normal;font-variant:normal;text=
-decoration:none;vertical-align:baseline;">What

        do you think? Are there other issues in iostreams that need to
        be mentioned?</span><br>
    </blockquote>
    <br>
    First, I do not consider myself C++ IO streams expert, rather an
    advanced user. I agree that current C++ IO streams have some
    problems.<br>
    <br>
    <b>Performance</b><br>
    I have never needed that much performance that I would have to not
    use C++ IO streams to get the performance. Thus, I do not consider
    performance an issue with the current IO streams except for
    std::stringstream et al. I think that it is a failure in design that
    getting the string out of the stringstream is by value. Second, that
    the only way to reset the stream easily is to call 'stream.str("")'
    or 'stream.str(std::string())'. There should be some sort of
    'clear()' like member function.<br>
    <br>
    <b>Problematic cases</b><br>
    Here are some use cases and experiences where I think the current
    C++ IO streams are lacking or failing.<br>
    <br>
    Recently, I have decided that I wanted to read (on Windows with
    MSVC) UTF-16 or UTF-32 text files using wchar_t variants of file IO
    streams. Now, to get that with C++11 I have to imbue the streams
    with one of codecvt_utf{16,32} facets. So far that's ok and
    understandable. What I consider a failure in design is that to
    actually get it working, I have to open files in binary mode.
    Opening the file in binary mode means that the stream will stop
    translating DOS/*NIX EOLs. Clearly, IMHO, the EOLs and encoding are
    two separate issues, or should be. Maybe locale should also have
    some sort of EOL facet to do this?<br>
    <br>
    Second problem I consider important is that writing own streambufs
    is exceptionally hard. This seems to be because both the semantics
    and names of streambuf's member functions are bizarre.<br>
    <br>
    <b>Possible solution?</b><br>
    On few occasions, I have used Boost.IOStreams. Their abstractions
    and categories of streams are richer than what standard C++ IO
    streams offer and they have worked for me well enough, certainly
    better than raw streams, in some situations. Especially the 'stream'
    and 'stream_buffer' class templates are extremely useful.
    Implementing own stream and stream_buf on to of Device concept using
    these two templates is rather easy. Filtering stream with chain of
    filters is another very useful concept.<br>
    <br>
    If Boost.IOStreams are not directly usable to be adopted as a
    standard library, then at least they can server as an example of
    successful library, IMHO, from which anybody who would like to
    improve existing C++ IO streams should learn.<br>
    <br>
    If nothing else could be accepted from the library, just the stream
    and the stream_buffer classes alone (with the necessary support
    classes/code) would be a huge improvement to standard C++ IO
    streams.<br>
    <br>
    HTH,<br>
    <br>
    -- <br>
    VZ<br>
    <br>
  </body>
</html>

--------------000603040209040803000603--

--------------enig1B64C79C16F23B7D09F55C8E
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.17 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://www.enigmail.net/

iF4EAREIAAYFAlCoENsACgkQ6OWUyaYNY6M6EwD+MlTi4v7jTBs8Mm6MVM1x036p
TOU5303ehU4gjqP4DrwA/2Uc55DrsHCdtLMAevCjLBWiMEsnzXMGGQnV7qJoT46l
=jVyp
-----END PGP SIGNATURE-----

--------------enig1B64C79C16F23B7D09F55C8E--

.


Author: Beman Dawes <bdawes@acm.org>
Date: Sat, 17 Nov 2012 18:03:25 -0500
Raw View
On Sat, Nov 17, 2012 at 2:36 PM, Jason McKesson <jmckesson@gmail.com> wrote:

> ...
> The Iostreams library in C++ has a problem.

Um... I suspect most of the LWG believes iostreams has far more than
one problem.

> What do you think? Are there other issues in iostreams that need to be
> mentioned?

You might want to ask Herb Sutter for his list of problems with
iostreams. IIRC, there are eight or ten issues on his list, and he
believes a C++11 version of Boost.Format, or something similar, would
solve a lot of them. But best to ask him directly.

This mailing list is a good place to float an idea about your library,
as mentioned in http://isocpp.org/std/submit-a-proposal

But the assumption was that you had an existing library you wanted to
float for possible standardization, not just a wish-list and some
ideas about a possible future library.

As has been noted many times by many LWG members, the problem with
libraries that don't exist yet is that they are inevitably presented
as far superior to existing libraries for the problem domain. And if
someone raises an issue with the not-yet-existing library, the
response is often that the issue will be easy to fix. So of course
everyone would love to have this wondrous library for the standard!
But only If it ever gets implemented, documented, used, refined, and
matures into something useful, and someone writes an actual proposal
document.

--Beman

--




.


Author: Martinho Fernandes <martinho.fernandes@gmail.com>
Date: Sun, 18 Nov 2012 00:20:12 +0100
Raw View
--047d7b33d1a67e869504ceb92196
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On Sat, Nov 17, 2012 at 11:34 PM, V=E1clav Zeman <vhaisman@gmail.com> wrote=
:

>  On 11/17/2012 08:36 PM, Jason McKesson wrote:
> I think that it is a failure in design that getting the string out of the
> stringstream is by value.
>

I think getting the string by value is the correct design. What I think is
missing is to make str() have lvalue and rvalue ref-qualified overloads so
you can get it out of a temporary stringstream with a move, or even write
std::move(some_stringstream).str() and "move a string out", but stealing
the buffer from the underlying stringbuf.

Martinho

--=20




--047d7b33d1a67e869504ceb92196
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On Sat, Nov 17, 2012 at 11:34 PM, V=E1clav Zeman <span dir=3D"ltr">&lt;<a h=
ref=3D"mailto:vhaisman@gmail.com" target=3D"_blank">vhaisman@gmail.com</a>&=
gt;</span> wrote:<br><div class=3D"gmail_quote"><blockquote class=3D"gmail_=
quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1=
ex">


 =20
   =20
 =20
  <div text=3D"#000000" bgcolor=3D"#FFFFFF"><div class=3D"im">
    <div>On 11/17/2012 08:36 PM, Jason McKesson
      wrote:<br>
    </div>I think that it is a failure in design that
    getting the string out of the stringstream is by value.</div></div></bl=
ockquote><div text=3D"#000000" bgcolor=3D"#FFFFFF"><br>I think getting the =
string by value is the correct design. What I think is missing is to make s=
tr() have lvalue and rvalue ref-qualified overloads so you can get it out o=
f a temporary stringstream with a move, or even write std::move(some_string=
stream).str() and &quot;move a string out&quot;, but stealing the buffer fr=
om the underlying stringbuf.<br>

<br clear=3D"all">Martinho<span class=3D"HOEnZb"></span><br></div></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--047d7b33d1a67e869504ceb92196--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 17 Nov 2012 15:21:22 -0800 (PST)
Raw View
------=_Part_5_31319013.1353194482554
Content-Type: text/plain; charset=ISO-8859-1



On Saturday, November 17, 2012 3:03:28 PM UTC-8, Beman Dawes wrote:
>
> On Sat, Nov 17, 2012 at 2:36 PM, Jason McKesson <jmck...@gmail.com<javascript:>>
> wrote:
>
> > ...
> > The Iostreams library in C++ has a problem.
>
> Um... I suspect most of the LWG believes iostreams has far more than
> one problem.
>
> > What do you think? Are there other issues in iostreams that need to be
> > mentioned?
>
> You might want to ask Herb Sutter for his list of problems with
> iostreams. IIRC, there are eight or ten issues on his list, and he
> believes a C++11 version of Boost.Format, or something similar, would
> solve a lot of them. But best to ask him directly.
>
> This mailing list is a good place to float an idea about your library,
> as mentioned in http://isocpp.org/std/submit-a-proposal
>
> But the assumption was that you had an existing library you wanted to
> float for possible standardization, not just a wish-list and some
> ideas about a possible future library.
>
> As has been noted many times by many LWG members, the problem with
> libraries that don't exist yet is that they are inevitably presented
> as far superior to existing libraries for the problem domain. And if
> someone raises an issue with the not-yet-existing library, the
> response is often that the issue will be easy to fix. So of course
> everyone would love to have this wondrous library for the standard!
> But only If it ever gets implemented, documented, used, refined, and
> matures into something useful, and someone writes an actual proposal
> document.
>
> --Beman
>

The main purpose of this thread is to collect a list of legitimate
grievances towards iostreams. That way, when someone writes or submits a
proposal, we can check it against the list and know how well it's doing.
Even better, if I (or anyone reading this) were inclined to write such a
library and a proposal, it would help guide my interface to know what the
major issues that need resolving are.

--




------=_Part_5_31319013.1353194482554
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br>On Saturday, November 17, 2012 3:03:28 PM UTC-8, Beman Dawes wrote:=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;">On Sat, Nov 17, 2012 at 2:36 P=
M, Jason McKesson &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfusca=
ted-mailto=3D"KjndDPIbb-AJ">jmck...@gmail.com</a>&gt; wrote:
<br>
<br>&gt; ...
<br>&gt; The Iostreams library in C++ has a problem.
<br>
<br>Um... I suspect most of the LWG believes iostreams has far more than
<br>one problem.
<br>
<br>&gt; What do you think? Are there other issues in iostreams that need t=
o be
<br>&gt; mentioned?
<br>
<br>You might want to ask Herb Sutter for his list of problems with
<br>iostreams. IIRC, there are eight or ten issues on his list, and he
<br>believes a C++11 version of Boost.Format, or something similar, would
<br>solve a lot of them. But best to ask him directly.
<br>
<br>This mailing list is a good place to float an idea about your library,
<br>as mentioned in <a href=3D"http://isocpp.org/std/submit-a-proposal" tar=
get=3D"_blank">http://isocpp.org/std/submit-<wbr>a-proposal</a>
<br>
<br>But the assumption was that you had an existing library you wanted to
<br>float for possible standardization, not just a wish-list and some
<br>ideas about a possible future library.
<br>
<br>As has been noted many times by many LWG members, the problem with
<br>libraries that don't exist yet is that they are inevitably presented
<br>as far superior to existing libraries for the problem domain. And if
<br>someone raises an issue with the not-yet-existing library, the
<br>response is often that the issue will be easy to fix. So of course
<br>everyone would love to have this wondrous library for the standard!
<br>But only If it ever gets implemented, documented, used, refined, and
<br>matures into something useful, and someone writes an actual proposal
<br>document.
<br>
<br>--Beman
<br></blockquote><div><br>The main purpose of this thread is to collect a l=
ist of legitimate grievances towards iostreams. That way, when someone writ=
es or submits a proposal, we can check it against the list and know how wel=
l it's doing. Even better, if I (or anyone reading this) were inclined to w=
rite such a library and a proposal, it would help guide my interface to kno=
w what the major issues that need resolving are.<br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_5_31319013.1353194482554--

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Sun, 18 Nov 2012 00:56:10
Raw View
--20cf303349d787433504ceba7763
Content-Type: text/plain; charset=ISO-8859-1

I think beyond just a list problems, you need a list of features / uses. I
know what it streams does today, but is that what we really want in a new
class?

I think maybe it should be split into separate classes.

Tony


*From: *Nicol Bolas
*Sent: *Saturday, November 17, 2012 6:21:24 PM EDT
*To: *std-proposals@isocpp.org
*Reply To: *std-proposals@isocpp.org
*Cc: *bdawes@acm.org
*Subject: *Re: [std-proposals] The failures of iostreams



On Saturday, November 17, 2012 3:03:28 PM UTC-8, Beman Dawes wrote:
>
> On Sat, Nov 17, 2012 at 2:36 PM, Jason McKesson <jmck...@gmail.com<javascript:>>
> wrote:
>
> > ...
> > The Iostreams library in C++ has a problem.
>
> Um... I suspect most of the LWG believes iostreams has far more than
> one problem.
>
> > What do you think? Are there other issues in iostreams that need to be
> > mentioned?
>
> You might want to ask Herb Sutter for his list of problems with
> iostreams. IIRC, there are eight or ten issues on his list, and he
> believes a C++11 version of Boost.Format, or something similar, would
> solve a lot of them. But best to ask him directly.
>
> This mailing list is a good place to float an idea about your library,
> as mentioned in http://isocpp.org/std/submit-a-proposal
>
> But the assumption was that you had an existing library you wanted to
> float for possible standardization, not just a wish-list and some
> ideas about a possible future library.
>
> As has been noted many times by many LWG members, the problem with
> libraries that don't exist yet is that they are inevitably presented
> as far superior to existing libraries for the problem domain. And if
> someone raises an issue with the not-yet-existing library, the
> response is often that the issue will be easy to fix. So of course
> everyone would love to have this wondrous library for the standard!
> But only If it ever gets implemented, documented, used, refined, and
> matures into something useful, and someone writes an actual proposal
> document.
>
> --Beman
>

The main purpose of this thread is to collect a list of legitimate
grievances towards iostreams. That way, when someone writes or submits a
proposal, we can check it against the list and know how well it's doing.
Even better, if I (or anyone reading this) were inclined to write such a
library and a proposal, it would help guide my interface to know what the
major issues that need resolving are.

--

--




--20cf303349d787433504ceba7763
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<head></head><body style=3D"background-color:rgb(255,255,255)" dir=3D"LTR">=
<div id=3D"BB10_response_div" style=3D"width:100%;background:#ffffff;font-f=
amily:&quot;Slate Pro&quot;,&quot;Calibri&quot;,&quot;sans-serif&quot;;colo=
r:#1f497d">
I think beyond just a list problems, you need a list of features / uses. I =
know what it streams does today, but is that what we really want in a new c=
lass?=A0</div><div id=3D"BB10_response_div" style=3D"width:100%;background:=
#ffffff;font-family:&quot;Slate Pro&quot;,&quot;Calibri&quot;,&quot;sans-se=
rif&quot;;color:#1f497d">
<br></div><div id=3D"BB10_response_div" style=3D"width:100%;background:#fff=
fff;font-family:&quot;Slate Pro&quot;,&quot;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1f497d">I think maybe it should be split into separate classes=
..</div>
<div id=3D"BB10_response_div" style=3D"width:100%;background:#ffffff;font-f=
amily:&quot;Slate Pro&quot;,&quot;Calibri&quot;,&quot;sans-serif&quot;;colo=
r:#1f497d"><br></div><div id=3D"BB10_response_div" style=3D"width:100%;back=
ground:#ffffff;font-family:&quot;Slate Pro&quot;,&quot;Calibri&quot;,&quot;=
sans-serif&quot;;color:#1f497d">
Tony</div><div id=3D"BB10_response_div" style=3D"width:100%;background:#fff=
fff;font-family:&quot;Slate Pro&quot;,&quot;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1f497d"><br><br></div><p id=3D"_signaturePlaceholder" style=3D=
"font-family:&quot;Slate Pro&quot;,&quot;Calibri&quot;,&quot;sans-serif&quo=
t;;color:#1f497d">
</p><table id=3D"_bb10TempSeparator" width=3D"100%" style=3D"border-spacing=
:0px"><tbody><tr><td colspan=3D"2"><div id=3D"_persistentSeparator" style=
=3D"border-style:solid none none;border-top-color:rgb(181,196,223);border-t=
op-width:1pt;padding:3pt 0in 0in;font-family:Tahoma,&#39;BB Alpha Sans&#39;=
,&#39;Slate Pro&#39;;font-size:10pt">
<span><b>From: </b>Nicol Bolas</span><br><span><b>Sent: </b>Saturday, Novem=
ber 17, 2012 6:21:24 PM EDT</span><br><span><b>To: </b><a href=3D"mailto:st=
d-proposals@isocpp.org">std-proposals@isocpp.org</a></span><br><span><b>Rep=
ly To: </b><a href=3D"mailto:std-proposals@isocpp.org">std-proposals@isocpp=
..org</a></span><br>
<span><b>Cc: </b><a href=3D"mailto:bdawes@acm.org">bdawes@acm.org</a></span=
><br><span><b>Subject: </b>Re: [std-proposals] The failures of iostreams</s=
pan><br></div></td></tr></tbody></table><div style=3D"border:none;border-to=
p:solid #babcd1 1pt">
</div><br><div id=3D"_originalContent" style><br><br>On Saturday, November =
17, 2012 3:03:28 PM UTC-8, Beman Dawes wrote:<blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex">
On Sat, Nov 17, 2012 at 2:36 PM, Jason McKesson &lt;<a href=3D"javascript:"=
 target=3D"_blank">jmck...@gmail.com</a>&gt; wrote:
<br>
<br>&gt; ...
<br>&gt; The Iostreams library in C++ has a problem.
<br>
<br>Um... I suspect most of the LWG believes iostreams has far more than
<br>one problem.
<br>
<br>&gt; What do you think? Are there other issues in iostreams that need t=
o be
<br>&gt; mentioned?
<br>
<br>You might want to ask Herb Sutter for his list of problems with
<br>iostreams. IIRC, there are eight or ten issues on his list, and he
<br>believes a C++11 version of Boost.Format, or something similar, would
<br>solve a lot of them. But best to ask him directly.
<br>
<br>This mailing list is a good place to float an idea about your library,
<br>as mentioned in <a href=3D"http://isocpp.org/std/submit-a-proposal" tar=
get=3D"_blank">http://isocpp.org/std/submit-a-proposal</a>
<br>
<br>But the assumption was that you had an existing library you wanted to
<br>float for possible standardization, not just a wish-list and some
<br>ideas about a possible future library.
<br>
<br>As has been noted many times by many LWG members, the problem with
<br>libraries that don&#39;t exist yet is that they are inevitably presente=
d
<br>as far superior to existing libraries for the problem domain. And if
<br>someone raises an issue with the not-yet-existing library, the
<br>response is often that the issue will be easy to fix. So of course
<br>everyone would love to have this wondrous library for the standard!
<br>But only If it ever gets implemented, documented, used, refined, and
<br>matures into something useful, and someone writes an actual proposal
<br>document.
<br>
<br>--Beman
<br></blockquote><div><br>The main purpose of this thread is to collect a l=
ist of legitimate grievances towards iostreams. That way, when someone writ=
es or submits a proposal, we can check it against the list and know how wel=
l it&#39;s doing. Even better, if I (or anyone reading this) were inclined =
to write such a library and a proposal, it would help guide my interface to=
 know what the major issues that need resolving are.<br>
</div>

<p></p>

-- <br>
=A0<br>
=A0<br>
=A0<br>
<br></div> </body>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--20cf303349d787433504ceba7763--

.


Author: VinceRev <vince.rev@gmail.com>
Date: Sat, 17 Nov 2012 18:06:23 -0800 (PST)
Raw View
------=_Part_173_17122227.1353204383572
Content-Type: multipart/alternative;
 boundary="----=_Part_174_10475459.1353204383572"

------=_Part_174_10475459.1353204383572
Content-Type: text/plain; charset=ISO-8859-1

I agree with your 2 main points : the problem of performance and number
formatting. Concerning the format, I think that having the choice between
the both syntax in C++ streams would be great, because the printf
formatting is sometimes far more easier to use to print numbers on
std::cout or to text files. Concerning, the performance, here we have
clearly a problem of virtual calls. I work with supercomputers, and I
oftenly need to write hundreds of several GB files. Consequently I've run
some benchmarks and I've compared the following cases :
- the standard solution using a loop of write()/read() and varying the size
of the internal buffer with pubsetbuf
- another one, where I put "manually" the data in a large memory buffer,
and when the buffer is full, I call the write()/read() function passing
this buffer as parameter

.... and the second technique is in general 10x faster than the first one
(see the attached plot).

I don't have any elegant solution to provide, but the fact is that the
write() and read() functions have a substantial overhead....


--




------=_Part_174_10475459.1353204383572
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

I agree with your 2 main points : the problem of performance and number for=
matting. Concerning the format, I think that having the choice between the =
both syntax in C++ streams would be great, because the printf formatting is=
 sometimes far more easier to use to print numbers on std::cout or to text =
files. Concerning, the performance, here we have clearly a problem of virtu=
al calls. I work with supercomputers, and I oftenly need to write hundreds =
of several GB files. Consequently I've run some benchmarks and I've compare=
d the following cases :<br>- the standard solution using a loop of write()/=
read() and varying the size of the internal buffer with pubsetbuf<br>- anot=
her one, where I put "manually" the data in a large memory buffer, and when=
 the buffer is full, I call the write()/read() function passing this buffer=
 as parameter<br><br>... and the second technique is in general 10x faster =
than the first one (see the attached plot).<br><br>I don't have any elegant=
 solution to provide, but the fact is that the write() and read() functions=
 have a substantial overhead....<br><br><br>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_174_10475459.1353204383572--
------=_Part_173_17122227.1353204383572
Content-Type: image/png; name=benchmark.png
Content-Transfer-Encoding: base64
Content-ID: <f952aabb-3af9-4c0c-a829-0e2b32860ab0>
Content-Disposition: attachment; filename=benchmark.png
X-Attachment-Id: f952aabb-3af9-4c0c-a829-0e2b32860ab0

iVBORw0KGgoAAAANSUhEUgAABCEAAAKRCAYAAABqaLOxAACAAElEQVR42uydCbxVU/vHkSlDSUhK
KEqZipSSeZ5CptKbKWNmMpPwKplekvlvpkmkKKSB0mB4m4iKSCUlL5VGqvW/33Ws27rr7jPec+74
+34++1N3n332sPZa66znt57nWRsYIYQQQgghhBBCiGJgAxWBEEIIIYQQQgghigOJEEIIIYQQQggh
hCgWJEIIIYQQQgghhBCiWJAIIYQQQgghhBBCiGJBIoQQQgghhBBCCCGKBYkQQgghhBBCCCGEKBYk
QgghhBBCCCGEEKJYkAghhBBCCCGEEEKIYkEihBBCCCGEEEIIIYoFiRBCCCFSZtSoUWbDDTc0Xbt2
LTfP9OOPP9pnuuCCC/TOPHbZZRez6667qtIXEy+99JJ9Ty+//HK5bDfF2Xf897//Ncccc4zZbrvt
7DUbN26c/9l3331n2rRpY3bccUf72TbbbJOz+zjssMPsNYQQQkiEEEKIEoHBaLhtttlm1tA7//zz
zbfffltmDNp77rmn3IkQF154YbkWIcJ3lsxAol7utttuarjFLEK88sor5bLdFFffsWTJElOjRg0r
Llx99dX2es8++6z9bO3atWbvvfe2/e4ll1xiP+vRo0fO7uXwww83G220kSq3EEJIhBBCiJITIRiQ
MvB12w033GAOPvhg+9lWW21lJk+eLBFCIkRWWbFihZkxY4b53//+V0iESGQg/fDDD3YTEiHKkgjx
0Ucf2et079690Gd4QfDZZZddVixlNGfOHNv2hBBCSIQQQogSFSGiYMauLIQESIQoPyQTIYREiLIo
QlB+8cJaPvnkk3IXTiaEEGURiRBCCFFMJBIhBg8ebD8/+eSTIz/v3bu3de2tWrWq2XzzzU3Dhg3N
v//9b7N69erI63Dsb7/9Zl2OiX3G/XivvfYyL7zwQtz7+/DDD+31t99+e3v8zjvvbE499VQzfPjw
SENi0qRJ5sQTT7T3tMUWW5hDDz3UjB07ttB57777bvudjz/+2D7HAQccYI+vWbOmue6668yqVavs
ccxgco6tt97aulL/61//KjR7DyNHjrTPRRlUqVLFVK5c2T4b11m5cmXC62OgNG3a1F7f5TuIZ0zh
un3NNdfYz84444zIcxcVyqB27dqF9u+00072uvfdd1+B/UOHDrX7eSYHoTzsw2vhP//5j3U3p0yo
A/47c4aXe96ozX0HonJC+HkLeA8IGbwv3gN1Ydq0aZHPyWwwcfi81y233NK0bNnSDBkyJO08CIsX
L7bP0ahRI3tdvIe4x7POOsvmAQgNZEQ9wpyox9WqVbPXbtWqlRk2bFjca6TT1oDz8w54j5tuuqkN
BTj33HPjzoAzG3/mmWcWKIv33nsvbRHi559/tu2Q73NNrk29adeuXeR78MuE/59zzjmmevXq9hlp
k/RBUSxdutRcf/31platWvbYPffc0zzyyCNm1qxZGYsQ48aNM0cddZQtY97jcccdZ7788stC33F1
+6effop7vlTqNfUr3me+IPH333+bJ5980jRv3tzeF/1EkyZNTK9evcy6devilid1gD6CHBT08Ygd
TugLQ578+061D4X58+fba9E/077Jc0FdKY95eoQQEiGEEEIUgwjhjN1777230GcM8vkMoxDju3Pn
zvkhHEcccYQdOIfXYYDaoEEDs++++9pz436MEcZnGDshXbp0sZ9hTJ533nnmjjvusAPePfbYo4CR
4Qa8iBUMmo8++mhz0003mbPPPttUqlTJGilhbgsnAjBI5zvt27e3z7DPPvvY/fz95ptvWuGDY26+
+eb85zvhhBMK3evxxx9vcxXwPY7FiwRDgeMZxK9Zsyby+twz98e93nrrrebyyy+PK0IgOGA0s5/z
p4ozmlI1qhFaON43WCm/KFEAbrzxRrt/9OjRha7J8znxhufjHYbGn2/IY7y7/W7zDWDqW5gTwhnK
GNGbbLKJNe55ByeddJLdj4G0aNGiQka6q3unnHKKva+2bdtao/m0005L2fDGCDzooIPs8dQPyuKW
W26xBj/GN8ZjaCBiBHJt/r399tttncaAo67269evyG3t/ffft+dzddfdD/UMw3LixIkFjp85c6Y1
/DkfZUZZUB833nhj07p167REiD59+tj2xHu/6qqr7LVPP/10+14QN8LQLlcmPMcOO+xgWrRoYcPB
qD/cL33TiBEjCnwHgfDAAw+036ONUa9cX8K7zESEoE1TXty3//yU45gxYwq1J+4rkQgR1mtXpygL
V68pC/7l/bsycJ85weCvv/6yYgifI3JdccUVVnzZb7/97D7aVVR5ImrR7qiblOell16a/96jvI0y
6UMXLlxo66TrE6jLlDvv2T1vefJOE0JIhBBCCJFFEcLNWGEYszHIZRDLQJVB8/LlyyONPgao4Uws
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
T+fOndUyRPEytIkxEy5e//d99xlTvbrqrqgwqO5qnCCEEEJUtN9MiRAaXOTTs2dPtQxRvIw7z5gP
mq//u3//WHLK335T3RUVAtVdjROEEEKIivabKRFCgwshSo5pDxrTbytj1q2N/T15ckyEGD9eZSOE
0DhBCCGEKIe/mRIhNLgQouT4eWgsOeWfP8b+XrYsJkK88orKRgihcYLI5/zzzzcbbrih3fbZZ59y
81zPP/+8faatttoqre+988475tBDDzVVqlQxW265pdlrr73Mc889l/R7vXv3NocccoipUaOG2Wyz
zcxOO+1kTjnlFDNu3LicPeNff/1lnnrqKXPQQQfZ+61cubJp2LChufXWWwsZH/D444+b5s2bm+22
287eY506dUzbtm3NtGnTChz3xx9/5NcJtocffrhY3hkebPXq1TObbrqpve6SJUvUQIWQCKHBhRBl
hmVzYiLEvHfX76td25g77lDZCCE0ThAFRAgM5s8++8x89dVX5eKZ5s2bZ6pWrWpq1apltt5665S/
1717d1OpUiVz1VVXmQ8//NCMHDnSPPnkk3ZLRq9evcztt99u3n77bTN69GjTt29f06xZM7Pxxhub
Tz75JOvPuHz5cnPYYYfZ81955ZXm/fffNx9//LHp1q2b2Xbbba3AMGPGjALfufvuu819991nBg0a
ZO/xpZdeMg0aNLBCjX/s2rVrbX0YOHCgFQMeeeSRnL+zSZMm2WtdeumlZuzYsfb63IcQQiKEBhcZ
8u2336pliOJl3Tpj+lc15utu6/cdeaQxZ52luisqBKq7GieI1EWIXXfdNevnxUC+IIOloXfZZRfT
tWvXIl375JNPNqeddpq9fqqeEF9++aUVIB566KGslQEz+czqn3feeVkvX4x1jPb+5HwKmDlzptlm
m23M3nvvndSQp6/kPF26dCn02Y8//pixCLFixYq0jn/99dfttT7//POslRFCjRASIcqgCDFq1KgC
7lj+hkLp/4BFHYNLmAYXxrrjCVHsDDvYmE/PXf/35Zcbs99+qruiQqC6KxGiLIDrPyEQuMbXrVvX
usszW80YygdDElf1/fL6cFzuMTBxwR88eHCB49544w27H8ObrXHjxuaFF17IWITALf+iiy4y1apV
s+c76aSTzKxZs+z9JRMKDj/8cHPhhRemXSbcyz333JNxmb722mvWC+Lnn3+2z5aqCIFgQfjFqlWr
svZ+eW94YlCG2eSXX36xHhAnnHBC3GPw6uA9vfXWWwnPtWjRInvcvffem7EIgUcFxw0bNsy+c8I9
+Hv16tX2c7xCqJeUL+/juOOOs54PDgSr0IbwBayPPvrIHHnkkfkhJwcffLAZMWJEgXtw7WbixImm
TZs2ts7WrFnTfrZu3TrrzeLaD5+deeaZ5ocffihwDu4D4QYhpFWrVmaLLbaw7fKBBx6w5wjbxg03
3GB2220323532GEHc+KJJ5rp06fnH8Pz43mCtwnHbL/99rZ8KHMhJEKkIELQ+BAd/G0ZMebeDxgN
NTxm6tSpEiHy+Omnn9QyRPHz2WXGDNl3/d+PPmryfn0ZFanuCvW7olyKEEvnLzXz/zs/7vbrtF+T
noNjor7LubMJ7vMbbbSRNa5wjx8wYIA11DBq2O/ToUMHu4/Z73fffdeGCuB2/8QTT+Qfc9ddd9kx
G8YVhufw4cPtIBTjLBMRAgMaYw+j7cEHH7Tnw1DdY4897HWSCQUlIUIsWLDAVK9e3Tz99NP5z5aq
CIGx2bRpUyti1K9f33pF1K5d2+ZXIPdCqqxZs8YejwHP++L6eFlkE/JP8A6effbZuMc4D4crrrgi
8h4RWzjm1FNPtQb03LlziyxC7LzzzvZ61E/CUqhD999/v627F198sRk6dKgN8WjZsqUtl2+++cZ+
n39d/X3llVesDeEEAt4H+xEWEO3ee+89KzIjwvhChBMhqD+ExfCZE+kuueQS65Fy0003WaGkT58+
dqJ0xx13NAsXLixQZxFQeP/kAeEchLpw3ldffXV9P7N0qc0VwjNg8CGS8LzXX3+9tZ1c+zn++OPt
MQgRnAtBkDrFd1euXKlOXkiESCZCJFNR6eTTibmraCKEECXCjLzBaZ9N834J/xk85f1w2+SUc+ao
bIQQ5VKEGHX3KNN1g65xtycbJY/t55io73LubHLggQfa0IO///47fx8TPBjRvghB7D5jMYy0eGCw
YTQjVqRLPBFiyJAhkYYuE1NRIgTP4W8kd+TcGLz+/pDwe9wLoQHh/lQ444wzbHJI/9lSFSGYqWam
nXwKJHskv8Kdd95pjd327dunXJ7MervZfGa+OU+2ce8AgzoeGLkcg/dK1LO6e0T0ijdpmK4IEYbf
zMkbb1B+1157bYH91HO8FM4555xC5/DbO+EUvA+EEh+8EvBqIMlmKEKEHjrjx4+3+x977LEC+8kb
wgTqLbfckr/PeWR88cUXBY5FNEBQcCDGcVzojeGD0MExCCc+CFLsd0KZEBIhEogQqPPJfsDSzT4s
EUKIHLNgVCw55eLYTIP57ruYCDF8uMpGCFEuRYiy4gmBEYbQEBpngCHnh2Pcdttt9m9m+eOBUMAx
EyZMyJoIcfPNN9tz4nbug5dRKEIkCt8NN99LyRmeybbQMySKN9980xrXvjt8OuPTTTbZxF6rX79+
BfYzu83+77//PqXzMKuPEcvY+eijj7bXT2SsJiKeEFNUEYJQCLwNCN/B+wNPiKikpOmKEHjp+LgV
SjC8w2dBgGAlkUQiBB4GbjI0/D7iAfXC5Z5wIkT4HHfccYc9jhCI8Bx4HvlCBiIESVpDWEHEDzFv
0aKF2XPPPROWCcIVAkp4TTY8MHwBRgiJEHFECDoJlEwUYuK4Pv3000I/YCjwNCrnvkZm4d9//10i
hBAlxcpFMRFidj83mjF5DdmYp55S2QghyqUIUVbA9Z3xFSEVIRhXvgiBGzsGciIYdPIdZnezJUJ0
7Ngx8rrOuPVFiD///NO+J7dhdB5wwAGmdevWBfaz+aENDJDD72EEXnbZZYW+lwiuz1gVd3tEE7e1
a9fOigCLFy8uEEYcBWNYjFWO9SG0IJUJuSjwAiHnx7777pv2d50A4G9ulQ0XjvHMM88kFEPihWNE
lR3vqqgiRBh24uplvA3bIpEI4ZJVJhKnXJ13IsRvv/1W4B5oP4nOsfvuuxcQIaKWqQ3bCN9BYEoE
nye6brLvC1GhRQiUUhRgYhURHuggGjVqZDsNOmUHD4mbE/GCbLivkXwG1TBep1+RRAgUayFKhLd2
NGaK58LboIEx112nuivU7wqJECVIIk8Il+zb4TwhSEYYD+cJget5tkSIeJ4QzjAtTTkhogz2cDv9
9NMTnoNJNo6LJ0IkC02OBytjbL755ml/D7EmFGIQDACvGAQiP0QgBIGL+yZXQTIInYlKJp+uCBG2
VUQSdw/hs4TiUtQ5PvjgA7uPpJLxvu9ELSdChEYXOT1oa+PGjYv8/tdff522CEFOC8JuEoH3BPkl
4t03K5gIIREiDeicSTxDxuWEtk9eZx0VgxUWAuorCWb8DfcoEteEPwJR2c47depkCzo8N8eG2WeJ
MQwHprgFcmy4nBtZqDt37lxgH7FpHDtmzJgC+1Gko5ahOvvss+1z+MseleXnKC/vo0I9R+va5v9u
brJ+R94x/z344JSfgwGy3oeeQ/2u3kdJPEd5n6xo1qyZqVOnTgHPAIzMMCcEZR1vCUXH7Nmz7QRR
JktBxhMhSCIYFbvuVl0oTSIESRbJvYCngNv4GyOdxJr8PW3atITncKED1GWfa665xpbtnAzyKeE1
QpLDTDwhkoG3SLwlOmfMmGFXCMGgDld1CKGPYLWIbHhChG2VeolYQmLTZESdA7GOe6NvSEY8EWLs
2LFxyykkVRGCRJOcc+TIkXHPRahLuJqgEMUhQpAXhzZ39dVX2+WK+b1l1Zd69erZz8qsCAGXX365
bViJljGi08MFDle4RAWlcAwhcsiX1xkzeI/1f994I36EKhchRJkZUJXXcQKzvISwHnHEETZ5He7+
xKdj7LDfB3EBYQLDk4z/CDmISf7qGIgUjM3OOuus/NUxEJIyXR2DcZxbprBHjx42Pt9fHQNDLJlB
FyVMJYNknUVZojN8tqicECyZGQoLxOoTQsLyp5Qbz0toDMcxmPdhRRM/lADIE8A74V0SzoxRjdCE
Ec6KDuF9hfkx0gVBEKGH87OCA6utYBTjAUEuAgQuf7adSUSSoTI5yP2QpwKBidwGlFFUOyuqCOFE
K+4R2wFBEnGIJTtvzBuP+HUz3jkIyaA94FlA3g8EJdoKiVr9UJN4IoQTbPDQxruHvBWUEyIB3/dF
NrdEZ7I2gljIcSTlZ/UPcnPgNc6Snf7qGCzZiahIu+H90CZffvll2y5CcVaIbP1mlltPCF+EcOv/
RkHj44dLIoQQJcj3/2fMGxvmja6Wx/4myzmD2wRtVwghJEIUDxiszJKTUBEjh9krPNAwIkNBAOOR
WVqOxVBm+UxWsPBhOUMMX2b/MZAwqlnyMJmhzgoJURCKgcHObDRGHCELzOwyBvQFkChKYonOEIy9
qNXb2I+oE4oA5DJjjEt+CJZ0xECPMsB5tjBZJl5DeAnzbjC6Wf2B1TqiQmTYT3kuWbKkSM+HcMJK
HngQk7eNsA/CKghBCPOyMWZnqUrCqikT7hHPZgSu0AsqExGC8ojXVjHQEW7wzuAeecd4SfmeBInO
wQoxzOhi0FP/uW9md/0QGVbF4PtRIoQ7P+WE4IJ9Ql4H6sHEiRMLvNcoTwiOC9sIos51111nRTPq
ivPs9oUfcoJQdtQL1yZ5P4gfs2bNUicvJEKkA51arVq1zP7775/wOLIL03GhJkuEEKKE+O2zWHLK
//2TLAqFnhUy4gw4hBBCIkTJQWgGRiLGfnHhZnkxmNiS4dzMM8k/IWKwGgWz8qUZBA5WBElFhBBC
SITIKueee65d2galEfei5557ziZiQfFzyw0R74W7HkosroW4G6HAovihJrqlcyry4CKMyRWi+Ea0
f8ZEiFkvx/6ePz8mQgwapLor1O8KiRAlDF4Gffr0yXdRZyYW1/NMl3TMBLckKFs4C0x+hIceesiO
7XA5x62cGXfuU2QGiRDxCIg3Y18awAPGX4FCIoQQEiGKFWLbmjRpYl3LiH1DucWFzF+Ch46qTZs2
1k0J9ybcpBAqECKWLl1aoQcXjqgEXEIUG+/sZszEf5LLkaCK+Ni8QaXqrlC/KyRClCy4pLOsOWMn
3MSJSfdXHysOmExyGftZ1tGH3AFNmzbNDzHA9ZxwEbdKgyifEFLtr+SwcOFCFYoQEiE0uCiLzypE
ifFxnjE20lvGi1CqSy5R3RXqd4XGCUIIIUQ5+s2UCKHBhRClg0m3GfN2rfV/t21LCmiVixBC4wQh
hBCiHP1mSoTQ4EKI0sGPvWN5IVb/kymbteZr1lS5CCE0ThBCCCHK0W+mRAgNLoQoHfwxNSZCLBwT
+/v112PJKYu4NJgQQmicIIQQQpSe30yJEBpc5ENFEKLEWLPamN4bGzPz6djfn38eEyG8BLOqu0L9
rtA4QQghhCjbv5kSITS4yKdTp05qGaJkea+RMZ9fGfv/4sUxEaJ3b9VdoX5XaJwghBBClJPfTIkQ
GlwIUXoYc44xHx26/u8aNYzp2lXlIoTQOEEIIYQoJ7+ZEiE0uBCi9PDVfca8ua0x69bF/j7kEGPO
PVflIoTQOEEIIYQoJ7+ZEiE0uBCi9DBnYCw55Yr5sb87djSmaVOVixBC44QS4qWXXjIbbrih+emn
n9L+7s8//2zuvvtuM3ny5IyvP2rUKHv9Tz75JOFxXIfj2LbaaqsCnx122GHm8MMPL5Xl++6775oO
HTqYvffe22y88cb2/iN/HufMMaeddpqpW7eu2XLLLU3VqlVNkyZNzBNPPGHWrFmT0rX+/PNPc+21
15qddtrJbL755qZx48amb9++Kd/rwoULzfnnn2+22247s8UWW5gWLVqYESNG5Kxs1q1bZ9544w1z
xBFHmGrVqpnNNtvMPv+VV15p5s6dW+j43r17m0MOOcTUqFHDHstznnLKKWbcuHGFjqX8XH256qqr
inyvY8eONV27djWLCSVNkV122cVccMEFCY/58ccf7T0+/PDDWS1bjL5zzjnH7LDDDvb8p59+ev71
TjzxRLPtttva/ddff33Wrsn57rnnnhJrazNmzLD14nNyjuUQ2kjYBxUH999/v3nnnXfi9uHZ/o2a
OHGiOfTQQ/Pb0uOPP277a/qnqPYpEUKDCyFKL0u/i4kQ84fF/u7Rw5gqVdZ7RgghRBkdJ/z666+m
c57BcWKjRuaU+vXtv/zN/qKSy3MvWrTIfPbZZ2b16tVpf/eLL76wg9NXXnml2EQI7vXLIKHxt99+
a7fSSMeOHU2DBg1M27ZtTdOmTc1GG20Uedz06dOtcfPyyy+bkSNHmg8++MBcffXV9pkvvvjilK51
zDHHWGP+ueeeMx9//LG55JJL7Pd7p5B7adWqVVYoqVOnjj1++PDhVhTZZJNNkr6bTFi7dq01krm/
9u3bm8GDB9vr9OzZ0+y88872OTD8fXr16mVuv/128/bbb5vRo0dbgaVZs2ZW3AnvkfY6YcIEe37K
sag89NBDaYt1u+66q7nwwgtTEiEeeeSRrJbvddddZw1y3iVt5rvvvrP7eaeITIMGDbL7Eb+yBedD
mCwpTjjhBHPmmWfm/Dq006233rrYnw/jP6o+5UqEQMSk7/rwww/tu0WkhOOPP972ZxIhJEKkDGqx
ECXK2jXG9K1szDf//NgOHBhLTvnLL6q7Qv2uKLPjBAZnR9SrZ8bnHbeOPi1vW5u38Tf7iyIW5PLc
RcWJEBjOxSVClDXWeSI7M/zpPgOGOkLAX3/9lfC4IUOG2HOHng/HHnusqVWrljX6E/Hkk0/a72O4
O/DA2GuvvUzz5s2zXi7dunWz13vwwQcj6zwG/I477pjU82DJkiVm0003Needd17k59kWIWbPnl0m
RIijjz7avruQ3Xff3Zx00klZrd8rV64sFf005ThmzJhiESFKwhOCa0Z51uRKhKDfoc+K6msQU52w
JRFCIkRSULKEKHHeb2rM+H9+lKdNi4kQSQafqrtC/a4ozeMEvBLG/yMQhNu4vK1zEpfsROTy3P4A
1p/hJbyBWXHcmlu1amVd83GTf+CBB/KNaicehJvvjo1IgRCH6zfhAYQX9O/fP+siRFQ4BjP73Mue
e+5pr129enXr9u+77jtX/Weeecbssccedua4UaNGkSEM8+bNs54FtWvXtkYvoQDMurrZwVTIRITg
O9xXMhEBb4kqVaoUOq5Pnz72mlEhC6HR2rBhw0L7u3fvbr8/f/78rLUpvG7wdIgyksP7Tmac87zM
Sl900UUZixCc47777jP169e3dX2bbbYx++67r3U/9+teuLk6i0B000032TARvk+bYeY4HRECMQaj
DS8Q6iteM2EoDMYv50zUNtz5wg3PmKj9rt0j5tx44432/NRvhCu8KZYvX16oPGkzTz/9tG1bHPvs
s8/mf9bVSzbu+hba+OWXX249MGiHbdq0KVSfaK833HBDfhkSBoDHUyohLcD7p4+K6hvoy/CcQUyr
XLmyfba77rqrQFuJ1w+58vSFVidCTMsbwx555JHWQ2H77be35bJixYoC36e/w1uHkAbXj4Z1NZWy
j3p39Gd+OX/00Ue2rOhvuSf63h9++KHAteKVp9+HuvOFmy9O8p46d+4sEUIihBBliPF5nd/7B7pf
HWNwTX3+eZWLEKLMjhMIj1gXRyjAa+HE3XbjRBltfDfhufOunW0RgsEoBgNGGa79GEPOgH711Vft
MUuXLrUDc/Z16dLFGl2+OzYhBQyoGdy++eabZtiwYdYgC8M3siFCcL9uQA5///23/ZuZvJtvvtmG
NpCb4Y477jD9+vUrMLAn/AAjhf0cg0s3+wcMGFBAgKhZs6aNr3/sscfss2FcYPgTRpFtEYL7//33
360YgrFzyy23JP3OQQcdFOmx8PXXX9trPp/kdxavA7wuQt577718AydbIIhwzttuuy3uMeS3qFSp
kn0fIRhBGP4YiJdeeqktozBEJx0RAqGFkA5EK+ojdRUB4t57781//9dcc409FzH5rq7TBpxRysww
74kwFowuDEkMz1RFCOohhvfAgQNt3cNwpf2MHz++gPG7G31JRNtwYT4IPHiz7L///tbrwb9X9lOP
yavh9nM8xi6u9379JiwGMeaoo44qVJ4IcS7fCOLGN998k/+ZL0K6vqVevXo2Vwl16IUXXrBGMsa7
T7t27ew7oI1ShpQ/ZcI9JCtD4LmijnN9Ge8Dbx/ugXsJc4UkEyH8Pov3gDCIQU/d4X4RX+hvfO9H
won47rnnnmv7IMqKPpPvO1Ite94dIsbJJ5+c/+5cCJorZ8qLPonJD9o7QgH7fG+ieMKY34cSoudC
mc4+++z86/mcccYZkaKlRAiJEEKUXr552Ji+Wxiz7h8FGuX6pptULkKIMjtOIE+DiSMUsJ2S4LNk
W7Lv2mtnWYRAOGAfngw+zFwTD+xIlBOCWVJmc8OZeQbpeBFkU4Tgfn0RAqGEYzF4EsExzBj6IS3c
L4NrPCMczFxidKQjOGQqQjjPA7fFm20M4X6jDHZmnDkPXiyJwOC94oor4goG6SS4TAbn4pwIXInA
iIryliBO3ZUPM9AYd4necTIRAsMOoz0R8XJCYAiyn5lsH3IxsD9VEQLD3s/LggiD1wB5PnzjN5kn
hN8m9tlnn0LHYjiHYYLUOQSfsI9766237Hnff//9AuWJF0tUmEw8ESJMDOrK0nkR4VEQJUq5epKs
DMlrwXEY8VF9A58hMPogXvHMLidGuiIE+0ga6+NCjFwuE5KN8rcTq+K191TLHrEtUU4IhIGotktC
y2QiRNiHJms7vGc+x4tDIoRECCHKBvM/iCWn/HNW7G8GtKeeqnIRQpTZcUJ584RgQOoLBQ6Skfmz
X/FECGKFnSs9s/r+9tRTT9nPnEGfCxGCWVVmDZPB+Vq3bh33Ws6rg1lWX3zJpQixYMECW9eYsb31
1lut+BElDpQFESJ899kSIZh5p+7hMUAYCcZZvFU8UhEhCMXAk6BTp052xjrKsIonQrj6zEoC4bMz
M56qCIGnRYibcXchULkSIQ4++GA7G4+Hif++EEKch4dfnqGxm0yEwLPEhzJmv1vFwpXhpEmTMipD
zsP3X3/99ci+AY+UEBeewuosmYoQeCv5kC/EN/oJAeHv4447znpa4VETkk7ZJxMhSNgaQn2hjWRb
hHA5ZFiRRCKERIik4OIlRImzfF5MhJj7zzJD/PDGcelS3RXqd0VZGCeUx5wQUQZMaATFEyE+/fTT
yJhitzG45phciRAMunFFT0WEYEY0hHh3Pps6dar9G0Mo1RUqiipChPTo0SPSyA0hHAMX/pBUwzEQ
WrIdjhG+d1dPnLCByBKPZcuW2XoSJaz4YLxRV8nhkKkIwTkeffRR6w3BNXnfuML7IR7xRAgEjHg5
MwhxSVWEYBY9BAPUn0nPlQhBW0nUVv26n2jJ03giRNh3hm2+qGWYTISoH+Et5jxYCH3IRISgjoSQ
oJNjyW3hYBUS6hJ5PviM0C/ynWRS9slEiKi8L4Ro+V4+EiEkQpQIxPUIUeKg6L9ZzZiv/h37u1cv
RniMAlR3hfpdUSbHCbjzs1LFuH+8E5yXwrgsrGCRy3PnSoTAy4H9xHdTblEbM325EiGcJ8S6JMs/
p+oJgVcIs5klIUIQI853/FwWUSCmkKAxXmJKP7dAFKyikSgx5S9JVrGK13b8zRki5HMgL0CjBF48
LpwBcSAZrIyBkZepCOGDFwQeFhiuhEO4lR+SeUKE/QOz2eQ4SFWEiLpH2hvP5erxZZddZsWiEESB
oogQLVq0MPvtt1/ctuo/c6LyzFSESORNkkoZJgvHIGFriLsH5wlB+4jy2kCIiucJERrW7l364Q8O
6jzPi0cV4oJrj+mUfTIRghCOqPfth/QQJkeOihDEEYVjSIQQovwz7BBjPv1njWE6fAbWs2apXIQQ
ZXacgBiAVwLhEeRp4F/+zsYSmrk8d7oihJ8YD08BvsvqEiEYcaksBZgLEeK1116zx7744otJRQhy
QvgrXDArzkDdzwnRsWNHG64QNeuXaxGCLP6peEIQOx4lViCekG8gmSDjvD/8BHQYgYRDYChlGydu
xFuiE+MJgztRPD0gElDXiuIJEQUGLd91yf+YMff/drgZdX/2GzBu08kJQeJEVohw8NwINb4B6fIH
+PWVPBLMprvElJmIEBjNtAPuJRm5ECFcTogwAasT0FJNTBlv1QfOMXjw4AL7WekGgWPu3Ln2b0Q2
jkNsimp/USKE86Lwy9HPCRHF5MmT7TG0t3TLHlGMkLh4fTirjvi4xJi+KIIIEoY40a9RFumIEFxL
iSklQghR9vj8CmPe2zv2f9bcRoQYOlTlIoTQOKGYSbREZ5QI4XtCkNndLUlIjDWeEc6lGkODWVyM
YIwJDA7Ck3A7P+uss7IuQvhLdCIkkH0f4QDDBgOdte1ZxcPPbeAyyjMoZz+Gipup9JcSxSMCbwhy
FJC1n/wDzDrifZAsWSVx4qwOwsa53cob/O27+3NvLGOIBwBlSVnxN8ZBGCaBoYcxGpYZ3gwYroRe
4EGBocX1OKcPiTY5r0vK54xZ3jnlwfGEX5x++um2DIltj3oXyd5ZIhBFMKg4T/v27a3bOs+NYccy
lTxH6F6OGEJuC1aooN5QdwlBwTWesJFMRQgSU5IUkffCM5HYlHqO4LbmHy9Nl0OAd8J9UdedN0+H
Dh3y4/eZScd7w62OkWx5SX91DFatcKtjHHjggbbs/TLgWPZhLA7NGzNRB6n7LPsY5QkR1YajRAja
MS77lDv3zrt3Kyy41RFyKUIAs/PUydtvv91eHxHIrY6BCJgMhIqolUMoB1bHoP326tXLPpdbHQNR
0AfBh3qH4cx75H0icMVbHYM6Qn/GsW51DF94RcCgrSFIUX+ot7w7vutWFEmn7Onj6INIskn9c6Ko
K2feLeEb5Nzg+6y4wXn/+OOPQuIY+U9Y1YPkvYiulE+4zHG8d423FecOhTeJEBpcCFH6mfGkMb03
zhsprqY3MwY3ygg3OiGE0Dgh9yIEBlS4RGfULCoGVTjQx3hnRgzjKDRC8JTAgGbgzOfMVpKvwU9I
iEHC9bO5RCcwq8x3MCIY9GOIcG2WngsH2cxKMpvMPRIi4MdsO0gqhzHEM3AcRiZGdDJvFGcg+HHe
7v/+DC+GBUYQMfAYM4RWkOcBwykMscDgiSoz8ihgYHGPPDMJ76LCOHiP4TsHZtgxsJhxrVy5smnZ
smVkwkdWgkAEKapnCCB48O5YcYF7ZjlHjEM3Q+3DSiE8E4YpZcRzkiQxUahJKiIExh8JAllpwy29
iIDjizSAgcx759n98sfVnnujnrtyo57Fi7+PEiGYgWdJUIxG7uGAAw6IzMOBoNakSRMr/lFnCWVw
9SFsE1FtmHsKRQhnDGM005YRDyljvEt4177nRboiBPcVJUKE9RcRjGv5ZYgBzn2EK49E4ULDXK4Z
X4SgHBDSEHZ4Nt7hnXfeWahdkRQWgZT6z3UJ8+HeQxGC9kP7JN8KdZd3Qf9CvV2xYkX+cQifJ554
ovVE4p3ybAheoadEqmU/ZcoUK/jiOcE9uT7PlTOiAvdMW3LLec6K8DKmrtHOKGdEPASSqD403rtG
AON6M2fOlAihwYUQZYyFo2PJKf/4KvY3P5SdOqlchBAaJ4iEIgQz02sS5BBKh0xd9Ss6GHOlPd+N
W21A77js4sIJokTBKPC68r2sfBFCZA+SxSZq/xIhNLgoxAVFzKAtRNZY9b+YCDH7nx8WlnvylhBS
3RXqd4XGCcKH2V7nQcAspESIkoFEdMzqJgtDKWkIhXCeJ3rHpR9CGvCiIKwG7xu8U3D5b9CggfWS
SAU8c/AkwCvCFyGiwlJEZuC9QoLMKE8liRAaXMQljAkUokR5eydjJt8R+/9ttxlTp47qrlC/KzRO
EJGQa8JljCe5m0QIkQhc1119CcMqROmD0AtCDcjJ4EJtCGUhRKIoxAtLEbn/zZQIocGFEKWTEcca
88mpsf+/9FIsOaUXSyeEEBonCCGEEGXvN1MihAYXQpTSxneDMYPqxv5Pkh5EiKlTVS5CCI0ThBBC
iDL8mykRQoMLIUons16K5YX4e5kxixbFRIg331S5CCE0ThBCCCHK8G+mRAgNLvIZM2aMWoYoPfz2
RUyE+O1zFgw3plo1Y+6/X3VXqN8VGicIIYQQZfg3UyKEBhf5RK0LLESJgQfEGxsa8/2Lsb8POsiY
889X3RXqd4XGCUIIIUQZ/s2UCKHBRT7Lly9XyxCli0H1Yrkh4LzzjGnRQnVXqN8VGicIIYQQZfg3
UyKEBhdClF4+Oc2YEcfE/p/XWZnq1VUmQgiNE4QQQogy/JspEUKDCyFKL5PvNObtmrH/9+8fS075
228qFyGExglCCCFEGf3NlAihwYUQpZfZfWPJKVf9ZszkyTERYvx4lYsQQuOECsb5559vNtxwQ7vt
s88+5ea5nn/+eftMW221VVrfe+edd8yhhx5qqlSpYrbcckuz1157meeeey7p93r37m0OOeQQU6NG
DbPZZpuZnXbayeamGTduXM6e8a+//jJPPfWUOeigg+z9Vq5c2TRs2NDceuuthYwPePzxx03z5s3N
dtttZ++xTp06pm3btmbatGkFjvvjjz/y6wTbww8/XOR7HTJkiOnatWta3+Hayb4zatQoe9xbb72V
1bL98ccfzYknnmi23XZbe/7rr7/e7p84caKtH1WrVrX7KdNsXY/zvfLKKyXWZihL6tDcuXNzep3D
DjvM7L333sX6bCtWrDB33323+fjjjwt9xn7KPqrNFIXhw4ebAw44wPYjnJ++5aWXXrJ9w7JlyyRC
aHCRezp37qxRjihd/PF1TIRY+IkxdISIEC+/rLor1O8KjRMqoAjBoPizzz4zX331Vbl4pnnz5lkj
sVatWmbrrbdO+Xvdu3c3lSpVMldddZX58MMPzciRI82TTz5pt2T06tXL3H777ebtt982o0ePNn37
9jXNmjUzG2+8sfnkk0+y/ozkvcGY4/xXXnmlef/9962B1a1bN2s4IzDMmDGjkLF13333mUGDBtl7
xCBq0KCBFWr8Y9euXWvrw8CBA63x9MgjjxT5frlHzpWuCHHPPfeUiAhx2mmnWbGGsqIs5syZY/c3
btzYlhn1g/0LFizIyvVWr15tz/dbCXmlrlmzxgoDxfHbSb0tbsFz0aJFcetTLkSIdevW2XbYsmVL
24/wbhcvXmz3I2wiFEqE0OAi5/Ts2VOjHFG6WPuXMX02MWbGPwOr2rVN3uhJdVeo3xVlbpzw66+/
ms5XX2BOPKyROeWw+vZf/mZ/UcnluUuTCLHrrrvmxNC44IIL0v7eLrvskvaMecjJJ59sjUiun6on
xJdffmkFiIceeihrZbBkyRKz6aabmvNIAJ1lLr30Ums49SekMmDmzJlmm222sUYlgkIivv32W3ue
Ll26FPrMzc5nS4TYaKONyowIsfvuu5uTTjqp0P5NNtnEPks2jX8EiJKG8uP9/PTTT+VahIjqW3Ih
QiCEcs6o/gRRk36J/kEihEQIISoeQ/J+AD67PPb/I4805swzVSZCiDI1Tli4cKE5olk9M77rBmbd
6xtYD6+1r21g/2Z/UcSCXJ7bgXsug3Fc4+vWrWtdu92A2AdDEmFtv/32s+7SGJi44A8ePLjAcW+8
8YbdzwCXjVnbF154IWMRArf8iy66yFSrVs2eD6Ns1qxZKbnJH3744ebCCy9Mu0y4l2SGZyJee+01
6wXx888/22dLVYRAsMBtetWqVVmrw7w3PDEow2zyyy+/WA+IE044Ie4xeHWkYpw74+zee+/NWITA
K+PGG2+0727zzTe3M8BNmzY1ffr0ya9jfniH25zBizF28cUX2+/xvo4//njrmZGOCPH666/bkIkd
d9zRthEM3UmTJhUyfqmXidqAO1+4vfzyy5H7/XeCMFS7dm0rPO2222723hEZwvJ88MEHrUcK1+Q9
4lXhPnvZ80p1fQHhMoTNUK8J96FdhQZsUdpqbBh4pDniiCMK7UcURNTDw4e+ivdLXxUK/XjV+O80
fD++N5ALx8Abh/Ag3hdeS3fddVch0Yxwo3333dc+E21pzz33tB5HYXtIVPaubMPN9U+unKkvp59+
ug1toqz/9a9/2fYRCmNR5Uk5OdHVnc/f/D72999/t+8d7ymJEBIhhKh4fNrOmGGtYv+/4gqT18ur
TIQQZWqcgFcCooANLwu2cXn7+TxTcnluwH2emUcG/7h8DxgwwAoIDKDDGeMOHTrYfQy03333XWu0
4Hb/xBNP5B/DAJ7B7plnnmkNT+KRGYQyIM5EhMAYOPjgg62BgNHE+TBU99hjj5SMw5IQIXCNr169
unn66afzny1VEQLDCsMZEaN+/frWKwKjBrdpci+kCoYPx2P48L64Pl4W2YT8E7yDZ599Nu4xzsPh
Cn7fI+4RsYVjTj31VLPDDjtE5gFIVYS47LLLrIDz2GOPWWNz6NChpkePHvlhLBjDZ511lj0Xbulu
wwMA93SMX4xbhBPqGUYe7yMdEYLwEwxIck8gxlFPMSR/+OGHAnUyytCmntDuYOnSpWbChAmmZs2a
NseHu1dESfZzrbPPPjt/vzOCd955Z3sOcpHgfo8hyDP5bcCVJ/XqqKOOsoY9zzt79uzInBDOmMXw
pkxGjBhh2zTn9YWtorbVP//80xrvUcfRHrlfjGwEkg8++MAa52GukHRFCEJdEB6oIx999JG59tpr
7XGEQjkQsdjHZzwT5Uqdv+666woIEMnKnnpGn8m5Lrnkkvx35+qGK2ee9ZZbbrH3QznTdvfff3/z
999/FxAh4pWTux5eEC6UiXvnWpPJv+ZBrohEImKFFyHiqYGuEwkfigbFC0Ohb9OmTYGGLxFCiFLG
1/cb038bAtdMXk9l8n69+CVTuQghyowIQXiE81IIN7wWTmyVZ1j8778ZbXw34bnzrl0UDjzwQDuw
9we4JCvDiPZFCGYLGXchMsSD8RZGM2JFusQTITDmogzdBx54IHIgznP4G8n7ODcGr78/JPwe90Jo
QLg/Fc444wxrOPrPlqoIgTcKM6DMxjP7Sn6FO++8085Ytm/fPuXyJF+AGytvv/32kYnwiop7B8OG
DYt7zMqVK+0xUSEFPKu7R4y3qVOnRp4jVRGCWW3G/YmIlxMCMY79vqAGiGzpiBC0Jx+MYQxrjE7f
+I0nQoRtgLZJYtEQrnX11VcXEmGoO6GQQ7lx/DfffFOgPBEHfA8J/7MoESJMDEpZIjhk2lZDXB+D
Z1YI5UDfEtaRY4891oo81LNMRAj2Iaj6INpxLVeOCBJ4diQTwFIp+1RyQuDNEyX2IWqlI0Kk0nY4
NtmzSYTIK0Aqsa9csvlZPVFScZGhUtGZoOzRIaFwhW4sFVGEoHyEKHXMHRQbUC+fxy9YLDnlP4mX
VHeF+l1RFkQI8jREiQRuO2X/DRJ+XpTv2mtnCGMohAZmyUJw6fWNtdtuu83+nSgBHsYHxzBTmy0R
4uabb7bnxM07NO7CgXiiSat4Lvi+4ZJsSyWXwJtvvmmN6+nTp2ckQhDrz7X69etXYD8u/uz//vvv
UzoPRs8XX3xhPVuOPvpoe31msDMhnhBTVBECt3PG8hhXeH/gCRGVlDRVEaJjx4627PEaoS6wEkGq
IoSrZ7io++AdkI4I8eijjxb6DM8HcjvkWoTA3sGjJBTcCKPgeOeZ48ozNHaTiRDk+PB55pln7H4X
EpZOW42CvCIc9+mnn0aKEPtGeMq6tjt27NiMRAgEjBAEO9/oxyuJv9u1a2cFkiibMtWyT0WEYOWT
sP3RL/hCVrZEiJtuusl+ns18IOVShEgWT4aLFR0Y7jyhAolbS0UXIaI6MSFKnD9nxQbTP79vzHff
xUSI4cNVd4X6XVFmRIiy6gnBrB3jK2Z7Qxg3+cYasfIMhBPBoJPv4AacLRECwzLqus649QfijP94
T24j/AB349atWxfYz+aHNjBADr/HSh3MbobfS/hzlnd9YuUZ2GOIuQ3jBRGArPTJlsQjlwBiB8f6
ODduRIV0wTAijn7fDMIdo+LYnSHnZmgxRhOJIfHCMaLKjneVqQhBTggMOcIGOJ5ZehKDfsfYIokI
kU49S2SrUCYh55xzToHZ5lyJEHjLJBLQaJ9+eUYteZpIhAgNydDgL2oZJhMh8HoIcR4sLi9NuiIE
IU8hLoTIzzfBeVlhgjKmLMkhQbhEumWfiggxf/78Qp/RNnwvn3jnoJwkQuRAhEjU8aIS0dlEdXLH
HXdcZCWraCJEcWSaFSJt1q01pt+WeSOVh2jI9OSk7FXdFep3RZkRIcpqTohEnhAuiZ/DeUIQ+xwP
5wkxfvz4rIkQ8WZX3eC6NOWEiJd4zt/IF5AIxqwcF0+EyHT1BVbGID49XRBrQiHGTfbhFYPRSQLH
eLhwBryTk0HoTMOGDTMWIXyYnSd3AKIOokQyEcLVs9BYSrWeOVsl6h4xdgl98N9xixYtCh1H4kWX
EyITEYL8EbyL8H25zRm3icqzKCJEUdtqsnCMqJUsQk8Il78h9NrAhowSIQihiPcu/fAHB941CB8s
e4vXjVsyNdWyT0WECH9rsHEROXxPCNry7RGryRERoHCMHIgQqEC8BCoMDdhXynB7891dCvyAd+5s
f2SjVB7lhBCiFPBBM2PGnR/7f4MGxkQMiIUQorSKEBg8rFSBKIB3gvNSGJeFFSxyeW5gME0yPd8z
ACMzzAkxZsyYuEsoOnBdZ5yWyVKQ8UQIkgtGje/cqgulSYQgySKu3Bg6buNvjBMmyvgb9+xEkNQu
akb9mmuusWU7JwhXTAVmopmM2zcHiZ/xFom3RCcrS+DujvFI4sdEYJxhDBXFEyIKkgfyXZcz4IYb
bijwd/4w5IMPCs1+w/3335+WCEFYSdgmQlf6yy+/3LYv3y757bff7PMXRYTgGoQFhCJAOuVZFBGi
qG2VfoeyijfDT380ZcqUAvuPOeaYAjkhEEC5FmFRPuSpiZcTIlzdh3KkrUUlSXUglPBdBIl0yp6E
o3yPkKF4IgR11AcxJBRFENbCECfCrfzVNlJpOyS8VGLKBBAzRiwcWZsRHqj0jRo1yl9OBlDAomLo
fBU2Ko5RIoQQpYDxFxnz/gGx//Njm+UOUQghcilCOLEArwTCI8jTwL/8nY0lNHN5bowvkrDhHs7A
mhlDXI0xwtnvg7iAIYDhycCdMRh5AfxkfogUjLkIkXWrY2DYZbo6BsZrq1atzBZbbGFXOsAF2s+4
zxKDicDQcEvWpQNGT1GW6AyfLSonBCsLhMICs56EkJBcnXLjeQmN4bjQ6GRFE/b7MMPOO+FdYhgz
ZkZowrh77733Ct1XlOt6OhACgdDD+fEywChjZQDG3iTXRODyZ6Xx8CB5IytYcD8YThitGFWUUVQ7
S1WE4DmpDzw7xiZhIqx+QP1xuCUuWeWB3CXkzUCAo55RV9zqGOS5oM7Wq1cv7dUxCAFxq2OQCyJc
HcPZLLQR2hCCU5MmTWz9L0o4Bl5KfB9vEsqUsuU+WPkBLwsXJpUrEaKobRXoh+It0YmRz79cl3pG
olbO+9BDD+Ufxwod1CWOwyuC40g06VY5iVodg9ArlqnkXbjVMajLDkLREAH79u1rv4+tybLDiEaI
R+mUvRM4uUfqGPUPocovZ4QovEr43K2OQf3w87EgjtEX09+6PpZktPQbfn+X6F0jmNB/hMKbRIgk
0ImxFAqVIBsiBF4WNHJ/Y4kqljbxoYJGdQadOnWyBR2em2PDBCZUGH4gfGjAHBsmMaNi4MkRdvgc
y6yED51Y1A8tS/joOfQcpfo5vn3UmL6sirHGdGEAlTdw0fvQc+g59Byl4TkqwmQFRhuz5LgXM0Bm
eT0G49sGfTFGBsYjM9scy4CXJfkYbPuQyA2DkNl/3IMxqn2jJp6hHs4C+4NlDHYG/SzBiDcsCQ2j
VjMIKYklOkOok5RD1H4MiVAEIDkis+WEEpDXDIMlyojg2cJkmbQVxsa8G4QB3MRZrSMqRIb9lOeS
JUuK9HwYR6zkwbgZb2UMeYwxZnvDRI/M/jNrzGQiZcI9Mp5H4IqXyDdVEYKQIQQO6i33gABA8kX/
HhAcuD455Cg7v/wpB/Ia+PUMb45URQjOhfBA2+H83AOGbphoEF599VVbBrQRkugzc099CNsA9TBV
EQIwirk+Rjd1B48L2iKr2tBvZiJCINjwbFEiRFh/i9JWgXJA/Aw9fpwY4xYdoP/hGR9//PFC5yAH
CNdF/OE9UB54aXCvvghB+6EvIwyEesP7QuhgNZq13iptvCtWXqQ9cl2Oadu2rfn666/TLntAoMAD
gev5nguIENwjk+94BNE+aE+ILeFvKPUYcRLRC9EH4QYvkXQSU9JmeUdh6Fe2RAhWCOK3hHqKEMP7
490h7PFZmRUhgA6agsX9TeEYyQkHfEKUGn75KBbjvGSmMc89ZwyDKq+9qu4K9buipKiIHpMMcDGQ
GMgXF84TgiSK4bKBUTgX5UzyT4gYGGjMuJZmEDhYESTTcAxR8qTTVjH+99prL5swMUqEENmBckYQ
yEX7L/eeEL4IgbhAJ4USFC8xJS4qFX1wkSiOU4gSZcUvMRFiztusjRRbIcObEVHdFep3hUSI3MHM
Ja7L5C/A5ZgZQmYjM13SMRPckqBsYQI6PFxwuca1GhdlXLyZIeQ+RWYwi8tMcWgclCaYVfdXGJAI
UfrJRlvFqwSbzs/JIBEiuxCWhEdHstV6JEJEgGsVhYc7i4MlcAiriFqiExetii5CCFFqIWHVgOrG
fHWvMWQQRoQYNEjlIoSQCFEMEK5Su3Zt62pM/DEu5C7nVnFBXLTLJM+yjj7kDiDhnwsxwCDB7dkf
74nyB7O1/goDCxcuVKGUcnLVVuOFpYjS+5tZLkSIc88919xxxx02wRHq2HPPPWc9GxAXfJWekAzi
Z/jxRIFzcUP8sLrEIRIhhCilfHSYMWPOjgkSJPB68EGViRBCIoQQQgghEaL4IaaWrKCoamTxJIaN
ZDpffvll5IMfffTRNtEGbmZt2rQpkJFWgwshSimfX2nMu/+sD46H08UXq0yEEBIhhBBCCIkQGlyU
VcLMqkKUKmY+Y0zvSsasWWVM27bGHHqo6q5Qvys0ThBCCCHK2G+mRAgNLvJRLJUo1fz6aSw55e9T
WKfImB13VN0V6neFxglCCCFEGfvNlAihwUWBZxWi1LL6j5gI8eMbrOcUS075z9rlqrtC/a7QOEEI
IYQoG7+ZEiE0uBCi7DCwtjGTbjPmiy9iIkRE3hchhNA4QQghhCi9v5kSITS4EKLsMOoEYz4+2ZjF
i2MiRO/eKhMhhMYJQgghRBn6zZQIocGFEGWHiTcZ886usf/XqGFM164qEyGExglCCCFEGfrNlAih
wUU+VAQhSjWzXonlhfhrqTGHHGJMu3aqu0L9rtA4QQghhChDv5kSITS4yKdTp05qGaJ087//xkSI
RROM6djRmAMOUN0V6neFxgk55KWXXjIbbrih+emnn9L+7s8//2zuvvtuM3ny5IyvP2rUKHv9Tz75
JOFxXIfj2LbaaqsCnx122GHm8MMPL5Xl++6775oOHTqYvffe22y88cb2/qOYM2eOOe2000zdunXN
lltuaapWrWqaNGlinnjiCbNmzZqUrvXnn3+aa6+91uy0005m8803N40bNzZ9+/ZN+V4XLlxozj//
fLPddtuZLbbYwrRo0cKMGDEiZ2Wzbt0688Ybb5gjjjjCVKtWzWy22Wb2+a+88kozd+7cQsf37t3b
HHLIIaZGjRr2WJ6TFYjGjRtX6FjKz9WXq666Sh1ZGm3dtbXQcCwqw4cPzxvWHWDrN+cfNGiQ3U8d
bdSokalcubLdP2XKlBLv24RECA0uhKhI/L0ib5SxkTHf/58xPXoYs/XWjFJULkKIUj9O+PXXX80F
F3TOG0yfaOrXP8X+y9/sLyq5PPeiRYvMZ599ZlavXp32d7/44gs7yH/llVeKTYTgXr8MkhZ/++23
diuNdOzY0TRo0MC0bdvWNG3a1Gy00UaRx02fPt0KAC+//LIZOXKk+eCDD8zVV19tn/niiy9O6VrH
HHOMNeafe+458/HHH5tLLrnEfr93CvmVVq1aZYWSOnXq2OMxGBFFNtlkk6TvJhPWrl1rzjnnHHt/
7du3N4MHD7bX6dmzp9l5553tc4wdO7bAd3r16mVuv/128/bbb5vRo0db47VZs2ZW3AnvkfY6YcIE
e37KUZSsCIHgtO2225qWLVva+k07Xrx4se3DqGOnnnqqfafsX7FiRVauWZS+TUiEkAghREVjcH1j
vrzWmHfeiSWn/OUXlYkQolSPE5hBrlfviLzjxudt62zXtcEGa+3f7C+KWJDLcxcVJ0JgOBeXCFHW
WOcJ6czwp/sMGOoYaX/99VfC44YMGWLPHXo+HHvssaZWrVrW6E/Ek08+ab+P4e7AA2OvvfYyzZs3
z3q5dOvWzV7vwQcfjKzzu+66q9lxxx2toZqIJUuWmE033dScd955kZ9LhCgdIsS8efPsOR966KEC
+z/99FO7v3///lm7VrZEDCERQiKEEBWJ0W2MGX6UMd98ExMhcjADI4QQ2Rwn4JUQEwlMxDbOfp4p
uTx3PMOE8AZmxT///HPTqlUr65qPm/wDDzyQb1Q78SDc7rnnngIiBe7yzIASHkB4QWhsZEOEiArH
YGafe9lzzz3ttatXr27d/n3Xfeeq/8wzz5g99tjDuvjjFh4VwoARhWdB7dq1rdFLKMCZZ55pDeZU
yUSE4DvcVzIRAW+JKlWqFDquT58+9ppRIQs+Rx99tGnYsGGh/d27d7ffnz9/ftbaFDPTeDogcMTD
3fcjjzyS8Fw879Zbb20uuuiijEUIVwfxALn55ptNzZo1bcjPySefbBYsWGCFEMqXMBU2vFuWL19e
4Bx4aRAqssMOO9hwg3322ccKLH///XehupqsbSUSDKLay7Bhw0zr1q1t3aSu77777uayyy4zv/32
W5FEiEmTJpnTTz/d1ivCW/71r39Z74KwfLtGJBHfZZdd8vqmCwqcz98Qmfg83O+341T6D/dMlMGF
F15o3w9/U8cy7dscX3/9tfUu4pjtt9/etsX33nsvpf5Kv5kSISRCCFHWmNLFmLdqMII0BrfV559X
mQghSvU4gfCI9V4K4bbW7LbbiYavZ7Lx3UTn5trZFiEwBBjM169f37r2kxfAGdCvvvqqPWbp0qXW
A4J9Xbp0sW7PbOSJAFyuMdYZ9L/55pv5RkIYvpENEYL7RWBwYPjxNx4EGJWENpCb4Y477jD9+vUr
YEARfoBRwn6OOeGEE+z+AQMGFBAgMEwxMB977DH7bBhDGKaEUWRbhOD+f//9dyuGYAzfcsstSb9z
0EEHRXosYEhxzeeT/JbidYDXRYgzuj766KOstSkEEc552223xT2G/BaVKlWy7yMEDw08Q3788Udz
6aWX2jIKQ3QyESEwjBEzqKvPPvusFTeoW4ceeqitR4SoICwQ/nHdddcVOMf1119vvUmoa4TCUE8w
XENxJJW2la4I8fTTT1vPEnIsENLAecgHggDniyDpihCUB3WPd48hSTnvv//+Bc4ZCo8Ovkt7d+1n
4MCB9lhyltBPkEdm1qxZ5qmnnrL7EQHY78KqUu0/3DMRwnPFFVeYDz/80IbrIE5l2rcBohvCJc/B
/vfff9962/A3IVUSISRCSIRIA9REIUo9P/WPJadc+asxdesac9NNqrtC/a4o1eME8jREiwRuS/Z5
5t/l2tkWIRj4s4+ZSB9mro8//vj8vxPlhMAAIgdCODNPm8CLIJsiBPfrixAYDRz7wgsvJDwnxzBr
7Ye0cL94BOAZ4cCQxBshHcEhUxHCeR64rXPn1DxduN8ogx1jyhl5icDgw4iLJxikk+AyGZyLc2IE
JoIElFHeEuTYcOWDoY/Rn+gdpypCkJcgFBbYHwoOeAdgyMaDOoShTj1EsPBDSlJtW+mIED7M5nNt
vsdx5NrIVIS48cYbC+zHU4T9JBNNR4QABKMozxb3PG+99VZG/Yd7Jud1ka2+7aa8sSdiQ5hrhmPk
CSERQiJEmqAOClHqWfxNTIRYMJLe3pjWrVV3hfpdUarHCeXNE4KBuj/Qd5Bc0XfZjydCfPfdd/kG
BwaRv7mZT2fQ50KEaNeunXWhTgbnw4093rWcVwdeEL6BkksRAvd/6hqzz7feeqsVP6LEgbIgQoTv
PlsixDfffGPrHt4qhJEwQx9vFY90RIjQWwRviCgvEDw42O+HZEycONEayMye+yIShiwz/Om2rXRE
CEKCCL8gHAPvEf/6fs6NdEUInil8n3gXEZaUSxEinf7DPRNeTNns20h4ut9++xU6jr5OIoRECIkQ
QpRH1uYNVPpsasz0nsZccw1yuMpECFGqxwnlMScEMe0hrN6AcZFMhHDJ5uJtGGYckysRAsOUuPhU
RAjc+UNwb+ezqVOn2r8xvFJdoaKoIkRIjx49Ig3CEMIxMJxCUg3HQGjJdjhG+N5dPXHCBiJLPJYt
W2brSZSw4kNoBnV13333LbIIEc7Gu7YRtv0wcSNtByGEmXu8BFjVg+84g9mv26m2rVRFCDwFMJYR
bMhLwX5CUxA+QoEgXREiKg8I12nTpk1SEYKcEJmKEOn0H+6ZosJxitK31atXzyZ1DSEsQyKERAiJ
EEKUV4bsZ8xnl5LpidEf8rvKRAhRascJuPPHVrAY98/KFW4Fi3FFXsEil+fOlQjBLCX7ycFAuUVt
xPznSoRwnhDrkizxnKonBDOnxx13XImIEMTG8x0/l0UUiCnkMIiXmHL8+PEJv4/BlSgx5S8ZrFQV
vnNniJDPgWSDJAGNh3P9f/TRR5Neh1h9EheWlAjx+OOP27/nzJlT4DiEn0xFCPfeZs6cWeA4vD/8
c06ZMqVQPgNw3gRFESHC58YTgfAS3xOCcmfZ1BDqYqYiRDr9R7x3VNS+DUEvSthy55QIIRFCIoQQ
5ZGx7Y35sKUxzLww4v7+e5WJEKJUjxMQA/BKIDyCPA38y9/ZWEIzl+dOd6C+22675f+NpwDfZXWJ
EBK/nXTSSUmvnwsR4rXXXrPHvvjii0lFCHJC+CtcMLNOPLqfE4LVEAhXmDFjRrGLEHfddVdKnhBu
hjYUKxBPcNNPJsg47w8/dACjk3CIFi1aZL1dOXEj3hKdzKTjnUEC1ESsXLnS1rWS9ITo2bOn/ZtQ
GgfljSGbjgjhty1EI75LUkafDh06FDina4NhuAy5RIoqQtxwww0F9uPlEeaEoK2E7ZzQGI4rSk6I
VPuPXIkQJCLF44LQn7A9SYSQCCERIk3ITCtEmeDr7sb0r2LM7NlWhBiYNwgTQv2u0Dgh+yRaxi7Z
QJ2YeDwOWOqO5IB4RjgXbowLZkkZtDOry6Cd9kAW/7POOivrIoS/tB9CwpFHHmmFA7L7Y6APGTLE
ruLhG2tudQwMbfaTxI/cDxgf/lKAeETgDYErOrPeGFkYTXgfJEtWOTvvdwxDks0ltWM2m799F3Lu
7fLLL7ceAJQlZcXfzDyHYRIYlsT+h2WGNwMeBszA40HBjLVbetKHRJuc15+5Z0lD3jnlwfGEX5CA
kTJkxYWod1EUQwwjnTh8ztO+fXu7sgPPjUHPSgc8R7isKGIIuS3eeecdW2+ouxj6hMsQNlJSIgR1
gNwdCGHUNVZnYGlHDOkoESKVtoVHCwY+Ygzth/NS31hO0j8nQhGhR3yX41idA7HLJe8sigiBKIIx
zsoUbnUMlsn083vcf//9tr1Qf1k9hPfHtbfZZpsCySLTFSFS7T8yESFSKX/6MZKPUv54elH+CEAc
wznHjBmjH0eJEBpcpMrZZ5+tliHKBvPeiyWnXPojvn7m7MaNVSZC/a7QOCFHIgRGRLiMXdRsIUaF
P1sLGO+48WOshkYPs7QY0BjvfM7MNvka/ISEGBupLHmXzhKdsGrVKvsdDEEMRAwKrj1hwoRCBipe
ABhy3CMhAhg9hX6W5s2zHhE8A8fVqlXLGtHJvFGcIeTHs7v/+zPFJNbDcGWpTIxq3NnJ80Ccfxhi
0bVr18gyI48CSyByjzwzyzRGhXHwHsN3DnggYIyRXLFy5cqmZcuWkQkfWTUBEaSoniGA4MG7q1at
mr1nYvExoufOnVvoWGb3eSYMXMqI5zzjjDMShpqkKkJQHlEiBPvDtu/K3zesEEG4N8oNzxPELwSB
8D2l07YIqcAIr1q1ql0elnc7dOjQQudkBQcEqCpVqljxhjZH+UWJEFHvPcQ936RJk2y4EnWRcyMW
LVq0qMCxhNbwrIhXCJK8S0JE0klMGVX2qfYf8d5RNvq2adOm2TbJO6VNIOq5lXe++uor/ThKhNDg
Qohyx7LZMRFi3hBj+LHo1EllIoTQOKEC40QIvBzYskEqBqoozIEHHljqBVbqCDP2escimyBEIMj8
rVxlEiE0uBCiHELsar+tjJnWw5gzzjDmqKNUJkIIjRMqMMzOOg8CZmYlQpQMS5YssR4LycJQShq8
B5znid6xyAS8SAhtwhuIcCEECOoTgqiQCKHBhRDllQ8PMmZcBxbkNmbnnVUeQgiNEyowxGi7zPiT
J0+WCCESQkiAqy/hqhVCpALJU8lvQfJahDfCOMgJIyRCaHAhRHlmwsXGDG1CUF9shYzly1UmQgiN
E4QQQohS/pspEUKDi3z8LLVClHb+/PJ+89erlczJdXcxO+e10RPr1jWd8+pwNpakE0L9rtA4QQgh
hMjNb6ZECA0u8gmXaBKitEKG7uuPrmmTU66ruYHpnddG1+Zt4/O2I+rVkxAh1O/+P3vnAd5U+Ubx
ssooG9mILFki4kKGjAr+QbAOFAQHFBdLxYETGSoCijhQnCiIUDZlQ9l7y97I3hTZZbac/z33NjVJ
0zbpoknO73m+p83NTXK/775J7nvyDqHrBCGEECKDfmdKhNDFhRBeByMe1uQNsDpk3B9gpWPEjuXG
6KZfl4UQuk4QQgghMuR3pkQIXVwI4XU0q1oVNyg6/GiMJx1FCEZE8H4hhNB1ghBCCJHxvjMlQuji
QgivI6RiRUt0+NAYbziKEBzm/UIIoesEIYQQIsN9Z0qE0MVFHEuWLNE7Q3gFcZEQLxhjQACWKBJC
6HNX6DpBCCGE8IrvTIkQuriIIyQkRO8M4RWw5gOLUCLYGH8FICSTU02IZs20SEKfu0LXCUIIIUQG
/M6UCKGLiziioqL0zhBeAbtfsAvGpgpWccqoUlYEBAWI4OzZcTJrVuD774EbN7RYQp+7QtcJPkC7
du2QKVMmc9x5550+M6/ffvvNnFPu3Lk9etykSZNQv3595M2bF0FBQbjjjjvw66+/Jvk4duSpV68e
ihYtiuzG92WJEiVMMXT58uVpNsdr167hxx9/RK1atczjzZkzJ6pUqYIPPvggnvNBvvvuOzzwwAO4
5ZZbzGMsXbo0Wrduja1btzrsd+bMmTib4Pjqq6/0RjHo1auXuR7uvKc8tTt3GD16NKpWrWqeZx7H
xo0bze2DBg1CeePaLTAw0Nx+7ty5dJ2vkAihiwshRKoIEd1fetYUIb56qpiZgsEIiZNHjgBdu1qR
Ec8a91+8qMUSQtz06wR+ZoV2DkXVOlVRsU5F8y9vp0ZL4bR87owkQtBhXrVqFTZv3uwTczp8+DDy
5cuHkiVLIk+ePG4/rl+/fsiSJQtee+01REREYP78+Rg8eLA5kuKHH37ARx99hIkTJ2Lx4sWmw1iz
Zk1kzZoVixYtSvU5Umht0KCB+fxdunTBzJkzsXDhQvTt2xcFCxY0BYadO3fGcyo/++wzTJ482TzG
oUOHolKlSqbDbL9vTEyMaQ/h4eGmEzpw4EB9IMWuX+bMmd16T3lid+5+FmXLlg2PP/64ee54fi5d
uoT169eb5+jVV1/FsmXLzO08f6n1PuLzCYkQEiGEEOnHpNuAde/F3z5qFBAUBNxxB+B0gSOEEOl5
nXDixAmUv6c8Al4OQEAvY/SO/Wvc5vaUiAVp+dwZTYQoU6ZMqj8vHeTQZLR1vu2229C7d+8Uvfaj
jz6KJ554wnx9d3+RXrt2rSlADBgwINXWgL9I89fptm3bpvr60umk8zl27Nh49+3atQv58+dHtWrV
knRIt2/fbj5Pz5494923b98+iRBOIsTNioRYunSpy/M9YsQIc/vq1atT7bUUSSgRQiKEEOLmsaC5
MRKoAcHQzUqVACr9EyZorYQQN+U6gVEJpkjQ28V4KcC8P7mk5XPbYOg/UyAYGl+uXDkzXN6Vo0NH
kiHXd911lxmKTQeTIfhTpkxx2G/kyJHmdjpAHDVq1MDvv/+ebBGCYfkvvvgiChQoYD5f8+bNsWfP
HvP4khIKGjZsiPbt23u8JjyWTz75JNlr+tdff5lREEeOHPHIGaRgwfSLK1eupJoN87zxF3GuYWpy
7NgxMwLikUceSXAfRnXwPE1I4js6MjLS3O/TTz9NtgjBiArux8iRl19+GYUKFTLPwQsvvICLFy+a
v6g//fTT5jZG3bz//vuIjo52eA7aEyNHGMXB1JJ77rnHpe1SpKLIxMiPu+++23w/VK5cGX/88Ydb
goHtWA8cOBC3jVErDz/8MIoXL+6Q0uLsjHsqQjDN5aGHHjLtqnDhwmaEDaMXnNd32LBh8Z6D223v
A/uUKdvg+4vDebu98Ddnzhzz9W2pOnXr1sW8efNczmndunVo0aKF+V7nOUpovu6uP2GBaH4e5ciR
w4xK6tGjR1yalP36C4kQEiHSiG7duumdIbyP9e+j2+OJhBMy59C4qDDTM959F7h+XWsm9Lkr0vU6
gekRcVEKzsPYXrZmWfx99O9kDT42sefma6cEXsQztJtOAsPjx48fb16wly1bNl7IN505buOv31On
TjVTBRh2/z1r9MTCC3xe3NPZo+M5d+5c8yKUjkRyRAg60HRa6GR8+eWX5vPRUb399tsdHKSMJEIc
P37cdIB/+uknB2fQHSgC3XfffaaIUbFiRTMqolSpUqYzytoL7kLnmvvTweT54uszyiI1Yf0JnoNf
fvklwX1sEQ6dOnVyeYwUW7gPw/uLFCmCQ4cOpViE4Bq+a1wP0FZoMxRKWrVqZQpttFc6wFxP7vvt
t9/GE4HoONFx5n50pOi8O4sjtI9bb73VrNXBKADuz9fgczJNwd65dpU64UqEYIrK119/jenTp5vP
wXXlXPjeTK4IQWGRDjvFIK4HRRamU9gXTbat759//pmoCEHhj7U/uK1///5migTP3bZt2+Le93wO
bt+7d2+cGMftFBYodk6bNs18bZ4TeyHCNieuK9OJeJ9N3HS1hu6uP+tVUHygEMroDX5uUcTk4/mc
EiEkQkiESAf464UQ3gJDjLu9HopmtUugWqkANKtf2bztMvSYBSp5cWJcrBlXnLwC1AIKfe6KdLtO
YJ0GlyKBbVQKSPz+FDyWr50S7r//ftNJuW4n4PJXYzrR9hf+vLDnBT6djYSg40GnmWKFpyQkQtAh
c+Xo0glyJUJwHvaDxR353HR47bc74/w4HgtTA5y3u8NTTz1lFoe0n5u7IgSdRv5izF/i6fCxvsLH
H39sOm3PPfec2+vJGgu2X6X56zefJ7WxnYPZs2cnuM/ly5fNfej4uZqr7Rgpem3atMnlc3gqQnRl
3Sg7nnzySZeCA39Bp+CTEBTAeM4pQLCIpj18z+TKlctBNKGgwvdNx44dkxQMXIkQjpc1N8zXZh0P
7me/Np6IENzPXiQkFGK4nbUbPBEhyIIFC1xGttjmY/85yQgO2jEFJue5MZqKxUmd5+QqsimhSAh3
1r9ly5ZmFJC9E8zXp3ghEUIiRLJIqNqwq1AhDoY0+bsIIYS3wBzo4JrlscK4wL4xwuqQEfNXgHmb
2xPMgWbRrWLFgOLFmbiohRRCpIsI4a2REBQbeCHu7LQR/iJsf+H/4YcfmrePJyLyUijgPitXrkw1
EeK9994zn5MpGfbQeUjIQXJn2DsfNgcqqeFOMcBx48aZzvWOHTuSJULwV2q+1pgxYxy2v/XWW+b2
f/75x63n4a/Ta9asMSNbGjdubL6+cwi8uyQkxKRUhGAxQ/5qzvQdigGMhHBVlNRTEYK/ittjs93d
u3c7bG/Tpo0p0NjDNWrUqJGZsuF87u2vPegE16lTJ94x1K5dG83s2oh7IkIw0oDHVMy4juHr2b++
fQ0GT0WI06dPO2zfv3+/uf3zzz9PUxGC58G2r7MNMRWGc7Slhdjm5Or8JyRCuLP+tClnEYRQ7FA6
hkQIj0ms2jDfcFTG+KFmPxJSVyVCCJHxYMQDBQeKD85jubGd9yfI0aPAgw8CbOPJXz3UxlMIkcYi
hLfWhOCviLwQ5y+jztBJsL/wZ449HeTE4EUnH8PrtNQSIV566SWXr2tzbu0dpAsXLpjnyTaYfnDv
vffisccec9jOYZ/awAtk58cxH71Dhw7xHpcYfH22xmQqAEUT26BjSRHg7NmzpvCTGDYHlPvaw9QX
zpeigqcwCoSpCNWrV/f4sTYH1X7YumzY0jF+/vnnRMWQhNIxXK0dz1VKRQjn82RzYp0dIWdxiP4C
I05Yl4Fi0ooVK8znYiSKs8NKJ9g+pcEGC6EGBwd7LEJw/rS5ChUqmDUoWMeAr23rDGIvEHgiQiT2
3nn77bfTVISwFatMTNSzfVbY5nTq1Cm3RQh31p/nk+lIzjBVSiKERAiPSazasKftaCRCCJHxaNag
alwEhPNgRATvTxReXL71llUn4pln+O2uRRVCpJkIwV9IzQ4WLzl1sHgp5R0s0vK5E4uEsP2KasP2
azKLESaELRKCzltqiRAJRULYHKeMVBPClcPuPJgakBhNmjQx90tIhJiQzCLM7IzB3HhPoVjjLMRc
iP1OZVQMndymTZsm+Hhb6D9bhiYFU2dcRS6nlwjBaBP+kHn16lWH/bp3755sEcJWmNO5nsdXX33l
8Jysx+Jcz4DYogmSK0K4mrdtPW2REHxP8/avv/7qsB8FgZSIELNmzTK3sbWssw05i4EJnaOUihAJ
CVu255QIIRHCbZKqNuxpOxp/EiFYPEYIbyCkQUUH4WH7AEchwrzfHRi+yM+DqlX5BtDCCn3uijQR
IWxiAaMSmB7BOg38y9up0UIzLZ+bnQBKly7t4CTRyXSuCcFfZhNqoWiDYd785TE5rSATEiFmzJhh
vq6tyKOzc5eRRAjmpLP2AiMFbIO36aSzsCZvs1NBYtjSjRllYM8bb7xhru3Bgwc9ngt/+WaRy+RE
QiQFo0USatG5c+dO85qdURg3kohKZHcMdkRI70gI+x8uGRnA2/YpJ0wX4PvDuX6Au07wqFGjzNdm
aoyz4GL/nCzC6CqViQVeUypCONcmovhgXxOC54b22aVLF4f9GJGREhGCIifPaefOnZM81rQSIVis
kn6hfYQFa31UNa4LVRNCIoTbuFNtmNtYFInhbLaKwmxF45wP5Y8ihKs3qxAZEedIiJB7PIyEsGfb
NoC/rPCzYtw4La7Q565IExHCW+Gvlbxe4oU7q9cz3J8F4+iEc7s9FBd44U7Hk04Tf51nXQD7wncU
KegwsCCcrTsGnaDkdsegg/Tggw+av1B/8cUX5i/D9t0x2FEgMeiU2LcLdBc6OSlp0ek8N1c/kLFl
prOwQAeYKSRsf8p143yZGsP9Xn/9dYfHs2sCt9vDnHieE55LOox0Dik0MWKBnQlcOakpccRYfJBC
D5+fTiy7rbBFJiMgWJSQDvyuXbvi9meEB4uhskgkj4c1GHhdz/aKXCNX77P0ioTgcdtsl3UuKCDw
XFDA8SQSguth4/z586bvQgGI54TdGVi4lF0v7J+Tx8b1YhcHpmBwv9atW8e9dnJFCNYn4fuK54Nz
snXHcK7R8corr5hCBLtz8D3L/SkepUSEIEzJ4OcI58IUFwpx/IxhgVv7FJ3UFCHs15/dMTgvFsKk
UMbPLdaM4JrwOV11YxESIeLhTrVhTpQfbHwDcTCPi611GN7lKg/Pn0QIqX3CW3CuCXHgO6eaEC83
9ewJjYsAtGplpWe8846VriGEPneFRAgTOkd0kmwOC9saMkWDTpGzIMBrLDon3JeOMttnsoOFPYxa
pePLi3/+skxHzlW+ubPDxA4JrmAqBh12/qrKazqmLDB/31Xlf2duRotOZyiCuEoV5nZXv8byhzNW
+OcPaoGBgaaD7soB59yci2WyLTAdWZ4bOpvFixc3r59dpchwO9fzHFtdpwAKJ+zkwdau7OzBtA9e
d7MNpvOPgEx1oMPLX6K5JjxGtlqkwJVQ5JgnIgTXw/m9Sseb250dIVfnhc/B9eYcWJ+Bwtcff/wR
7zzRPlw5wTwn9r/EE0ZB8H1Cn4VzpV0xysD5OXmOWGyR54QFFVnLgMU7nUUI23zctbstW7aYx0Qh
j10+KBbZCkLaiyU8L7Q5HieLOSZU/JWv7UqEcLX2hCkmTKWnGMPPDa4B187+ORI6RwnN15P1X7p0
qWmbPKesu0FRj59xnNsFpetKhEiKlFQbppG7as1jvwjMGaIx2w8aLNVIe6j6uzJ6hhpxoZ2fm/sy
xMwe/kpAldr5QpX7On8AUwV37jNP1Zn7MjTSHobuuVL7GYqkeWge3jQPKuTsgkHBgZEPFCFC7g7A
qNcCEHxnDpz8yfhI2tAdg777xv15jByJUOOi2CxYSTEzNq9Z50Pz0Dw0j8Tm4Y+1o5iaQSeRzn56
YYuEYBFFjqRgR4Xk1p8QFnR0WXMjI0OBgx1B3BEhhHAXFh9lG1uRdiIEAwco9jCCiyIUv2+rVauG
8uXLm/d5hQiR0mrDVO65H/dPaKFUmFKIjAVznRkRwdQL1oDgX94+efwYsLmP4W1kMbyI2sYHxD7P
nphOC1t4spWnUwEoIYTwx+sERhkw9Jz1C0aPHm3+msgQ6uS2dEwOtpagHIy0sIfi0oABA8xQf4aU
Mx2Dv7jbh10Lz+Cv46zX4OqX54wCr/XtOylIhBDJgQVHhw8fbkZx8IfpFi1amDbF6A2Rdt+ZPhEJ
kdJqwyxAwhAkiRBC+JJKsRyYVAYYmxfYP8qzxzIKon59gPnOX3+tNp5CCL8WIRgpwhpajDjljzbM
q2akSHrCopa2ivls62gPawfcd999cSkGzAdnuohCqX0bXr/bd1I4ceKEFkV4DD8rmOrF9DD6g6xJ
wkgqIREiSVJabXjMmDEuq8P6mwjhHPoqhNfb7tWzwNLWVr2IFe2Bax5ckLIuBEO8WSeiZUurboQQ
+twVfnydIIQQQkiESALnmhBU0VlBmcVxWO2ZYXssikOhgqF9zkVY/O3iIrG2WkJ4re0yimHPUGBM
EDClIvCvh+/l8eMBFqaqXNnqpCGEPneFRAghhBBCIoQrnKvaMneMeT4MuWG4DcMKWXSEQsT5BH7l
1MWFED7CuZ3AjLuBUdmAbQOBGzHuP5YFb6tWBYKCGDqltRRC6DpBCCGEkAihiwshRBJEXzHe1G9b
6RnzmwKXjrv/WOYWt25tpWe8+abaeAohdJ0ghBBCJOM7UyKELi6E8D+OzAQmFLHG0VnuP46pHd99
Z7XxfPBB47FHtZZC6IJK1wlCCCGEB9+ZEiF0cRGHc592IeB1HbsAAIAASURBVHzadhkFMb+JFRXx
9ztA9FX3H7t0KVCiBFC0KLBokU6A0OeuLqgwYsQIh0r9GhoaGhoaGo6D35USISRCOBASEqKrSeFf
tsu6EKwPwToRM+6x6ka4y/HjAHvQs43ngAFq4yn0ueun7Nq1y7xO0NDQ0NDQ0HBvDBw4UCKERIj/
5iqEX9ruv2uBKbdbHTTYScNdQeH6deC996w6EU89BZw7p5Mh9Lnrp0IEz+X8+fPxzjvvoEePHuav
PL483nzzTZ+fo4ZsV0NDtpv6gwLEyJEjJUJIhBBC4NoFYEV7Kz1jaWvg6ln3HztxotXGs1IlYMsW
raUQfgovpHhBNXjwYPPiSkNDQ0NDQ8P14HelRAiJEEIIsn8UMDYvMKkMELnC/cft3AlUqwbkygWM
GqV1FMIPOXfuHH799VfzokpDQ0NDQ0Mj8cHvzHNOkcQSISRCCOGfXNgLRNQCwrIAWz4HYqLde9zF
i8Czz1rpGW+8AVy9qrUUwg+FCP6qo6GhoaGhoZH4OOcilVkihJ+JEAyLEUK2G0vMNWBDd2BkJmBO
QyDqsHuPYz2JH34AsmUD6tQBDh/WCRL63BWyXSFku0LIdlPZ/5YI4QN07txZ724h23Xm+HxgYglg
XEHg0CT3H7d8OVCyJFCkCDB/vk6S0OeukO0KIdsVQrabiv63RAghhO9yORJY+JhVtHK18QVw/ZJ7
jztxAnjoISBzZuCLL9TGUwghhBBCiFTyvyVCCCF8GwoIOwcDo7ID06oBZ9zsgsE2nh98YNWJePJJ
4OxZraUQQgghhBAp9L8lQggh/IMzm4BpdwCjcwC7fnI/umHSJCBvXuD224HNm7WOQgghhBBCpMD/
lgghhPAfmI6xupOVnrHoCeDKv+49bvdu4M47rTaeI0ZoHYUQQgghhEim/y0RwgcICQmR1QvZricc
DAfGFQDCSwHHF7r3mKgo4IUXrPSM115TG0/ZrhZByHaFkO0KIdtNhv8tEcIHiIiI0LtbyHY9JeoQ
MKeB1cpzYw8g5nrSj2EKx48/Wm08a9UCDh3SSZTtCiHbFUK2K4Tf265ECCgdQwjhBjHRwObPgLAs
xjdEHeDCPvcet3IlUKoUULgwMG+e1lEIIYQQQvg1EiEgEUII4QEnlwGTbgPG5gP2j3bzMSeBxo2t
Np79+gExMVpHIYQQQgjhl0iEgEQIIYSHXD0DLHnGKlq54kXg+sWkHxMdDXTvbtWJeOwx4MwZraMQ
QgghhPA7JELAv0SI8PBwWb2Q7aYGrPnwz+/A6FzAlIrAv+vce9yUKUC+fECFCsDGjTqxsl0hZLtC
yHaF8CvblQgB/xIhWrVqpXe3kO2mJud2ADNqAKMCge3fWOJEUvzzD3DXXUDOnMDw4Tq5sl0hZLtC
yHaF8BvblQgBpWMIIVJI9BXjg+QtKz1jwSPA5RNJP4ZtPNu1s9IzOnUCrlzROgohhBBCCJ9HIgQk
QgghUokjM4DxhYEJRYGjbrRYYtTEL78AgYFAzZrAwYNaQyGEEEII4dNIhIBECCFEKnLpGDDvf1ZU
xLpuQPTVpB+zejVQujRwyy3AnDlaQyGEEEII4bNIhIBECCFEKnMjBtg2ABiVDZh5L3BuV9KPiYwE
/vc/IFMmoE8ftfEUQgghhBB+739LhPABQkNDZfVCtpte/LsWmFIBGBME7BmWdNFKtvHs0cOqExES
ojaesl0hZLtCyHaFbNev/W+JED5AWFiY3t1CtpueXDsPLG9npWcsfda4fS7px0ybBuTPD5QrB6xf
r5Mv2xVCtiuEbFfIdv3S/5YIIYQQyWXfSGBMHmBSWSByRdL779kD1KgB5MgBDBum9RNCCCGEEH7n
fydLhIiJicGmTZsQERFhjo0bNyKaIcdeughCCJFsLuwBZj0AhGUBtvQ1PiCT+Cy8dAlo395Kz+jQ
QW08hRBCCCGE15NmIsS8efPw9NNPI2/evMiUKZPD4LYWLVpgTgapAi8RQgiRbsRcAzZ8BIzMBMx9
CIg6kvRjfvsNyJ4duP9+4MABraEQQgghhPBaUl2EWLt2LWrVqmWKDffeey/efvtt/Pnnn5g+fbo5
+D+38T7u88ADD2DNmjVeswjezpIlS2T1QrabETg2D5hYAhhfCDg0xZ0PV+C224BCxv4RETII2a4Q
sl0hZLtCtisRgmTPnh0dO3bE1q1bk9x327Zt6NSpE3Iw59lLFsHbCWHFfSFkuxmDy5HAwhCraOWa
14Doy4nvf+oU0LSp1cbz00/VxlO2K4RsVwjZrpDteh2pLkLs3r3b44NIzmNu1iJ4O1FRUXp3C9lu
RoJtO3f+AIzKDky/EzibhIBL4aFXL0uIaN4cOH1axiHbFUK2K4RsV8h2vQZ1x4BqQgghMgCnNwLT
qgKjcwC7frbEicSYMQMoUAAoWxZYt07rJ4QQQgghfM7/ThURYsWKFfjpp5/MVAxvXAQhhEgzrkcB
qzpa6RmLWwBX/k18/337gHvusYpW/vGH1k8IIYQQQmR40lSEePHFF9GuXbu426NGjULmzJnNgpSs
HbFs2TKvWwQhhEhzDk4AxhUAwksBJxYlvu/ly8DLL1ttPF95xbothBBCCCFEBiVNRYhy5cph2LBh
cberVauGpk2bYsOGDQgODsajjz6a7AP/7bffTDEjd+7cLifVqFEj8778+fOb7UD37t0rEcKgW7du
snoh2/UGLh4E5tQHwjIDG3sAMdcT3//3362IiHvvtSIkhGxXCNmukO0KIdv1NxEiV65cWLhwofn/
4cOHTdFg0SLrV71JkyahaNGiyTpoPle+fPlQsmRJ5MmTx+G+7du3m9saNGiAmTNnYuLEiab4wX0j
IyP9XoQYNGiQ3t1CtustxEQDmz8FwrIAEXWAi/uT+kQHypQBChaE8QEoo5HtCiHbFbJdIWS7/iVC
UCiYNWuW+f+YMWPMVpzXrl0zb1OcYEpGcmAExRNPPIHQ0NB4kRAtW7ZEkSJFcOHChbhtBw4cQGBg
IN5//32/FyGEEF7IyaVAeGlgbD7jA21s4vv++y/QrJnVPaN3b7XxFEIIIYQQ/iNC1KxZE88++yzO
nz+PJk2amCkSNkaOHIlSpUp5fMB//fWXKW4cOXLErDdhL0Jcv34dOXPmRKdOneI9jq9fsWJFiRBC
CO/k6hlgSUuraOXKl4wPvIsJ70vh4dNPLSGiaVNLmBBCCCGEEMLXRYixY8eaKRi2MXny5Lj7WLSy
GX+t84Djx4+jUKFCZncN4ixC7Nixw3wd2/32ML+GRTGvXr0qEUII4Z2wbec/Q4DRuYCplYDT6xPf
n5FoTM247TZg7VqtnxBCCCGE8G0RgrADxldffYXFixc7bO/RowemT5/u0XM99dRTqFevXtxtZxGC
r0URgqkfzvTt29e8j0JGShbB22HNDCFku17OWWMtZtQARgUaC/ONJU4kxP79wH33WUUrf/tNayfb
FUK2K2S7Qsh2fVuESC3GjRtn1pBgtENaiRAslBkSEuIwatWqhfDwcIf9IyIizPuc6dy5M4YMGRLv
ubmvc1HMnj17on///g7bWLuC+zobHwuUOFdKjYqKMvddsmSJw/awsDCzVoYzrVq1Mudhf9zePA9f
OR+ah/vzYDqXzofdPNq9AKx900rPWNAMuHwi4Xk0bw506GC18XzxReDSJdmVPnf1eaV56HNX89Dn
rs6H5qHP3TQ/Hzwem2/NhhHly5c3AwtSVYS4ePGixwIDFzAxWGSSAsG7776LM2fOxI02bdqYIsTZ
s2fN11U6RtLQIISQ7foQh6cD4wsDE4oBR2cnvu/QoUCOHMDddwOJtC0Wsl0hZLtCtiuEbDetSPVI
CIoFP/zwAy5dupTkvtxn8ODBKFasWKL77du3z6G2hKvx5JNPIjo62mwLmlBhykqVKqV4EYQQIsNx
6Sgw72ErKmLdu0D01YT3Xb8eKFcOKFAA8DAlTgghhBBCiAwnQgwdOtQUItjBon379vjzzz+xYcMG
HD582Bz8n9t4H/dhO00+JjGuXLlitvRctGhR3ODtpk2bmt0weHvr1q3mvs8884z5+q5adH744YcS
IYQQvsmNGGDbACAsKzDzPuD87oT3PX2avY6t9IwePYDoaK2fEEIIIYTwThGCsCXnwIEDzXyPhCIX
ypYtiwEDBuDcuXPJPnjnmhCEKRl58uRBgwYNMHPmTEycONHMPWE70FOnTkmEEEL4NqfWAFMqAGOM
z8a9wxPej208+/Sx2nj+73/G405p7YQQQgghhHeKEM6iwPDhw/Hll1+ag/+nVtVPFtyg4OBqUo0b
N0ZQUJAZbdGiRQvsTST/2Z9ECOeiIULIdn2Qa+eB5W2t9Ixlzxm3ExF7Z88GChUCSpcGVq/W2sl2
hZDtCtmuELJd7xYhfG0RvB1WLxVCtusn7BsJjMkDTC4HRK5MeD8WQapZEwgMBH75JfGWn0K2K2S7
Qsh2hZDtppP/LRFCCCG8jQt7gFk1rVoRW/pZtSNcceUKwKK+rBPBtk5uFBcWQgghhBAiLf1viRBC
COGNxFwD1n8AjMwEzG0ERB1JeN/hw4GcOYEaNYA9e7R2QgghhBDipvnfEiGEEMKbOTYXmFgcGF8I
ODw14f02bgTKlwfy5wemTtW6CSGEEEKIm+J/S4TwASIjI2X1Qrbrz1w21nHho1bRyjWvA9GXXe93
5gzw2GNWekb37mrjKdsVsl0hZLtCyHbT3f+WCOEDhISE6N0tZLv+DgtP7vweGJUdmF4dOLvV9X5s
49m3L5A5M/Dww/xm1NrJdoVsVwjZrhCy3XTzvyVC+MhchZDtCpPTG4GpVYDROYHdiXTFmDsXKFwY
uPVWYNUqrZtsV8h2hZDtCiHbTRf/O1kixLZt2/DMM8+gaNGiyJo1a9wL9erVC/Pnz/e6RRBCCJ/i
ehSw6lUrPWNxC+DKv673O3QIqFULyJYN+OkntfEUQgghhBBp7n97LEKsX78euXPnRvHixU0hIlOm
THEv9M4776BVq1ZetwhCCOGTHJwAjM0PhN8KnFjsep+rV4EuXaw6EW3bAlFRWjchhBBCCJFm/rfH
IkSTJk1Qp04dXLx4EdevX3cQIUaPHo0yZcp43SIIIYTPcvEAMLseEJYZ2NQLiLnuer8RI6w2ntWr
A7t3a92EEEIIIUSa+N8eixCMgggPDzf/dxYhFi5ciBw5cnjdIng7Q4YMkdUL2a5ImJhoYNMnlhAx
uy5wcb/r/TZtAipUAPLlAyZP1rrJdoVsVwjZrhCy3VT3vz0WIYKCgjBjxgzzf2cRguJEPl68etki
eDudO3fWu1vIdkXSnFhifFCXtlI0Doxzvc/Zs8ATT1jpGR9+yA96rZtsV8h2hZDtCiHbTTX/22MR
olatWnj55ZfN/51FiI4dO+Khhx7yukUQQgi/4eppYElLq2jlyleMD/KL8fdhgcovvrDaePIz/cQJ
rZsQQgghhEgV/9tjEYJ1HzIbF6Zdu3bF2rVrTRFi4sSJ+PLLL5EtWzZMziAhvBIhhBAiASgy7P7N
auM5tTJweoPr/djtqEgRoFQpYMUKrZsQQgghhEix/52sFp2ff/652ZqTAoRtUIDo16+fVy6CEEL4
JWe3AdPvAkYFAju+c92i8/BhoHZtq43nDz+ojacQQgghhEiR/x2Q3Bc5ePAgfvvtN/Tp0wc///wz
9u/f77WLIIQQfkv0ZWBtVys9Y0Fz4PLJ+Puwjecbb1h1Ip5/Hrh4UesmhBBCCCGS5X8HaBG8n5CQ
EFm9kO2KlHF4GjD+FmBCMeDYHNf7hIUBuXIB1aoBO3fKdoWQ7Qoh2xVCtuux/y0RwgeIiIjQu1vI
dkXKuXQUmNcYGJkJWP8+EHMt/j5btgAVKwJ58wITJ8p2hZDtCiHbFUK2m/oiBGs+sBilfQ2IhAb3
kwghhBBeyo0YYOsXQFhWYOb9wPl/4u9z7hzQooWVnvHee2rjKYQQQgjh56S6CNGrVy+3R+/evb1u
EYQQQjhxajUwuTwwJjew96/497NA5VdfAVmyAMHBwPHjWjMhhBBCCD9F6RiQCCGEECnm2nlg+QtW
0cplzxu3z8XfZ+FCoGhRoEQJY59lWjMhhBBCCD9EIgT8S4QIDw+X1QvZrkg7GAnBiAhGRjBCwpkj
R4C6dYGsWYFBg/yijadsV8h2hZDtCiHbTZ7/7ZYIsWjRIpw/fz7u/6SGRIj0pVWrVnp3C9muSFtY
G4I1IlgrYmt/q3aEPdeuAW++adWJaNPG59t4ynaFbFcI2a4Qst00FCFYcHLVqlVx/6swpRBC+CHR
V62uGeyewS4a7KbhzOjRQFAQcMcdwI4dWjMhhBBCCD8g1UWIBQsWxEVC8P+khrctghBCCA84NgeY
UAwYfwtweGr8+7duBSpXBvLkMfYZr/USQgghhPBxUl2E+O6773DcyyqfS4QQQog05PJJYEFzq2jl
2jeA6MuO91O4fvppKz2jWze18RRCCCGE8GHSPB3D9r+vLIIQQohkwAKUOwYBowKB6XcBZ7fFv//r
r602ng0aAMeOac2EEEIIIXyQVBch8uXLh4iICPN/iRAZj9DQUFm9kO2Km8fpDcDUysDonMDuX+N3
x1i8GChWDCheHFi6VLYrhGxXCNmukO36GKkuQtSvXx+VKlVCly5dTBGCFT5ff/31BIdEiPQlLCxM
724h2xU3l+tRwKpXrfSMxU8DV0873n/0KFCvntXG89tvvb6Np2xXyHaFkO0KIdtNQxFi3bp1qFGj
BrJly5ZkdwwOiRBCCOGnHBgHjM0PhJcGTixxvI9tPN9+26oT8cwzwIULWi8hhBBCCB8g1UUIeygy
rFy50qcWQQghRCpy8QAw+0EgLDOwqTcQ41SUcuxYIHduoEoVYPt2rZcQQgghhJeTpiLE0KFDERkZ
6VOLIIQQIpWh8EABgkIEBQkKE/ZQfKAIQTFi3DitlxBCCCGEF5OmIoQvLoK3s2TJElm9kO2KjAlT
MsJvtVI0Dox3vI/pGEzLYHoG0zSYriHbFUK2K4RsV8h2fdr/lgjhA4SEhOjdLWS7IuPCIpWLn7KK
Vq58xSpiaYMFKlmokgUrWbiSBSxlu0LIdoWQ7QrZrs/63xIhfICoqCi9u4VsV2RsKDawfSfbeE6t
YrX1tIetO9nCk6082dJTtiuEbFcI2a6Q7fqk/y0RQgghRPpxdhswvTowKjuwY5Bjq85jx4AGDYAs
WYCBA72+jacQQgghhL/gNSLE+vXr0axZM5QuXRo5c+ZEwYIFUbt2bYwYMcJhv3bt2rlsBVqFRc1S
YRGEEEKkI9GXgbVvWOkZCx8FLp/8777r14F337XqRLRsCZw/r/USQgghhMjgeI0IsXDhQnTs2BEj
R440/582bRratGljCgx9+vSJ248iRK5cubBq1SqHsWnTplRZBCGEEDeBw1OB8bcAE4sDx+Y63jdh
ApAnD1C5MrB1q9ZKCCGEECIDkyYixKVLlzBnzhxTLLgWW8F89+7dpmhwxx13IDg4GJMnT06VCdSq
VcuMjrAXIfLwYjSNFsHb6datm6xeyHaFdxJ1BJjbCBiZCVj/ARBj1yFjxw4YXzBAUBAwerRsVwjZ
rpDtCiHb9RcR4sCBA6YoYEuDqFChgnFtuAMlS5ZE5syZUbhwYXN7lixZsDgVCoo1b94c5cqVcxAh
crOXvEQIlwwaNEjvbiHbFd7LjRhga38gLCswqyZw/p//7rt4EWjTxkrP6No1w7TxlO0Kfe4KIdsV
QrabhiLESy+9hKJFi+KPP/7A+PHjUb16dVSqVAk1atTAMRYSMzh06BDuvPNOU0Dw+Przxg1cv34d
J0+exODBg5E1a1b8+OOPDiIEBY5ixYqZf0uVKoXXXnsNp0+flgghhBC+wqlVwORywJg8wL4R9l8S
wPffW20869YFjhzRWgkhhBBC+LIIUaZMGQdRgPUYGPkwatQoh/3++usvMzrCUzp06BAXZUEB4lv2
jLfjm2++MbfNnTvXHB9//DGCgoLMwpQX+SuZRAghhPANrp0Dlj1vFa1c/oJx264w5fLlQIkSQNGi
LCqktRJCCCGE8FURIlu2bFiyZEncbfY6pWBAMcKepUuXmpEKnnLw4EHzYGfOnIlOnTqZKR79+/dP
9DETJkwwj8FZsHBeBEZwhISEOAzWnAgPD3fYPyIiwrzPmc6dO2PIkCHxnpv7RkZGOmzv2bNnvONm
Kgv33b59u8N2huU45wdxXbmv/VqTsLAwhIaGxju2Vq1aaR6ah+ahefjmPPq/BIzJDUypAJxa/d88
tm0DgoOtNp4DBuh8aB6ah+aheWgemofmoXmk8zx4PDbfulq1aihfvjzq1auXuiKEs+DA1Aluc36B
FStWmNtTCoUICh9Mz0gIpnCwTgQLY6ZUifF2nA1aCNmu8AnO7wZm3m/Vitj6pVU7wvoSAt5/36oT
8dRTwLlzsl0hZLtCtiuEbPcmkuqREM4iRHR0tEsRYuXKlakiQrD2hKtIC3tiYmLMtp0SIeBS6RJC
tit8guirwLr3rPSMeQ8Dl47+dx+V/7x5gYoVgS1bZLtCyHaFbFcI2a4viRDsiMHCkxwMueC222+/
PW4bB8MwmEqRUl544QWzNsSpU6cS3GfMmDHmMSRUbdSfRAiGxggh2xU+zdHZwIRiwPjCwOHp/23f
tQvGlxKQKxdjFWW7Qsh2hWxXCNmuL4gQDRo0cHs0bNjQ7QN95ZVXzDwYCgoLFy40O28888wzprjw
PkNtDfbv348HH3zQLIw5a9Yss27EBx98gJw5c5rCx6VLl/xehBBCCL/g8klgQTMrKmJtVyD6irWd
BYqff95Kz3j9deDqVa2VEEIIIYQ3ixBpxdChQ1G/fn0ULlzYrAFRoEABBAcHY+TIkXH7nDlzBi1a
tEDZsmXN9Ivs2bOb7UEpRJw/fz5VFkEIIYSXwHad278FRgUCM2oAZ7f/t33wYFZSBmrXBg4f1loJ
IYQQQqQTXiNCZJRFEEII4WWcXg9MrQyMzgX8M8QSIciKFUCpUkCRIsD8+VonIYQQQogM5n+nSIRY
u3at+SK2kZEqf/qTCJFUO1MhZLvCJ7l+EVj5spWesaQlcPWMtZ2dlRo1Alij6Isv/hMoZLtCyHaF
bFcI2e5N97/dEiF27dqFW2+91azLEHftF9um034wpYL7SoRIX9jHVQjZrvBbDowDxuYHwksDJ5da
26KjgY8+supEPPEEcPasbFcI2a6Q7Qoh2/UWEYLFI8uVK2e25nQWIXr37m3WduC477778O6770qE
EEIIkb5c3A/MrguEZQY2fQLExH5fTZ4M5MsH3H67sX2T1kkIIYQQ4ib7326JEHfffTc+++wzh202
EcL+RX7++Wfcc889XrcIQgghfICY68CmXpYQMac+cPGgtX33bqB6dSBnTmDECK2TEEIIIcRN9L/d
EiHy5MmDiIgIh22uRIjZs2cjb968XrcIQgghfIgTi4HwW4FxBYCDE6xtUVFA27ZWekaXLmrjKYQQ
Qghxk/xvt0SIwMBALF68ON52ts+MiYmJu71o0SKzLoS3LYK3ExkZKasXsl0h7LnyL7C4hVW0clUH
4HqUVaDyp5/4pQY88ABw6JBsV+hzVwjZrhCy3XT2v90SIUqUKIHhw4cnuR/3KVasmNctgrcTEhKi
d7eQ7QrhDEWH3b8Ao3MC06oCpzda21etAm69FbjlFmDuXNmu0OeuELJdIWS76eh/uyVCPPbYY2je
vHmS+3Ef7utti+ALJ1wI2a4QCXB2KzD9TmBUdmDn95Y4wV8lHn7YauPZty9gF9Un2xX63BVCtiuE
bDft/G+3RIipU6ea9R++YL/1BOB93If7etsiCCGE8HGiLwNrXrfSMxaGAJcjrTaeH39s1YmggH7m
jNZJCCGEECKN/e8Ad5+0bdu2pshQvXp1dO/eHb/++qs5PvroI9x5553mfe3atfPKRRBCCOEnHJoC
jC8ETCwBHJtnbaN4nj8/UL48sHGj1kgIIYQQIg39b7dFCBag7Nu3r3Gdlt8UHOxHwYIF0a9fP9xg
iKsXLoIQQgg/IuoIMPchYGQmYP2HxhfcNWDPHqBGDauN559/ao2EEEIIIdLI/w7w9MmvXr2KZcuW
YfTo0eZYvnw5rl275tWL4O0MGTJEVi9ku0J4Qkw0sKUfEJYVmPUAcGEPcOkSEBpqpWd07AhcuSLb
FfrcFUK2K4RsN5X97wAtgvfTuXNnvbuFbFeI5BC5EphUFhiTB9g30ipa+euvVhvPmjWBAwdku0Kf
u0LIdoWQ7aai/52qIgR7oC5atMjrFkEIIYQfc+0csPRZq2jl8nbG7fPAmjVA6dJAoULA7NlaIyGE
EEKIVPK/U1WEGDduHDKz3VkGWoS545LuAX9y60kc/ftoguP80fOJX79eupbo4zm4T2LwNRJ7PI9R
89A8NA/NQ/NIo3msPYIz879DzKggXB9bFpFLZyJy2Q6gSRMgUyagTx+cPH4c3UJD0axqVYRUrGj+
fe2J1tg8d7POh+aheWgemofmoXloHn49j5sqQrBQZUYSId4v+36S+w6uOhi9A3onOBb0WpDo409s
OZHo4zm4T2LwNRJ7PI9R89A8NA/NQ/NI23kMKvo6jnxWAtF/ZsGy9k8C140v2p49ccL4PgnOlQsr
jL83WDPCGDHGWG6MuwIK4N2Ad3U+NA/NQ/PQPDQPzUPz8Nt5pLoIERoaivbt2yc5goODM1wkxDA3
IiFWbD2JeX8fTXD8k4RidO7StUQfz3EuCeWLr5HY41e4oXxpHpqH5qF5aB4pn8f8tfuxf2ZnKz1j
3v+AS8fQrXFjU4CAi7HMGM+FtNL50Dw0D81D89A8NA/Nw2/nkeoiBKMbsmfPjty5cyc6cuTIkeFE
iLJuLELV2IVIaPRK4vFbknh8QOw+idEricdXTeSxISEhPjEPXzkfmocH8zBsV+dD88io83j5aAQw
oSgwvjB6hJQ2oyG65Q5As1sCUDS79Ze3jxvbb6taVedD89Dnrs6H5qHrXdmV5uG3n7upLkKUKFEC
nTp1SnK/jJiOMc6NRdjK/RMZR5N4/KUkHv937D6JcTSJx29N5LERERE+MQ9fOR+ah/vz+MGwXZ0P
zSNDz+PyCWBBM5z4MQDBZQKwoncAbowIQMT7AYj5y7jdy9heyBjFi2PLzp1YFxWl86F56HNX50Pz
0PWu7Erz8LvP3VQXIZo3b446dep4pQih7hhCCCFSxI0bCKmRA8t7B1gpGk5jWc8A3JXbLkWDHTVq
1ODPduzLBfTrB4wYAbB71N69wNWrWlMhhBBC+BSpLkJ0794dQUFBSe63cOFCNGzY0OsWQQghhEiM
eyvkMyMgXIkQjIi4t1weYP584M8/zU4a6NABaNYMuPNOIH9+xzoSFOuLFQPuvx9o0QLo2hX46itg
zBhgxQrg8GEgOlqLLoQQQgj/FSF8fRGEEEKIxGj2YHmXAoRtNK9VFDi5FLh4AIhxUbDpwgVg2zbG
EwNDhgC9egEvvgg8/DBQuTKQK5ejUJE1K1C6NFC3LtC6NfDuu8CgQUB4OLB2LXDihBmhIYQQQggh
EUIiRLoTzotSIWS7QqSdCNGgqkMkRPhbjpEQzWrYixKZgInFgVk1gcUtgLVdgW0DgP2jYoWK/fGF
CgoK//4LbNgATJ0K/Pgj8OGHwPPPAw0aAOXKAYGBjkJF9uxA+fIAIxBfeAH46CPgp5+AadOATZuA
M2ckVAh97grZrhCyXYkQEiFSn1atWundLWS7QqQh3V4PNYtS2oSGVrX++5+1Irp1ftZw+rcAR2YC
u38DNvUCVrxotficWgUYk9speiJWqJh5f6xQ8Qaw9UtLqDixBLiwD4h2qh0REwMcPw6sWWM8diLw
3XfGgXUDnnkGYN2mW28FsmRxFCpyG69bxXj9/xnH8dJLQO/ewO+/A7NnA9u3Axcv6uTqc1cI2a4Q
sl2JEBIhhBBCZCROnjyJ4JrlTcGBkQ+2CAje5nbenyTXzllCxdFZwD9DLKFi5UuWUDGtKjA2b3yh
YkIxS6hY9CSw5nVLqNgXBpxY7FqouH4dOHQIWLYMGD0aGDAAeOMN4Enj8ffdBxQt6ihScBQoAFSv
zirUQMeOwOefA8OHAwsWAHv2AFeuyACEEEIIIRFCIoQQQoj0FiIYEcHUjJAGFc2/vO2WAOEuFCrO
bgWORsQKFb0toWJ+E2DaHS6ECmNMKArMvA9Y9ESsUPEFsG9krFCxF4h2EhEoKlBcWLgQ+OsvoG9f
gG24H30UuOsuoGDB+EIFxQuKGBQzKGpQ3KDIQbHj4EFL/BBCCCGERAiJEBIhhBBC+BimULEtVqj4
PVaoeBmY3zRWqMiXgFBxb6xQ8RqwtX+sULEIuLAnvlDBNI0dO6y0DaZvMI2D6RxM62B6B9M87EUK
poGUKgXUrs24U+Cdd4BvvzVedwKwerWVRsJ0EiGEEEJIhNAiCCGEEL4mVJyPFSpmxwoVnwArX4kV
KqoBY/O7ECqKADPuARY9DqzuEitUjACOL4wvVLDgJQtfsgDm9OnAzz+znzfQti0QHAxUqGAVzrQX
KlhYkwU2WWiTBTdZeJMFOFmIkwU5WZhThTSFEEIIiRASITI+oaGhsnoh2xVCtpsMoWJ7rFDxB7D5
U0uoWPAIMP1O10LF+MKWULHwMWB1Z2BLP2DvX5ZQcf4fIPqyo1DBVBV+D0+aBHz/vdVqlC1H2XqU
LUidC2myVWmlSkDjxkD79kDPnsBvvwGzZlktTtnqVMh2hWxXCNmuf4oQmzdvxtixY/Hnn3/GGxIh
0pewsDC9u4VsVwjZbhoIFYbTf24HcGwOsGeoJVSsehVY0MwSKsYVSECouBtYGBIrVPSNFSoWAOd3
OwoV0dHA4cPAihUwLiqAgQOBN98EnnoKqFkTKF4cyJTJUajInx+403jtZsYxdOgA9OkD8Npj/nxg
t/H8ly/LQGW7QrYrhGzXl0SIqKgoPPTQQ8Y1QaYEh0QIIYQQwk+4fjFWqJgbK1R8BqzqECtUVE9A
qLgFmFEjVqjoFCtUDAeOz7eEiuuX/nv+q1eBffuAxYuNx44E+vcHOncGQozH1jCeo1Ch+IU0CxcG
7rkHePxx4LXXgC++4FUgsGQJcOCACmkKIYQQ3iRCfPDBByhXrhwWLVpkCg7h4eGYM2cOnn76aVSs
WBHr16+XCCGEEEIIJ6FiZ6xQMQzY3CdWqGgOTL8LGFfQhVBRKFaoeNTYtyOw5XPjsX9aQsW5XcZz
Rv33/FHG/zuN559rPP/QocCnnwKvvAI0bQrccQeQN6+jSJE5M1CyJFCrFtCyJfD228A33xivOd54
rVXA0aMqpCmEEEJkFBGiSpUq+OWXX3D9+nVThLB/kdatW+PVV1+VCCGEEEIID4WKqFihYp4lNphC
RUdLhKBQQVHClVDB+yhmcF8+hiIHn4PPZS9UnDsHbNkCzJwJ/Por0KMHE3WBhx4Cbr8dyJHDUajI
lg0oUwaoVw949lng/feBH34AJk8G1q0DTp1SIU0hhBAiPUSInDlzYvHixcb37g1kzpwZSxjaGMvU
qVNRpEgRiRDpjP05EEK2K4Rs17eFil1WNASFCkZHMJ2DQgWjJlwJFYyyYFqIKVR0sNJFTKFirqNQ
QUEhMtISGCg0UHCg8EABgkIEBQkKE/ZChXFNhIoVgUaNLEGDwgYFDgodFDwofMh2hZDtCtmuRIiU
iRDFixfHdLbjMihWrBh+Z//wWJiaERQUJBEinQlhXqwQsl0hZLvCqifBuhIUKlhngvUmTKEixCqY
yXoU8YSKArFCRTOr8KYpVAy1CnKy3gXTSQhTNJiqwZQNpm4whYOpHEzpYGpHiRLxC2kyFYQpIUwN
YYoIU0WYMsLUEaaQXLqU5kty8uRJdAsNRbOqVVHUuE7jX97mdiH0uSuEbDfDixAPP/wwvv76a/P/
Nm3aoEKFCmZkxMqVK1GjRg3UqVPH7edi/YhmzZqhdOnSZoRFwYIFUbt2bYwYMcLlpBo1aoTcuXMj
f/78aNGiBfbu3SsRAlaxUCFku0LIdoWnQsUCq3OHKVR0thMqCicgVNxptTA1hYpPrdamFCrY6tQm
VFy7BuzfbxXBZDFMFsVkcUwWyWSxTBbNdC6kecstwN3G6z72GNCli1V8k0U4WYyTRTn5nMnkxIkT
CC5fHiuM17lhjChjxBiDt7ldQoTQ564Qst0ML0KMHj0an332mfn/nj17UKJEibiuGBQRVrDNlpss
XLgQHTt2NL5nR5r/T5s2zRQ2+Fx92HIrlu3btyNPnjxo0KABZs6ciYkTJ6JatWooWbIkIhk66eci
hBBCCCFSGbYSPf8PcHxhrFDRL1aoeAyYcY9roWJsfmBaNUuoWPkKsOkTS6g4Ohs4u81qeUrYRpTt
RNlWlO1Fec3DdqNsO8r2o/nyOYoUjK5gu1K2LWX7UrYxZTtTtjXldRfbnLLdqQsY8TDDeI5uuQPQ
7JYAhBSz/vL2dG73k/71QgghvFiEcObChQuYPHkypkyZgn///TdVJlCrVi0zOsJGy5YtzVoTfC0b
Bw4cQGBgIN5nvqZECCGEEELcDKHiwh5LqNg3AtjaH1jdBVj0uCVUTCjiQqjIZwkV85sCK1+OFSp+
B45GxAoV563nPm/83boVmDUL+O03oGdPoH17oHFjoFIlIFcuR6Eia1bgttuABx9kqCrw3nvA99+j
UYkSCC4UgBW9A3BjhHUMMX8Zt3sFmNsbsaaFEBkU+1SiEMNWlUokhESINKN58+ZmG1DCLhxM1ejU
qVO8/Zo0aWK2BZUIIYQQQoiMKVRcsYSKE4uAfSMtoWLNa5ZQMfNeYEJRF0JFXmDaHcD8JrFCRW/g
nyGxQsVW4No5q5Amf/zZsIGVwYEffwQ+/BB4/nmgQQOA11GBgaiR2xIc4r2GMZb3DECN/FmBJ56w
6lqwCGe7dsBLLwEdOwKvv27VvOAPPt27A72N4/j8c+DLL616GN9/D/z8M8D6YMOHA6NGAePGAZMm
AawfNns2sGCBlZqyciUvzoy5bGKIqzGff6y0lSNH6GkCZ84AFy8CV66oPaowcU4lglKJhJAIkZqw
0wbFBn6YDB48GFmzZjW+S38079uxY4eZnvHTTz/Fe1y3bt3MDh1Xr171axGC6yCEbFcI2a7wZqFi
r+F1LY4VKr6IFSqeAGbel4hQUTVWqHjJcO57xQoVswyHfoslVBjOfLUSgXEREBzdmv/3PyMiqhXJ
BDzyiBVhQfGCtb2Y9sEaFdWqWVEXFDQYocqUENavYLoIIzECA+MX4kytYVzfIXt2IHduIH9+q5YG
C38y2qNCBaByZSt1hXU2HnjAigBp2JDFy6y0FtbgePpp9o8HXngBePFFK+WF9TmYzvLuu8BHHwG9
elnpMKzdwRSXQYMAXnMOGWKlyrA2B9NewsON9Z4GREQA8+ZZ9TqYCrN2LbBxoxW1smuXVcOD6TGG
A22KRIxoYfpNAukyIpHPWadUovK5lEokvAf7KJ7yBQr4RRSP14kQHYwvBVtdCQoQ3377bdx9y5Yt
M7ePGTMm3uP69u1r3nf8+HG/FiEG8QtTCNmuELJd4cNCxVXgwr5YoSIsVqh4HVj0ZKxQUcxwmDM5
ChVj8qBZjcwO2wa1dRQz6lXNZT3nyeXAqdWG42xcN53eaEVcsIUp62Jc3A9EGY71JeN663IkcPWM
Vd+CBT5jrjFs1XK06XCfPm054HTE6ZDTMd+2zXLU6bDTcacDz3oYdOjp2NPBp6PPQp50/CkAUAjg
+4zF0CkQUCigYEDhgKkmb71lCQoUFigwtG1rpaFQeKAAQSHif/8DgoMtgYJCBQWL6tWBKlUsIYOC
BoUNtpc3nART8KDwQQEkLYQVCjZs80oBh0IOBR0KO7feagk9FHwo/FAAuv9+SxCiMESBiEIRC5e2
aAE884wV8cL0nFdfBTp3Brp2pTpqRcMwdYddWPr1A776CvjuOytShu1j2ZmFBeB5XT1xIjBlitVS
lt1aFi0Clht2sHo1q8dbbWbZwYWF4A8eBI4dM2zklNV6ll1dWDCVETlpBFOF7FOJaLtKJRLegHMU
zyA/ieLxOhHioPHBxoNl0UmmXTC6oT8rQ6eCCFG0aFGzLYr9YM0JthO1J8L4InTVPqWz8cE+hF+G
Ts/NfZ2LYvY0PvRtx22DtSu4L4trOl/AOv+Sxsqp3Ne5l2yY8aUc6kLtbdWqleaheWgemofmoXlo
HpqHNY/jR2KFiiWmUNGzU2NULJXDIRLiwHcBCLknANsHWA5dsxr/iRP2URIcUX9Y+y7p6bg9rEsA
Qus7RWaEZUarWpkQ/k6gKX6Y3UTG34KIHgUQcn8OYFIZYHJ5YGolM9Wkc/NCGNK1NDCrpjFZw9me
Ux9//3QfQmoXRuSkRlanEkaCLH4aPdvfgf6dDMd8eTsr6mNVBxyY0hYh9cti+3hjPde9B2z4CNjY
A4M+aIZuoQ9aIs02wwHf/i2iNnyNkIeqY8mo96zWqyw0un8Uwga9gdCWwcAhwxE/MsNKdzk2D60e
D0b4sL7GbWMdDxvjwBJEDB9oPEddYIfhqG9daLzWAuN156Pz049hyIdvG8c5G5hnOPOzZ+Dv7741
5nw/Iv/4w0pR+ct4PeP/ns2boz8FEqayDBjAC1kceOsthNx+O7a//DLwzjvAG2/AuBjGoNq10Y2t
XZ97jgYCPPkkoh55BCGFC2PJvfcC9esDxj647z6ElS6NUEaL0CkvWxYoVQrGBTBaBQYiPGdOgIM1
Q4zr4ghjhLgQSDobY4jTtr9j94102t7TGP2d6pEcyJ4dIcbf7TwO47XNYzCOZZBxvN0KFQLuuss8
Vh5zVN26CLnlFixhxM2jj5pz4xzDjO2hhoMGroWxBjUKZjMFh1a1AhD+lqO9ffNcAPIGZgb4wyXF
qsGDTeGqc8OGGMKUIootFLRGjMDfn3+OEGPNIpk2ROGF6UJTp6JnmzboTwGLaUOMblmwAAfGjUOI
cRzbed7YipfC2bp1hl19YEVeUFDbscMsLBu1ZQtCGjfGkgkTrLQiijSGcxn2yy8IZWoTxRqmGFGw
uXoVrVq2RDhfX59XPj+P+oa9rbB7jxyIfS9tN8Zyuygebz4fPB6bb82GEeWN9269evW8uyYEhYhs
2bKZi6F0DCGEEEKI5NHt9VAs7+26JsQyY3u3ji0MZ2mHlcJxegPwr+F0nTKcr5PLrDoWhlNudveg
k05n/aDhRB0YZzrxpjNPp55pILt+Bnb+YDr92DbQEgG2fG4V3tzY0xIJKBb8bTjsa7taBTxXdbBE
hRXGhfWy54GlrU3RwYzuoAjBLiPzHgbmPmSKFKZYQdGCtTSm32XVzaCoMaWCJXKEl7IiQti5hCII
xZDRhgM+KtAUSVytQdqNTMZrGo7/6BzGceS2OqeML2Sl1kwsaRzvbcDkcsaxV7TSaqZXt9rDzrzf
mGdtwzGuZ8y5oTH/xlYR04WPWnVEFj8FLHnGWK/ngOVtjbV70WoZy84tjIz5+y1jnd8F1n9orPnH
Vj2RzX2sWiRbvzSGcW42f21s/8bYx/j7t/F3rXHOVhtjhTGWGmOxsW2h8Xeu8TfC2GeG8ZgpXxnr
O8CYg/Eco41zO6Kf4egb53eI8dw/fQp8b7zO1z2AL7oDnxuv3ds41x+9A7z7JtDVOK4una2oDUZv
MIqD0Rzs9MLoDvt0oLp149KBqhUOcBDQ7IeZSmTcj6AgIEcOKzUoS5a0Sw9K7cFjZVQMj52RMXny
WNExBQtaETIUchglQzGHqVAUlyjQUGhiKhIFKqYjUdxhhA8FHkb7UJhi5A9FKkYBNWpkRQQ1bcqi
ewAdU9aAYUQN68DwPFAw4TmheMPzQxGI54r1+NgymMIYU5gokjGN6YMPrIikHj2s6CRG3TBSiZE3
jFpi9A0jmBiBw7oxjMJh7RgW2KUQNGyYVUOGqU4UexgFNX68FRE1ebIVHTVjhhUpNWeOFTW1cKFV
W2bZMqu+DKN16OMxYod1Zhi1Q6GCkTusN8PoHcNhxqFDxufXUYA/WNPJZorU2bNW1BbbZjKCixE9
TJdKxagepl7cSODcMyKC9/siXl+Y8o8//jCFh1WrVpm1InIZb86EClNWYuhaChdBCCGEEMIXYdhv
cM3yphBBx83mwPE2t/tVcb8bMVb6CLuaMJ2EaSVML2GaCdNNmHbC9BOmoTAdhWkpTE9hmgrTVZi2
ctxwiI4ZjtGRmcDhqcBBw3E6YDhQ+0dbHVL2DLO6nez+xXCIBgM7DEds+9eWALClL7D5U6t+xwbD
WV//PrCuG7D2TasGyKqOVmvXFYYjuPwFYGkbw/FqBSxuYbWGXdDMqgEy13As5xgO+2zDYY+oZaXj
zKhhdV2ZWgWYcjswyXBaw28FJpawurSMK2jVERljOO2jsgNhWdJZlAmwXpOvzWPgsfCYeGw8Rh4r
j5nHzjkYc3mkRuLC0f+qZ7WEGBZvpahFgWu94SBvNNZ302fGWlMIM9Z+yyBj/Q0neOsQY/xpDNZd
GWOMCcaYYtw/3RiGw7t5njEY5WI4uxtXGM+1yjg/f1vREHR6mUpEJ5jpRHSKGT1BJ5kdbOg0s0As
nWhGO9CpZhQ3nWymv9DpZnQGnXCmxdApZ/QGnXRGc9BpZ3QMnfi+fS2n/pNPLCf/448tp58FYikC
sFgsRQEWjqVIwCKyFA1YUJYiAlOTKCowPYkiA1OUKDowCociBFOVKEqwfgpFCtZSoWhBAYgiBkUg
ihpMC2L6ElOEmMJEn4tpTEwdYioT04iYzlSsmFWzhREvjITJm9cShxiBQ3GIUTjeIg7xOHm8PG4e
P+fB+XBenB/nyfly3pw/14HrwXXh+nCdjPUKyZ4dJxNojcztIT6aSpQuIsS2bdvM6IQ+xpvkKBUm
MP3vsBlCklJeeOEFszbEKeadge+fZ8y0ClctOj9k7pufixDOIUpCyHaFkO0KYS9EMCKiWYOqaHh/
GfMvb6u7gJ/DX35joq3CqNcvAlfPAlf+BS6fAKKOABcPWAVTz+2y2see2QScXg+cWgNErrDSftie
9thcqyDq4WnAIcMJP2g49/vHWEVW9xrO9z9/ALsNx3vXj8BOw+ne/o3hSBgO95Z+VpQGozUYtUEB
gVEcjOZY8zqa3pfPIRKCKUT2kRCP3Gs4ibMftKJHGEkytbIlZFDUGH+LFQlD0SM1xJPRuazoGkay
hJe2xBJG4rAVL4UgikLz/mdFrDBaZemzVoQPo30YoUKxicITI4MYlcI1oEjFKCIzPchYr0OTrIgj
Rh+dXGqJXxTCGKnE88BzQtGMbXxZIyYN63Gkmb0x4oCRB4xAoM/IiARGJjBCgZEKjFigX8kIBkYy
MKKBkQ2McOD3LiMeGPnACAj6eBSHGBlBcYiREhSHGDlBcYiRFBSHGFlBcYiRFhSHGHlBcYiRGBSH
GJlBcYiRGhSHGLlBcYiRHBSHGNlBcYiRHhSHGPlBcYiRIBSHGBlCcYiRIhSH3ngDjfLlc6hnYkt/
8/V6JmkqQkQbxtO+ffu4QpJMh7C90KOPPmqcjx5uP9crr7xiplSw3sNCw2jGG4ZBwYHP+z7VvliY
kpEnTx40aNDArBsxceJEM/ekVKlScUKFP4sQrnJ+hJDtCiHbFUK2K7wV51Qi1idxSCV63c3uGKbz
e9WKfrlyynLmWTvFTEPaZIkqdPoZ5cIIF4oBB8Za4gCjWiieUDRgihEjWSgmUCxZ+4YVvcLIFYoO
TCViGhHFCKbSMK2GqUOMUDGjU26z0oXMVKEgK10npQLJqNgaLEz1ofjCtCSmKFGUYYQMo2WYzsSU
HqbzLGlppT4xDWp1JysKhxE5G3vEpu18aUXvML2K4hGFJEb6MBWLNVMoOjEqiBFCZzZbAhXFqkvH
gKungetRQMx1v7fdBjUqYHmvBGy3Z4B5v0QID/nkk0+QI0cODBw4EFu3bjUFA9sLsb1mTYbwuMnQ
oUNRv359FC5c2KwBUaBAAQQHB2MklSkXk2rcuDGCgoKQL18+tGjRAnupjqXCIng7jAoRQrYrhGxX
CNmu8BWcU4lYVNXnUomYIsT0IEahXDbmE3XISgli5IkZdbLKSgNiCtDh6VZNFqb+7PnTii5hHRbW
YGGqDyNKWAvk73es9B6m9rCYK2utsM7KguZWjRHWV5n1QGwKT1WrYKxZT6UIMDafVUclpTVU+HjW
Q+Hz8Xn5/Hwdvh5fl6/Puic8Hh4Xj4/HaRaffcU6fjO95kNrXpwf58n5ct6cP+vScD24LlwfrhPX
i+vG9buwx1pPrivXl+vM9U4HmtStGK8gsH0UD++XCOEhZcuWNVMwCOs12IsQ06dPRyHmy3jZIggh
hBBCCCEynhBhSyUKaVBRqUTpCSMaGNnACAdGOjDigZEPLGLLSAhGRDAyghESjJRgxAQjJ1islpEU
jKhg2g0jLBhpwYgLRl6wiCojMRiRwZonjNBgpAYjNhi5EZdeU8kuvaZQbHpNYCqk12S1IlHMmiTF
rAgVM72mmhW5wggWRrKw/gojWxjhYqbXtLciXxgBw0gYphAxMoYRMoyUYcQMI2f2/oWQusUTPQba
skQID2EdhvnMtXEhQsybN8+8XyKEEEIIIYQQQohUJS695nz89BrW0LCl17C2Rrz0miF26TX9XaTX
dLBLr3kqfnoNa4DY0mtYGySB9Bq2Pk6sswvFNIkQHsI6DL+xcIcLEYKFKsuxQqhECCGEEEIIIYQQ
/kJsek23zs+aRSldiRDLPaln4mWkqQjx6quvmikZhw4dMotU2kSIM2fOoEqVKujatavXLYK3079/
f73phWxXCNmuELJdIdsV4ibjXM+kf2v/aI2cpiLEsWPHcOuttyJv3rx4/PHHTRGiadOmKFmyJMqU
KZNgt4qMvAjeTs+ePfVuF7JdIWS7Qsh2hWxXiAyAfT2TircV9It6JmkqQhAKER06dDCFh6xZs6J4
8eJmu01u98ZFEEIIIYQQQgghRNr73wFaBCGEEEIIIYQQQqSH/+2xCBEcHIzt27e7vG/nzp3m/d62
CEIIIYQQQgghhEh7/9tjEYI1IFatWuXyvjVr1pj3e9sieDuRkZGyeiHbFUK2K4RsV8h2hZDtZnj/
O1VFiKlTpyIoKMjrFsHbCQkJ0btbyHaFkO0KIdsVsl0hZLsZ3v92S4SYNGkS2rdvj9DQUFOEePTR
R83b9qN169YoWrQoHnzwQa9bBF844ULIdoWQ7Qoh2xWyXSFkuxnd/3ZLhPj888/NCIfcuXObIkSu
XLnM/+1HoUKF0LBhQ2zcuNHrFkEIIYQQQgghhBBp738nKx1j5cqVPrUIQgghhBBCCCGESHv/Wy06
hRBCCCGEEEIIkS7+t0QIH2DIkCGyeiHbFUK2K4RsV8h2hZDtZnj/2y0RokyZMtiwYUPc/2XLljX/
2g/bNv71tkXwdjp37qx3t5DtCiHbFUK2K2S7Qsh2M7z/7ZYI0a5dO+zZsyfu/8QGO2h42yIIIYQQ
QgghhBAi7f1vpWMIIYQQQgghhBAiXfxvj0SIqKgo1KlTB3PmzPGpRRBCCCGEEEIIIUTa+98eR0Lk
yZMHCxYs8KlFEEIIIYQQQgghRNr73x6LEA8//DC++OILn1oEbyckJERWL2S7Qsh2hZDtCtmuELLd
DO9/eyxCbN682eyAMWzYMFy4cMEnFsHbiYiI0LtbyHaFkO0KIdsVsl0hZLsZ3v/2WITInTs3AgMD
kSlTJnPwNgfTNGx/vW0RhBBCCCGEEEIIkfb+t8cihFp0CiGEEEIIIYQQIjn+t1p0CiGEEEIIIYQQ
Il38b49FiHPnzvncIng74eHhsnoh2xVCtiuEbFfIdoWQ7WZ4/9tjESJLlix44IEH0L17d7NV57Vr
17x+EbydVq1a6d0tZLtCyHaFkO0K2a4Qst0M7397LEIMHDgQjzzyCIKCgszClPzbpEkTDBgwAOvX
r/fKRRBCCCGEEEIIIUTa+9/JrgnBCIhFixahR48eqF27NrJly2aKEoULF/a6RRBCCCGEEEIIIUTa
+98pLky5c+dO/PDDD3jooYfi2nZ62yIIIYQQQgghhBAi7f1vj0WIkydPIiwsDC+++CJKly5tig4l
S5ZE27ZtMXz4cBw9etTrFkEIIYQQQgghhBBp7397LEJkzpzZrAPx+OOP4/vvv8f27du9fhG8ndDQ
UFm9kO0KIdsVQrYrZLtCyHYzvP/tsQiRP39+M/qhSpUq6Nq1K6ZNm4aLFy969SJ4O4xMEUK2K4Rs
VwjZrpDtCiHbzej+t8ciRHR0NFauXIk+ffqgQYMGyJ49u1mUsn79+vjss8+wYsUKr1sEIYQQQggh
hBBCpL3/neLClJcuXcKMGTPMNp2MkGC6hrctghBCCCGEEEIIIdLe/062CHH48GEMGzYMzz//PIoV
KxbXGeOee+7xukUQQgghhBBCCCFE2vvfHosQXbp0QaVKleJEhwoVKqBDhw4YN24c/v33X4+ea+7c
uWZXjdtvvx25cuUyu2yw4KXzgbdr1y7u9ewH61KkxiJ4O0uWLJHVC9muELJdIWS7QrYrhGzX90SI
IkWKoE2bNvj999+xb9++FB1oy5Yt0bBhQ/z4449YtGgRxo8fj9q1a5s1JubPn+8gQlCkWLVqlcPY
tGmTRAiDkJAQvbuFbFcI2a4Qsl0h2xVCtut7IsSNGzdS7UBPnDgRbxs7bTC9o3HjxnHbKELkyZMn
zRbB24mKitK7W8h2hZDtCiHbFbJdIWS7N4V0LUyZFgQHB6Ny5cpxtylC5M6dO80WQQghhBBCCCGE
EMnDq0WIs2fPIl++fHjqqafitlGEyJIlixkhwb+lSpXCa6+9htOnT6fKIgghhBBCCCGEECJ5eLUI
8dxzzyEwMBDr1q2L2/bNN9/g22+/NQtZcnz88ccICgoyC1MyfSOliyCEEEIIIYQQQojk4bUiBMUF
dr0YPHhwkvtOmDDB3JfiRGKLULRoUbMYiP2oVasWwsPDHfaPiIhwWTSkc+fOGDJkSLzn5r6RkZEO
23v27In+/fs7bDtw4IC57/bt2x22Dxo0CN26dXPYxnwh7utcQTUsLAyhoaHxjq1Vq1bmPOyfx5vn
4SvnQ/Nwfx6vvvqqzofmoc9dnQ/NQ5+7sivNQ5+7moc+d73ofPB4bL51tWrVUL58edSrV8/7RIje
vXubokK/fv3c2p8FMlkngp06UqrEeDs0YCFku0LIdoWQ7QrZrhCy3ZtBukVCXL58GUePHjX/pgSb
APHpp5+6/ZiYmBizbadECCGEEEIIIYQQ4uaR5iLE0qVLUbduXbNIJMUD/mX4xbJlyzx+LgoPfA6G
fHjCmDFjzMclpCxJhBBCiP+zdx/gUVVbG8fpJYRepUhTEET5wAYKAgI2zFXxil1RbGC5oig2kKIQ
mhSpGnqR3qSF3rv03kF6gEAggRDC+7HOESSFEITAzOT/e555QmbOQGbPmkP2OmuvDQAAACS9JE1C
LFq0SOnTp3d6LdSvX18tW7Z0vubJk0cZMmRwHk+s9u3bO4mEp556SosXL3aee/nN7Nq1S5UqVVL3
7t01ZcoUTZ48WV9//bUyZsyoe+65RxERESQhAAAAAADwxSREzZo1df/998fZlcK+f+CBB5zHE6tq
1apKlSqVk4iIfbP7TWhoqGrXrq2iRYs6yy8sAVKyZEknEREWFnZDBsHbxW5yAhC7ALELELsgdgFi
1yeSEJkzZ9bw4cPjfczut2aR3jYI3i6+7qcAsQsQuwCxC2IXIHY9bf59zUkIq0YYP358vI+NGzfO
WSbhbYPg7Wy7FIDYBYhdgNgFsQsQu54+/77mJESFChX05JNPxvtYrVq1nMe9bRAAAAAAAEDSz7+v
OQlh1Q7Ws6Fs2bJOY8nBgwerXbt2KleunHO/Pe5tgwAAAAAAAJJ+/v2vtui0xEP+/PljNJIsWLCg
hgwZ4pWDAAAAAAAAkn7+neLf/iPR0dHasGGD5s2b53w9f/681w6CtwsMDCTqQewCxC5A7ILYBYhd
j59/X3MSonnz5tq3b1+8j+3fv9953NsGwds1bdqUTzeIXYDYBYhdELsAsevx8+9rTkLY0oslS5bE
+9iyZcucx71tEAAAAAAAQNLPv29oEmL27NlKly6d1w0CAAAAAABI+vl3opIQq1atUv/+/dWvXz8n
CWElJfb95beePXuqUqVKKlWqlNcNAgAAAAAASPr5d6KSED/88EOMnTCudPPz89PQoUO9bhC8XUhI
CFEPYhcgdgFiF8QuQOx6/Pw7UUkIa0Rp/R4u9nywioiL31+8rVmzRuHh4V45CN4uICCATzeIXYDY
BYhdELsAsevx8+9r7gkxa9YshYWF+dQg+MIbDhC7ALELELsgdgFi19Pn3ykYBAAAAAAAcDPm3yQh
AAAAAADATZl/k4QAAAAAAAA3Zf5NEsIHBAUFEfUgdgFiFyB2QewCxK7Hz79JQviABg0a8OkGsQsQ
uwCxC2IXIHY9fv59XUmIiIgI7d27V2fPnvXqQQAAAAAAAEk///5XSYgZM2booYceUqpUqZzbxX+o
fv36GjVqlNcNAgAAAAAASPr59zUnISwBkSZNGpUtW1aNGzdWypQpL/1DTZo0UUBAgNcNAgAAAAAA
SPr59zUnIR555BEn0XD+/HlFRUXFSEKMHDlShQoV8rpBAAAAAAAAST//vuYkRMaMGTVhwgTnz7GT
EHPmzFH69Om9bhC8nadUnwDELohdgNgFiF0g+cVukiYhsmTJorFjxzp/jp2EGDFihHLmzOl1g+Dt
goOD+XSD2AWIXYDYBbELELseP/++5iTEY489ptq1azt/jp2EePnll/XMM8943SAAAAAAAICkn39f
cxJi2rRpTuLh2WefdXbCsD9369bN2f80derUmjt3rtcNAgAAAAAASPr597/aonPgwIHKkSOHk4C4
eMuePbsGDRrklYMAAAAAAACSfv6d4t/+I+Hh4U5VhCUepkyZopMnT3rtIHi7MWPGEPUgdgFiFyB2
QewCxK7Hz79TMAjer06dOny6QewCxC5A7ILYBYhdj59//+skxLp16zRp0iSnL0Tsm7cNAgAAAAAA
SPr59zUnIXbs2KFy5crF6Adx+S1VqlReNwgAAAAAACDp59/XnISoUaOG8uXLp86dOzt7ns6aNSvO
zdsGAQAAAAAAJP38+5qTEJkzZ9aQIUN8ahAAAAAAAEDSz7+vOQlRpEgRpxeELw2Ct6tbty5RD2IX
IHYBYhfELkDsevz8+5qTEIGBgXr++ed9ahC8nTdUpgDELohdgNgFiF0Qu74pSZMQ58+fV/369VW+
fHl999136tChQ5ybtw0CAAAAAABI+vn3NSchFi1apBw5clxxdwy7Jdb06dP15ptv6s4775Sfn58K
FCigZ599Nt4f3O6rXr26/P39lS1bNtWuXdvZqeNGDAIAAAAAAPh3kjQJcd9996lkyZIaN26cNm/e
rJ07d8a5JdaLL76oqlWrqnv37pozZ45GjhypihUrKm3atJo5c+al4zZu3Og0xKxSpYomT56s0aNH
q0yZMk7SIiQk5LoHAQAAAAAA/DtJmoTImDGjxo4de0N+0EOHDsW579SpU84WoLYV6EWWrMiTJ49O
njx56b7du3crXbp0aty48XUPgrebN28eUQ9iFyB2AWIXxC5A7N4SSZqEKFGixA1LQlxJtWrVdNdd
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
------=_Part_173_17122227.1353204383572--

.


Author: Julien Nitard <julien.nitard@m4tp.org>
Date: Sun, 18 Nov 2012 11:28:01 +0900
Raw View
--e89a8f3ba029ef556304cebbbf86
Content-Type: text/plain; charset=ISO-8859-1

Hi All,

This SO question may be of interest to understand the frustration of some
users with iostream:

http://stackoverflow.com/questions/9371238/why-is-reading-lines-from-stdin-much-slower-in-c-than-python/9371651#9371651

Regards,

Julien

--




--e89a8f3ba029ef556304cebbbf86
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Hi All,<div><br></div><div class=3D"gmail_extra">This SO question may be of=
 interest to understand the frustration of some users with iostream:</div><=
div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra"><a href=3D"h=
ttp://stackoverflow.com/questions/9371238/why-is-reading-lines-from-stdin-m=
uch-slower-in-c-than-python/9371651#9371651">http://stackoverflow.com/quest=
ions/9371238/why-is-reading-lines-from-stdin-much-slower-in-c-than-python/9=
371651#9371651</a><br>
</div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">Regar=
ds,</div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">Ju=
lien</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--e89a8f3ba029ef556304cebbbf86--

.


Author: Bjorn Reese <breese@mail1.stofanet.dk>
Date: Sun, 18 Nov 2012 12:12:27 +0100
Raw View
On 2012-11-17 20:36, Jason McKesson wrote:

> What do you think? Are there other issues in iostreams that need to be
> mentioned?

Perhaps peripheral, but std::cout (and std::cerr) are objects, so you
cannot use them for debug printing from the destructors of global
objects.

Having said that, I also think that we should consider the virtues of
iostream-style. How would to create something like Boost.Serialization
using a printf-style?

--




.


Author: Arthur Tchaikovsky <atch.cpp@gmail.com>
Date: Sun, 18 Nov 2012 05:20:12 -0800 (PST)
Raw View
------=_Part_190_10515242.1353244813017
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable


>
> It=92s very compact, for one. Once you understand the basic syntax of it,=
=20
> it=92s very easy to see what=92s going on. Especially for complex formatt=
ing.=20
> Just consider the physical size difference between these two:
>
snprintf(..., =930x%08x=94, integer);
>
stream << "0x" << std::right << std::hex << std::setw(8) << iVal <<=20
> std::endl;
>
It may take a bit longer to become used to the printf version, but this is=
=20
> something you can easily look up in a reference.
>

a) every heard of "type safety"?
b) What a warped logic. I remember hell unleashed on my proposal to unify=
=20
class declaration rules, just to cite few:
"Oh, no, another rule to learn", "We don't need it because we do not see=20
point in it etc",
and here what do I see as an argument?=20

"It may take a bit longer to become used to the printf version, but this is=
=20
something you can easily look up in a reference."
a) I am not interested in things that may take a bit longer if I have=20
already things that are safe and easy to use
b) I am not interested in looking something as simple and rudimentary as up=
=20
in a reference.

We are supposed to make C++ easier. The C++ cannot become a language where=
=20
every single smallest thing is so complicated that must be looked up in a=
=20
reference.

Anyway, the point is that you simply don't know what you're talking about=
=20
when you say that  snprintf is better option to cout. =20

On Saturday, 17 November 2012 19:36:37 UTC, Nicol Bolas wrote:
>
>  The Iostreams library in C++ has a problem. We have real, reasonable,=20
> legitimate C++ professional, who like C++ and use modern C++ idioms,=20
> telling people to not use iostreams. This is not due to differing ideas o=
n=20
> C++ or C-in-classes-style development, but the simple practical realities=
=20
> of the situation.
>
> This kind of thing is indicative of a real problem in iostreams. In order=
=20
> to eventually solve that problem, we must first identify exactly what the=
=20
> problems are. This discussion should be focused on exactly that:=20
> identifying the problems with the library. Once we know what the real=20
> problems are, we can be certain that any new system that is proposed=20
> addresses them.
>
> Note that this is about problems within iostreams. This is not about a=20
> list of things you *wish* it could do. This is about what iostreams=20
> actually tries to do but fails at in some way. So stuff like async file I=
O=20
> doesn=92t go here, since iostreams doesn=92t try to provide that.
>
> Feel free to add to this list other flaws you see in iostreams. Or if you=
=20
> think that some of them are not real flaws, feel free to explain why.
>
> Performance
> This is the big one, generally the #1 reason why people suggest using=20
> C-standard file IO rather than iostreams.
>
> Oftentimes, when people defend iostreams performance, they will say=20
> something to the effect of, =93iostreams does far more than C-standard fi=
le=20
> IO.=94 And that=92s true. With iostreams, you have an extensible mechanis=
m for=20
> writing any type directly to a stream. You can =93easily=94 write new=20
> streambuf=92s that will allow you to (via runtime polymorphism) be able t=
o=20
> work with existing code, thus allowing you to leverage your file IO for=
=20
> other forms of IO. You could even use a network pipe as an input or outpu=
t=20
> stream.
>
> There=92s one real problem with this logic, and it is exactly why people=
=20
> suggest C-standard file IO. Iostreams violates a fundamental precept of=
=20
> C++: pay *only* for what you use.
>
> Consider this suite of benchmarks<http://stackoverflow.com/questions/4340=
396/does-the-c-standard-mandate-poor-performance-for-iostreams-or-am-i-just=
-deali>.=20
> This code doesn=92t do file IO; it writes directly to a string. All it=92=
s=20
> doing is measuring the time it takes to append 4-characters to a string. =
A=20
> lot. It uses a `char[]` as a useful control. It also tests the use of=20
> `vector<char>` (presumably `basic_string` would have similar results).=20
> Therefore, this is a solid test for the efficiency of the iostreams=20
> codebase itself.
>
> Obviously there will be some efficiency loss. But consider the numbers in=
=20
> the results.
>
> The ostringstream is more than full order of magnitude slower than the=20
> control. It=92s almost 100x in some cases. Note that it=92s not using << =
to=20
> write to the stream; it=92s using `ostream::write()`.
>
> Note that the vector<char> implementations are fairly comparable to the=
=20
> control, usually being around 1x-4x the speed. So clearly this is somethi=
ng=20
> in ostringstream.
>
> Now, you might say that one could use the stringbuf directly. And that wa=
s=20
> done. While it does improve performance over the ostringstream case=20
> substantially (generally half to a quarter the performance), it=92s still=
=20
> over 10x slower than the control or most vector<char> implementations.
>
> Why? The stringbuf operations ought to be a thin wrapper over std::string=
..=20
> After all, that=92s what was asked for.
>
> Where does this inefficiency come from? I haven=92t done any extensive=20
> profiling analysis, but my educated guesses are from two places: virtual=
=20
> function overhead and an interface that does too much.
>
> ostringstream is supposed to be able to be used as an ostream for=20
> runtime-polymorphism. But here=92s where the C++ maxim comes into play.=
=20
> Runtime-polymorphism is not being used here. Every function call should=
=20
> be able to be statically dispatched. And it is, but all of the virtual=20
> machinery comes from *within* ostringstream.
>
> This problem seems to come mostly from the fact that basic_ostream, which=
=20
> does most of the leg-work for ostringstream, has no specific knowledge of=
=20
> its stream type. Therefore it's always a virtual call. And it may be doin=
g=20
> many such virtual calls.
>
> You can achieve the same runtime polymorphism (being able to overload=20
> operator<< for any stream) by using a static set of stream classes, tight=
ly=20
> coupled to their specific streambufs, and a single =93anystream=94 type t=
hat=20
> those streams can be converted into. It would use std::function-style typ=
e=20
> erasure to remember the original type and feed function calls to it. It=
=20
> would use a single function call to initiate each write operation, rather=
=20
> than what appears to be many virtual calls within each write.
>
> Then, there=92s the fact that streambuf itself is overdesigned. stringbuf=
=20
> ought to be a simple interface wrapper around a std::string, but it=92s n=
ot.=20
> It=92s a complex thing. It has locale support of all things. Why? Isn=92t=
=20
> that something that should be handled at the stream level?
>
> This API has no way to get a low-level interface to a=20
> file/string/whatever. There=92s no way to just open a filebuf and blast t=
he=20
> file into some memory, or to shove some memory out of a filebuf. It will=
=20
> always employ the locale machinery even if you didn=92t ask for it. It wi=
ll=20
> always make these internal virtual calls, even if they are completely=20
> statically dispatched.
>
> With iostreams, you are paying for a lot of stuff that you don=92t=20
> frequently use. At the stream level, it makes sense that you=92re paying =
for=20
> certain machinery (though again, some way to say that you=92re not using =
some=20
> of it would be nice). At the buffer level, it does not, since that is the=
=20
> lowest level you=92re allowed to use.
>
> Utility
> While performance is the big issue, it=92s not the only one.
>
> The biggest selling point for iostreams is the ability to extend its=20
> formatted writing functionality. You can overload operator<< for various=
=20
> types and simply use them. You can=92t do that with fprintf. And thanks t=
o=20
> ADL, it will work just fine for classes in namespaces. You can create new=
=20
> streambuf types and even streams if you like. All relatively easily.
>
> Here=92s the problem, and it is admittedly one that is subjective: printf=
 is=20
> really nice syntax.
>
> It=92s very compact, for one. Once you understand the basic syntax of it,=
=20
> it=92s very easy to see what=92s going on. Especially for complex formatt=
ing.=20
> Just consider the physical size difference between these two:
>
> snprintf(..., =930x%08x=94, integer);
>
> stream << "0x" << std::right << std::hex << std::setw(8) << iVal << std::=
endl;
>
> It may take a bit longer to become used to the printf version, but this i=
s=20
> something you can easily look up in a reference.
>
> Plus, it makes it much easier to do translations on formatted strings. Yo=
u=20
> can look the pattern string up in a table that changes from language to=
=20
> language. This is rather more difficult in iostreams, though not=20
> impossible. Granted, pattern changes may not be enough, as some languages=
=20
> have different subject/verb/object grammars that would require reshufflin=
g=20
> patterns around. However, there are printf-style systems that do allow fo=
r=20
> reshuffling, whereas no such mechanism exists for iostream-style.
>
> C++ used the << method because the alternatives were less flexible.=20
> Boost.Format and other systems show that C++03 did not really have to use=
=20
> this mechanism to achieve the extensibility features that iostreams provi=
de.
>
> What do you think? Are there other issues in iostreams that need to be=20
> mentioned?
> =20

--=20




------=_Part_190_10515242.1353244813017
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;">It=92s very compact, for one. =
Once you understand the basic syntax of it, it=92s very easy to see what=92=
s going on. Especially for complex formatting. Just consider the physical s=
ize difference between these two:<br></blockquote><blockquote class=3D"gmai=
l_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;=
padding-left: 1ex;">snprintf(..., =930x%08x=94, integer);<br></blockquote><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;">stream &lt;&lt; "0x" &lt;&lt; s=
td::right &lt;&lt; std::hex &lt;&lt; std::setw(8) &lt;&lt; iVal &lt;&lt; st=
d::endl;<br></blockquote><blockquote class=3D"gmail_quote" style=3D"margin:=
 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">It ma=
y take a bit longer to become used to the printf version, but this is somet=
hing you can easily look up in a reference.<br></blockquote><div>
<div><br></div><div>a) every heard of "type safety"?</div><div>b) What a wa=
rped logic. I remember hell unleashed on my proposal to unify class declara=
tion rules, just to cite few:</div><div>"Oh, no, another rule to learn", "W=
e don't need it because we do not see point in it etc",</div><div>and here =
what do I see as an argument?&nbsp;</div><div><br></div><div>"It may take a=
 bit longer to become used to the printf version, but this is something you=
 can easily look up in a reference."</div><div>a) I am not interested in th=
ings that may take a bit longer if I have already things that are safe and =
easy to use</div><div>b) I am not interested in looking something as simple=
 and rudimentary as up in a reference.</div><div><br></div><div>We are supp=
osed to make C++ easier. The C++ cannot become a language where every singl=
e smallest thing is so complicated that must be looked up in a reference.</=
div><div><br></div><div>Anyway, the point is that you simply don't know wha=
t you're talking about when you say that&nbsp; snprintf is better option to=
 cout. &nbsp;</div><div><br></div></div>On Saturday, 17 November 2012 19:36=
:37 UTC, Nicol Bolas  wrote:<blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
 =20

   =20
 =20
  <div bgcolor=3D"#FFFFFF" text=3D"#000000">
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">The Iostreams
      library in C++ has a problem. We have real, reasonable, legitimate
      C++ professional, who like C++ and use modern C++ idioms, telling
      people to not use iostreams. This is not due to differing ideas on
      C++ or C-in-classes-style development, but the simple practical
      realities of the situation.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">This

      kind of thing is indicative of a real problem in iostreams. In
      order to eventually solve that problem, we must first identify
      exactly what the problems are. This discussion should be focused
      on exactly that: identifying the problems with the library. Once
      we know what the real problems are, we can be certain that any new
      system that is proposed addresses them.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Note
      that this is about problems </span><span style=3D"font-size:15px;font=
-family:Arial;color:#000000;background-color:transparent;font-weight:normal=
;font-style:italic;font-variant:normal;text-decoration:none;vertical-align:=
baseline">within</span><span style=3D"font-size:15px;font-family:Arial;colo=
r:#000000;background-color:transparent;font-weight:normal;font-style:normal=
;font-variant:normal;text-decoration:none;vertical-align:baseline">
      iostreams. This is not about a list of things you <i>wish</i> it
      could do. This is about what iostreams actually tries to do but
      fails at in some way. So stuff like async file IO doesn=92t go here,
      since iostreams doesn=92t try to provide that.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Feel

      free to add to this list other flaws you see in iostreams. Or if
      you think that some of them are not real flaws, feel free to
      explain why.</span><br>
    <p dir=3D"ltr"><span style=3D"font-size:32px;font-family:Georgia;color:=
#666666;background-color:transparent;font-weight:normal;font-style:italic;f=
ont-variant:normal;text-decoration:none;vertical-align:baseline">Performanc=
e</span></p>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">This
      is the big one, generally the #1 reason why people suggest using
      C-standard file IO rather than iostreams.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Oftentimes,

      when people defend iostreams performance, they will say something
      to the effect of, =93iostreams does far more than C-standard file
      IO.=94 And that=92s true. With iostreams, you have an extensible
      mechanism for writing any type directly to a stream. You can
      =93easily=94 write new streambuf=92s that will allow you to (via runt=
ime
      polymorphism) be able to work with existing code, thus allowing
      you to leverage your file IO for other forms of IO. You could even
      use a network pipe as an input or output stream.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">There=92s

      one real problem with this logic, and it is exactly why people
      suggest C-standard file IO. Iostreams violates a fundamental
      precept of C++: pay <i>only</i> for what you </span><span style=3D"fo=
nt-size:15px;font-family:Arial;color:#000000;background-color:transparent;f=
ont-weight:normal;font-style:italic;font-variant:normal;text-decoration:non=
e;vertical-align:baseline">use</span><span style=3D"font-size:15px;font-fam=
ily:Arial;color:#000000;background-color:transparent;font-weight:normal;fon=
t-style:normal;font-variant:normal;text-decoration:none;vertical-align:base=
line">.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Consider
    </span><a href=3D"http://stackoverflow.com/questions/4340396/does-the-c=
-standard-mandate-poor-performance-for-iostreams-or-am-i-just-deali" target=
=3D"_blank"><span style=3D"font-size:15px;font-family:Arial;color:#1155cc;b=
ackground-color:transparent;font-weight:normal;font-style:normal;font-varia=
nt:normal;text-decoration:underline;vertical-align:baseline">this
        suite of benchmarks</span></a><span style=3D"font-size:15px;font-fa=
mily:Arial;color:#000000;background-color:transparent;font-weight:normal;fo=
nt-style:normal;font-variant:normal;text-decoration:none;vertical-align:bas=
eline">.
      This code doesn=92t do file IO; it writes directly to a string. All
      it=92s doing is measuring the time it takes to append 4-characters
      to a string. A lot. It uses a `char[]` as a useful control. It
      also tests the use of `vector&lt;char&gt;` (presumably
      `basic_string` would have similar results). Therefore, this is a
      solid test for the efficiency of the iostreams codebase itself.</span=
><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Obviously
      there will be some efficiency loss. But consider the numbers in
      the results.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">The
      ostringstream is more than </span><span style=3D"font-size:15px;font-=
family:Arial;color:#000000;background-color:transparent;font-weight:normal;=
font-style:italic;font-variant:normal;text-decoration:none;vertical-align:b=
aseline">full
      order of magnitude</span><span style=3D"font-size:15px;font-family:Ar=
ial;color:#000000;background-color:transparent;font-weight:normal;font-styl=
e:normal;font-variant:normal;text-decoration:none;vertical-align:baseline">
      slower than the control. It=92s almost 100x in some cases. Note that
      it=92s not using &lt;&lt; to write to the stream; it=92s using
      `ostream::write()`.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Note

      that the vector&lt;char&gt; implementations are fairly comparable
      to the control, usually being around 1x-4x the speed. So clearly
      this is something in ostringstream.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Now,

      you might say that one could use the stringbuf directly. And that
      was done. While it does improve performance over the ostringstream
      case substantially (generally half to a quarter the performance),
      it=92s still over 10x slower than the control or most
      vector&lt;char&gt; implementations.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Why?
      The stringbuf operations ought to be a thin wrapper over
      std::string. After all, that=92s what was asked for.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Where

      does this inefficiency come from? I haven=92t done any extensive
      profiling analysis, but my educated guesses are from two places:
      virtual function overhead and an interface that does too much.</span>=
<br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">ostringstream

      is supposed to be able to be used as an ostream for
      runtime-polymorphism. But here=92s where the C++ maxim comes into
      play. Runtime-polymorphism is </span><span style=3D"font-size:15px;fo=
nt-family:Arial;color:#000000;background-color:transparent;font-weight:norm=
al;font-style:italic;font-variant:normal;text-decoration:none;vertical-alig=
n:baseline">not
      being used here</span><span style=3D"font-size:15px;font-family:Arial=
;color:#000000;background-color:transparent;font-weight:normal;font-style:n=
ormal;font-variant:normal;text-decoration:none;vertical-align:baseline">.
      Every function call should be able to be statically dispatched.
      And it is, but all of the virtual machinery comes from <i>within</i>
      ostringstream.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">This
      problem seems to come mostly from the fact that basic_ostream,
      which does most of the leg-work for ostringstream, has no specific
      knowledge of its stream type. Therefore it's always a virtual
      call. And it may be doing many such virtual calls.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">You

      can achieve the same runtime polymorphism (being able to overload
      operator&lt;&lt; for any stream) by using a static set of stream
      classes, tightly coupled to their specific streambufs, and a
      single =93anystream=94 type that those streams can be converted into.
      It would use std::function-style type erasure to remember the
      original type and feed function calls to it. It would use a single
      function call to initiate each write operation, rather than what
      appears to be many virtual calls within each write.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Then,

      there=92s the fact that streambuf itself is overdesigned. stringbuf
      ought to be a simple interface wrapper around a std::string, but
      it=92s not. It=92s a complex thing. It has </span><span style=3D"font=
-size:15px;font-family:Arial;color:#000000;background-color:transparent;fon=
t-weight:normal;font-style:italic;font-variant:normal;text-decoration:none;=
vertical-align:baseline">locale
      support</span><span style=3D"font-size:15px;font-family:Arial;color:#=
000000;background-color:transparent;font-weight:normal;font-style:normal;fo=
nt-variant:normal;text-decoration:none;vertical-align:baseline">
      of all things. Why? Isn=92t that something that should be handled at
      the stream level?</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">This

      API has no way to get a low-level interface to a
      file/string/whatever. There=92s no way to just open a filebuf and
      blast the file into some memory, or to shove some memory out of a
      filebuf. It will always employ the locale machinery even if you
      didn=92t ask for it. It will always make these internal virtual
      calls, even if they are completely statically dispatched.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">With

      iostreams, you are paying for a lot of stuff that you don=92t
      frequently use. At the stream level, it makes sense that you=92re
      paying for certain machinery (though again, some way to say that
      you=92re not using some of it would be nice). At the buffer level,
      it does not, since that is the lowest level you=92re allowed to use.<=
/span><br>
    <p dir=3D"ltr"><span style=3D"font-size:32px;font-family:Georgia;color:=
#666666;background-color:transparent;font-weight:normal;font-style:italic;f=
ont-variant:normal;text-decoration:none;vertical-align:baseline">Utility</s=
pan></p>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">While
      performance is the big issue, it=92s not the only one.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">The

      biggest selling point for iostreams is the ability to extend its
      formatted writing functionality. You can overload operator&lt;&lt;
      for various types and simply use them. You can=92t do that with
      fprintf. And thanks to ADL, it will work just fine for classes in
      namespaces. You can create new streambuf types and even streams if
      you like. All relatively easily.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Here=92s
      the problem, and it is admittedly one that is subjective: printf
      is really nice syntax.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">It=92s

      very compact, for one. Once you understand the basic syntax of it,
      it=92s very easy to see what=92s going on. Especially for complex
      formatting. Just consider the physical size difference between
      these two:</span><br>
    <pre><tt><span style=3D"font-size:15px;color:rgb(0,0,0);background-colo=
r:transparent;font-weight:normal;font-style:normal;font-variant:normal;text=
-decoration:none;vertical-align:baseline">snprintf(..., =930x%08x=94, integ=
er);</span></tt></pre>
   =20
    <pre><tt><span style=3D"font-size:15px;color:rgb(0,0,0);background-colo=
r:transparent;font-weight:normal;font-style:normal;font-variant:normal;text=
-decoration:none;vertical-align:baseline">stream &lt;&lt; "0x" &lt;&lt; std=
::right &lt;&lt; std::hex &lt;&lt; std::setw(8) &lt;&lt; iVal &lt;&lt; std:=
:endl;</span></tt></pre>
   =20
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">It
      may take a bit longer to become used to the printf version, but
      this is something you can easily look up in a reference.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Plus,

      it makes it much easier to do translations on formatted strings.
      You can look the pattern string up in a table that changes from
      language to language. This is rather more difficult in iostreams,
      though not impossible. Granted, pattern changes may not be enough,
      as some languages have different subject/verb/object grammars that
      would require reshuffling patterns around. However, there are
      printf-style systems that do allow for reshuffling, whereas no
      such mechanism exists for iostream-style.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">C++

      used the &lt;&lt; method because the alternatives were less
      flexible. Boost.Format and other systems show that C++03 did not
      really have to use this mechanism to achieve the extensibility
      features that iostreams provide.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">What
      do you think? Are there other issues in iostreams that need to be
      mentioned?</span><br>
  </div>

</blockquote>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_190_10515242.1353244813017--

.


Author: Arthur Tchaikovsky <atch.cpp@gmail.com>
Date: Sun, 18 Nov 2012 05:38:08 -0800 (PST)
Raw View
------=_Part_286_29635840.1353245888501
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable


>
> It=92s very compact, for one. Once you understand the basic syntax of it,=
=20
> it=92s very easy to see what=92s going on. Especially for complex formatt=
ing.=20
> Just consider the physical size difference between these two:
>
snprintf(..., =930x%08x=94, integer);
>
stream << "0x" << std::right << std::hex << std::setw(8) << iVal <<=20
> std::endl;
>
It may take a bit longer to become used to the printf version, but this is=
=20
> something you can easily look up in a reference.
>

Again, logic of a person for whom recursion is as easy to understand and=20
use as iteration.

On Saturday, 17 November 2012 19:36:37 UTC, Nicol Bolas wrote:
>
>  The Iostreams library in C++ has a problem. We have real, reasonable,=20
> legitimate C++ professional, who like C++ and use modern C++ idioms,=20
> telling people to not use iostreams. This is not due to differing ideas o=
n=20
> C++ or C-in-classes-style development, but the simple practical realities=
=20
> of the situation.
>
> This kind of thing is indicative of a real problem in iostreams. In order=
=20
> to eventually solve that problem, we must first identify exactly what the=
=20
> problems are. This discussion should be focused on exactly that:=20
> identifying the problems with the library. Once we know what the real=20
> problems are, we can be certain that any new system that is proposed=20
> addresses them.
>
> Note that this is about problems within iostreams. This is not about a=20
> list of things you *wish* it could do. This is about what iostreams=20
> actually tries to do but fails at in some way. So stuff like async file I=
O=20
> doesn=92t go here, since iostreams doesn=92t try to provide that.
>
> Feel free to add to this list other flaws you see in iostreams. Or if you=
=20
> think that some of them are not real flaws, feel free to explain why.
>
> Performance
> This is the big one, generally the #1 reason why people suggest using=20
> C-standard file IO rather than iostreams.
>
> Oftentimes, when people defend iostreams performance, they will say=20
> something to the effect of, =93iostreams does far more than C-standard fi=
le=20
> IO.=94 And that=92s true. With iostreams, you have an extensible mechanis=
m for=20
> writing any type directly to a stream. You can =93easily=94 write new=20
> streambuf=92s that will allow you to (via runtime polymorphism) be able t=
o=20
> work with existing code, thus allowing you to leverage your file IO for=
=20
> other forms of IO. You could even use a network pipe as an input or outpu=
t=20
> stream.
>
> There=92s one real problem with this logic, and it is exactly why people=
=20
> suggest C-standard file IO. Iostreams violates a fundamental precept of=
=20
> C++: pay *only* for what you use.
>
> Consider this suite of benchmarks<http://stackoverflow.com/questions/4340=
396/does-the-c-standard-mandate-poor-performance-for-iostreams-or-am-i-just=
-deali>.=20
> This code doesn=92t do file IO; it writes directly to a string. All it=92=
s=20
> doing is measuring the time it takes to append 4-characters to a string. =
A=20
> lot. It uses a `char[]` as a useful control. It also tests the use of=20
> `vector<char>` (presumably `basic_string` would have similar results).=20
> Therefore, this is a solid test for the efficiency of the iostreams=20
> codebase itself.
>
> Obviously there will be some efficiency loss. But consider the numbers in=
=20
> the results.
>
> The ostringstream is more than full order of magnitude slower than the=20
> control. It=92s almost 100x in some cases. Note that it=92s not using << =
to=20
> write to the stream; it=92s using `ostream::write()`.
>
> Note that the vector<char> implementations are fairly comparable to the=
=20
> control, usually being around 1x-4x the speed. So clearly this is somethi=
ng=20
> in ostringstream.
>
> Now, you might say that one could use the stringbuf directly. And that wa=
s=20
> done. While it does improve performance over the ostringstream case=20
> substantially (generally half to a quarter the performance), it=92s still=
=20
> over 10x slower than the control or most vector<char> implementations.
>
> Why? The stringbuf operations ought to be a thin wrapper over std::string=
..=20
> After all, that=92s what was asked for.
>
> Where does this inefficiency come from? I haven=92t done any extensive=20
> profiling analysis, but my educated guesses are from two places: virtual=
=20
> function overhead and an interface that does too much.
>
> ostringstream is supposed to be able to be used as an ostream for=20
> runtime-polymorphism. But here=92s where the C++ maxim comes into play.=
=20
> Runtime-polymorphism is not being used here. Every function call should=
=20
> be able to be statically dispatched. And it is, but all of the virtual=20
> machinery comes from *within* ostringstream.
>
> This problem seems to come mostly from the fact that basic_ostream, which=
=20
> does most of the leg-work for ostringstream, has no specific knowledge of=
=20
> its stream type. Therefore it's always a virtual call. And it may be doin=
g=20
> many such virtual calls.
>
> You can achieve the same runtime polymorphism (being able to overload=20
> operator<< for any stream) by using a static set of stream classes, tight=
ly=20
> coupled to their specific streambufs, and a single =93anystream=94 type t=
hat=20
> those streams can be converted into. It would use std::function-style typ=
e=20
> erasure to remember the original type and feed function calls to it. It=
=20
> would use a single function call to initiate each write operation, rather=
=20
> than what appears to be many virtual calls within each write.
>
> Then, there=92s the fact that streambuf itself is overdesigned. stringbuf=
=20
> ought to be a simple interface wrapper around a std::string, but it=92s n=
ot.=20
> It=92s a complex thing. It has locale support of all things. Why? Isn=92t=
=20
> that something that should be handled at the stream level?
>
> This API has no way to get a low-level interface to a=20
> file/string/whatever. There=92s no way to just open a filebuf and blast t=
he=20
> file into some memory, or to shove some memory out of a filebuf. It will=
=20
> always employ the locale machinery even if you didn=92t ask for it. It wi=
ll=20
> always make these internal virtual calls, even if they are completely=20
> statically dispatched.
>
> With iostreams, you are paying for a lot of stuff that you don=92t=20
> frequently use. At the stream level, it makes sense that you=92re paying =
for=20
> certain machinery (though again, some way to say that you=92re not using =
some=20
> of it would be nice). At the buffer level, it does not, since that is the=
=20
> lowest level you=92re allowed to use.
>
> Utility
> While performance is the big issue, it=92s not the only one.
>
> The biggest selling point for iostreams is the ability to extend its=20
> formatted writing functionality. You can overload operator<< for various=
=20
> types and simply use them. You can=92t do that with fprintf. And thanks t=
o=20
> ADL, it will work just fine for classes in namespaces. You can create new=
=20
> streambuf types and even streams if you like. All relatively easily.
>
> Here=92s the problem, and it is admittedly one that is subjective: printf=
 is=20
> really nice syntax.
>
> It=92s very compact, for one. Once you understand the basic syntax of it,=
=20
> it=92s very easy to see what=92s going on. Especially for complex formatt=
ing.=20
> Just consider the physical size difference between these two:
>
> snprintf(..., =930x%08x=94, integer);
>
> stream << "0x" << std::right << std::hex << std::setw(8) << iVal << std::=
endl;
>
> It may take a bit longer to become used to the printf version, but this i=
s=20
> something you can easily look up in a reference.
>
> Plus, it makes it much easier to do translations on formatted strings. Yo=
u=20
> can look the pattern string up in a table that changes from language to=
=20
> language. This is rather more difficult in iostreams, though not=20
> impossible. Granted, pattern changes may not be enough, as some languages=
=20
> have different subject/verb/object grammars that would require reshufflin=
g=20
> patterns around. However, there are printf-style systems that do allow fo=
r=20
> reshuffling, whereas no such mechanism exists for iostream-style.
>
> C++ used the << method because the alternatives were less flexible.=20
> Boost.Format and other systems show that C++03 did not really have to use=
=20
> this mechanism to achieve the extensibility features that iostreams provi=
de.
>
> What do you think? Are there other issues in iostreams that need to be=20
> mentioned?
> =20

--=20




------=_Part_286_29635840.1353245888501
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;">It=92s very compact, for one. =
Once you understand the basic syntax of it, it=92s very easy to see what=92=
s going on. Especially for complex formatting. Just consider the physical s=
ize difference between these two:<br></blockquote><blockquote class=3D"gmai=
l_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;=
padding-left: 1ex;">snprintf(..., =930x%08x=94, integer);<br></blockquote><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;">stream &lt;&lt; "0x" &lt;&lt; s=
td::right &lt;&lt; std::hex &lt;&lt; std::setw(8) &lt;&lt; iVal &lt;&lt; st=
d::endl;<br></blockquote><blockquote class=3D"gmail_quote" style=3D"margin:=
 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">It ma=
y take a bit longer to become used to the printf version, but this is somet=
hing you can easily look up in a reference.<br></blockquote><div><br></div>=
<div>Again, logic of a person for whom recursion is as easy to understand a=
nd use as iteration.<br></div><div><br></div>On Saturday, 17 November 2012 =
19:36:37 UTC, Nicol Bolas  wrote:<blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;">
 =20

   =20
 =20
  <div bgcolor=3D"#FFFFFF" text=3D"#000000">
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">The Iostreams
      library in C++ has a problem. We have real, reasonable, legitimate
      C++ professional, who like C++ and use modern C++ idioms, telling
      people to not use iostreams. This is not due to differing ideas on
      C++ or C-in-classes-style development, but the simple practical
      realities of the situation.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">This

      kind of thing is indicative of a real problem in iostreams. In
      order to eventually solve that problem, we must first identify
      exactly what the problems are. This discussion should be focused
      on exactly that: identifying the problems with the library. Once
      we know what the real problems are, we can be certain that any new
      system that is proposed addresses them.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Note
      that this is about problems </span><span style=3D"font-size:15px;font=
-family:Arial;color:#000000;background-color:transparent;font-weight:normal=
;font-style:italic;font-variant:normal;text-decoration:none;vertical-align:=
baseline">within</span><span style=3D"font-size:15px;font-family:Arial;colo=
r:#000000;background-color:transparent;font-weight:normal;font-style:normal=
;font-variant:normal;text-decoration:none;vertical-align:baseline">
      iostreams. This is not about a list of things you <i>wish</i> it
      could do. This is about what iostreams actually tries to do but
      fails at in some way. So stuff like async file IO doesn=92t go here,
      since iostreams doesn=92t try to provide that.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Feel

      free to add to this list other flaws you see in iostreams. Or if
      you think that some of them are not real flaws, feel free to
      explain why.</span><br>
    <p dir=3D"ltr"><span style=3D"font-size:32px;font-family:Georgia;color:=
#666666;background-color:transparent;font-weight:normal;font-style:italic;f=
ont-variant:normal;text-decoration:none;vertical-align:baseline">Performanc=
e</span></p>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">This
      is the big one, generally the #1 reason why people suggest using
      C-standard file IO rather than iostreams.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Oftentimes,

      when people defend iostreams performance, they will say something
      to the effect of, =93iostreams does far more than C-standard file
      IO.=94 And that=92s true. With iostreams, you have an extensible
      mechanism for writing any type directly to a stream. You can
      =93easily=94 write new streambuf=92s that will allow you to (via runt=
ime
      polymorphism) be able to work with existing code, thus allowing
      you to leverage your file IO for other forms of IO. You could even
      use a network pipe as an input or output stream.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">There=92s

      one real problem with this logic, and it is exactly why people
      suggest C-standard file IO. Iostreams violates a fundamental
      precept of C++: pay <i>only</i> for what you </span><span style=3D"fo=
nt-size:15px;font-family:Arial;color:#000000;background-color:transparent;f=
ont-weight:normal;font-style:italic;font-variant:normal;text-decoration:non=
e;vertical-align:baseline">use</span><span style=3D"font-size:15px;font-fam=
ily:Arial;color:#000000;background-color:transparent;font-weight:normal;fon=
t-style:normal;font-variant:normal;text-decoration:none;vertical-align:base=
line">.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Consider
    </span><a href=3D"http://stackoverflow.com/questions/4340396/does-the-c=
-standard-mandate-poor-performance-for-iostreams-or-am-i-just-deali" target=
=3D"_blank"><span style=3D"font-size:15px;font-family:Arial;color:#1155cc;b=
ackground-color:transparent;font-weight:normal;font-style:normal;font-varia=
nt:normal;text-decoration:underline;vertical-align:baseline">this
        suite of benchmarks</span></a><span style=3D"font-size:15px;font-fa=
mily:Arial;color:#000000;background-color:transparent;font-weight:normal;fo=
nt-style:normal;font-variant:normal;text-decoration:none;vertical-align:bas=
eline">.
      This code doesn=92t do file IO; it writes directly to a string. All
      it=92s doing is measuring the time it takes to append 4-characters
      to a string. A lot. It uses a `char[]` as a useful control. It
      also tests the use of `vector&lt;char&gt;` (presumably
      `basic_string` would have similar results). Therefore, this is a
      solid test for the efficiency of the iostreams codebase itself.</span=
><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Obviously
      there will be some efficiency loss. But consider the numbers in
      the results.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">The
      ostringstream is more than </span><span style=3D"font-size:15px;font-=
family:Arial;color:#000000;background-color:transparent;font-weight:normal;=
font-style:italic;font-variant:normal;text-decoration:none;vertical-align:b=
aseline">full
      order of magnitude</span><span style=3D"font-size:15px;font-family:Ar=
ial;color:#000000;background-color:transparent;font-weight:normal;font-styl=
e:normal;font-variant:normal;text-decoration:none;vertical-align:baseline">
      slower than the control. It=92s almost 100x in some cases. Note that
      it=92s not using &lt;&lt; to write to the stream; it=92s using
      `ostream::write()`.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Note

      that the vector&lt;char&gt; implementations are fairly comparable
      to the control, usually being around 1x-4x the speed. So clearly
      this is something in ostringstream.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Now,

      you might say that one could use the stringbuf directly. And that
      was done. While it does improve performance over the ostringstream
      case substantially (generally half to a quarter the performance),
      it=92s still over 10x slower than the control or most
      vector&lt;char&gt; implementations.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Why?
      The stringbuf operations ought to be a thin wrapper over
      std::string. After all, that=92s what was asked for.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Where

      does this inefficiency come from? I haven=92t done any extensive
      profiling analysis, but my educated guesses are from two places:
      virtual function overhead and an interface that does too much.</span>=
<br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">ostringstream

      is supposed to be able to be used as an ostream for
      runtime-polymorphism. But here=92s where the C++ maxim comes into
      play. Runtime-polymorphism is </span><span style=3D"font-size:15px;fo=
nt-family:Arial;color:#000000;background-color:transparent;font-weight:norm=
al;font-style:italic;font-variant:normal;text-decoration:none;vertical-alig=
n:baseline">not
      being used here</span><span style=3D"font-size:15px;font-family:Arial=
;color:#000000;background-color:transparent;font-weight:normal;font-style:n=
ormal;font-variant:normal;text-decoration:none;vertical-align:baseline">.
      Every function call should be able to be statically dispatched.
      And it is, but all of the virtual machinery comes from <i>within</i>
      ostringstream.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">This
      problem seems to come mostly from the fact that basic_ostream,
      which does most of the leg-work for ostringstream, has no specific
      knowledge of its stream type. Therefore it's always a virtual
      call. And it may be doing many such virtual calls.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">You

      can achieve the same runtime polymorphism (being able to overload
      operator&lt;&lt; for any stream) by using a static set of stream
      classes, tightly coupled to their specific streambufs, and a
      single =93anystream=94 type that those streams can be converted into.
      It would use std::function-style type erasure to remember the
      original type and feed function calls to it. It would use a single
      function call to initiate each write operation, rather than what
      appears to be many virtual calls within each write.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Then,

      there=92s the fact that streambuf itself is overdesigned. stringbuf
      ought to be a simple interface wrapper around a std::string, but
      it=92s not. It=92s a complex thing. It has </span><span style=3D"font=
-size:15px;font-family:Arial;color:#000000;background-color:transparent;fon=
t-weight:normal;font-style:italic;font-variant:normal;text-decoration:none;=
vertical-align:baseline">locale
      support</span><span style=3D"font-size:15px;font-family:Arial;color:#=
000000;background-color:transparent;font-weight:normal;font-style:normal;fo=
nt-variant:normal;text-decoration:none;vertical-align:baseline">
      of all things. Why? Isn=92t that something that should be handled at
      the stream level?</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">This

      API has no way to get a low-level interface to a
      file/string/whatever. There=92s no way to just open a filebuf and
      blast the file into some memory, or to shove some memory out of a
      filebuf. It will always employ the locale machinery even if you
      didn=92t ask for it. It will always make these internal virtual
      calls, even if they are completely statically dispatched.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">With

      iostreams, you are paying for a lot of stuff that you don=92t
      frequently use. At the stream level, it makes sense that you=92re
      paying for certain machinery (though again, some way to say that
      you=92re not using some of it would be nice). At the buffer level,
      it does not, since that is the lowest level you=92re allowed to use.<=
/span><br>
    <p dir=3D"ltr"><span style=3D"font-size:32px;font-family:Georgia;color:=
#666666;background-color:transparent;font-weight:normal;font-style:italic;f=
ont-variant:normal;text-decoration:none;vertical-align:baseline">Utility</s=
pan></p>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">While
      performance is the big issue, it=92s not the only one.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">The

      biggest selling point for iostreams is the ability to extend its
      formatted writing functionality. You can overload operator&lt;&lt;
      for various types and simply use them. You can=92t do that with
      fprintf. And thanks to ADL, it will work just fine for classes in
      namespaces. You can create new streambuf types and even streams if
      you like. All relatively easily.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Here=92s
      the problem, and it is admittedly one that is subjective: printf
      is really nice syntax.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">It=92s

      very compact, for one. Once you understand the basic syntax of it,
      it=92s very easy to see what=92s going on. Especially for complex
      formatting. Just consider the physical size difference between
      these two:</span><br>
    <pre><tt><span style=3D"font-size:15px;color:rgb(0,0,0);background-colo=
r:transparent;font-weight:normal;font-style:normal;font-variant:normal;text=
-decoration:none;vertical-align:baseline">snprintf(..., =930x%08x=94, integ=
er);</span></tt></pre>
   =20
    <pre><tt><span style=3D"font-size:15px;color:rgb(0,0,0);background-colo=
r:transparent;font-weight:normal;font-style:normal;font-variant:normal;text=
-decoration:none;vertical-align:baseline">stream &lt;&lt; "0x" &lt;&lt; std=
::right &lt;&lt; std::hex &lt;&lt; std::setw(8) &lt;&lt; iVal &lt;&lt; std:=
:endl;</span></tt></pre>
   =20
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">It
      may take a bit longer to become used to the printf version, but
      this is something you can easily look up in a reference.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Plus,

      it makes it much easier to do translations on formatted strings.
      You can look the pattern string up in a table that changes from
      language to language. This is rather more difficult in iostreams,
      though not impossible. Granted, pattern changes may not be enough,
      as some languages have different subject/verb/object grammars that
      would require reshuffling patterns around. However, there are
      printf-style systems that do allow for reshuffling, whereas no
      such mechanism exists for iostream-style.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">C++

      used the &lt;&lt; method because the alternatives were less
      flexible. Boost.Format and other systems show that C++03 did not
      really have to use this mechanism to achieve the extensibility
      features that iostreams provide.</span><br>
    <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">What
      do you think? Are there other issues in iostreams that need to be
      mentioned?</span><br>
  </div>

</blockquote>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_286_29635840.1353245888501--

.


Author: Martinho Fernandes <martinho.fernandes@gmail.com>
Date: Sun, 18 Nov 2012 14:42:33 +0100
Raw View
--f46d042fddde76d93604cec52d7c
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

On Sun, Nov 18, 2012 at 2:38 PM, Arthur Tchaikovsky <atch.cpp@gmail.com>wro=
te:

> It=92s very compact, for one. Once you understand the basic syntax of it,
>> it=92s very easy to see what=92s going on. Especially for complex format=
ting.
>> Just consider the physical size difference between these two:
>>
> snprintf(..., =930x%08x=94, integer);
>>
> stream << "0x" << std::right << std::hex << std::setw(8) << iVal <<
>> std::endl;
>>
> It may take a bit longer to become used to the printf version, but this i=
s
>> something you can easily look up in a reference.
>>
>
> Again, logic of a person for whom recursion is as easy to understand and
> use as iteration.
>

Your most recent replies have been getting somewhat inflamatory. I think
you should take a break.

Martinho

--=20




--f46d042fddde76d93604cec52d7c
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

On Sun, Nov 18, 2012 at 2:38 PM, Arthur Tchaikovsky <span dir=3D"ltr">&lt;<=
a href=3D"mailto:atch.cpp@gmail.com" target=3D"_blank">atch.cpp@gmail.com</=
a>&gt;</span> wrote:<br><div class=3D"gmail_quote"><blockquote class=3D"gma=
il_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-lef=
t:1ex">

<div class=3D"im"><blockquote class=3D"gmail_quote" style=3D"margin:0;margi=
n-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">It=92s very compa=
ct, for one. Once you understand the basic syntax of it, it=92s very easy t=
o see what=92s going on. Especially for complex formatting. Just consider t=
he physical size difference between these two:<br>

</blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex">snprintf(..., =930x%08=
x=94, integer);<br></blockquote><blockquote class=3D"gmail_quote" style=3D"=
margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">

stream &lt;&lt; &quot;0x&quot; &lt;&lt; std::right &lt;&lt; std::hex &lt;&l=
t; std::setw(8) &lt;&lt; iVal &lt;&lt; std::endl;<br></blockquote><blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex">

It may take a bit longer to become used to the printf version, but this is =
something you can easily look up in a reference.<br></blockquote><div><br><=
/div></div><div>Again, logic of a person for whom recursion is as easy to u=
nderstand and use as iteration.<br>

</div></blockquote><div><br>Your most recent replies have been getting some=
what inflamatory. I think you should take a break.<br><br clear=3D"all">Mar=
tinho </div></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--f46d042fddde76d93604cec52d7c--

.


Author: "J. Daniel Garcia" <josedaniel.garcia@uc3m.es>
Date: Sun, 18 Nov 2012 07:59:14 -0600
Raw View
--e89a8f2350975f72c304cec56a98
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

While I do not share inflammatory style, I think we should clearly make a
separate of concerns here. If I understood correctly (and that might not be
the case), we have here 2 different issues:

+ Performance issue: iostreams are slow. This seems to be relevant only for
large size files.
+ Usability issue: Current interfaces is very convenient for simple cases,
although there are some complains for complex cases

Is this accurate summary?

On Sun, Nov 18, 2012 at 7:42 AM, Martinho Fernandes <martinho.fernandes
@gmail.com> wrote:

> On Sun, Nov 18, 2012 at 2:38 PM, Arthur Tchaikovsky <atch.cpp@gmail.com>w=
rote:
>
>> It=92s very compact, for one. Once you understand the basic syntax of it=
,
>>> it=92s very easy to see what=92s going on. Especially for complex forma=
tting.
>>> Just consider the physical size difference between these two:
>>>
>> snprintf(..., =930x%08x=94, integer);
>>>
>> stream << "0x" << std::right << std::hex << std::setw(8) << iVal <<
>>> std::endl;
>>>
>> It may take a bit longer to become used to the printf version, but this
>>> is something you can easily look up in a reference.
>>>
>>
>> Again, logic of a person for whom recursion is as easy to understand and
>> use as iteration.
>>
>
> Your most recent replies have been getting somewhat inflamatory. I think
> you should take a break.
>
> Martinho
>
> --
>
>
>
>

--=20




--e89a8f2350975f72c304cec56a98
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

While I do not share inflammatory style, I think we should clearly make a s=
eparate of concerns here. If I understood correctly (and that might not be =
the case), we have here 2 different issues:<div><br></div><div>+ Performanc=
e issue: <span class=3D"" style>iostreams</span> are slow. This seems to be=
 relevant only for large size files.<br>

</div><div>+ Usability issue: Current interfaces is very convenient for sim=
ple cases, although there are some complains for complex cases</div><div cl=
ass=3D"gmail_extra"><br></div><div class=3D"gmail_extra">Is this accurate s=
ummary?<br>

<br><div class=3D"gmail_quote">On Sun, Nov 18, 2012 at 7:42 AM, <span class=
=3D"" style>Martinho</span> <span class=3D"" style>Fernandes</span> <span d=
ir=3D"ltr">&lt;<a href=3D"mailto:martinho.fernandes@gmail.com" target=3D"_b=
lank"><span class=3D"" style>martinho</span>.<span class=3D"" style>fernand=
es</span>@gmail.com</a>&gt;</span> wrote:<br>

<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div class=3D"im">On Sun, Nov 18, 2012 at 2:=
38 PM, Arthur Tchaikovsky <span dir=3D"ltr">&lt;<a href=3D"mailto:atch.cpp@=
gmail.com" target=3D"_blank">atch.cpp@gmail.com</a>&gt;</span> wrote:<br>

</div><div class=3D"gmail_quote"><div class=3D"im"><blockquote class=3D"gma=
il_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-lef=
t:1ex">

<div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;=
border-left:1px #ccc solid;padding-left:1ex">It=92s very compact, for one. =
Once you understand the basic syntax of it, it=92s very easy to see what=92=
s going on. Especially for complex formatting. Just consider the physical s=
ize difference between these two:<br>



</blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex">snprintf(..., =930x%08=
x=94, integer);<br></blockquote><blockquote class=3D"gmail_quote" style=3D"=
margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">



stream &lt;&lt; &quot;0x&quot; &lt;&lt; std::right &lt;&lt; std::hex &lt;&l=
t; std::setw(8) &lt;&lt; iVal &lt;&lt; std::endl;<br></blockquote><blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex">



It may take a bit longer to become used to the printf version, but this is =
something you can easily look up in a reference.<br></blockquote><div><br><=
/div></div><div>Again, logic of a person for whom recursion is as easy to u=
nderstand and use as iteration.<br>



</div></blockquote></div><div><br>Your most recent replies have been gettin=
g somewhat inflamatory. I think you should take a break.<span class=3D"HOEn=
Zb"><font color=3D"#888888"><br><br clear=3D"all">Martinho </font></span></=
div>

</div><span class=3D"HOEnZb"><font color=3D"#888888">

<p></p>

-- <br>
=A0<br>
=A0<br>
=A0<br>
</font></span></blockquote></div><br><br clear=3D"all"><div><br></div><br>
</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--e89a8f2350975f72c304cec56a98--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 18 Nov 2012 09:21:34 -0800 (PST)
Raw View
------=_Part_1048_3251000.1353259294212
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable



On Sunday, November 18, 2012 5:20:13 AM UTC-8, Arthur Tchaikovsky wrote:
>
> It=92s very compact, for one. Once you understand the basic syntax of it,=
=20
>> it=92s very easy to see what=92s going on. Especially for complex format=
ting.=20
>> Just consider the physical size difference between these two:
>>
> snprintf(..., =930x%08x=94, integer);
>>
> stream << "0x" << std::right << std::hex << std::setw(8) << iVal <<=20
>> std::endl;
>>
> It may take a bit longer to become used to the printf version, but this i=
s=20
>> something you can easily look up in a reference.
>>
>
> a) every heard of "type safety"?
>

Yes. Which Boost.Format provides quite nicely while still using=20
printf-style syntax.

--=20




------=_Part_1048_3251000.1353259294212
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

<br><br>On Sunday, November 18, 2012 5:20:13 AM UTC-8, Arthur Tchaikovsky w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex">It=92s very compact, for one. Once you understand the basic =
syntax of it, it=92s very easy to see what=92s going on. Especially for com=
plex formatting. Just consider the physical size difference between these t=
wo:<br></blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0;mar=
gin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">snprintf(..., =
=930x%08x=94, integer);<br></blockquote><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:=
1ex">stream &lt;&lt; "0x" &lt;&lt; std::right &lt;&lt; std::hex &lt;&lt; st=
d::setw(8) &lt;&lt; iVal &lt;&lt; std::endl;<br></blockquote><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #cc=
c solid;padding-left:1ex">It may take a bit longer to become used to the pr=
intf version, but this is something you can easily look up in a reference.<=
br></blockquote><div>
<div><br></div><div>a) every heard of "type safety"?</div></div></blockquot=
e><div><br>Yes. Which Boost.Format provides quite nicely while still using =
printf-style syntax.</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_1048_3251000.1353259294212--

.


Author: Jens Maurer <Jens.Maurer@gmx.net>
Date: Sun, 18 Nov 2012 21:19:41 +0100
Raw View
On 11/18/2012 12:12 PM, Bjorn Reese wrote:
> Perhaps peripheral, but std::cout (and std::cerr) are objects, so you
> cannot use them for debug printing from the destructors of global
> objects.

That's not quite accurate, see 27.4.1p2:

"The objects are not destroyed during program execution."

plus footnote:

"294) Constructors and destructors for static objects can access these
objects to read input from stdin or write output to stdout or stderr."

Jens

--




.


Author: Brendon Costa <brendon.j.costa@gmail.com>
Date: Mon, 19 Nov 2012 12:04:21 +1100
Raw View
--e89a8fb1f7ee98a93c04ceceb21c
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

I am not an expert on these things but just want to add my two cents in
case it is helpful.

I have found in the workplaces I have been at that people
generally prefer to use printf style string formatting over the ostream
style. Despite the significant issues that come with using printf in
particular (programs that crash on incorrect usage comes to mind).

There have been a number of reasons for this:

1) Performance
This is the big one, particularly for log messages.

2) A preference on how people like to read strings
This is subjective but again I think that most people I have spoken to
about this prefer to read strings where the code does not get inserted in
the middle of reading the textual string (not the best code fragment but
gives an example):

printf("Client %s, failed to connect at address: %s for reason: %s\n",
c->name, c->address, strerror(errno));

instead of:

std::cout << "Client " << cl->name << ", failed to connect at address: " <<
c->address << " for reason: " << strerror(errno) << std::endl;

The reasoning is that you don't have to mentally "parse" through the code
to read what the message is saying using the printf style of formatting.
The % symbols are "less intrusive" than inserting code in the middle of the
text string.

3) Simplicity formatting in certain cases
Good examples of this have already been mentioned. The two that come up a
lot are printing a hex integer or prefixing things with 0's to a specific
width.

4) Inconsistencies in the stream interface
One example here are flags. Some work on only the next item, but others set
details globally. One example I have seen a few times is
std::setprecision() being used and not expecting it to last past the next
item but resulting in changing the precision for components that follow.

5) Dynamic memory allocation
The one other item that seems to have been relatively important (or at
least perceived to be important) in the past is dynamic allocation of
memory. It should be possible to use a custom streambuf on a pre-allocated
buffer, but in general people simply seem to fall back to snprintf() for
its simplicity. Again, this was common in logging where say a subsystem
(like syslog) has a max sized buffer it accepts we would allocate a pool of
objects that size and simply construct messages into those buffers
(truncating as necessary). I don't think this is currently easily supported
by iostreams, but then dont know if it should be (and why it is last on my
list).


Now Boost.Format solves most of these issues IMO except possibly the
performance issue. This may have changed since it was measured or the
measurements done may have been incorrect:
http://fastformat.sourceforge.net/performance.html






On Monday, 19 November 2012, J. Daniel Garcia wrote:

> While I do not share inflammatory style, I think we should clearly make a
> separate of concerns here. If I understood correctly (and that might not =
be
> the case), we have here 2 different issues:
>
> + Performance issue: iostreams are slow. This seems to be relevant only
> for large size files.
> + Usability issue: Current interfaces is very convenient for simple cases=
,
> although there are some complains for complex cases
>
> Is this accurate summary?
>
> On Sun, Nov 18, 2012 at 7:42 AM, Martinho Fernandes <martinho.fernandes
> @gmail.com <javascript:_e({}, 'cvml', 'martinho.fernandes@gmail.com');>>w=
rote:
>
>> On Sun, Nov 18, 2012 at 2:38 PM, Arthur Tchaikovsky <atch.cpp@gmail.com<=
javascript:_e({}, 'cvml', 'atch.cpp@gmail.com');>
>> > wrote:
>>
>>> It=92s very compact, for one. Once you understand the basic syntax of i=
t,
>>>> it=92s very easy to see what=92s going on. Especially for complex form=
atting.
>>>> Just consider the physical size difference between these two:
>>>>
>>> snprintf(..., =930x%08x=94, integer);
>>>>
>>> stream << "0x" << std::right << std::hex << std::setw(8) << iVal <<
>>>> std::endl;
>>>>
>>> It may take a bit longer to become used to the printf version, but this
>>>> is something you can easily look up in a reference.
>>>>
>>>
>>> Again, logic of a person for whom recursion is as easy to understand an=
d
>>> use as iteration.
>>>
>>
>> Your most recent replies have been getting somewhat inflamatory. I think
>> you should take a break.
>>
>> Martinho
>>
>> --
>>
>>
>>
>>
>
>
>
>
>  --
>
>
>
>

--=20




--e89a8fb1f7ee98a93c04ceceb21c
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

<div>I am not an expert on these things but just want to add my two cents i=
n case it is helpful.</div><div><br></div>I have found in the workplaces I =
have been at that people generally=A0prefer=A0to use printf style string fo=
rmatting over the ostream style. Despite the significant issues that come w=
ith using printf in particular (programs that crash on incorrect usage come=
s to mind).=A0<div>
<br></div><div>There have been a number of reasons for this:<div><br></div>=
<div>1) Performance</div><div>This is the big one,=A0particularly=A0for log=
 messages.=A0</div><div><br></div><div>2) A preference on how people like t=
o read strings</div>
<div>This is subjective but again I think that most people I have spoken to=
 about this prefer to read strings where the code does not get inserted in =
the middle of reading the textual string (not the best code fragment but gi=
ves an example):</div>
<div><br></div><div>printf(&quot;Client %s, failed to connect at address: %=
s for reason: %s\n&quot;, c-&gt;name, c-&gt;address, strerror(errno));</div=
><div><br></div><div>instead of:</div><div><br></div><div>std::cout &lt;&lt=
; &quot;Client &quot; &lt;&lt; cl-&gt;name &lt;&lt; &quot;, failed to conne=
ct at address: &quot; &lt;&lt; c-&gt;address &lt;&lt; &quot; for reason: &q=
uot; &lt;&lt; strerror(errno) &lt;&lt; std::endl;</div>
<div><br></div><div>The reasoning is that you don&#39;t have to mentally &q=
uot;parse&quot; through the code to read what the message is saying using t=
he printf style of formatting. The % symbols are &quot;less intrusive&quot;=
 than inserting code in the middle of the text string.</div>
<div><br></div><div>3) Simplicity formatting in certain cases</div><div>Goo=
d examples of this have already been mentioned. The two that come up a lot =
are printing a hex integer or prefixing things with 0&#39;s to a specific w=
idth.=A0</div>
<div><br></div><div>4) Inconsistencies in the stream interface</div><div>On=
e example here are flags. Some work on only the next item, but others set d=
etails globally. One example I have seen a few times is std::setprecision()=
 being used and not expecting it to last past the next item but resulting i=
n changing the precision for components that follow.</div>
<div><br></div><div><div>5) Dynamic memory allocation</div><div>The one oth=
er item that seems to have been relatively important (or at least=A0perceiv=
ed=A0to be important) in the past is dynamic allocation of memory. It shoul=
d be possible to use a custom streambuf on a pre-allocated buffer, but in g=
eneral people simply seem to fall back to snprintf() for its simplicity. Ag=
ain, this was common in logging where say a subsystem (like syslog) has a m=
ax sized buffer it accepts we would allocate a pool of objects that size an=
d simply construct messages into those buffers (truncating as necessary). I=
 don&#39;t think this is currently easily supported by iostreams, but then =
dont know if it should be (and why it is last on my list).</div>
</div><div><br></div><div><br></div><div>Now Boost.Format solves most of th=
ese issues IMO except possibly the performance issue. This may have changed=
 since it was measured or the measurements done may have been incorrect:</d=
iv>
<div><a href=3D"http://fastformat.sourceforge.net/performance.html">http://=
fastformat.sourceforge.net/performance.html</a></div><div><br></div><div><b=
r></div><div><br></div><div><br></div><div><br><br>On Monday, 19 November 2=
012, J. Daniel Garcia  wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">While I do not share inflammatory style, I t=
hink we should clearly make a separate of concerns here. If I understood co=
rrectly (and that might not be the case), we have here 2 different issues:<=
div>
<br></div><div>+ Performance issue: <span>iostreams</span> are slow. This s=
eems to be relevant only for large size files.<br>

</div><div>+ Usability issue: Current interfaces is very convenient for sim=
ple cases, although there are some complains for complex cases</div><div cl=
ass=3D"gmail_extra"><br></div><div class=3D"gmail_extra">Is this accurate s=
ummary?<br>


<br><div class=3D"gmail_quote">On Sun, Nov 18, 2012 at 7:42 AM, <span>Marti=
nho</span> <span>Fernandes</span> <span dir=3D"ltr">&lt;<a href=3D"javascri=
pt:_e({}, &#39;cvml&#39;, &#39;martinho.fernandes@gmail.com&#39;);" target=
=3D"_blank"><span>martinho</span>.<span>fernandes</span>@gmail.com</a>&gt;<=
/span> wrote:<br>


<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div>On Sun, Nov 18, 2012 at 2:38 PM, Arthur=
 Tchaikovsky <span dir=3D"ltr">&lt;<a href=3D"javascript:_e({}, &#39;cvml&#=
39;, &#39;atch.cpp@gmail.com&#39;);" target=3D"_blank">atch.cpp@gmail.com</=
a>&gt;</span> wrote:<br>


</div><div class=3D"gmail_quote"><div><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;=
border-left:1px #ccc solid;padding-left:1ex">It=92s very compact, for one. =
Once you understand the basic syntax of it, it=92s very easy to see what=92=
s going on. Especially for complex formatting. Just consider the physical s=
ize difference between these two:<br>




</blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex">snprintf(..., =930x%08=
x=94, integer);<br></blockquote><blockquote class=3D"gmail_quote" style=3D"=
margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">




stream &lt;&lt; &quot;0x&quot; &lt;&lt; std::right &lt;&lt; std::hex &lt;&l=
t; std::setw(8) &lt;&lt; iVal &lt;&lt; std::endl;<br></blockquote><blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex">




It may take a bit longer to become used to the printf version, but this is =
something you can easily look up in a reference.<br></blockquote><div><br><=
/div></div><div>Again, logic of a person for whom recursion is as easy to u=
nderstand and use as iteration.<br>




</div></blockquote></div><div><br>Your most recent replies have been gettin=
g somewhat inflamatory. I think you should take a break.<span><font color=
=3D"#888888"><br><br clear=3D"all">Martinho </font></span></div>

</div><span><font color=3D"#888888">

<p></p>

-- <br>
=A0<br>
=A0<br>
=A0<br>
</font></span></blockquote></div><br><br clear=3D"all"><div><br></div><br>
</div>

<p></p>

-- <br>
=A0<br>
=A0<br>
=A0<br>
</blockquote></div></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--e89a8fb1f7ee98a93c04ceceb21c--

.


Author: Bjorn Reese <breese@mail1.stofanet.dk>
Date: Mon, 19 Nov 2012 17:01:22 +0100
Raw View
On 2012-11-18 21:19, Jens Maurer wrote:
> On 11/18/2012 12:12 PM, Bjorn Reese wrote:
>> Perhaps peripheral, but std::cout (and std::cerr) are objects, so you
>> cannot use them for debug printing from the destructors of global
>> objects.
>
> That's not quite accurate, see 27.4.1p2:
>
> "The objects are not destroyed during program execution."
>
> plus footnote:
>
> "294) Constructors and destructors for static objects can access these
> objects to read input from stdin or write output to stdout or stderr."

I supposed I have found a bug in the compiler (or standard C++ library)
then. I just checked C++98, and it also contains the passages you quote.

--




.


Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Mon, 19 Nov 2012 15:51:12 -0800 (PST)
Raw View
------=_Part_388_19285720.1353369072971
Content-Type: text/plain; charset=ISO-8859-1

On Saturday, November 17, 2012 8:36:37 PM UTC+1, Nicol Bolas wrote:

> What do you think? Are there other issues in iostreams that need to be
> mentioned?
>

I think a C++11 variant of printf / boost::format should be standardized to
deal with the utility issue.
I think a lower-level interface should be provided for binary (unbuffered
and maybe async) IO.
This wouldn't fix iostreams, but it'd avoid it for a number of use cases.


Olaf

--




------=_Part_388_19285720.1353369072971
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On Saturday, November 17, 2012 8:36:37 PM UTC+1, Nicol Bolas wrote:<br><blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;">
 =20

   =20
 =20
  <div bgcolor=3D"#FFFFFF" text=3D"#000000"><span style=3D"background-color=
: transparent; color: rgb(0, 0, 0); font-family: Arial; font-size: 15px;">W=
hat
      do you think? Are there other issues in iostreams that need to be
      mentioned?</span></div></blockquote><div><br></div><div>I think a C++=
11 variant of printf / boost::format should be standardized to deal with th=
e utility issue.</div><div>I think a lower-level interface should be provid=
ed for binary (unbuffered and maybe async) IO.&nbsp;<br></div><div>This wou=
ldn't fix iostreams, but it'd avoid it for a number of use cases.</div><div=
><br></div><div><br></div><div>Olaf</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_388_19285720.1353369072971--

.


Author: Arthur Tchaikovsky <atch.cpp@gmail.com>
Date: Tue, 20 Nov 2012 02:23:26 -0800 (PST)
Raw View
------=_Part_804_9043296.1353407006699
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable


>
> Your most recent replies have been getting somewhat inflamatory. I think=
=20
> you should take a break.


Fair enough, but interestingly, you didn't say anything to the guy who=20
claimed that my suggestion is idiotic. I believe that either apply rules=20
(of correct manners etc) to everyone and I am more than happy for it, or=20
don't apply them at all. Saying just to one guy (me) to ease off and don't=
=20
say anything to another guy why I believe presented far worse behavior than=
=20
I (calling someone's suggestion "idiotic") is simply not fair. I would like=
=20
you to note that I wasn't the first guy who posted "somewhat" inflammatory=
=20
posts. Some people here are passive aggressive and this bad too yet you=20
don't mind them doing so. And also, please note that I didn't use any=20
offensive words, like commenting on someone's suggestion as "idiotic", for=
=20
example.

On Sunday, 18 November 2012 13:42:54 UTC, R. Martinho Fernandes wrote:
>
> On Sun, Nov 18, 2012 at 2:38 PM, Arthur Tchaikovsky <atch...@gmail.com<ja=
vascript:>
> > wrote:
>
>> It=92s very compact, for one. Once you understand the basic syntax of it=
,=20
>>> it=92s very easy to see what=92s going on. Especially for complex forma=
tting.=20
>>> Just consider the physical size difference between these two:
>>>
>> snprintf(..., =930x%08x=94, integer);
>>>
>> stream << "0x" << std::right << std::hex << std::setw(8) << iVal <<=20
>>> std::endl;
>>>
>> It may take a bit longer to become used to the printf version, but this=
=20
>>> is something you can easily look up in a reference.
>>>
>>
>> Again, logic of a person for whom recursion is as easy to understand and=
=20
>> use as iteration.
>>
>
> Your most recent replies have been getting somewhat inflamatory. I think=
=20
> you should take a break.
>
> Martinho=20
>

--=20




------=_Part_804_9043296.1353407006699
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;">
Your most recent replies have been getting somewhat inflamatory. I think yo=
u should take a break.</blockquote><div><br></div><div>Fair enough, but int=
erestingly, you didn't say anything to the guy who claimed that my suggesti=
on is idiotic. I believe that either apply rules (of correct manners etc) t=
o everyone and I am more than happy for it, or don't apply them at all. Say=
ing just to one guy (me) to ease off and don't say anything to another guy =
why I believe presented far worse behavior than I (calling someone's sugges=
tion "idiotic") is simply not fair. I would like you to note that I wasn't =
the first guy who posted "somewhat" inflammatory posts. Some people here ar=
e passive aggressive and this bad too yet you don't mind them doing so. And=
 also, please note that I didn't use any offensive words, like commenting o=
n someone's suggestion as "idiotic", for example.</div><br>On Sunday, 18 No=
vember 2012 13:42:54 UTC, R. Martinho Fernandes  wrote:<blockquote class=3D=
"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc s=
olid;padding-left: 1ex;">On Sun, Nov 18, 2012 at 2:38 PM, Arthur Tchaikovsk=
y <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfus=
cated-mailto=3D"xbeq8nWOPZ4J">atch...@gmail.com</a>&gt;</span> wrote:<br><d=
iv class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:=
0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;=
border-left:1px #ccc solid;padding-left:1ex">It=92s very compact, for one. =
Once you understand the basic syntax of it, it=92s very easy to see what=92=
s going on. Especially for complex formatting. Just consider the physical s=
ize difference between these two:<br>

</blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex">snprintf(..., =930x%08=
x=94, integer);<br></blockquote><blockquote class=3D"gmail_quote" style=3D"=
margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">

stream &lt;&lt; "0x" &lt;&lt; std::right &lt;&lt; std::hex &lt;&lt; std::se=
tw(8) &lt;&lt; iVal &lt;&lt; std::endl;<br></blockquote><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex">

It may take a bit longer to become used to the printf version, but this is =
something you can easily look up in a reference.<br></blockquote><div><br><=
/div></div><div>Again, logic of a person for whom recursion is as easy to u=
nderstand and use as iteration.<br>

</div></blockquote><div><br>Your most recent replies have been getting some=
what inflamatory. I think you should take a break.<br><br clear=3D"all">Mar=
tinho </div></div>
</blockquote>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_804_9043296.1353407006699--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 20 Nov 2012 09:01:16 -0800 (PST)
Raw View
------=_Part_984_23500860.1353430876498
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable



On Tuesday, November 20, 2012 2:23:26 AM UTC-8, Arthur Tchaikovsky wrote:
>
> Your most recent replies have been getting somewhat inflamatory. I think=
=20
>> you should take a break.
>
>
> Fair enough, but interestingly, you didn't say anything to the guy who=20
> claimed that my suggestion is idiotic. I believe that either apply rules=
=20
> (of correct manners etc) to everyone and I am more than happy for it, or=
=20
> don't apply them at all. Saying just to one guy (me) to ease off and don'=
t=20
> say anything to another guy why I believe presented far worse behavior th=
an=20
> I (calling someone's suggestion "idiotic") is simply not fair. I would li=
ke=20
> you to note that I wasn't the first guy who posted "somewhat" inflammator=
y=20
> posts. Some people here are passive aggressive and this bad too yet you=
=20
> don't mind them doing so. And also, please note that I didn't use any=20
> offensive words, like commenting on someone's suggestion as "idiotic", fo=
r=20
> example.
>

"idiotic" is not an offensive word. More importantly, he called your *
suggestion* idiotic, which is very different from calling *you* idiotic.=20
Attacks against your suggestion are going to happen; that's what this=20
discussion forum is *about*. Attacking you as a person is what we wouldn't=
=20
allow; attacking a suggestion is perfectly reasonable.

Plus, the "idiotic" comment came after an extended period of discussion=20
where you continued to use the same reasoning over and over, without=20
showing the slightest sense that you understood the opposing argument. Nor=
=20
did you display any recognition or understanding of the simple fact that=20
the standard *doesn't cover* what you were talking about. Given the=20
substance of the discussion, I think it was a perfectly reasonable=20
assessment of your suggestion.

On Sunday, 18 November 2012 13:42:54 UTC, R. Martinho Fernandes wrote:
>>
>> On Sun, Nov 18, 2012 at 2:38 PM, Arthur Tchaikovsky <atch...@gmail.com>w=
rote:
>>
>>> It=92s very compact, for one. Once you understand the basic syntax of i=
t,=20
>>>> it=92s very easy to see what=92s going on. Especially for complex form=
atting.=20
>>>> Just consider the physical size difference between these two:
>>>>
>>> snprintf(..., =930x%08x=94, integer);
>>>>
>>> stream << "0x" << std::right << std::hex << std::setw(8) << iVal <<=20
>>>> std::endl;
>>>>
>>> It may take a bit longer to become used to the printf version, but this=
=20
>>>> is something you can easily look up in a reference.
>>>>
>>>
>>> Again, logic of a person for whom recursion is as easy to understand an=
d=20
>>> use as iteration.
>>>
>>
>> Your most recent replies have been getting somewhat inflamatory. I think=
=20
>> you should take a break.
>>
>> Martinho=20
>>
>

--=20




------=_Part_984_23500860.1353430876498
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

<br><br>On Tuesday, November 20, 2012 2:23:26 AM UTC-8, Arthur Tchaikovsky =
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex">
Your most recent replies have been getting somewhat inflamatory. I think yo=
u should take a break.</blockquote><div><br></div><div>Fair enough, but int=
erestingly, you didn't say anything to the guy who claimed that my suggesti=
on is idiotic. I believe that either apply rules (of correct manners etc) t=
o everyone and I am more than happy for it, or don't apply them at all. Say=
ing just to one guy (me) to ease off and don't say anything to another guy =
why I believe presented far worse behavior than I (calling someone's sugges=
tion "idiotic") is simply not fair. I would like you to note that I wasn't =
the first guy who posted "somewhat" inflammatory posts. Some people here ar=
e passive aggressive and this bad too yet you don't mind them doing so. And=
 also, please note that I didn't use any offensive words, like commenting o=
n someone's suggestion as "idiotic", for example.<br></div></blockquote><di=
v><br>"idiotic" is not an offensive word. More importantly, he called your =
<i>suggestion</i> idiotic, which is very different from calling <i>you</i> =
idiotic. Attacks against your suggestion are going to happen; that's what t=
his discussion forum is <i>about</i>. Attacking you as a person is what we =
wouldn't allow; attacking a suggestion is perfectly reasonable.<br><br>Plus=
, the "idiotic" comment came after an extended period of discussion where y=
ou continued to use the same reasoning over and over, without showing the s=
lightest sense that you understood the opposing argument. Nor did you displ=
ay any recognition or understanding of the simple fact that the standard <i=
>doesn't cover</i> what you were talking about. Given the substance of the =
discussion, I think it was a perfectly reasonable assessment of your sugges=
tion.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Sunday, =
18 November 2012 13:42:54 UTC, R. Martinho Fernandes  wrote:<blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc=
 solid;padding-left:1ex">On Sun, Nov 18, 2012 at 2:38 PM, Arthur Tchaikovsk=
y <span dir=3D"ltr">&lt;<a>atch...@gmail.com</a>&gt;</span> wrote:<br><div =
class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0=
 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;=
border-left:1px #ccc solid;padding-left:1ex">It=92s very compact, for one. =
Once you understand the basic syntax of it, it=92s very easy to see what=92=
s going on. Especially for complex formatting. Just consider the physical s=
ize difference between these two:<br>

</blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex">snprintf(..., =930x%08=
x=94, integer);<br></blockquote><blockquote class=3D"gmail_quote" style=3D"=
margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">

stream &lt;&lt; "0x" &lt;&lt; std::right &lt;&lt; std::hex &lt;&lt; std::se=
tw(8) &lt;&lt; iVal &lt;&lt; std::endl;<br></blockquote><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex">

It may take a bit longer to become used to the printf version, but this is =
something you can easily look up in a reference.<br></blockquote><div><br><=
/div></div><div>Again, logic of a person for whom recursion is as easy to u=
nderstand and use as iteration.<br>

</div></blockquote><div><br>Your most recent replies have been getting some=
what inflamatory. I think you should take a break.<br><br clear=3D"all">Mar=
tinho </div></div>
</blockquote></blockquote>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_984_23500860.1353430876498--

.


Author: DeadMG <wolfeinstein@gmail.com>
Date: Tue, 20 Nov 2012 09:39:44 -0800 (PST)
Raw View
------=_Part_14_10453442.1353433184387
Content-Type: text/plain; charset=ISO-8859-1

I think that a replacement should focus on just I/O. Let the Unicode
proposal propose text formatting replacements.

--




------=_Part_14_10453442.1353433184387
Content-Type: text/html; charset=ISO-8859-1

I think that a replacement should focus on just I/O. Let the Unicode proposal propose text formatting replacements.

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_14_10453442.1353433184387--

.


Author: magfr@lysator.liu.se
Date: Thu, 22 Nov 2012 23:11:42 -0800 (PST)
Raw View
------=_Part_1931_2854264.1353654702958
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

The performance problem of iostreams is the locale support.
If you remove the locale support then everything can be nicely inlined into=
=20
nothingness and run in circles around printf. Remember that printf do parse=
=20
the format string every time it runs so there is a pretty big wiggle room=
=20
if that is what you wish to beat.

> There=92s one real problem with this logic, and it is exactly why people=
=20
> suggest C-standard file IO. Iostreams violates a fundamental precept of=
=20
> C++: pay *only* for what you use.

> =20
Yes. See above.

> Consider this suite of benchmarks<http://stackoverflow.com/questions/4340=
396/does-the-c-standard-mandate-poor-performance-for-iostreams-or-am-i-just=
-deali>.=20
This code doesn=92t do file IO; it writes=20
> directly to a string. All it=92s doing is measuring the time it takes to=
=20
append=20
> 4-characters to a string. A lot. It uses a `char[]` as a useful control.=
=20
It also=20
> tests the use of `vector<char>` (presumably `basic_string` would have=20
> similar results). Therefore, this is a solid test for the efficiency of=
=20
the=20
> iostreams codebase itself.
>=20
> Obviously there will be some efficiency loss. But consider the numbers in=
=20
> the results.

I did download the tests and ran them using g++ -O2 <filename>.cpp
My g++ is g++-4.7.2 on linux.
All tests run in about the same time save for 'putting binary data into a=
=20
vector<char> using back_inserter' which took about 6x the times of the rest=
=20
and, contradicting your analysis, 'putting binary data directly into=20
stringbuf' which took about half the time of the rest.
If I were to remove the -O2 flag, telling the compiler to not optimize the=
=20
code, then my test results show some similarity to yours (Worst case 15x)=
=20
but who compiles benchmarks without optimization?

/MF

>

--=20




------=_Part_1931_2854264.1353654702958
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

The performance problem of iostreams is the locale support.<br>If you remov=
e the locale support then everything can be nicely inlined into nothingness=
 and run in circles around printf. Remember that printf do parse the format=
 string every time it runs so there is a pretty big wiggle room if that is =
what you wish to beat.<br><br>&gt; There=92s

      one real problem with this logic, and it is exactly why people
      <br>&gt; suggest C-standard file IO. Iostreams violates a fundamental
      precept of <span style=3D"font-size:15px;font-family:Arial;color:#000=
000;background-color:transparent;font-weight:normal;font-style:normal;font-=
variant:normal;text-decoration:none;vertical-align:baseline"><br>&gt; C++: =
pay <i>only</i> for what you </span><span style=3D"font-size:15px;font-fami=
ly:Arial;color:#000000;background-color:transparent;font-weight:normal;font=
-style:italic;font-variant:normal;text-decoration:none;vertical-align:basel=
ine">use</span><span style=3D"font-size:15px;font-family:Arial;color:#00000=
0;background-color:transparent;font-weight:normal;font-style:normal;font-va=
riant:normal;text-decoration:none;vertical-align:baseline">.</span><br><blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;"><div bgcolor=3D"#FFFFFF" text=3D"#=
000000">
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span></div></blockquote><=
div bgcolor=3D"#FFFFFF" text=3D"#000000">&nbsp;<br>Yes. See above.<br><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">&gt; Consider
    </span><a href=3D"http://stackoverflow.com/questions/4340396/does-the-c=
-standard-mandate-poor-performance-for-iostreams-or-am-i-just-deali" target=
=3D"_blank"><span style=3D"font-size:15px;font-family:Arial;color:#1155cc;b=
ackground-color:transparent;font-weight:normal;font-style:normal;font-varia=
nt:normal;text-decoration:underline;vertical-align:baseline">this
        suite of benchmarks</span></a><span style=3D"font-size:15px;font-fa=
mily:Arial;color:#000000;background-color:transparent;font-weight:normal;fo=
nt-style:normal;font-variant:normal;text-decoration:none;vertical-align:bas=
eline">.
      This code doesn=92t do file IO; it writes <br>&gt; directly to a stri=
ng. All
      it=92s doing is measuring the time it takes to append <br>&gt; 4-char=
acters
      to a string. A lot. It uses a `char[]` as a useful control. It
      also <br>&gt; tests the use of `vector&lt;char&gt;` (presumably
      `basic_string` would have <br>&gt; similar results). Therefore, this =
is a
      solid test for the efficiency of the <br>&gt; iostreams codebase itse=
lf.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span>&gt; <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">&gt; Obviously
      there will be some efficiency loss. But consider the numbers in
      <br>&gt; the results.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>I did download t=
he tests and ran them using g++ -O2 &lt;filename&gt;.cpp<br>My g++ is g++-4=
..7.2 on linux.<br>All tests run in about the same time save for 'putting bi=
nary data into a <code>vector&lt;char&gt;</code> using <code>back_inserter<=
/code>' which took about 6x the times of the rest and, contradicting your a=
nalysis, 'putting binary data directly into <code>stringbuf</code>' which t=
ook about half the time of the rest.<br>If I were to remove the -O2 flag, t=
elling the compiler to not optimize the code, then my test results show som=
e similarity to yours (Worst case 15x) but who compiles benchmarks without =
optimization?<br><span style=3D"font-size:15px;font-family:Arial;color:#000=
000;background-color:transparent;font-weight:normal;font-style:normal;font-=
variant:normal;text-decoration:none;vertical-align:baseline"></span><span s=
tyle=3D"font-size:15px;font-family:Arial;color:#000000;background-color:tra=
nsparent;font-weight:normal;font-style:normal;font-variant:normal;text-deco=
ration:none;vertical-align:baseline"></span><br>/MF<br>
  </div><blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8e=
x; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

</blockquote>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_1931_2854264.1353654702958--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 23 Nov 2012 00:47:19 -0800 (PST)
Raw View
------=_Part_84_31377078.1353660439572
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable



On Thursday, November 22, 2012 11:11:43 PM UTC-8, ma...@lysator.liu.se=20
wrote:
>
> The performance problem of iostreams is the locale support.
> If you remove the locale support then everything can be nicely inlined=20
> into nothingness and run in circles around printf.

=20
I'm curious as to how this "inlined into nothingness" thing works when most=
=20
of iostreams' interface, particularly all of the overloads of types, is=20
based on virtual calls. Non-statically-determinable virtual calls.
=20

> Remember that printf do parse the format string every time it runs so=20
> there is a pretty big wiggle room if that is what you wish to beat.
>
> > There=92s one real problem with this logic, and it is exactly why peopl=
e=20
> > suggest C-standard file IO. Iostreams violates a fundamental precept of=
=20
> > C++: pay *only* for what you use.
>
>> =20
> Yes. See above.
>
> > Consider this suite of benchmarks<http://stackoverflow.com/questions/43=
40396/does-the-c-standard-mandate-poor-performance-for-iostreams-or-am-i-ju=
st-deali>.=20
> This code doesn=92t do file IO; it writes=20
> > directly to a string. All it=92s doing is measuring the time it takes t=
o=20
> append=20
> > 4-characters to a string. A lot. It uses a `char[]` as a useful control=
..=20
> It also=20
> > tests the use of `vector<char>` (presumably `basic_string` would have=
=20
> > similar results). Therefore, this is a solid test for the efficiency of=
=20
> the=20
> > iostreams codebase itself.
> >=20
> > Obviously there will be some efficiency loss. But consider the numbers=
=20
> in=20
> > the results.
>
> I did download the tests and ran them using g++ -O2 <filename>.cpp
> My g++ is g++-4.7.2 on linux.
> All tests run in about the same time save for 'putting binary data into a=
=20
> vector<char> using back_inserter' which took about 6x the times of the=20
> rest and, contradicting your analysis, 'putting binary data directly into=
=20
> stringbuf' which took about half the time of the rest.
> If I were to remove the -O2 flag, telling the compiler to not optimize th=
e=20
> code, then my test results show some similarity to yours (Worst case 15x)=
=20
> but who compiles benchmarks without optimization?
>

As stated in the page, the benchmarks were compiled with O3 on g++ 4.3.4.=
=20
Thus, this is more likely due to more aggressive optimizations and/or=20
better standard library implementations. Also, were you compiling as C++11=
=20
or as C++03?
=20

>
> /MF
>
>>

--=20




------=_Part_84_31377078.1353660439572
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

<br><br>On Thursday, November 22, 2012 11:11:43 PM UTC-8, ma...@lysator.liu=
..se wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">The performance prob=
lem of iostreams is the locale support.<br>If you remove the locale support=
 then everything can be nicely inlined into nothingness and run in circles =
around printf.</blockquote><div>&nbsp;</div><div>I'm curious as to how this=
 "inlined into nothingness" thing works when most of iostreams' interface, =
particularly all of the overloads of types, is based on virtual calls. Non-=
statically-determinable virtual calls.<br>&nbsp;</div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;">Remember that printf do parse the format string eve=
ry time it runs so there is a pretty big wiggle room if that is what you wi=
sh to beat.<br><br>&gt; There=92s

      one real problem with this logic, and it is exactly why people
      <br>&gt; suggest C-standard file IO. Iostreams violates a fundamental
      precept of <span style=3D"font-size:15px;font-family:Arial;color:#000=
000;background-color:transparent;font-weight:normal;font-style:normal;font-=
variant:normal;text-decoration:none;vertical-align:baseline"><br>&gt; C++: =
pay <i>only</i> for what you </span><span style=3D"font-size:15px;font-fami=
ly:Arial;color:#000000;background-color:transparent;font-weight:normal;font=
-style:italic;font-variant:normal;text-decoration:none;vertical-align:basel=
ine">use</span><span style=3D"font-size:15px;font-family:Arial;color:#00000=
0;background-color:transparent;font-weight:normal;font-style:normal;font-va=
riant:normal;text-decoration:none;vertical-align:baseline">.</span><br><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div bgcolor=3D"#FFFFFF" text=3D"#00000=
0">
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span></div></blockquote><=
div bgcolor=3D"#FFFFFF" text=3D"#000000">&nbsp;<br>Yes. See above.<br><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">&gt; Consider
    </span><a href=3D"http://stackoverflow.com/questions/4340396/does-the-c=
-standard-mandate-poor-performance-for-iostreams-or-am-i-just-deali" target=
=3D"_blank"><span style=3D"font-size:15px;font-family:Arial;color:#1155cc;b=
ackground-color:transparent;font-weight:normal;font-style:normal;font-varia=
nt:normal;text-decoration:underline;vertical-align:baseline">this
        suite of benchmarks</span></a><span style=3D"font-size:15px;font-fa=
mily:Arial;color:#000000;background-color:transparent;font-weight:normal;fo=
nt-style:normal;font-variant:normal;text-decoration:none;vertical-align:bas=
eline">.
      This code doesn=92t do file IO; it writes <br>&gt; directly to a stri=
ng. All
      it=92s doing is measuring the time it takes to append <br>&gt; 4-char=
acters
      to a string. A lot. It uses a `char[]` as a useful control. It
      also <br>&gt; tests the use of `vector&lt;char&gt;` (presumably
      `basic_string` would have <br>&gt; similar results). Therefore, this =
is a
      solid test for the efficiency of the <br>&gt; iostreams codebase itse=
lf.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span>&gt; <br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">&gt; Obviously
      there will be some efficiency loss. But consider the numbers in
      <br>&gt; the results.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>I did download t=
he tests and ran them using g++ -O2 &lt;filename&gt;.cpp<br>My g++ is g++-4=
..7.2 on linux.<br>All tests run in about the same time save for 'putting bi=
nary data into a <code>vector&lt;char&gt;</code> using <code>back_inserter<=
/code>' which took about 6x the times of the rest and, contradicting your a=
nalysis, 'putting binary data directly into <code>stringbuf</code>' which t=
ook about half the time of the rest.<br>If I were to remove the -O2 flag, t=
elling the compiler to not optimize the code, then my test results show som=
e similarity to yours (Worst case 15x) but who compiles benchmarks without =
optimization?<br></div></blockquote><div><br>As stated in the page, the ben=
chmarks were compiled with O3 on g++ 4.3.4. Thus, this is more likely due t=
o more aggressive optimizations and/or better standard library implementati=
ons. Also, were you compiling as C++11 or as C++03?<br>&nbsp;</div><blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;"><div bgcolor=3D"#FFFFFF" text=3D"#0000=
00"><span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><span style=3D"font-=
size:15px;font-family:Arial;color:#000000;background-color:transparent;font=
-weight:normal;font-style:normal;font-variant:normal;text-decoration:none;v=
ertical-align:baseline"></span><br>/MF<br>
  </div><blockquote class=3D"gmail_quote" style=3D"margin:0pt 0pt 0pt 0.8ex=
;border-left:1px solid rgb(204,204,204);padding-left:1ex">

</blockquote></blockquote>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_84_31377078.1353660439572--

.


Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Fri, 23 Nov 2012 02:16:19 -0800 (PST)
Raw View
------=_Part_1031_26286190.1353665779547
Content-Type: text/plain; charset=ISO-8859-1

Op vrijdag 23 november 2012 08:11:43 UTC+1 schreef ma...@lysator.liu.se het
volgende:

> The performance problem of iostreams is the locale support.
> If you remove the locale support then everything can be nicely inlined
> into nothingness and run in circles around printf. Remember that printf do
> parse the format string every time it runs so there is a pretty big wiggle
> room if that is what you wish to beat.
>

If the format argument is known at compile time, you could parse it at
compile time and gain type safety as a bonus.

Is anyone actually using locales?
When writing to files I don't want the output to be affected by locales.

--




------=_Part_1031_26286190.1353665779547
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Op vrijdag 23 november 2012 08:11:43 UTC+1 schreef ma...@lysator.liu.se het=
 volgende:<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">The performance =
problem of iostreams is the locale support.<br>If you remove the locale sup=
port then everything can be nicely inlined into nothingness and run in circ=
les around printf. Remember that printf do parse the format string every ti=
me it runs so there is a pretty big wiggle room if that is what you wish to=
 beat.<br></blockquote><div><br></div><div>If the format argument is known =
at compile time, you could parse it at compile time and gain type safety as=
 a bonus.</div><div><br></div><div>Is anyone actually using locales?</div><=
div>When writing to files I don't want the output to be affected by locales=
..</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_1031_26286190.1353665779547--

.


Author: Arthur Tchaikovsky <atch.cpp@gmail.com>
Date: Fri, 23 Nov 2012 02:24:53 -0800 (PST)
Raw View
------=_Part_371_2462208.1353666293961
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable


>
> "idiotic" is not an offensive word


Your suggestion that idiotic isn't offensive word is idiotic and ignorant.=
=20
No offense though. I'm not calling you idiotic just your suggestion.=20

On Tuesday, 20 November 2012 17:01:16 UTC, Nicol Bolas wrote:
>
>
>
> On Tuesday, November 20, 2012 2:23:26 AM UTC-8, Arthur Tchaikovsky wrote:
>>
>> Your most recent replies have been getting somewhat inflamatory. I think=
=20
>>> you should take a break.
>>
>>
>> Fair enough, but interestingly, you didn't say anything to the guy who=
=20
>> claimed that my suggestion is idiotic. I believe that either apply rules=
=20
>> (of correct manners etc) to everyone and I am more than happy for it, or=
=20
>> don't apply them at all. Saying just to one guy (me) to ease off and don=
't=20
>> say anything to another guy why I believe presented far worse behavior t=
han=20
>> I (calling someone's suggestion "idiotic") is simply not fair. I would l=
ike=20
>> you to note that I wasn't the first guy who posted "somewhat" inflammato=
ry=20
>> posts. Some people here are passive aggressive and this bad too yet you=
=20
>> don't mind them doing so. And also, please note that I didn't use any=20
>> offensive words, like commenting on someone's suggestion as "idiotic", f=
or=20
>> example.
>>
>
> "idiotic" is not an offensive word. More importantly, he called your *
> suggestion* idiotic, which is very different from calling *you* idiotic.=
=20
> Attacks against your suggestion are going to happen; that's what this=20
> discussion forum is *about*. Attacking you as a person is what we=20
> wouldn't allow; attacking a suggestion is perfectly reasonable.
>
> Plus, the "idiotic" comment came after an extended period of discussion=
=20
> where you continued to use the same reasoning over and over, without=20
> showing the slightest sense that you understood the opposing argument. No=
r=20
> did you display any recognition or understanding of the simple fact that=
=20
> the standard *doesn't cover* what you were talking about. Given the=20
> substance of the discussion, I think it was a perfectly reasonable=20
> assessment of your suggestion.
>
> On Sunday, 18 November 2012 13:42:54 UTC, R. Martinho Fernandes wrote:
>>>
>>> On Sun, Nov 18, 2012 at 2:38 PM, Arthur Tchaikovsky <atch...@gmail.com>=
wrote:
>>>
>>>> It=92s very compact, for one. Once you understand the basic syntax of =
it,=20
>>>>> it=92s very easy to see what=92s going on. Especially for complex for=
matting.=20
>>>>> Just consider the physical size difference between these two:
>>>>>
>>>> snprintf(..., =930x%08x=94, integer);
>>>>>
>>>> stream << "0x" << std::right << std::hex << std::setw(8) << iVal <<=20
>>>>> std::endl;
>>>>>
>>>> It may take a bit longer to become used to the printf version, but thi=
s=20
>>>>> is something you can easily look up in a reference.
>>>>>
>>>>
>>>> Again, logic of a person for whom recursion is as easy to understand=
=20
>>>> and use as iteration.
>>>>
>>>
>>> Your most recent replies have been getting somewhat inflamatory. I thin=
k=20
>>> you should take a break.
>>>
>>> Martinho=20
>>>
>>

--=20




------=_Part_371_2462208.1353666293961
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;">
"idiotic" is not an offensive word</blockquote><div><br></div><div>Your sug=
gestion that idiotic isn't offensive word is idiotic and ignorant. No offen=
se though. I'm not calling you idiotic just your suggestion.&nbsp;</div><br=
>On Tuesday, 20 November 2012 17:01:16 UTC, Nicol Bolas  wrote:<blockquote =
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1p=
x #ccc solid;padding-left: 1ex;"><br><br>On Tuesday, November 20, 2012 2:23=
:26 AM UTC-8, Arthur Tchaikovsky wrote:<blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;b=
order-left:1px #ccc solid;padding-left:1ex">
Your most recent replies have been getting somewhat inflamatory. I think yo=
u should take a break.</blockquote><div><br></div><div>Fair enough, but int=
erestingly, you didn't say anything to the guy who claimed that my suggesti=
on is idiotic. I believe that either apply rules (of correct manners etc) t=
o everyone and I am more than happy for it, or don't apply them at all. Say=
ing just to one guy (me) to ease off and don't say anything to another guy =
why I believe presented far worse behavior than I (calling someone's sugges=
tion "idiotic") is simply not fair. I would like you to note that I wasn't =
the first guy who posted "somewhat" inflammatory posts. Some people here ar=
e passive aggressive and this bad too yet you don't mind them doing so. And=
 also, please note that I didn't use any offensive words, like commenting o=
n someone's suggestion as "idiotic", for example.<br></div></blockquote><di=
v><br>"idiotic" is not an offensive word. More importantly, he called your =
<i>suggestion</i> idiotic, which is very different from calling <i>you</i> =
idiotic. Attacks against your suggestion are going to happen; that's what t=
his discussion forum is <i>about</i>. Attacking you as a person is what we =
wouldn't allow; attacking a suggestion is perfectly reasonable.<br><br>Plus=
, the "idiotic" comment came after an extended period of discussion where y=
ou continued to use the same reasoning over and over, without showing the s=
lightest sense that you understood the opposing argument. Nor did you displ=
ay any recognition or understanding of the simple fact that the standard <i=
>doesn't cover</i> what you were talking about. Given the substance of the =
discussion, I think it was a perfectly reasonable assessment of your sugges=
tion.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">On Sunday, 18 No=
vember 2012 13:42:54 UTC, R. Martinho Fernandes  wrote:<blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex">On Sun, Nov 18, 2012 at 2:38 PM, Arthur Tchaikovsky <sp=
an dir=3D"ltr">&lt;<a>atch...@gmail.com</a>&gt;</span> wrote:<br><div class=
=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex">

<div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;=
border-left:1px #ccc solid;padding-left:1ex">It=92s very compact, for one. =
Once you understand the basic syntax of it, it=92s very easy to see what=92=
s going on. Especially for complex formatting. Just consider the physical s=
ize difference between these two:<br>

</blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex">snprintf(..., =930x%08=
x=94, integer);<br></blockquote><blockquote class=3D"gmail_quote" style=3D"=
margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">

stream &lt;&lt; "0x" &lt;&lt; std::right &lt;&lt; std::hex &lt;&lt; std::se=
tw(8) &lt;&lt; iVal &lt;&lt; std::endl;<br></blockquote><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex">

It may take a bit longer to become used to the printf version, but this is =
something you can easily look up in a reference.<br></blockquote><div><br><=
/div></div><div>Again, logic of a person for whom recursion is as easy to u=
nderstand and use as iteration.<br>

</div></blockquote><div><br>Your most recent replies have been getting some=
what inflamatory. I think you should take a break.<br><br clear=3D"all">Mar=
tinho </div></div>
</blockquote></blockquote></blockquote>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_371_2462208.1353666293961--

.


Author: Arthur Tchaikovsky <atch.cpp@gmail.com>
Date: Fri, 23 Nov 2012 09:33:23 -0800 (PST)
Raw View
------=_Part_134_6226431.1353692003585
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

After all, iteration is more natural to C++ than recursion=20
(Alexandrescu,Modern C++ Design Generic Programming and Design Patterns=20
Applied, chapter 3.5)

One more prove that your logic is flawed (oopss, not flawed, idiotic as you=
=20
don't find this word offending), that you're rude, that you're not=20
interested in listening in others opinions etc. etc.

On Tuesday, 20 November 2012 17:01:16 UTC, Nicol Bolas wrote:
>
>
>
> On Tuesday, November 20, 2012 2:23:26 AM UTC-8, Arthur Tchaikovsky wrote:
>>
>> Your most recent replies have been getting somewhat inflamatory. I think=
=20
>>> you should take a break.
>>
>>
>> Fair enough, but interestingly, you didn't say anything to the guy who=
=20
>> claimed that my suggestion is idiotic. I believe that either apply rules=
=20
>> (of correct manners etc) to everyone and I am more than happy for it, or=
=20
>> don't apply them at all. Saying just to one guy (me) to ease off and don=
't=20
>> say anything to another guy why I believe presented far worse behavior t=
han=20
>> I (calling someone's suggestion "idiotic") is simply not fair. I would l=
ike=20
>> you to note that I wasn't the first guy who posted "somewhat" inflammato=
ry=20
>> posts. Some people here are passive aggressive and this bad too yet you=
=20
>> don't mind them doing so. And also, please note that I didn't use any=20
>> offensive words, like commenting on someone's suggestion as "idiotic", f=
or=20
>> example.
>>
>
> "idiotic" is not an offensive word. More importantly, he called your *
> suggestion* idiotic, which is very different from calling *you* idiotic.=
=20
> Attacks against your suggestion are going to happen; that's what this=20
> discussion forum is *about*. Attacking you as a person is what we=20
> wouldn't allow; attacking a suggestion is perfectly reasonable.
>
> Plus, the "idiotic" comment came after an extended period of discussion=
=20
> where you continued to use the same reasoning over and over, without=20
> showing the slightest sense that you understood the opposing argument. No=
r=20
> did you display any recognition or understanding of the simple fact that=
=20
> the standard *doesn't cover* what you were talking about. Given the=20
> substance of the discussion, I think it was a perfectly reasonable=20
> assessment of your suggestion.
>
> On Sunday, 18 November 2012 13:42:54 UTC, R. Martinho Fernandes wrote:
>>>
>>> On Sun, Nov 18, 2012 at 2:38 PM, Arthur Tchaikovsky <atch...@gmail.com>=
wrote:
>>>
>>>> It=92s very compact, for one. Once you understand the basic syntax of =
it,=20
>>>>> it=92s very easy to see what=92s going on. Especially for complex for=
matting.=20
>>>>> Just consider the physical size difference between these two:
>>>>>
>>>> snprintf(..., =930x%08x=94, integer);
>>>>>
>>>> stream << "0x" << std::right << std::hex << std::setw(8) << iVal <<=20
>>>>> std::endl;
>>>>>
>>>> It may take a bit longer to become used to the printf version, but thi=
s=20
>>>>> is something you can easily look up in a reference.
>>>>>
>>>>
>>>> Again, logic of a person for whom recursion is as easy to understand=
=20
>>>> and use as iteration.
>>>>
>>>
>>> Your most recent replies have been getting somewhat inflamatory. I thin=
k=20
>>> you should take a break.
>>>
>>> Martinho=20
>>>
>>

--=20




------=_Part_134_6226431.1353692003585
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

After all, iteration is more natural to C++ than recursion (Alexandrescu,Mo=
dern C++ Design Generic Programming and Design Patterns Applied, chapter 3.=
5)<div><br></div><div>One more prove that your logic is flawed (oopss, not =
flawed, idiotic as you don't find this word offending), that you're rude, t=
hat you're not interested in listening in others opinions etc. etc.<br><br>=
On Tuesday, 20 November 2012 17:01:16 UTC, Nicol Bolas  wrote:<blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px=
 #ccc solid;padding-left: 1ex;"><br><br>On Tuesday, November 20, 2012 2:23:=
26 AM UTC-8, Arthur Tchaikovsky wrote:<blockquote class=3D"gmail_quote" sty=
le=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1e=
x"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex">
Your most recent replies have been getting somewhat inflamatory. I think yo=
u should take a break.</blockquote><div><br></div><div>Fair enough, but int=
erestingly, you didn't say anything to the guy who claimed that my suggesti=
on is idiotic. I believe that either apply rules (of correct manners etc) t=
o everyone and I am more than happy for it, or don't apply them at all. Say=
ing just to one guy (me) to ease off and don't say anything to another guy =
why I believe presented far worse behavior than I (calling someone's sugges=
tion "idiotic") is simply not fair. I would like you to note that I wasn't =
the first guy who posted "somewhat" inflammatory posts. Some people here ar=
e passive aggressive and this bad too yet you don't mind them doing so. And=
 also, please note that I didn't use any offensive words, like commenting o=
n someone's suggestion as "idiotic", for example.<br></div></blockquote><di=
v><br>"idiotic" is not an offensive word. More importantly, he called your =
<i>suggestion</i> idiotic, which is very different from calling <i>you</i> =
idiotic. Attacks against your suggestion are going to happen; that's what t=
his discussion forum is <i>about</i>. Attacking you as a person is what we =
wouldn't allow; attacking a suggestion is perfectly reasonable.<br><br>Plus=
, the "idiotic" comment came after an extended period of discussion where y=
ou continued to use the same reasoning over and over, without showing the s=
lightest sense that you understood the opposing argument. Nor did you displ=
ay any recognition or understanding of the simple fact that the standard <i=
>doesn't cover</i> what you were talking about. Given the substance of the =
discussion, I think it was a perfectly reasonable assessment of your sugges=
tion.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">On Sunday, 18 No=
vember 2012 13:42:54 UTC, R. Martinho Fernandes  wrote:<blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex">On Sun, Nov 18, 2012 at 2:38 PM, Arthur Tchaikovsky <sp=
an dir=3D"ltr">&lt;<a>atch...@gmail.com</a>&gt;</span> wrote:<br><div class=
=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex">

<div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;=
border-left:1px #ccc solid;padding-left:1ex">It=92s very compact, for one. =
Once you understand the basic syntax of it, it=92s very easy to see what=92=
s going on. Especially for complex formatting. Just consider the physical s=
ize difference between these two:<br>

</blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex">snprintf(..., =930x%08=
x=94, integer);<br></blockquote><blockquote class=3D"gmail_quote" style=3D"=
margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">

stream &lt;&lt; "0x" &lt;&lt; std::right &lt;&lt; std::hex &lt;&lt; std::se=
tw(8) &lt;&lt; iVal &lt;&lt; std::endl;<br></blockquote><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex">

It may take a bit longer to become used to the printf version, but this is =
something you can easily look up in a reference.<br></blockquote><div><br><=
/div></div><div>Again, logic of a person for whom recursion is as easy to u=
nderstand and use as iteration.<br>

</div></blockquote><div><br>Your most recent replies have been getting some=
what inflamatory. I think you should take a break.<br><br clear=3D"all">Mar=
tinho </div></div>
</blockquote></blockquote></blockquote></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_134_6226431.1353692003585--

.


Author: Xeo <hivemaster@hotmail.de>
Date: Fri, 23 Nov 2012 09:37:53 -0800 (PST)
Raw View
------=_Part_141_30312429.1353692273716
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

Please take a leave, cool your head down, and come back when you're ready=
=20
for professional discussions again. You're just sounding childish right=20
now, bringing unrelated topics into the discussion.

On Friday, November 23, 2012 6:33:23 PM UTC+1, Arthur Tchaikovsky wrote:
>
> After all, iteration is more natural to C++ than recursion=20
> (Alexandrescu,Modern C++ Design Generic Programming and Design Patterns=
=20
> Applied, chapter 3.5)
>
> One more prove that your logic is flawed (oopss, not flawed, idiotic as=
=20
> you don't find this word offending), that you're rude, that you're not=20
> interested in listening in others opinions etc. etc.
>
> On Tuesday, 20 November 2012 17:01:16 UTC, Nicol Bolas wrote:
>>
>>
>>
>> On Tuesday, November 20, 2012 2:23:26 AM UTC-8, Arthur Tchaikovsky wrote=
:
>>>
>>> Your most recent replies have been getting somewhat inflamatory. I thin=
k=20
>>>> you should take a break.
>>>
>>>
>>> Fair enough, but interestingly, you didn't say anything to the guy who=
=20
>>> claimed that my suggestion is idiotic. I believe that either apply rule=
s=20
>>> (of correct manners etc) to everyone and I am more than happy for it, o=
r=20
>>> don't apply them at all. Saying just to one guy (me) to ease off and do=
n't=20
>>> say anything to another guy why I believe presented far worse behavior =
than=20
>>> I (calling someone's suggestion "idiotic") is simply not fair. I would =
like=20
>>> you to note that I wasn't the first guy who posted "somewhat" inflammat=
ory=20
>>> posts. Some people here are passive aggressive and this bad too yet you=
=20
>>> don't mind them doing so. And also, please note that I didn't use any=
=20
>>> offensive words, like commenting on someone's suggestion as "idiotic", =
for=20
>>> example.
>>>
>>
>> "idiotic" is not an offensive word. More importantly, he called your *
>> suggestion* idiotic, which is very different from calling *you* idiotic.=
=20
>> Attacks against your suggestion are going to happen; that's what this=20
>> discussion forum is *about*. Attacking you as a person is what we=20
>> wouldn't allow; attacking a suggestion is perfectly reasonable.
>>
>> Plus, the "idiotic" comment came after an extended period of discussion=
=20
>> where you continued to use the same reasoning over and over, without=20
>> showing the slightest sense that you understood the opposing argument. N=
or=20
>> did you display any recognition or understanding of the simple fact that=
=20
>> the standard *doesn't cover* what you were talking about. Given the=20
>> substance of the discussion, I think it was a perfectly reasonable=20
>> assessment of your suggestion.
>>
>> On Sunday, 18 November 2012 13:42:54 UTC, R. Martinho Fernandes wrote:
>>>>
>>>> On Sun, Nov 18, 2012 at 2:38 PM, Arthur Tchaikovsky <atch...@gmail.com=
>wrote:
>>>>
>>>>> It=92s very compact, for one. Once you understand the basic syntax of=
=20
>>>>>> it, it=92s very easy to see what=92s going on. Especially for comple=
x=20
>>>>>> formatting. Just consider the physical size difference between these=
 two:
>>>>>>
>>>>> snprintf(..., =930x%08x=94, integer);
>>>>>>
>>>>> stream << "0x" << std::right << std::hex << std::setw(8) << iVal <<=
=20
>>>>>> std::endl;
>>>>>>
>>>>> It may take a bit longer to become used to the printf version, but=20
>>>>>> this is something you can easily look up in a reference.
>>>>>>
>>>>>
>>>>> Again, logic of a person for whom recursion is as easy to understand=
=20
>>>>> and use as iteration.
>>>>>
>>>>
>>>> Your most recent replies have been getting somewhat inflamatory. I=20
>>>> think you should take a break.
>>>>
>>>> Martinho=20
>>>>
>>>

--=20




------=_Part_141_30312429.1353692273716
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

Please take a leave, cool your head down, and come back when you're ready f=
or professional discussions again. You're just sounding childish right now,=
 bringing unrelated topics into the discussion.<br><br>On Friday, November =
23, 2012 6:33:23 PM UTC+1, Arthur Tchaikovsky wrote:<blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;">After all, iteration is more natural to C++ than recu=
rsion (Alexandrescu,Modern C++ Design Generic Programming and Design Patter=
ns Applied, chapter 3.5)<div><br></div><div>One more prove that your logic =
is flawed (oopss, not flawed, idiotic as you don't find this word offending=
), that you're rude, that you're not interested in listening in others opin=
ions etc. etc.<br><br>On Tuesday, 20 November 2012 17:01:16 UTC, Nicol Bola=
s  wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.=
8ex;border-left:1px #ccc solid;padding-left:1ex"><br><br>On Tuesday, Novemb=
er 20, 2012 2:23:26 AM UTC-8, Arthur Tchaikovsky wrote:<blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><blockquote class=3D"gmail_quote" style=3D"margin:0;mar=
gin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
Your most recent replies have been getting somewhat inflamatory. I think yo=
u should take a break.</blockquote><div><br></div><div>Fair enough, but int=
erestingly, you didn't say anything to the guy who claimed that my suggesti=
on is idiotic. I believe that either apply rules (of correct manners etc) t=
o everyone and I am more than happy for it, or don't apply them at all. Say=
ing just to one guy (me) to ease off and don't say anything to another guy =
why I believe presented far worse behavior than I (calling someone's sugges=
tion "idiotic") is simply not fair. I would like you to note that I wasn't =
the first guy who posted "somewhat" inflammatory posts. Some people here ar=
e passive aggressive and this bad too yet you don't mind them doing so. And=
 also, please note that I didn't use any offensive words, like commenting o=
n someone's suggestion as "idiotic", for example.<br></div></blockquote><di=
v><br>"idiotic" is not an offensive word. More importantly, he called your =
<i>suggestion</i> idiotic, which is very different from calling <i>you</i> =
idiotic. Attacks against your suggestion are going to happen; that's what t=
his discussion forum is <i>about</i>. Attacking you as a person is what we =
wouldn't allow; attacking a suggestion is perfectly reasonable.<br><br>Plus=
, the "idiotic" comment came after an extended period of discussion where y=
ou continued to use the same reasoning over and over, without showing the s=
lightest sense that you understood the opposing argument. Nor did you displ=
ay any recognition or understanding of the simple fact that the standard <i=
>doesn't cover</i> what you were talking about. Given the substance of the =
discussion, I think it was a perfectly reasonable assessment of your sugges=
tion.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">On Sunday, 18 No=
vember 2012 13:42:54 UTC, R. Martinho Fernandes  wrote:<blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex">On Sun, Nov 18, 2012 at 2:38 PM, Arthur Tchaikovsky <sp=
an dir=3D"ltr">&lt;<a>atch...@gmail.com</a>&gt;</span> wrote:<br><div class=
=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex">

<div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;=
border-left:1px #ccc solid;padding-left:1ex">It=92s very compact, for one. =
Once you understand the basic syntax of it, it=92s very easy to see what=92=
s going on. Especially for complex formatting. Just consider the physical s=
ize difference between these two:<br>

</blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex">snprintf(..., =930x%08=
x=94, integer);<br></blockquote><blockquote class=3D"gmail_quote" style=3D"=
margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">

stream &lt;&lt; "0x" &lt;&lt; std::right &lt;&lt; std::hex &lt;&lt; std::se=
tw(8) &lt;&lt; iVal &lt;&lt; std::endl;<br></blockquote><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex">

It may take a bit longer to become used to the printf version, but this is =
something you can easily look up in a reference.<br></blockquote><div><br><=
/div></div><div>Again, logic of a person for whom recursion is as easy to u=
nderstand and use as iteration.<br>

</div></blockquote><div><br>Your most recent replies have been getting some=
what inflamatory. I think you should take a break.<br><br clear=3D"all">Mar=
tinho </div></div>
</blockquote></blockquote></blockquote></div></blockquote>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_141_30312429.1353692273716--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 23 Nov 2012 19:37:58 +0200
Raw View
On 23 November 2012 19:33, Arthur Tchaikovsky <atch.cpp@gmail.com> wrote:
> After all, iteration is more natural to C++ than recursion
> (Alexandrescu,Modern C++ Design Generic Programming and Design Patterns
> Applied, chapter 3.5)
> One more prove that your logic is flawed (oopss, not flawed, idiotic as you
> don't find this word offending), that you're rude, that you're not
> interested in listening in others opinions etc. etc.

Please do explain what this response has to do with "the failures of iostreams"?
Or with std-proposals? Well, actually, please *don't* explain that, I
don't think
we want to hear.

--




.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 23 Nov 2012 09:49:37 -0800 (PST)
Raw View
------=_Part_470_13047278.1353692977938
Content-Type: text/plain; charset=ISO-8859-1



On Friday, November 23, 2012 2:16:19 AM UTC-8, Olaf van der Spek wrote:
>
> Op vrijdag 23 november 2012 08:11:43 UTC+1 schreef ma...@lysator.liu.sehet volgende:
>
>> The performance problem of iostreams is the locale support.
>> If you remove the locale support then everything can be nicely inlined
>> into nothingness and run in circles around printf. Remember that printf do
>> parse the format string every time it runs so there is a pretty big wiggle
>> room if that is what you wish to beat.
>>
>
> If the format argument is known at compile time, you could parse it at
> compile time and gain type safety as a bonus.
>
> Is anyone actually using locales?
> When writing to files I don't want the output to be affected by locales.
>

I think locales would be important for things like formatting currency,
dates, times, etc. It could have its place in the formatting part of the
API. The reason locales aren't often used is because... they're terrible.
And unreliable. If we had Boost.Locale-style locales, then there'd be a
better chance of them seeing use.

The problem with iostreams is that locales are part of the *streambuf*, not
merely the formatting stream. The streambuf should be about basic "byte"
input/output to/from a stream, not locale-specific constructs.

--




------=_Part_470_13047278.1353692977938
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br>On Friday, November 23, 2012 2:16:19 AM UTC-8, Olaf van der Spek wr=
ote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;">Op vrijdag 23 november 201=
2 08:11:43 UTC+1 schreef <a>ma...@lysator.liu.se</a> het volgende:<br><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-lef=
t:1px #ccc solid;padding-left:1ex">The performance problem of iostreams is =
the locale support.<br>If you remove the locale support then everything can=
 be nicely inlined into nothingness and run in circles around printf. Remem=
ber that printf do parse the format string every time it runs so there is a=
 pretty big wiggle room if that is what you wish to beat.<br></blockquote><=
div><br></div><div>If the format argument is known at compile time, you cou=
ld parse it at compile time and gain type safety as a bonus.</div><div><br>=
</div><div>Is anyone actually using locales?</div><div>When writing to file=
s I don't want the output to be affected by locales.</div></blockquote><div=
><br>I think locales would be important for things like formatting currency=
, dates, times, etc. It could have its place in the formatting part of the =
API. The reason locales aren't often used is because... they're terrible. A=
nd unreliable. If we had Boost.Locale-style locales, then there'd be a bett=
er chance of them seeing use.<br><br>The problem with iostreams is that loc=
ales are part of the <i>streambuf</i>, not merely the formatting stream. Th=
e streambuf should be about basic "byte" input/output to/from a stream, not=
 locale-specific constructs.<br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_470_13047278.1353692977938--

.


Author: Arthur Tchaikovsky <atch.cpp@gmail.com>
Date: Sat, 24 Nov 2012 00:51:12 -0800 (PST)
Raw View
------=_Part_78_2422658.1353747072507
Content-Type: text/plain; charset=ISO-8859-1


>
> "idiotic" is not an offensive word. More importantly, he called your
> suggestion idiotic, which is very different from calling you idiotic.
> Attacks against your suggestion are going to happen; that's what this
> discussion forum is about. Attacking you as a person is what we wouldn't
> allow; attacking a suggestion is perfectly reasonable.
>

> Plus, the "idiotic" comment came after an extended period of discussion
> where you continued to use the same reasoning over and over, without
> showing the slightest sense that you understood the opposing argument. Nor
> did you display any recognition or understanding of the simple fact that
> the standard doesn't cover what you were talking about. Given the substance
> of the discussion, I think it was a perfectly reasonable assessment of your
> suggestion.
>

Please do explain what this response has to do with "the failures of
> iostreams"?


My response has as much to do with failures of iostreams as his reply to
me, which I've cited above. If they are rules, the rules should be obeyed
by everyone, and applied to everyone. Ville, why didn't you ask Nicol the
same question you've asked me? Why is it OK for him to behave like smart
as* and when I'm replying to his post and explain how idiotic his
suggestion is, it is me who is the bad guy? If you could note, it is not me
who starts being offensive - be it passive or active. You for example, with
your icecream are the best example of passive rudeness and lack of basic
manners. If someone tells you something, no matter how wrong he is, if you
have basic manners you don't tell him that you rather go and get some
icecream instead of listen to him. Yet you said exactly this. And yet, when
someone calls my suggestion idiotic you nor anyone reacts? You didn't say
to Nicol for example that he shouldn't post such idiotic reply (the one
cited above) - it was OK with you. Why? I'm not an aggressive person nor
person who is looking for any kind of trouble, but when I come across of
boorish behavior (you, Nicol, and the "idiotic" guy) I feel that I have to
defend myself. That's all.

On Friday, 23 November 2012 17:37:59 UTC, Ville Voutilainen wrote:
>
> On 23 November 2012 19:33, Arthur Tchaikovsky <atch...@gmail.com<javascript:>>
> wrote:
> > After all, iteration is more natural to C++ than recursion
> > (Alexandrescu,Modern C++ Design Generic Programming and Design Patterns
> > Applied, chapter 3.5)
> > One more prove that your logic is flawed (oopss, not flawed, idiotic as
> you
> > don't find this word offending), that you're rude, that you're not
> > interested in listening in others opinions etc. etc.
>
> Please do explain what this response has to do with "the failures of
> iostreams"?
> Or with std-proposals? Well, actually, please *don't* explain that, I
> don't think
> we want to hear.
>

--




------=_Part_78_2422658.1353747072507
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;">"idiotic" is not an offensive =
word. More importantly, he called your suggestion idiotic, which is very di=
fferent from calling you idiotic. Attacks against your suggestion are going=
 to happen; that's what this discussion forum is about. Attacking you as a =
person is what we wouldn't allow; attacking a suggestion is perfectly reaso=
nable.<br></blockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br></b=
lockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Plus, the "idiotic" =
comment came after an extended period of discussion where you continued to =
use the same reasoning over and over, without showing the slightest sense t=
hat you understood the opposing argument. Nor did you display any recogniti=
on or understanding of the simple fact that the standard doesn't cover what=
 you were talking about. Given the substance of the discussion, I think it =
was a perfectly reasonable assessment of your suggestion.<br></blockquote><=
div><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
Please do explain what this response has to do with "the failures of iostre=
ams"?</blockquote><div><br></div><div>My response has as much to do with fa=
ilures of iostreams as his reply to me, which I've cited above. If they are=
 rules, the rules should be obeyed by everyone, and applied to everyone. Vi=
lle, why didn't you ask Nicol the same question you've asked me? Why is it =
OK for him to behave like smart as* and when I'm replying to his post and e=
xplain how idiotic his suggestion is, it is me who is the bad guy? If you c=
ould note, it is not me who starts being offensive - be it passive or activ=
e. You for example, with your icecream are the best example of passive rude=
ness and lack of basic manners. If someone tells you something, no matter h=
ow wrong he is, if you have basic manners you don't tell him that you rathe=
r go and get some icecream instead of listen to him. Yet you said exactly t=
his. And yet, when someone calls my suggestion idiotic you nor anyone react=
s? You didn't say to Nicol for example that he shouldn't post such idiotic =
reply (the one cited above) - it was OK with you. Why? I'm not an aggressiv=
e person nor person who is looking for any kind of trouble, but when I come=
 across of boorish behavior (you, Nicol, and the "idiotic" guy) I feel that=
 I have to defend myself. That's all.</div><div><br></div>On Friday, 23 Nov=
ember 2012 17:37:59 UTC, Ville Voutilainen  wrote:<blockquote class=3D"gmai=
l_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;=
padding-left: 1ex;">On 23 November 2012 19:33, Arthur Tchaikovsky &lt;<a hr=
ef=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"rh3Mf7tyABwJ"=
>atch...@gmail.com</a>&gt; wrote:
<br>&gt; After all, iteration is more natural to C++ than recursion
<br>&gt; (Alexandrescu,Modern C++ Design Generic Programming and Design Pat=
terns
<br>&gt; Applied, chapter 3.5)
<br>&gt; One more prove that your logic is flawed (oopss, not flawed, idiot=
ic as you
<br>&gt; don't find this word offending), that you're rude, that you're not
<br>&gt; interested in listening in others opinions etc. etc.
<br>
<br>Please do explain what this response has to do with "the failures of io=
streams"?
<br>Or with std-proposals? Well, actually, please *don't* explain that, I
<br>don't think
<br>we want to hear.
<br></blockquote>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_78_2422658.1353747072507--

.


Author: rick@longbowgames.com
Date: Sat, 24 Nov 2012 04:51:16 -0800 (PST)
Raw View
------=_Part_44_31700556.1353761476253
Content-Type: text/plain; charset=ISO-8859-1

I'm just going to ignore the posts which are... let's call them 'off-topic'.

On Friday, November 23, 2012 12:49:38 PM UTC-5, Nicol Bolas wrote:

> The problem with iostreams is that locales are part of the *streambuf*,
> not merely the formatting stream. The streambuf should be about basic
> "byte" input/output to/from a stream, not locale-specific constructs.
>

There's an argument to be made that locale formatting shouldn't be done in
a stream at all, but rather be a collection of string operations.

--




------=_Part_44_31700556.1353761476253
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

I'm just going to ignore the posts which are... let's call them 'off-topic'=
..<br><br>On Friday, November 23, 2012 12:49:38 PM UTC-5, Nicol Bolas wrote:=
<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;"><div>The problem with iost=
reams is that locales are part of the <i>streambuf</i>, not merely the form=
atting stream. The streambuf should be about basic "byte" input/output to/f=
rom a stream, not locale-specific constructs.<br></div></blockquote><div><b=
r>There's an argument to be made that locale formatting shouldn't be done i=
n a stream at all, but rather be a collection of string operations.<br></di=
v>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_44_31700556.1353761476253--

.


Author: DeadMG <wolfeinstein@gmail.com>
Date: Sat, 24 Nov 2012 04:55:14 -0800 (PST)
Raw View
------=_Part_261_8074032.1353761714617
Content-Type: text/plain; charset=ISO-8859-1

A very important argument, IYAM. There's no reason to couple I/O and string
formatting. I/O should serve the purpose of "Writing bytes to an external
source", and that's all.

--




------=_Part_261_8074032.1353761714617
Content-Type: text/html; charset=ISO-8859-1

A very important argument, IYAM. There's no reason to couple I/O and string formatting. I/O should serve the purpose of "Writing bytes to an external source", and that's all.

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_261_8074032.1353761714617--

.


Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Sat, 24 Nov 2012 14:03:46 +0100
Raw View
On Sat, Nov 24, 2012 at 1:55 PM, DeadMG <wolfeinstein@gmail.com> wrote:
> A very important argument, IYAM. There's no reason to couple I/O and string
> formatting. I/O should serve the purpose of "Writing bytes to an external
> source", and that's all.

Where should newline translation be done?


--
Olaf

--




.


Author: rick@longbowgames.com
Date: Sat, 24 Nov 2012 05:16:48 -0800 (PST)
Raw View
------=_Part_368_29625408.1353763008885
Content-Type: text/plain; charset=ISO-8859-1

On Saturday, November 24, 2012 8:03:48 AM UTC-5, Olaf van der Spek wrote:

> Where should newline translation be done?
>

I would argue that newline translation is a serialization issue, not a
localization issue, and so is within the realm of I/O.  Same goes with BOMs
and byte order if we're dealing with Unicode streams. Number formats and
padding, on the other hand, are harder to justify.

--




------=_Part_368_29625408.1353763008885
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On Saturday, November 24, 2012 8:03:48 AM UTC-5, Olaf van der Spek wrote:<b=
r><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;">Where should newline transla=
tion be done?
<br></blockquote><div><br>I would argue that newline translation is a seria=
lization issue, not a localization issue, and so is within the realm of I/O=
..&nbsp; Same goes with BOMs and byte order if we're dealing with Unicode st=
reams. Number formats and padding, on the other hand, are harder to justify=
..<br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_368_29625408.1353763008885--

.


Author: DeadMG <wolfeinstein@gmail.com>
Date: Sat, 24 Nov 2012 05:16:55 -0800 (PST)
Raw View
------=_Part_486_8260784.1353763015797
Content-Type: text/plain; charset=ISO-8859-1

Nowhere- or at least, if the user wants to do it, he should do it himself.
I can see a potential argument for having a newline constant for different
plats but when dealing with input, the various kinds of newline are really
the user's problem. It's not like "Ignore \r and use \n" is a complex thing
to do.

The I/O library reads the bytes. If you want to change them or whatever,
that's your problem.

--




------=_Part_486_8260784.1353763015797
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Nowhere- or at least, if the user wants to do it, he should do it himself. =
I can see a potential argument for having a newline constant for different =
plats but when dealing with input, the various kinds of newline are really =
the user's problem. It's not like "Ignore \r and use \n" is a complex thing=
 to do.<div><br></div><div>The I/O library reads the bytes. If you want to =
change them or whatever, that's your problem.</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_486_8260784.1353763015797--

.


Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Sat, 24 Nov 2012 14:19:40 +0100
Raw View
On Sat, Nov 24, 2012 at 2:16 PM, DeadMG <wolfeinstein@gmail.com> wrote:
> Nowhere- or at least, if the user wants to do it, he should do it himself. I
> can see a potential argument for having a newline constant for different
> plats but when dealing with input, the various kinds of newline are really
> the user's problem. It's not like "Ignore \r and use \n" is a complex thing
> to do.

Are newlines guaranteed to be \r and \n?

--
Olaf

--




.


Author: DeadMG <wolfeinstein@gmail.com>
Date: Sat, 24 Nov 2012 05:38:43 -0800 (PST)
Raw View
------=_Part_255_2658449.1353764323378
Content-Type: text/plain; charset=ISO-8859-1

No, but they are the only conventions of note. In any case, it's still
outside the remit of IO. It serves the data- how you interpret it is your
problem.

--




------=_Part_255_2658449.1353764323378
Content-Type: text/html; charset=ISO-8859-1

No, but they are the only conventions of note. In any case, it's still outside the remit of IO. It serves the data- how you interpret it is your problem.

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_255_2658449.1353764323378--

.


Author: rick@longbowgames.com
Date: Sat, 24 Nov 2012 06:17:06 -0800 (PST)
Raw View
------=_Part_1422_1486576.1353766626759
Content-Type: text/plain; charset=ISO-8859-1

Whether it's in the 'basic' iostream or layered somewhere on top, surely
the standard library should support reading and writing .txt files.

However, even before Unicode, back when the only thing you had to worry
about when reading/writing text files was how newlines were encoded, the
standard library was already doing a pretty bad job, since it's fairly
difficult to choose exactly which kind of newline you want to output.

It appears to me that there's three things we're dealing with here: raw
I/O, I/O file format, and natural language localization. Locales currently
couple the last two, and IOStreams currently couple all three.

My personal feeling is that we should have classes for reading/writing raw
I/O, classes built on top of that for reading/writing text files (rather
than the existing ios_base::bin solution), and the natural language
localization should be string operations rather than I/O operations.

--




------=_Part_1422_1486576.1353766626759
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Whether it's in the 'basic' iostream or layered somewhere on top, surely
 the standard library should support reading and writing .txt files.<br><br=
>However,
 even before Unicode, back when the only thing you had to worry about when=
=20
reading/writing text files was how newlines were encoded, the standard=20
library was already doing a pretty bad job, since it's fairly difficult=20
to choose exactly which kind of newline you want to output.<br><br>It=20
appears to me that there's three things we're dealing with here: raw=20
I/O, I/O file format, and natural language localization. Locales currently=
=20
couple the last two, and IOStreams currently couple all three.<br><br>My pe=
rsonal feeling is that we should have classes for reading/writing raw I/O, =
classes built on top of that for reading/writing text files (rather than th=
e existing ios_base::bin solution), and the natural language localization s=
hould be string operations rather than I/O operations.<br>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_1422_1486576.1353766626759--

.


Author: DeadMG <wolfeinstein@gmail.com>
Date: Sat, 24 Nov 2012 07:13:59 -0800 (PST)
Raw View
------=_Part_186_463215.1353770039254
Content-Type: text/plain; charset=ISO-8859-1

The primary problem with that is that "Text file" isn't actually a
well-defined platform-independent concept because of the newlines.

I don't have a problem with the idea of a text stream or something for
simple uses, but it's not a part of the core- it's a wrapper on a stream of
bytes. As for localization, that's definitely a billion miles outside the
remit of IO.

--




------=_Part_186_463215.1353770039254
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

The primary problem with that is that "Text file" isn't actually a well-def=
ined platform-independent concept because of the newlines.<div><br></div><d=
iv>I don't have a problem with the idea of a text stream or something for s=
imple uses, but it's not a part of the core- it's a wrapper on a stream of =
bytes. As for localization, that's definitely a billion miles outside the r=
emit of IO.</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_186_463215.1353770039254--

.


Author: rick@longbowgames.com
Date: Sat, 24 Nov 2012 09:38:22 -0800 (PST)
Raw View
------=_Part_323_24651968.1353778702472
Content-Type: text/plain; charset=ISO-8859-1

On Saturday, November 24, 2012 10:13:59 AM UTC-5, DeadMG wrote:
>
> The primary problem with that is that "Text file" isn't actually a
> well-defined platform-independent concept because of the newlines.


Let's make it well defined :)

Ideally, an "oTextStream" would let you set the newline sequence, which
encoding to use (minimally UTF-8, UTF-16LE, UTF-16BE, UTF32-LE, or
UTF32BE), and whether or not to include a BOM.  The newline sequence should
*not* be decided by the platform, since it's not uncommon to want to write
Unix-style text files in a Windows app, for instance.

An "iTextStream" should attempt to determine the encoding based on the BOM,
or default to UTF-8 if no BOM is present. The user should also be able to
explicitly say which encoding to use and whether or not to parse BOMs.

Lets talk more about the IOStream library as a whole. It would be really
nice if it chained, like Boost.Iostreams. This would make the library
flexible enough to support things like sockets, compression, and encryption.

I would be tempted to stay with an inheritance design so that to chain all
you need to do is inherit from an iStream or oStream and hold a unique_ptr
to the next iStream or oStream. In the case of something like iTextStream,
this would give you enough flexibility to be constructed from a unique_ptr
or just a filename. The filename version would really just be for
convenience, but it would make it easier to teach new users how to read
text files.

Some people in this thread are worried about the cost of virtual calls, so
another option is to base the chaining on templates instead of inheritance.
That would complicate the interface, and it would require that you either
template-ize anything that deals with streams or to wrap your streams in
some sort of stream_ref class, but it would probably be faster and more
flexible.

The third option is to do it just like Boost.Iostreams, where you use
inheritance but you only store a reference to your chained streams instead
of taking ownership of them. This has the advantage of making it easier to
adjust a filter after it's bound, but it means the user is responsible for
the lifetime of each stream in the chain, which gets really annoying when
you want to give a stream to an object, since it means you have to manually
make sure the streams don't die before the object that's using them does.
It would also preclude things like a text stream accepting a file path,
since that would require the text stream to be able to optionally create
its own source/sink.

--




------=_Part_323_24651968.1353778702472
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On Saturday, November 24, 2012 10:13:59 AM UTC-5, DeadMG wrote:<blockquote =
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1p=
x #ccc solid;padding-left: 1ex;">The primary problem with that is that "Tex=
t file" isn't actually a well-defined platform-independent concept because =
of the newlines.</blockquote><div><br>Let's make it well defined :)<br><br>=
Ideally, an "oTextStream" would let you set the newline sequence, which enc=
oding to use (minimally UTF-8, UTF-16LE, UTF-16BE, UTF32-LE, or UTF32BE), a=
nd whether or not to include a BOM.&nbsp; The newline sequence should *not*=
 be decided by the platform, since it's not uncommon to want to write Unix-=
style text files in a Windows app, for instance.<br><br>An&nbsp;"iTextStrea=
m" should attempt to determine the encoding based on the BOM, or default to=
 UTF-8 if no BOM is present. The user should also be able to explicitly say=
 which encoding to use and whether or not to parse BOMs.<br><br>Lets talk m=
ore about the IOStream library as a whole. It would be really nice if it ch=
ained, like Boost.Iostreams. This would make the library flexible enough to=
 support things like sockets, compression, and encryption.<br><br>I would b=
e tempted to stay with an inheritance design so that to chain all you need =
to do is inherit from an iStream or oStream and hold a unique_ptr to the ne=
xt iStream or oStream. In the case of something like iTextStream, this woul=
d give you enough flexibility to be constructed from a unique_ptr or just a=
 filename. The filename version would really just be for convenience, but i=
t would make it easier to teach new users how to read text files.<br><br>So=
me people in this thread are worried about the cost of virtual calls, so an=
other option is to base the chaining on templates instead of inheritance. T=
hat would complicate the interface, and it would require that you either te=
mplate-ize anything that deals with streams or to wrap your streams in some=
 sort of stream_ref class, but it would probably be faster and more flexibl=
e.<br><br>The third option is to do it just like Boost.Iostreams, where you=
 use inheritance but you only store a reference to your chained streams ins=
tead of taking ownership of them. This has the advantage of making it easie=
r to adjust a filter after it's bound, but it means the user is responsible=
 for the lifetime of each stream in the chain, which gets really annoying w=
hen you want to give a stream to an object, since it means you have to manu=
ally make sure the streams don't die before the object that's using them do=
es. It would also preclude things like a text stream accepting a file path,=
 since that would require the text stream to be able to optionally create i=
ts own source/sink.<br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_323_24651968.1353778702472--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 24 Nov 2012 09:51:26 -0800 (PST)
Raw View
------=_Part_565_22018983.1353779486633
Content-Type: text/plain; charset=ISO-8859-1



On Saturday, November 24, 2012 9:38:22 AM UTC-8, ri...@longbowgames.com
wrote:
>
> On Saturday, November 24, 2012 10:13:59 AM UTC-5, DeadMG wrote:
>>
>> The primary problem with that is that "Text file" isn't actually a
>> well-defined platform-independent concept because of the newlines.
>
>
> Let's make it well defined :)
>
> Ideally, an "oTextStream" would let you set the newline sequence, which
> encoding to use (minimally UTF-8, UTF-16LE, UTF-16BE, UTF32-LE, or
> UTF32BE), and whether or not to include a BOM.  The newline sequence should
> *not* be decided by the platform, since it's not uncommon to want to write
> Unix-style text files in a Windows app, for instance.
>
> An "iTextStream" should attempt to determine the encoding based on the
> BOM, or default to UTF-8 if no BOM is present. The user should also be able
> to explicitly say which encoding to use and whether or not to parse BOMs.
>
> Lets talk more about the IOStream library as a whole. It would be really
> nice if it chained, like Boost.Iostreams. This would make the library
> flexible enough to support things like sockets, compression, and encryption.
>
> I would be tempted to stay with an inheritance design so that to chain all
> you need to do is inherit from an iStream or oStream and hold a unique_ptr
> to the next iStream or oStream. In the case of something like iTextStream,
> this would give you enough flexibility to be constructed from a unique_ptr
> or just a filename. The filename version would really just be for
> convenience, but it would make it easier to teach new users how to read
> text files.
>
> Some people in this thread are worried about the cost of virtual calls, so
> another option is to base the chaining on templates instead of inheritance.
> That would complicate the interface, and it would require that you either
> template-ize anything that deals with streams or to wrap your streams in
> some sort of stream_ref class, but it would probably be faster and more
> flexible.
>
> The third option is to do it just like Boost.Iostreams, where you use
> inheritance but you only store a reference to your chained streams instead
> of taking ownership of them. This has the advantage of making it easier to
> adjust a filter after it's bound, but it means the user is responsible for
> the lifetime of each stream in the chain, which gets really annoying when
> you want to give a stream to an object, since it means you have to manually
> make sure the streams don't die before the object that's using them does.
> It would also preclude things like a text stream accepting a file path,
> since that would require the text stream to be able to optionally create
> its own source/sink.
>

This is getting kind of off-topic (this is about finding out where
iostreams went wrong, not how to fix it), but the way I invisioned text
files was that they *were* *filters* that would be used on top of binary
files as sources/sinks. You wouldn't need a separate sink for them. They
scan text for a character; if they find '\n', they convert it into the
platform-specific equivalent. BOMs would work more or less the same way,
except that they only do the insertion once: the first time someone tries
to write something. After that, they're inert.

--




------=_Part_565_22018983.1353779486633
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br>On Saturday, November 24, 2012 9:38:22 AM UTC-8, ri...@longbowgames=
..com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Saturday, Novemb=
er 24, 2012 10:13:59 AM UTC-5, DeadMG wrote:<blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex">The primary problem with that is that "Text file" isn't actually a=
 well-defined platform-independent concept because of the newlines.</blockq=
uote><div><br>Let's make it well defined :)<br><br>Ideally, an "oTextStream=
" would let you set the newline sequence, which encoding to use (minimally =
UTF-8, UTF-16LE, UTF-16BE, UTF32-LE, or UTF32BE), and whether or not to inc=
lude a BOM.&nbsp; The newline sequence should *not* be decided by the platf=
orm, since it's not uncommon to want to write Unix-style text files in a Wi=
ndows app, for instance.<br><br>An&nbsp;"iTextStream" should attempt to det=
ermine the encoding based on the BOM, or default to UTF-8 if no BOM is pres=
ent. The user should also be able to explicitly say which encoding to use a=
nd whether or not to parse BOMs.<br><br>Lets talk more about the IOStream l=
ibrary as a whole. It would be really nice if it chained, like Boost.Iostre=
ams. This would make the library flexible enough to support things like soc=
kets, compression, and encryption.<br><br>I would be tempted to stay with a=
n inheritance design so that to chain all you need to do is inherit from an=
 iStream or oStream and hold a unique_ptr to the next iStream or oStream. I=
n the case of something like iTextStream, this would give you enough flexib=
ility to be constructed from a unique_ptr or just a filename. The filename =
version would really just be for convenience, but it would make it easier t=
o teach new users how to read text files.<br><br>Some people in this thread=
 are worried about the cost of virtual calls, so another option is to base =
the chaining on templates instead of inheritance. That would complicate the=
 interface, and it would require that you either template-ize anything that=
 deals with streams or to wrap your streams in some sort of stream_ref clas=
s, but it would probably be faster and more flexible.<br><br>The third opti=
on is to do it just like Boost.Iostreams, where you use inheritance but you=
 only store a reference to your chained streams instead of taking ownership=
 of them. This has the advantage of making it easier to adjust a filter aft=
er it's bound, but it means the user is responsible for the lifetime of eac=
h stream in the chain, which gets really annoying when you want to give a s=
tream to an object, since it means you have to manually make sure the strea=
ms don't die before the object that's using them does. It would also preclu=
de things like a text stream accepting a file path, since that would requir=
e the text stream to be able to optionally create its own source/sink.<br><=
/div></blockquote><div><br>This is getting kind of off-topic (this is about=
 finding out where iostreams went wrong, not how to fix it), but the way I =
invisioned text files was that they <i>were</i> <i>filters</i> that would b=
e used on top of binary files as sources/sinks. You wouldn't need a separat=
e sink for them. They scan text for a character; if they find '\n', they co=
nvert it into the platform-specific equivalent. BOMs would work more or les=
s the same way, except that they only do the insertion once: the first time=
 someone tries to write something. After that, they're inert.<br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_565_22018983.1353779486633--

.


Author: DeadMG <wolfeinstein@gmail.com>
Date: Sat, 24 Nov 2012 10:36:15 -0800 (PST)
Raw View
------=_Part_470_10282917.1353782175699
Content-Type: text/plain; charset=ISO-8859-1

We have iterators for that. Hell, you can do that right now.

template<typename Iterator, typename Out> void encrypt(Iterator begin,
Iterator end, Out o) { ... }
encrypt(begin, end, std::ostream_iterator(stream));

set the newline sequence,


And if I want to support multiple? Does that mean I have to be precognitive?

stay with an inheritance design


So we can continue to feel the pain of multiple inheritance? Getting rid of
inheritance is a big part of the objective.

See, here's where you're going wrong. You're treating streams like
iterators. They're not. Streams do not implement any functionality, at all,
ever, except reading and writing bytes from external sources. They do not
implement compression, or encryption. You do not compose them. They
implement one specific function, and that's it. We already have iterators
(ranges if we're lucky) and functions for this. The best model for a stream
is as a function object. Then, for writing a range, you could do something
as simple as std::for_each(begin, end, std::ref(stream));

 You wouldn't need a separate sink for them.


I agree, text files are really just about encoding data. A quick wrapper or
iterator would be fine.

 convert it into the platform-specific equivalent


No. Then, you cannot write newlines which are for another platform because
you're interoperating with it (say, a file to be sent over a network) or
because some other application won't play well with these or something like
that. The Standard should certainly expose a platform-specific newline
constant, but when reading or writing them, it should be the user's choice
as to what to do.

It also occurs to me that input iterators and output iterators are very
silly.

--




------=_Part_470_10282917.1353782175699
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

We have iterators for that. Hell, you can do that right now.<div><br></div>=
<div>template&lt;typename Iterator, typename Out&gt; void encrypt(Iterator =
begin, Iterator end, Out o) { ... }</div><div>encrypt(begin, end, std::ostr=
eam_iterator(stream));</div><div><br></div><blockquote class=3D"gmail_quote=
" style=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-c=
olor: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;">set=
 the newline sequence,</blockquote><div><br></div><div>And if I want to sup=
port multiple? Does that mean I have to be precognitive?</div><div><br></di=
v><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; bor=
der-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-sty=
le: solid; padding-left: 1ex;">stay with an inheritance design</blockquote>=
<div><br></div><div>So we can continue to feel the pain of multiple inherit=
ance? Getting rid of inheritance is a big part of the objective.</div><div>=
<br></div><div>See, here's where you're going wrong. You're treating stream=
s like iterators. They're not. Streams do not implement any functionality, =
at all, ever, except reading and writing bytes from external sources. They =
do not implement compression, or encryption. You do not compose them. They =
implement one specific function, and that's it. We already have iterators (=
ranges if we're lucky) and functions for this. The best model for a stream =
is as a function object. Then, for writing a range, you could do something =
as simple as std::for_each(begin, end, std::ref(stream));</div><div><br></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; bo=
rder-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-st=
yle: solid; padding-left: 1ex;">&nbsp;You wouldn't need a separate sink for=
 them.</blockquote><div><br></div><div>I agree, text files are really just =
about encoding data. A quick wrapper or iterator would be fine.</div><div><=
br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8=
ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-l=
eft-style: solid; padding-left: 1ex;">&nbsp;convert it into the platform-sp=
ecific equivalent</blockquote><div><br></div><div>No. Then, you cannot writ=
e newlines which are for another platform because you're interoperating wit=
h it (say, a file to be sent over a network) or because some other applicat=
ion won't play well with these or something like that. The Standard should =
certainly expose a platform-specific newline constant, but when reading or =
writing them, it should be the user's choice as to what to do.</div><div><b=
r></div><div>It also occurs to me that input iterators and output iterators=
 are very silly.</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_470_10282917.1353782175699--

.


Author: Jean-Marc Bourguet <jm.bourguet@gmail.com>
Date: Sat, 24 Nov 2012 11:07:08 -0800 (PST)
Raw View
------=_Part_680_13318584.1353784028341
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Le samedi 24 novembre 2012 16:13:59 UTC+1, DeadMG a =E9crit :
>
> The primary problem with that is that "Text file" isn't actually a=20
> well-defined platform-independent concept because of the newlines.


All platforms have a notion of text file. One needs to have a C++ notion=20
which is abstract enough that it can be used with the platform notion, not=
=20
a C++ notion which is specified in such a way that there are platforms=20
which may not implement C++ text files using their notion of text file.

Historically, OS have used notions of files which are far more than just a=
=20
stream of byte. They may have stream oriented files, sequence of record=20
files, key accessed record files,... lines in text file were numbered in=20
some OS.

I'm not sure if that variety is still relevant but C and C++ IO were=20
designed to handle them (for instance, spaces before end of line may=20
disappear when rereading a text file, NUL characters may appear at end of=
=20
file for binary files). Before designing a replacement which is unable to=
=20
handle them, I'd suggest to be sure that they are no more relevant (start=
=20
by looking at z/OS) and to bring people aware of the IO models of the OS=20
you want to support early enough that you don't have to restart your design=
=20
as not portable enough.

Yours,

--=20
Jean-Marc Bourguet

--=20




------=_Part_680_13318584.1353784028341
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Le samedi 24 novembre 2012 16:13:59 UTC+1, DeadMG a =E9crit&nbsp;:<blockquo=
te class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left:=
 1px #ccc solid;padding-left: 1ex;">The primary problem with that is that "=
Text file" isn't actually a well-defined platform-independent concept becau=
se of the newlines.</blockquote><div><br>All platforms have a notion of tex=
t file. One needs to have a C++ notion which is abstract enough that it can=
 be used with the platform notion, not a C++ notion which is specified in s=
uch a way that there are platforms which may not implement C++ text files u=
sing their notion of text file.<br><br>Historically, OS have used notions o=
f files which are far more than just a stream of byte. They may have stream=
 oriented files, sequence of record files, key accessed record files,... li=
nes in text file were numbered in some OS.<br><br>I'm not sure if that vari=
ety is still relevant but C and C++ IO were designed to handle them (for in=
stance, spaces before end of line may disappear when rereading a text file,=
 NUL characters may appear at end of file for binary files). Before designi=
ng a replacement which is unable to handle them, I'd suggest to be sure tha=
t they are no more relevant (start by looking at z/OS) and to bring people =
aware of the IO models of the OS you want to support early enough that you =
don't have to restart your design as not portable enough.<br><br>Yours,<br>=
<br>-- <br>Jean-Marc Bourguet<br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_680_13318584.1353784028341--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 24 Nov 2012 11:25:15 -0800 (PST)
Raw View
------=_Part_1221_8630084.1353785115209
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable



On Saturday, November 24, 2012 11:07:08 AM UTC-8, Jean-Marc Bourguet wrote:
>
> Le samedi 24 novembre 2012 16:13:59 UTC+1, DeadMG a =E9crit :
>>
>> The primary problem with that is that "Text file" isn't actually a=20
>> well-defined platform-independent concept because of the newlines.
>
>
> All platforms have a notion of text file. One needs to have a C++ notion=
=20
> which is abstract enough that it can be used with the platform notion, no=
t=20
> a C++ notion which is specified in such a way that there are platforms=20
> which may not implement C++ text files using their notion of text file.
>
> Historically, OS have used notions of files which are far more than just =
a=20
> stream of byte. They may have stream oriented files, sequence of record=
=20
> files, key accessed record files,... lines in text file were numbered in=
=20
> some OS.
>
> I'm not sure if that variety is still relevant but C and C++ IO were=20
> designed to handle them (for instance, spaces before end of line may=20
> disappear when rereading a text file, NUL characters may appear at end of=
=20
> file for binary files). Before designing a replacement which is unable to=
=20
> handle them, I'd suggest to be sure that they are no more relevant (start=
=20
> by looking at z/OS) and to bring people aware of the IO models of the OS=
=20
> you want to support early enough that you don't have to restart your desi=
gn=20
> as not portable enough.
>

Why do we have to support those?

I know it sounds silly to say, but iostream will continue to exist. Just as=
=20
fopen does. If you're working in such a system and need those specific=20
kinds of translations, I would suggest that the new system simply be able=
=20
to use an iostreambuf as a sink/source.

Yours,
>
> --=20
> Jean-Marc Bourguet
>

--=20




------=_Part_1221_8630084.1353785115209
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br>On Saturday, November 24, 2012 11:07:08 AM UTC-8, Jean-Marc Bourgue=
t wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Le samedi 24 novembre =
2012 16:13:59 UTC+1, DeadMG a =E9crit&nbsp;:<blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex">The primary problem with that is that "Text file" isn't actually a=
 well-defined platform-independent concept because of the newlines.</blockq=
uote><div><br>All platforms have a notion of text file. One needs to have a=
 C++ notion which is abstract enough that it can be used with the platform =
notion, not a C++ notion which is specified in such a way that there are pl=
atforms which may not implement C++ text files using their notion of text f=
ile.<br><br>Historically, OS have used notions of files which are far more =
than just a stream of byte. They may have stream oriented files, sequence o=
f record files, key accessed record files,... lines in text file were numbe=
red in some OS.<br><br>I'm not sure if that variety is still relevant but C=
 and C++ IO were designed to handle them (for instance, spaces before end o=
f line may disappear when rereading a text file, NUL characters may appear =
at end of file for binary files). Before designing a replacement which is u=
nable to handle them, I'd suggest to be sure that they are no more relevant=
 (start by looking at z/OS) and to bring people aware of the IO models of t=
he OS you want to support early enough that you don't have to restart your =
design as not portable enough.<br></div></blockquote><div><br>Why do we hav=
e to support those?<br><br>I know it sounds silly to say, but iostream will=
 continue to exist. Just as fopen does. If you're working in such a system =
and need those specific kinds of translations, I would suggest that the new=
 system simply be able to use an iostreambuf as a sink/source.<br><br></div=
><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bo=
rder-left: 1px #ccc solid;padding-left: 1ex;"><div>Yours,<br><br>-- <br>Jea=
n-Marc Bourguet<br></div></blockquote>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_1221_8630084.1353785115209--

.


Author: rick@longbowgames.com
Date: Sat, 24 Nov 2012 11:43:03 -0800 (PST)
Raw View
------=_Part_317_2032900.1353786183220
Content-Type: text/plain; charset=ISO-8859-1

On Saturday, November 24, 2012 1:36:15 PM UTC-5, DeadMG wrote:
>
> We have iterators for that. Hell, you can do that right now.


Let's say I have a compressed log file that I want to read one line at a
time. With chaining streams, you could do this:

ITextStream
stream(make_unique<ICompressedStream>(make_unique<IFileStream>("log.gz")));
while(s = getline(stream))
  // Do something

Try doing that with iterators. The only way you could do it is by loading
the entire file into memory, or by using those 'silly' input iterators.

set the newline sequence,
>
>
> And if I want to support multiple? Does that mean I have to be
> precognitive?
>

You'll notice I only suggested setting the newline sequence for output
streams. For input streams, a sane default would be to swallow \r
characters, unless the user is expecting a certain sequence.

So we can continue to feel the pain of multiple inheritance?
>

std::iostream is the only part of the existing library that uses multiple
inheritance, and with a filter design I'm not 100% convinced that multiple
inheritance is necessary. Even so, I've never experience any pain using
std::iostream; not that I use it often.

On Saturday, November 24, 2012 2:07:08 PM UTC-5, Jean-Marc Bourguet wrote:
>
> I'm not sure if that variety is still relevant but C and C++ IO were
> designed to handle them (for instance, spaces before end of line may
> disappear when rereading a text file, NUL characters may appear at end of
> file for binary files). Before designing a replacement which is unable to
> handle them, I'd suggest to be sure that they are no more relevant (start
> by looking at z/OS) and to bring people aware of the IO models of the OS
> you want to support early enough that you don't have to restart your design
> as not portable enough.
>

I wouldn't be against allowing vendors to offer their own encoding as an
option, however, the beauty of the filter design is that people can write
their own plaintext filter if they really care.

On Saturday, November 24, 2012 12:51:26 PM UTC-5, Nicol Bolas wrote:

> this is about finding out where iostreams went wrong, not how to fix it
>

You have no idea how much restraint I'm exercising by not giving a snarky
reply ;)

Okay, I'll 'answer in the form of a question', as it were. Here's my list:
* Not designed with filters in mind.
* Newline format is defined by the platform rather than the programmer.
* No support for UTF.
* Because binary mode is set with ios_base::bin instead of with a different
type, passing streams as parameters is unsafe.
* Locales conflate encoding with localization.
* You have no idea what you get with a locale, and defining your own is not
trivial.
* Since localization and formatting is tied to streams, you can't localize
or format a value to a string without going through a stream.

And a new one:
* Not designed with non-blocking streams in mind. This is necessary for
network sockets, but would also be nice to have for stdio.

--




------=_Part_317_2032900.1353786183220
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On Saturday, November 24, 2012 1:36:15 PM UTC-5, DeadMG wrote:<blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px=
 #ccc solid;padding-left: 1ex;">We have iterators for that. Hell, you can d=
o that right now.</blockquote><div><br>Let's say I have a compressed log fi=
le that I want to read one line at a time. With chaining streams, you could=
 do this:<br><br><span style=3D"font-family: courier new,monospace;">ITextS=
tream stream(make_unique&lt;ICompressedStream&gt;(make_unique&lt;IFileStrea=
m&gt;("log.gz")));<br>while(s =3D getline(stream))<br>&nbsp; // Do somethin=
g</span><br><br>Try
 doing that with iterators. The only way you could do it is by loading=20
the entire file into memory, or by using those 'silly' input iterators.<br>=
<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><blockquote class=3D=
"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;borde=
r-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">set=
 the newline sequence,</blockquote><div><br></div><div>And if I want to sup=
port multiple? Does that mean I have to be precognitive?</div></blockquote>=
<div><br>You'll
 notice I only suggested setting the newline sequence for output=20
streams. For input streams, a sane default would be to swallow \r=20
characters, unless the user is expecting a certain sequence.<br><br></div><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div>So we can continue to feel=
 the pain of multiple inheritance?<br></div></blockquote><div><br>std::iost=
ream is the only part of the existing library that uses multiple inheritanc=
e, and with a filter design I'm not 100% convinced that multiple inheritanc=
e is necessary. Even so, I've never experience any pain using std::iostream=
; not that I use it often.<br></div><br>On Saturday, November 24, 2012 2:07=
:08 PM UTC-5, Jean-Marc Bourguet wrote:<blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;"><div>I'm not sure if that variety is still relevant but C and C++ =
IO were designed to handle them (for instance, spaces before end of line ma=
y disappear when rereading a text file, NUL characters may appear at end of=
 file for binary files). Before designing a replacement which is unable to =
handle them, I'd suggest to be sure that they are no more relevant (start b=
y looking at z/OS) and to bring people aware of the IO models of the OS you=
 want to support early enough that you don't have to restart your design as=
 not portable enough.<br></div></blockquote><br>I wouldn't be against allow=
ing vendors to offer their own encoding as an option, however, the beauty o=
f the filter design is that people can write their own plaintext filter if =
they really care.<br><br>On Saturday, November 24, 2012 12:51:26 PM UTC-5, =
Nicol Bolas wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>thi=
s is about finding out where iostreams went wrong, not how
 to fix it<br></div></blockquote><br>You have no idea how much restraint I'=
m exercising by not giving a snarky reply ;)<br><br>Okay, I'll 'answer in t=
he form of a question', as it were. Here's my list:<br>* Not designed with =
filters in mind.<br>* Newline format is defined by the platform rather than=
 the programmer.<br>* No support for UTF.<br>* Because binary mode is set w=
ith ios_base::bin instead of with a different type, passing streams as para=
meters is unsafe.<br>* Locales conflate encoding with localization.<br>* Yo=
u have no idea what you get with a locale, and defining your own is not tri=
vial.<br>* Since localization and formatting is tied to streams, you can't =
localize or format a value to a string without going through a stream.<br><=
br>And a new one:<br>* Not designed with non-blocking streams in mind. This=
 is necessary for network sockets, but would also be nice to have for stdio=
..<br>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_317_2032900.1353786183220--

.


Author: Jean-Marc Bourguet <jm.bourguet@gmail.com>
Date: Sat, 24 Nov 2012 12:14:10 -0800 (PST)
Raw View
------=_Part_264_3421605.1353788050782
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Le samedi 24 novembre 2012 20:25:15 UTC+1, Nicol Bolas a =E9crit :
>
>
> On Saturday, November 24, 2012 11:07:08 AM UTC-8, Jean-Marc Bourguet wrot=
e:
>>
>> I'm not sure if that variety is still relevant but C and C++ IO were=20
>> designed to handle them (for instance, spaces before end of line may=20
>> disappear when rereading a text file, NUL characters may appear at end o=
f=20
>> file for binary files). Before designing a replacement which is unable t=
o=20
>> handle them, I'd suggest to be sure that they are no more relevant (star=
t=20
>> by looking at z/OS) and to bring people aware of the IO models of the OS=
=20
>> you want to support early enough that you don't have to restart your des=
ign=20
>> as not portable enough.
>>
>>
> Why do we have to support those?
>

Personally, I don't care. I consider the platforms I'm sure would have had=
=20
problems as no more relevant if they ever were. The more relevant platform=
=20
I know which could have problems is z/OS, but I don't know enough about it=
=20
to be sure.

But if this end up in a formal proposal and if my understanding of the=20
committee dynamic is right, it'll be confronted to people who are thinking=
=20
in the other direction and will ask why we should make a standard only=20
partially implementable on these platforms which were supported. Especially=
=20
if the platforms are still relevant, but possibly even if they aren't. See=
=20
what happened with the proposition to remove trigraphs. Its better to have=
=20
a design which doesn't have foreseeable objections, or at least to be=20
prepared to answer them.

Yours,

--=20
Jean-Marc Bourguet

--=20




------=_Part_264_3421605.1353788050782
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Le samedi 24 novembre 2012 20:25:15 UTC+1, Nicol Bolas a =E9crit&nbsp;:<blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;"><br>On Saturday, November 24, 2012=
 11:07:08 AM UTC-8, Jean-Marc Bourguet wrote:<blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div>I'm not sure if that variety is still relevant but C and C++=
 IO were designed to handle them (for instance, spaces before end of line m=
ay disappear when rereading a text file, NUL characters may appear at end o=
f file for binary files). Before designing a replacement which is unable to=
 handle them, I'd suggest to be sure that they are no more relevant (start =
by looking at z/OS) and to bring people aware of the IO models of the OS yo=
u want to support early enough that you don't have to restart your design a=
s not portable enough.<br></div><br></blockquote><div><br>Why do we have to=
 support those?<br></div></blockquote><div><br>Personally, I don't care. I =
consider the platforms I'm sure would have=20
had problems as no more relevant if they ever were. The more relevant platf=
orm I know=20
which could have problems is z/OS, but I don't know enough about it to be s=
ure.<br><br>But if
 this end up in a formal proposal and if my understanding of the=20
committee dynamic is right, it'll be confronted to people who are=20
thinking in the other direction and will ask why we should make a=20
standard only partially implementable on these platforms which were=20
supported. Especially if the platforms are still relevant, but possibly eve=
n if they aren't. See what=20
happened with the proposition to remove trigraphs. Its better to have a des=
ign which doesn't have foreseeable objections, or at least to be prepared t=
o answer them.<br><br>Yours,<br><br>-- <br>Jean-Marc Bourguet<br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_264_3421605.1353788050782--

.


Author: DeadMG <wolfeinstein@gmail.com>
Date: Sat, 24 Nov 2012 13:07:39 -0800 (PST)
Raw View
------=_Part_515_17052883.1353791259862
Content-Type: text/plain; charset=ISO-8859-1


>
> Try doing that with iterators. The only way you could do it is by loading
> the entire file into memory, or by using those 'silly' input iterators.


I agree that input iterators are really just functions in disguise, but
they do work and not badly either. There is no reason why an input-iterator
based solution could not work just fine. More relevantly, an input-iterator
based solution would actually be remotely generic- I could decompress a
file I had already loaded into memory, for example.

There's really no need for a filter, source, sink design in IO, because we
already have iterators and they already model those concepts and it would
be remotely compatible with existing code.

You'll notice I only suggested setting the newline sequence for output
> streams. For input streams, a sane default would be to swallow \r
> characters, unless the user is expecting a certain sequence.


You have no idea what the user is expecting. Only they know that.

--




------=_Part_515_17052883.1353791259862
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; borde=
r-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style=
: solid; padding-left: 1ex;">Try doing that with iterators. The only way yo=
u could do it is by loading the entire file into memory, or by using those =
'silly' input iterators.</blockquote><div><br></div><div>I agree that input=
 iterators are really just functions in disguise, but they do work and not =
badly either. There is no reason why an input-iterator based solution could=
 not work just fine. More relevantly, an input-iterator based solution woul=
d actually be remotely generic- I could decompress a file I had already loa=
ded into memory, for example.</div><div><br></div><div>There's really no ne=
ed for a filter, source, sink design in IO, because we already have iterato=
rs and they already model those concepts and it would be remotely compatibl=
e with existing code.</div><div><br></div><blockquote class=3D"gmail_quote"=
 style=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-co=
lor: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;">You'=
ll notice I only suggested setting the newline sequence for output streams.=
 For input streams, a sane default would be to swallow \r characters, unles=
s the user is expecting a certain sequence.</blockquote><div><br></div><div=
>You have no idea what the user is expecting. Only they know that.&nbsp;</d=
iv>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_515_17052883.1353791259862--

.


Author: rick@longbowgames.com
Date: Sat, 24 Nov 2012 14:41:15 -0800 (PST)
Raw View
------=_Part_406_11419982.1353796875052
Content-Type: text/plain; charset=ISO-8859-1

On Saturday, November 24, 2012 4:07:40 PM UTC-5, DeadMG wrote:
>
> I agree that input iterators are really just functions in disguise, but
> they do work and not badly either. There is no reason why an input-iterator
> based solution could not work just fine. More relevantly, an input-iterator
> based solution would actually be remotely generic- I could decompress a
> file I had already loaded into memory, for example.
>

Ah, input iterators aren't so silly now, are they?

You can always adapt an input iterator to a stream of vice versa, but
iterators are awkward in this case for three reasons:

1) The end of an input_iterator is a wasteful hack.
2) You can't differentiate between 'no data' and 'end of data'.
3) Iterators don't take ownership, so you have additional lifetime
management.

Here's what the code would look like with iterators:

ifstream fin("log.gz");
istream_iterator it1Start(fin), it1End();
ICompressorIterator it2Start(it1Start), it2End(it1End);
IPlaintextIterator it3Start(it2Start), it3End(it2End);

while(s = getline(it3Start, it3End))
  // Do something

And because iterators don't take ownership of the thing they're iterating
(at least not idiomatically), you can't give it3Start/End to an object
without ensuring that fin, it1Start/End, and it2StartEnd all outlive the
object in question.

It's much easier to go the other way:

ITextStream
stream(make_unique<ICompressedStream>(make_unique<IFileStream>("log.gz")));
copy(input_stream(stream), input_stream(), output_stream(some_buffer));

Like many things, the situation gets a lot better if you use ranges instead
of iterators. Why? It's not because streams are only useful for 'reading
and writing to external sources'. It's because one-directional ranges and
streams are effectively the same thing.

Now, completely abolishing streams and using input/output ranges is an
interesting idea. It's mostly just a naming issue, but assuming the
standard library adopted range-based algorithms, it would make things more
consistent and interoperable. It would look like this:

auto range =
make_iplaintext_range(make_icompressedrange_range(make_ifile_range("log.gz")));
while(s = getline(range))
  // Do something

Not bad. Unfortunately, a function expecting a range like that would look
like this:

void foo(IPlaintextRange<ICompressedRange<IFileRange>> range);

So you would either have to templatize anything that uses file streams, or
make wrapper objects for ranges. Not the end of the world.


> You'll notice I only suggested setting the newline sequence for output
>> streams. For input streams, a sane default would be to swallow \r
>> characters, unless the user is expecting a certain sequence.
>
>
> You have no idea what the user is expecting. Only they know that.
>

Oh for heaven's sake, are you seriously taking me to task for suggesting
that users who use line endings other than \n, \n\r, or \r\n, would have to
stoop so low as to override a default option?

--




------=_Part_406_11419982.1353796875052
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On Saturday, November 24, 2012 4:07:40 PM UTC-5, DeadMG wrote:<blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px=
 #ccc solid;padding-left: 1ex;"><div>I agree that input iterators are reall=
y just functions in disguise, but they do work and not badly either. There =
is no reason why an input-iterator based solution could not work just fine.=
 More relevantly, an input-iterator based solution would actually be remote=
ly generic- I could decompress a file I had already loaded into memory, for=
 example.</div></blockquote><div><br>Ah, input iterators aren't so silly no=
w, are they?<br><br>You can always adapt an input iterator to a stream of v=
ice versa, but iterators are awkward in this case for three reasons:<br><br=
>1) The end of an input_iterator is a wasteful hack.<br>2) You can't differ=
entiate between 'no data' and 'end of data'.<br>3) Iterators don't take own=
ership, so you have additional lifetime management.<br><br>Here's what the =
code would look like with iterators:<br><br><span style=3D"font-family: cou=
rier new,monospace;">ifstream fin("log.gz");<br>istream_iterator it1Start(f=
in), it1End();<br>ICompressorIterator it2Start(it1Start), it2End(it1End);<b=
r>IPlaintextIterator it3Start(it2Start), it3End(it2End);<br><br>while(s =3D=
 getline(it3Start, it3End))<br>&nbsp; // Do something</span><br><br>And bec=
ause iterators don't take ownership of the thing they're iterating (at leas=
t not idiomatically), you can't give it3Start/End to an object without ensu=
ring that fin, it1Start/End, and it2StartEnd all outlive the object in ques=
tion.<br><br>It's much easier to go the other way:<br><br><span style=3D"fo=
nt-family:courier new,monospace">ITextStream stream(make_unique&lt;<wbr>ICo=
mpressedStream&gt;(make_<wbr>unique&lt;IFileStream&gt;("log.gz"))<wbr>);<br=
>copy(input_stream(stream), input_stream(), output_stream(some_buffer));<br=
></span><br>Like many things, the situation gets a lot better if you use ra=
nges instead of iterators. Why? It's not because streams are only useful fo=
r 'reading and writing to external sources'. It's because one-directional r=
anges and streams are effectively the same thing.<br><br>Now, completely ab=
olishing streams and using input/output ranges is an interesting idea. It's=
 mostly just a naming issue, but assuming the standard library adopted rang=
e-based algorithms, it would make things more consistent and interoperable.=
 It would look like this:<br><br><span style=3D"font-family:courier new,mon=
ospace">auto range =3D make_iplaintext_range(make_icompressedrange_range(ma=
ke_ifile_range("log.gz"))<wbr>);<br>while(s =3D getline(range))<br>&nbsp; /=
/ Do something</span><br><br>Not bad. Unfortunately, a function expecting a=
 range like that would look like this:<br><br>void foo(IPlaintextRange&lt;I=
CompressedRange&lt;IFileRange&gt;&gt; range);<br><br>So you would either ha=
ve to templatize anything that uses file streams, or make wrapper objects f=
or ranges. Not the end of the world.<br>&nbsp;<br></div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,20=
4);border-left-style:solid;padding-left:1ex">You'll notice I only suggested=
 setting the newline sequence for output streams. For input streams, a sane=
 default would be to swallow \r characters, unless the user is expecting a =
certain sequence.</blockquote><div><br></div><div>You have no idea what the=
 user is expecting. Only they know that.&nbsp;</div></blockquote><div>&nbsp=
;<br>Oh for heaven's sake, are you seriously taking me to task for suggesti=
ng that users who use line endings other than \n, \n\r, or \r\n, would have=
 to stoop so low as to override a default option?<br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_406_11419982.1353796875052--

.


Author: DeadMG <wolfeinstein@gmail.com>
Date: Sun, 25 Nov 2012 07:23:58 -0800 (PST)
Raw View
------=_Part_1023_1118054.1353857038884
Content-Type: text/plain; charset=ISO-8859-1


>
> Oh for heaven's sake, are you seriously taking me to task for suggesting
> that users who use line endings other than \n, \n\r, or \r\n, would have to
> stoop so low as to override a default option?


Well, yes. I'm saying that the stream should not eat data unless explicitly
asked for.

 1) The end of an input_iterator is a wasteful hack.


It works, and it's compatible with other things. It's ironic for you to
call input iterators wasteful when you'd be re-inventing a massive amount
of existing functionality, especially when it would not meaningfully
interact with what we have now. That is wasteful.

 2) You can't differentiate between 'no data' and 'end of data'.


I don't see the difference. In either case, there is no more data to be had.

3) Iterators don't take ownership, so you have additional lifetime
> management.


Really depends on the iterator. There's absolutely no reason you can't
write an owning iterator. It would be unusual, but perfectly feasible. In
fact, iterator adaptors often own the iterator they are adapting.

ifstream fin("log.gz");
auto begin = plaintext(decompress(fin.begin()));
auto end = plaintext(decompress(fin.end()));
while(s = getline(begin, end)) {
    ...
}

Unlike your solution, this does not have the potential to require multiple
inheritance, nor dynamic allocation, nor virtual calls, and it works well
with the rest of the Standard library. Of course ranges makes this quite a
bit simpler- and so does ranged-for. You could do

for(string s : getline(plaintext(decompress(ifstream("log.gz")))) {
}

It's because one-directional ranges and streams are effectively the same
> thing.


Is exactly what I've been saying. It's really a bad idea to have one
completely separate interface for X, and then have another completely
separate interface for X but more generic. Not only are you duplicating X,
there's no reason to use X but less generic.

--




------=_Part_1023_1118054.1353857038884
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; borde=
r-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style=
: solid; padding-left: 1ex;">Oh for heaven's sake, are you seriously taking=
 me to task for suggesting that users who use line endings other than \n, \=
n\r, or \r\n, would have to stoop so low as to override a default option?</=
blockquote><div><br></div><div>Well, yes. I'm saying that the stream should=
 not eat data unless explicitly asked for.</div><div><br></div><blockquote =
class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-left-width=
: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; pad=
ding-left: 1ex;">&nbsp;1) The end of an input_iterator is a wasteful hack.<=
/blockquote><div><br></div><div>It works, and it's compatible with other th=
ings. It's ironic for you to call input iterators wasteful when you'd be re=
-inventing a massive amount of existing functionality, especially when it w=
ould not meaningfully interact with what we have now. That is wasteful.</di=
v><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px=
 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); =
border-left-style: solid; padding-left: 1ex;">&nbsp;2) You can't differenti=
ate between 'no data' and 'end of data'.</blockquote><br><div>I don't see t=
he difference. In either case, there is no more data to be had.</div><div><=
br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8=
ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-l=
eft-style: solid; padding-left: 1ex;">3) Iterators don't take ownership, so=
 you have additional lifetime management.</blockquote><div><br></div><div>R=
eally depends on the iterator. There's absolutely no reason you can't write=
 an owning iterator. It would be unusual, but perfectly feasible. In fact, =
iterator adaptors often own the iterator they are adapting.</div><div><br><=
/div>ifstream fin("log.gz");<div><div>auto begin =3D plaintext(decompress(f=
in.begin()));</div></div><div>auto end =3D plaintext(decompress(fin.end()))=
;</div><div>while(s =3D getline(begin, end)) {</div><div>&nbsp; &nbsp; ...<=
/div><div>}</div><div><br></div><div>Unlike your solution, this does not ha=
ve the potential to require multiple inheritance, nor dynamic allocation, n=
or virtual calls, and it works well with the rest of the Standard library. =
Of course ranges makes this quite a bit simpler- and so does ranged-for. Yo=
u could do</div><div><br></div><div>for(string s : getline(plaintext(decomp=
ress(ifstream("log.gz")))) {</div><div>}</div><div><br></div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-left-width: =
1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; paddi=
ng-left: 1ex;">It's because one-directional ranges and streams are effectiv=
ely the same thing.</blockquote><div><br></div><div>Is exactly what I've be=
en saying. It's really a bad idea to have one completely separate interface=
 for X, and then have another completely separate interface for X but more =
generic. Not only are you duplicating X, there's no reason to use X but les=
s generic.&nbsp;</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_1023_1118054.1353857038884--

.


Author: rick@longbowgames.com
Date: Sun, 25 Nov 2012 07:55:50 -0800 (PST)
Raw View
------=_Part_145_4917217.1353858950180
Content-Type: text/plain; charset=ISO-8859-1

Okay, you misunderstood some of the stuff I was saying about iterators, but
I'm pretty sure it's moot. We both agree that ranges are a superior
solution to iterators, and, while our confidence levels differ, we both
think ranges have the potential for making good streams, so we can stop
talking about iterators now, right?

First, a couple things I do want to respond to:

On Sunday, November 25, 2012 10:23:59 AM UTC-5, DeadMG wrote:
>
> Well, yes. I'm saying that the stream should not eat data unless
> explicitly asked for.


By using a plaintext stream you're already asking for translation. If you
want all the carriage returns, you probably want a binary stream. If you
want a stream that handles UTF translation and doesn't handle newline
translation, then you're certainly in the minority, and overriding a
default isn't the end of the world.

 2) You can't differentiate between 'no data' and 'end of data'.
>
>
> I don't see the difference. In either case, there is no more data to be
> had.
>

Think about non-blocking streams, like network sockets. There's a
difference between reaching the end of the stream and the rest of the
stream not being ready. This is one of the things that ranges typically
don't deal with.

If we're talking about replacing streams with file ranges, I think it would
be worth consideration that we give a ready() function to all input ranges,
and a flush() option to all output ranges. This can even be important for
something like compressing and decompressing a file, since you might have
to read/write a large amount of data before the next block is ready.

--




------=_Part_145_4917217.1353858950180
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Okay, you misunderstood some of the stuff I was saying about iterators, but=
 I'm pretty sure it's moot. We both agree that ranges are a superior soluti=
on to iterators, and, while our confidence levels differ, we both think ran=
ges have the potential for making good streams, so we can stop talking abou=
t iterators now, right?<br><br>First, a couple things I do want to respond =
to:<br><br>On Sunday, November 25, 2012 10:23:59 AM UTC-5, DeadMG wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;">Well, yes. I'm saying that the st=
ream should not eat data unless explicitly asked for.</blockquote><div><br>=
By using a plaintext stream you're already asking for translation. If you w=
ant all the carriage returns, you probably want a binary stream. If you wan=
t a stream that handles UTF translation and doesn't handle newline translat=
ion, then you're certainly in the minority, and overriding a default isn't =
the end of the world.<br><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:s=
olid;padding-left:1ex">&nbsp;2) You can't differentiate between 'no data' a=
nd 'end of data'.</blockquote><br><div>I don't see the difference. In eithe=
r case, there is no more data to be had.</div></blockquote><div><br>Think a=
bout non-blocking streams, like network sockets. There's a difference betwe=
en reaching the end of the stream and the rest of the stream not being read=
y. This is one of the things that ranges typically don't deal with.<br><br>=
If we're talking about replacing streams with file ranges, I think it would=
 be worth consideration that we give a ready() function to all input ranges=
, and a flush() option to all output ranges. This can even be important for=
 something like compressing and decompressing a file, since you might have =
to read/write a large amount of data before the next block is ready.<br></d=
iv>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_145_4917217.1353858950180--

.


Author: DeadMG <wolfeinstein@gmail.com>
Date: Sun, 25 Nov 2012 08:13:45 -0800 (PST)
Raw View
------=_Part_29_4061507.1353860025532
Content-Type: text/plain; charset=ISO-8859-1

I think that whilst it's definitely important to think about asynchronous
data, a replacement for IOstreams does not necessarily include one. Even if
one was included, it would have to be a completely new, independent
interface, which should be different from synchronous streams- not to
mention that networking has it's own study group, IIRC, and doesn't really
need consideration here. You can't really treat a blocking and non-blocking
stream interchangably.

Okay, you misunderstood some of the stuff I was saying about iterators, but
> I'm pretty sure it's moot. We both agree that ranges are a superior
> solution to iterators, and, while our confidence levels differ, we both
> think ranges have the potential for making good streams, so we can stop
> talking about iterators now, right?


Sure. All I'm saying is that unless ranges are accepted, there's little
choice but to use iterators. You can't really have half the Standard on
iterators and another part on ranges. Either we have ranges, or we'll need
to stick with iterators. AFAIK ranges are not currently an accepted
proposal, so for the interim, it will have to be an iterator-based design.
Fortunately, upgrading it shouldn't be too difficult.





--




------=_Part_29_4061507.1353860025532
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

I think that whilst it's definitely important to think about asynchronous d=
ata, a replacement for IOstreams does not necessarily include one. Even if =
one was included, it would have to be a completely new, independent interfa=
ce, which should be different from synchronous streams- not to mention that=
 networking has it's own study group, IIRC, and doesn't really need conside=
ration here. You can't really treat a blocking and non-blocking stream inte=
rchangably.<div><br></div><blockquote class=3D"gmail_quote" style=3D"margin=
: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 20=
4, 204); border-left-style: solid; padding-left: 1ex;">Okay, you misunderst=
ood some of the stuff I was saying about iterators, but I'm pretty sure it'=
s moot. We both agree that ranges are a superior solution to iterators, and=
, while our confidence levels differ, we both think ranges have the potenti=
al for making good streams, so we can stop talking about iterators now, rig=
ht?</blockquote><div><br></div><div>Sure. All I'm saying is that unless ran=
ges are accepted, there's little choice but to use iterators. You can't rea=
lly have half the Standard on iterators and another part on ranges. Either =
we have ranges, or we'll need to stick with iterators. AFAIK ranges are not=
 currently an accepted proposal, so for the interim, it will have to be an =
iterator-based design. Fortunately, upgrading it shouldn't be too difficult=
..</div><div><br></div><div><br></div><div><br></div><div>&nbsp;</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_29_4061507.1353860025532--

.


Author: robertmacleranramey@gmail.com
Date: Sun, 25 Nov 2012 08:26:15 -0800 (PST)
Raw View
------=_Part_31_10999435.1353860775202
Content-Type: text/plain; charset=ISO-8859-1

I' ve read through this thread and would like to mention a few points.
This information is fruit of my experience in implementing the boost
serialization library.  For "binary" archives performance was he supreme
consideration.  At the same time I wanted/needed it to be built on top of
the standard library constructs.

a) The std::binary flag was necessary to avoid the i/o stream from munching
characters.  Unfortunatly,  there is no way to inquire (e.g.
i/ostream.is_binary() ) to determine how a stream has been opened so that
certain user errors can be detected.

b) the << and >> interfaces turned out to be performance killers.  But the
functionality provided by these operators was totally unused.  So later
versions of the library just used the streambuf interface directly.  The
constructor for a binary archive can take as an argument either a streambuf
or a stream.  If passed a stream, the associated streambuf is used
directly.  This results in a huge performance boost # 1.

c) unfortunately, the streambuf implements the codecvt interface.  A
performance hit and not a good match for binary i/o.  So I made a custom
codecvt facet which does nothing. Another performance improvement.

So.....

if you want close to raw I/O speed without the stream features - do these
things.  If you want to make it convenient to use, derive your own variant
from stream and/or streambuf and implement these features in your own
variant. This would give you today most of what you need - close to max
performance with simple interface AND portable code.  Less functionality
though - of course.

 It would be very interesting in this discussion if someone were to do this
and re-run the bench marks.  (also increase the default buffer size).

Robert Ramey


--




------=_Part_31_10999435.1353860775202
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

I' ve read through this thread and would like to mention a few points.&nbsp=
; This information is fruit of my experience in implementing the boost seri=
alization library.&nbsp; For "binary" archives performance was he supreme c=
onsideration.&nbsp; At the same time I wanted/needed it to be built on top =
of the standard library constructs.<br><br>a) The std::binary flag was nece=
ssary to avoid the i/o stream from munching characters.&nbsp; Unfortunatly,=
&nbsp; there is no way to inquire (e.g. i/ostream.is_binary() ) to determin=
e how a stream has been opened so that certain user errors can be detected.=
<br><br>b) the &lt;&lt; and &gt;&gt; interfaces turned out to be performanc=
e killers.&nbsp; But the functionality provided by these operators was tota=
lly unused.&nbsp; So later versions of the library just used the streambuf =
interface directly.&nbsp; The constructor for a binary archive can take as =
an argument either a streambuf or a stream.&nbsp; If passed a stream, the a=
ssociated streambuf is used directly.&nbsp; This results in a huge performa=
nce boost # 1.<br><br>c) unfortunately, the streambuf implements the codecv=
t interface.&nbsp; A performance hit and not a good match for binary i/o.&n=
bsp; So I made a custom codecvt facet which does nothing. Another performan=
ce improvement.<br><br>So.....<br><br>if you want close to raw I/O speed wi=
thout the stream features - do these things.&nbsp; If you want to make it c=
onvenient to use, derive your own variant from stream and/or streambuf and =
implement these features in your own variant. This would give you today mos=
t of what you need - close to max performance with simple interface AND por=
table code.&nbsp; Less functionality though - of course.<br><br>&nbsp;It wo=
uld be very interesting in this discussion if someone were to do this and r=
e-run the bench marks.&nbsp; (also increase the default buffer size). <br><=
br>Robert Ramey<br><br><br>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_31_10999435.1353860775202--

.


Author: DeadMG <wolfeinstein@gmail.com>
Date: Sun, 25 Nov 2012 08:45:25 -0800 (PST)
Raw View
------=_Part_982_26412103.1353861925430
Content-Type: text/plain; charset=ISO-8859-1

The binary and text streams would likely comprise separate classes, so
there'd be no need for a flag. As for operator<< and codecvt_facet, they
are almost certain to be removed.

--




------=_Part_982_26412103.1353861925430
Content-Type: text/html; charset=ISO-8859-1

The binary and text streams would likely comprise separate classes, so there'd be no need for a flag. As for operator&lt;&lt; and codecvt_facet, they are almost certain to be removed.

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_982_26412103.1353861925430--

.


Author: Beman Dawes <bdawes@acm.org>
Date: Sun, 25 Nov 2012 12:09:20 -0500
Raw View
On Sun, Nov 25, 2012 at 11:26 AM,  <robertmacleranramey@gmail.com> wrote:

> a) The std::binary flag was necessary to avoid the i/o stream from munching
> characters.  Unfortunatly,  there is no way to inquire (e.g.
> i/ostream.is_binary() ) to determine how a stream has been opened so that
> certain user errors can be detected.

Interesting point. I've also run into cases I wanted to detect binary
streams to improve error detection.

If you write up an issue with the motivation for
i/ostream.is_binary(), and the suggested P/R, I'll champion it with
the LWG.

--Beman

--




.


Author: robertmacleranramey@gmail.com
Date: Sun, 25 Nov 2012 09:23:25 -0800 (PST)
Raw View
------=_Part_1075_9194296.1353864205237
Content-Type: text/plain; charset=ISO-8859-1



On Sunday, November 25, 2012 8:45:25 AM UTC-8, DeadMG wrote:
>
> The binary and text streams would likely comprise separate classes, so
> there'd be no need for a flag. As for operator<< and codecvt_facet, they
> are almost certain to be removed.


I'm not sure if this is a reply to my post (Am I the only one who finds he
operation of the forum a little ... funky?).

Assuming it is.

I'm only suggesting that many of the issues raised in this thread can be
addressed by modest (and one time) adjustments to usage of the current
library.  Phrasing it a different way - the current library provides means
to work around or diminish the complaints listed here.  It's clear to me
that the current library was designed to permit exactly this usage.  So if
someone want's to make a simple library for boost "raw_i/ostream" which
would set things up, I'm sure it would be looked at.  I would be very
curious to see how speed compares with the other examples here.

In short, I think that before starting design of some alternative library,
one should be sure that all other alternatives should be explored first -
and I don't think they have been.

Robert Ramey

--




------=_Part_1075_9194296.1353864205237
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br>On Sunday, November 25, 2012 8:45:25 AM UTC-8, DeadMG wrote:<blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;">The binary and text streams would lik=
ely comprise separate classes, so there'd be no need for a flag. As for ope=
rator&lt;&lt; and codecvt_facet, they are almost certain to be removed.</bl=
ockquote><div><br>I'm not sure if this is a reply to my post (Am I the only=
 one who finds he operation of the forum a little ... funky?).<br><br>Assum=
ing it is.<br><br>I'm only suggesting that many of the issues raised in thi=
s thread can be addressed by modest (and one time) adjustments to usage of =
the current library.&nbsp; Phrasing it a different way - the current librar=
y provides means to work around or diminish the complaints listed here.&nbs=
p; It's clear to me that the current library was designed to permit exactly=
 this usage.&nbsp; So if someone want's to make a simple library for boost =
"raw_i/ostream" which would set things up, I'm sure it would be looked at.&=
nbsp; I would be very curious to see how speed compares with the other exam=
ples here.<br><br>In short, I think that before starting design of some alt=
ernative library, one should be sure that all other alternatives should be =
explored first - and I don't think they have been.<br><br>Robert Ramey<br><=
br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_1075_9194296.1353864205237--

.


Author: robertmacleranramey@gmail.com
Date: Sun, 25 Nov 2012 09:24:25 -0800 (PST)
Raw View
------=_Part_196_16913495.1353864265060
Content-Type: text/plain; charset=ISO-8859-1



On Sunday, November 25, 2012 9:09:22 AM UTC-8, Beman Dawes wrote:
>
> On Sun, Nov 25, 2012 at 11:26 AM,  <robertmac...@gmail.com <javascript:>>
> wrote:
>
> > a) The std::binary flag was necessary to avoid the i/o stream from
> munching
> > characters.  Unfortunatly,  there is no way to inquire (e.g.
> > i/ostream.is_binary() ) to determine how a stream has been opened so
> that
> > certain user errors can be detected.
>
> Interesting point. I've also run into cases I wanted to detect binary
> streams to improve error detection.
>
> If you write up an issue with the motivation for
> i/ostream.is_binary(), and the suggested P/R, I'll champion it with
> the LWG.
>

what's a P/R? and where would one "write up" such an issue?

Robert Ramey

>
> --Beman
>

--




------=_Part_196_16913495.1353864265060
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br>On Sunday, November 25, 2012 9:09:22 AM UTC-8, Beman Dawes wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;">On Sun, Nov 25, 2012 at 11:26 AM=
, &nbsp;&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=
=3D"SjUW07KrJrwJ">robertmac...@gmail.<wbr>com</a>&gt; wrote:
<br>
<br>&gt; a) The std::binary flag was necessary to avoid the i/o stream from=
 munching
<br>&gt; characters. &nbsp;Unfortunatly, &nbsp;there is no way to inquire (=
e.g.
<br>&gt; i/ostream.is_binary() ) to determine how a stream has been opened =
so that
<br>&gt; certain user errors can be detected.
<br>
<br>Interesting point. I've also run into cases I wanted to detect binary
<br>streams to improve error detection.
<br>
<br>If you write up an issue with the motivation for
<br>i/ostream.is_binary(), and the suggested P/R, I'll champion it with
<br>the LWG.
<br></blockquote><div><br>what's a P/R? and where would one "write up" such=
 an issue?<br><br>Robert Ramey <br></div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;">
<br>--Beman
<br></blockquote>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_196_16913495.1353864265060--

.


Author: DeadMG <wolfeinstein@gmail.com>
Date: Sun, 25 Nov 2012 10:03:01 -0800 (PST)
Raw View
------=_Part_123_2901500.1353866581547
Content-Type: text/plain; charset=ISO-8859-1

Right, but the reason we want an alternative library isn't because of your
performance concerns. It's because the existing IOstreams are terrible in
absolutely every way. Facets, locales, the formatting manipulators,
multiple inheritance, the world's most obfuscated and redundant streambuf
API...

Really, the question is not "Why would you replace IOStreams?" and more
like "What are the few things about IOStreams that I wouldn't be looking to
throw in the hottest furnace available immediately?".

--




------=_Part_123_2901500.1353866581547
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Right, but the reason we want an alternative library isn't because of your =
performance concerns. It's because the existing IOstreams are terrible in a=
bsolutely every way. Facets, locales, the formatting manipulators, multiple=
 inheritance, the world's most obfuscated and redundant streambuf API...<di=
v><br></div><div>Really, the question is not "Why would you replace IOStrea=
ms?" and more like "What are the few things about IOStreams that I wouldn't=
 be looking to throw in the hottest furnace available immediately?".</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_123_2901500.1353866581547--

.


Author: Jean-Marc Bourguet <jm.bourguet@gmail.com>
Date: Sun, 25 Nov 2012 10:09:20 -0800 (PST)
Raw View
------=_Part_102_29767220.1353866960947
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Le dimanche 25 novembre 2012 17:26:15 UTC+1, robertmac...@gmail.com a=20
=E9crit :
>
> I' ve read through this thread and would like to mention a few points. =
=20
> This information is fruit of my experience in implementing the boost=20
> serialization library.  For "binary" archives performance was he supreme=
=20
> consideration.  At the same time I wanted/needed it to be built on top of=
=20
> the standard library constructs.
>
> a) The std::binary flag was necessary to avoid the i/o stream from=20
> munching characters.  Unfortunatly,  there is no way to inquire (e.g.=20
> i/ostream.is_binary() ) to determine how a stream has been opened so that=
=20
> certain user errors can be detected.
>

Never though about that, but I'd have been in situations where I'd have=20
used one if it had been available.

>
> b) the << and >> interfaces turned out to be performance killers.  But th=
e=20
> functionality provided by these operators was totally unused.  So later=
=20
> versions of the library just used the streambuf interface directly.  The=
=20
> constructor for a binary archive can take as an argument either a streamb=
uf=20
> or a stream.  If passed a stream, the associated streambuf is used=20
> directly.  This results in a huge performance boost # 1.
>

<< and >> are about providing a formatting interface. There is an=20
unformated API to stream, but like you I usually resort to streambuf as I=
=20
find it more convenient (but I usually use only streams in my public=20
interface and use its error reporting interface). One aspect I don't like=
=20
about streambuf from a performance POV is that sgetn and sputn directly=20
call xsgetn and xsputn which are virtual functions even if there is room in=
=20
the corresponding area, and that prevent them to be inlined when used with=
=20
small length.
=20

> c) unfortunately, the streambuf implements the codecvt interface.  A=20
> performance hit and not a good match for binary i/o.  So I made a custom=
=20
> codecvt facet which does nothing. Another performance improvement.
>

Wouldn't imbuing locale::classic() enough? That's what I do on my binary=20
stream but I've never though about measuring if there was a win in imbuing=
=20
a custom codecvt.

Yours,

--=20
Jean-Marc Bourguet

--=20




------=_Part_102_29767220.1353866960947
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Le dimanche 25 novembre 2012 17:26:15 UTC+1, robertmac...@gmail.com a =E9cr=
it&nbsp;:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">I' ve read through th=
is thread and would like to mention a few points.&nbsp; This information is=
 fruit of my experience in implementing the boost serialization library.&nb=
sp; For "binary" archives performance was he supreme consideration.&nbsp; A=
t the same time I wanted/needed it to be built on top of the standard libra=
ry constructs.<br><br>a) The std::binary flag was necessary to avoid the i/=
o stream from munching characters.&nbsp; Unfortunatly,&nbsp; there is no wa=
y to inquire (e.g. i/ostream.is_binary() ) to determine how a stream has be=
en opened so that certain user errors can be detected.<br></blockquote><div=
><br>Never though about that, but I'd have been in situations where I'd hav=
e used one if it had been available.<br></div><blockquote class=3D"gmail_qu=
ote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padd=
ing-left: 1ex;"><br>b) the &lt;&lt; and &gt;&gt; interfaces turned out to b=
e performance killers.&nbsp; But the functionality provided by these operat=
ors was totally unused.&nbsp; So later versions of the library just used th=
e streambuf interface directly.&nbsp; The constructor for a binary archive =
can take as an argument either a streambuf or a stream.&nbsp; If passed a s=
tream, the associated streambuf is used directly.&nbsp; This results in a h=
uge performance boost # 1.<br></blockquote><div><br>&lt;&lt; and &gt;&gt; a=
re about providing a formatting interface. There is an unformated API to st=
ream, but like you I usually resort to streambuf as I find it more convenie=
nt (but I usually use only streams in my public interface and use its error=
 reporting interface). One aspect I don't like about streambuf from a perfo=
rmance POV is that sgetn and sputn directly call xsgetn and xsputn which ar=
e virtual functions even if there is room in the corresponding area, and th=
at prevent them to be inlined when used with small length.<br>&nbsp;<br></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;=
border-left: 1px #ccc solid;padding-left: 1ex;">c) unfortunately, the strea=
mbuf implements the codecvt interface.&nbsp; A performance hit and not a go=
od match for binary i/o.&nbsp; So I made a custom codecvt facet which does =
nothing. Another performance improvement.<br></blockquote><div><br>Wouldn't=
 imbuing locale::classic() enough? That's what I do on my binary stream but=
 I've never though about measuring if there was a win in imbuing a custom c=
odecvt.<br><br>Yours,<br><br>-- <br>Jean-Marc Bourguet<br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_102_29767220.1353866960947--

.


Author: robertmacleranramey@gmail.com
Date: Sun, 25 Nov 2012 12:26:31 -0800 (PST)
Raw View
------=_Part_100_18668354.1353875191816
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable



On Sunday, November 25, 2012 10:09:21 AM UTC-8, Jean-Marc Bourguet wrote:
>
> Le dimanche 25 novembre 2012 17:26:15 UTC+1, robertmac...@gmail.com a=20
> =E9crit :
>>
>> I' ve read through this thread and would like to mention a few points. =
=20
>> This information is fruit of my experience in implementing the boost=20
>> serialization library.  For "binary" archives performance was he supreme=
=20
>> consideration.  At the same time I wanted/needed it to be built on top o=
f=20
>> the standard library constructs.
>>
>> a) The std::binary flag was necessary to avoid the i/o stream from=20
>> munching characters.  Unfortunatly,  there is no way to inquire (e.g.=20
>> i/ostream.is_binary() ) to determine how a stream has been opened so tha=
t=20
>> certain user errors can be detected.
>>
>
> Never though about that, but I'd have been in situations where I'd have=
=20
> used one if it had been available.
>
>>
>> b) the << and >> interfaces turned out to be performance killers.  But=
=20
>> the functionality provided by these operators was totally unused.  So la=
ter=20
>> versions of the library just used the streambuf interface directly.  The=
=20
>> constructor for a binary archive can take as an argument either a stream=
buf=20
>> or a stream.  If passed a stream, the associated streambuf is used=20
>> directly.  This results in a huge performance boost # 1.
>>
>
> << and >> are about providing a formatting interface. There is an=20
> unformated API to stream, but like you I usually resort to streambuf as I=
=20
> find it more convenient (but I usually use only streams in my public=20
> interface and use its error reporting interface). One aspect I don't like=
=20
> about streambuf from a performance POV is that sgetn and sputn directly=
=20
> call xsgetn and xsputn which are virtual functions even if there is room =
in=20
> the corresponding area, and that prevent them to be inlined when used wit=
h=20
> small length.
>

note that one is permitted to make his own streambuf implemenation as well.=
=20
Another path that should be exhausted before starting to think about a=20
whole new library.  I don't think that in my code I actually use these=20
put/get functions - but I could be wrong, I forget.

I was responding to the suggestion that in many cases they aren't=20
convenient to use and any other alternative could dispense with these.  My=
=20
view is that you don't have to use them and if you want to make your own=20
"raw_ostream" it doesn't have to support them if you feel this way.  My=20
real point is that it's premature to think about a new library when the=20
possibilities of the current one haven't been exhausted.  It's also=20
possible that attempts to make a "raw_i/ostream" class might work just fine=
=20
except for some small thing that could be addressed with a small tweak to=
=20
the current library - implementation of is_binary() is would be an example.
=20

> c) unfortunately, the streambuf implements the codecvt interface.  A=20
>> performance hit and not a good match for binary i/o.  So I made a custom=
=20
>> codecvt facet which does nothing. Another performance improvement.
>>
>
> Wouldn't imbuing locale::classic() enough? That's what I do on my binary=
=20
> stream but I've never though about measuring if there was a win in imbuin=
g=20
> a custom codecvt.
>

lol - truth is I don't know the answer to this.   I did this because I=20
thought it would make a difference.  I likely concluded this by tracing=20
into library code.  It was an easy fix so I implemented and forgot about it=
..

Too re-iterate my point,

a) the main concern of the original post was that streams have performance=
=20
issues and that a new library might be needed to address this.

b) Another (secondary concern) was the interface.

c) My view is that these ideas should be "Tested" by making some=20
derivations/ehancements to the current libraries to address these=20
concerns.  Now that we have things like variadic templates, there is much=
=20
opportunity in this area.  Boost is the perfect place to post any such=20
enhancements and or derivations. =20

d) So it's premature to start the haggling over a stream replacement.

Robert Ramey

--=20




------=_Part_100_18668354.1353875191816
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br>On Sunday, November 25, 2012 10:09:21 AM UTC-8, Jean-Marc Bourguet =
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;">Le dimanche 25 novembre =
2012 17:26:15 UTC+1, <a>robertmac...@gmail.com</a> a =E9crit&nbsp;:<blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex">I' ve read through this thread and would li=
ke to mention a few points.&nbsp; This information is fruit of my experienc=
e in implementing the boost serialization library.&nbsp; For "binary" archi=
ves performance was he supreme consideration.&nbsp; At the same time I want=
ed/needed it to be built on top of the standard library constructs.<br><br>=
a) The std::binary flag was necessary to avoid the i/o stream from munching=
 characters.&nbsp; Unfortunatly,&nbsp; there is no way to inquire (e.g. i/o=
stream.is_binary() ) to determine how a stream has been opened so that cert=
ain user errors can be detected.<br></blockquote><div><br>Never though abou=
t that, but I'd have been in situations where I'd have used one if it had b=
een available.<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0=
;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><br>b) the =
&lt;&lt; and &gt;&gt; interfaces turned out to be performance killers.&nbsp=
; But the functionality provided by these operators was totally unused.&nbs=
p; So later versions of the library just used the streambuf interface direc=
tly.&nbsp; The constructor for a binary archive can take as an argument eit=
her a streambuf or a stream.&nbsp; If passed a stream, the associated strea=
mbuf is used directly.&nbsp; This results in a huge performance boost # 1.<=
br></blockquote><div><br>&lt;&lt; and &gt;&gt; are about providing a format=
ting interface. There is an unformated API to stream, but like you I usuall=
y resort to streambuf as I find it more convenient (but I usually use only =
streams in my public interface and use its error reporting interface). One =
aspect I don't like about streambuf from a performance POV is that sgetn an=
d sputn directly call xsgetn and xsputn which are virtual functions even if=
 there is room in the corresponding area, and that prevent them to be inlin=
ed when used with small length.<br></div></blockquote><div><br>note that on=
e is permitted to make his own streambuf implemenation as well. Another pat=
h that should be exhausted before starting to think about a whole new libra=
ry.&nbsp; I don't think that in my code I actually use these put/get functi=
ons - but I could be wrong, I forget.<br></div><div><br>I was responding to=
 the suggestion that in many cases they aren't convenient to use and any ot=
her alternative could dispense with these.&nbsp; My view is that you don't =
have to use them and if you want to make your own "raw_ostream" it doesn't =
have to support them if you feel this way.&nbsp; My real point is that it's=
 premature to think about a new library when the possibilities of the curre=
nt one haven't been exhausted.&nbsp; It's also possible that attempts to ma=
ke a "raw_i/ostream" class might work just fine except for some small thing=
 that could be addressed with a small tweak to the current library - implem=
entation of is_binary() is would be an example.<br>&nbsp;<br></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;"><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex=
">c) unfortunately, the streambuf implements the codecvt interface.&nbsp; A=
 performance hit and not a good match for binary i/o.&nbsp; So I made a cus=
tom codecvt facet which does nothing. Another performance improvement.<br><=
/blockquote><div><br>Wouldn't imbuing locale::classic() enough? That's what=
 I do on my binary stream but I've never though about measuring if there wa=
s a win in imbuing a custom codecvt.<br></div></blockquote><div><br>lol - t=
ruth is I don't know the answer to this. &nbsp; I did this because I though=
t it would make a difference.&nbsp; I likely concluded this by tracing into=
 library code.&nbsp; It was an easy fix so I implemented and forgot about i=
t.<br><br>Too re-iterate my point,<br><br>a) the main concern of the origin=
al post was that streams have performance issues and that a new library mig=
ht be needed to address this.<br><br>b) Another (secondary concern) was the=
 interface.<br><br>c) My view is that these ideas should be "Tested" by mak=
ing some derivations/ehancements to the current libraries to address these =
concerns.&nbsp; Now that we have things like variadic templates, there is m=
uch opportunity in this area.&nbsp; Boost is the perfect place to post any =
such enhancements and or derivations.&nbsp; <br><br>d) So it's premature to=
 start the haggling over a stream replacement.<br><br>Robert Ramey<br></div=
>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_100_18668354.1353875191816--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 25 Nov 2012 12:52:45 -0800 (PST)
Raw View
------=_Part_389_26181072.1353876765167
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable



On Sunday, November 25, 2012 12:26:32 PM UTC-8, robertmac...@gmail.com=20
wrote:
>
>
>
> On Sunday, November 25, 2012 10:09:21 AM UTC-8, Jean-Marc Bourguet wrote:
>>
>> Le dimanche 25 novembre 2012 17:26:15 UTC+1, robertmac...@gmail.com a=20
>> =E9crit :
>>>
>>> I' ve read through this thread and would like to mention a few points. =
=20
>>> This information is fruit of my experience in implementing the boost=20
>>> serialization library.  For "binary" archives performance was he suprem=
e=20
>>> consideration.  At the same time I wanted/needed it to be built on top =
of=20
>>> the standard library constructs.
>>>
>>> a) The std::binary flag was necessary to avoid the i/o stream from=20
>>> munching characters.  Unfortunatly,  there is no way to inquire (e.g.=
=20
>>> i/ostream.is_binary() ) to determine how a stream has been opened so th=
at=20
>>> certain user errors can be detected.
>>>
>>
>> Never though about that, but I'd have been in situations where I'd have=
=20
>> used one if it had been available.
>>
>>>
>>> b) the << and >> interfaces turned out to be performance killers.  But=
=20
>>> the functionality provided by these operators was totally unused.  So l=
ater=20
>>> versions of the library just used the streambuf interface directly.  Th=
e=20
>>> constructor for a binary archive can take as an argument either a strea=
mbuf=20
>>> or a stream.  If passed a stream, the associated streambuf is used=20
>>> directly.  This results in a huge performance boost # 1.
>>>
>>
>> << and >> are about providing a formatting interface. There is an=20
>> unformated API to stream, but like you I usually resort to streambuf as =
I=20
>> find it more convenient (but I usually use only streams in my public=20
>> interface and use its error reporting interface). One aspect I don't lik=
e=20
>> about streambuf from a performance POV is that sgetn and sputn directly=
=20
>> call xsgetn and xsputn which are virtual functions even if there is room=
 in=20
>> the corresponding area, and that prevent them to be inlined when used wi=
th=20
>> small length.
>>
>
> note that one is permitted to make his own streambuf implemenation as=20
> well. Another path that should be exhausted before starting to think abou=
t=20
> a whole new library.  I don't think that in my code I actually use these=
=20
> put/get functions - but I could be wrong, I forget.
>
> I was responding to the suggestion that in many cases they aren't=20
> convenient to use and any other alternative could dispense with these.  M=
y=20
> view is that you don't have to use them and if you want to make your own=
=20
> "raw_ostream" it doesn't have to support them if you feel this way.  My=
=20
> real point is that it's premature to think about a new library when the=
=20
> possibilities of the current one haven't been exhausted.  It's also=20
> possible that attempts to make a "raw_i/ostream" class might work just fi=
ne=20
> except for some small thing that could be addressed with a small tweak to=
=20
> the current library - implementation of is_binary() is would be an exampl=
e.
>

The performance tests were designed to see what the cost of the *interface*=
is, not the underlying implementation. The streambuf interface is=20
sufficiently esoteric to me that I don't really understand how to implement=
=20
one, but if a basic_stringbuf implementation (which should be nothing more=
=20
than a wrapper around basic_string) is an order of magnitude less efficient=
=20
than just doing basic_string::push_back, then that's not a problem that's=
=20
going to be solved with a "small tweak."

The problem isn't basic_stringbuf; the problem is *basic_streambuf itself*.=
=20
It's the virtual interface with how characters are written to the buffer=20
that's causing the performance issue. You can't fix that with a different=
=20
version of basic_stringbuf.
=20

> c) unfortunately, the streambuf implements the codecvt interface.  A=20
>>> performance hit and not a good match for binary i/o.  So I made a custo=
m=20
>>> codecvt facet which does nothing. Another performance improvement.
>>>
>>
>> Wouldn't imbuing locale::classic() enough? That's what I do on my binary=
=20
>> stream but I've never though about measuring if there was a win in imbui=
ng=20
>> a custom codecvt.
>>
>
> lol - truth is I don't know the answer to this.   I did this because I=20
> thought it would make a difference.  I likely concluded this by tracing=
=20
> into library code.  It was an easy fix so I implemented and forgot about =
it.
>
> Too re-iterate my point,
>
> a) the main concern of the original post was that streams have performanc=
e=20
> issues and that a new library might be needed to address this.
>
> b) Another (secondary concern) was the interface.
>
> c) My view is that these ideas should be "Tested" by making some=20
> derivations/ehancements to the current libraries to address these concern=
s.
>

From the given performance tests, it would appear that=20
"derivations/ehancements(sic)" will be insufficient to resolve this=20
problem. It's an interface problem, and you can't solve an interface=20
problem by continuing to use the same interface.

Now that we have things like variadic templates, there is much opportunity=
=20
> in this area.  Boost is the perfect place to post any such enhancements a=
nd=20
> or derivations. =20
>
> d) So it's premature to start the haggling over a stream replacement.
>
> Robert Ramey
>

--=20




------=_Part_389_26181072.1353876765167
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br>On Sunday, November 25, 2012 12:26:32 PM UTC-8, robertmac...@gmail.=
com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br><br>On Sunday, N=
ovember 25, 2012 10:09:21 AM UTC-8, Jean-Marc Bourguet wrote:<blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #cc=
c solid;padding-left:1ex">Le dimanche 25 novembre 2012 17:26:15 UTC+1, <a>r=
obertmac...@gmail.com</a> a =E9crit&nbsp;:<blockquote class=3D"gmail_quote"=
 style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-lef=
t:1ex">I' ve read through this thread and would like to mention a few point=
s.&nbsp; This information is fruit of my experience in implementing the boo=
st serialization library.&nbsp; For "binary" archives performance was he su=
preme consideration.&nbsp; At the same time I wanted/needed it to be built =
on top of the standard library constructs.<br><br>a) The std::binary flag w=
as necessary to avoid the i/o stream from munching characters.&nbsp; Unfort=
unatly,&nbsp; there is no way to inquire (e.g. i/ostream.is_binary() ) to d=
etermine how a stream has been opened so that certain user errors can be de=
tected.<br></blockquote><div><br>Never though about that, but I'd have been=
 in situations where I'd have used one if it had been available.<br></div><=
blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border=
-left:1px #ccc solid;padding-left:1ex"><br>b) the &lt;&lt; and &gt;&gt; int=
erfaces turned out to be performance killers.&nbsp; But the functionality p=
rovided by these operators was totally unused.&nbsp; So later versions of t=
he library just used the streambuf interface directly.&nbsp; The constructo=
r for a binary archive can take as an argument either a streambuf or a stre=
am.&nbsp; If passed a stream, the associated streambuf is used directly.&nb=
sp; This results in a huge performance boost # 1.<br></blockquote><div><br>=
&lt;&lt; and &gt;&gt; are about providing a formatting interface. There is =
an unformated API to stream, but like you I usually resort to streambuf as =
I find it more convenient (but I usually use only streams in my public inte=
rface and use its error reporting interface). One aspect I don't like about=
 streambuf from a performance POV is that sgetn and sputn directly call xsg=
etn and xsputn which are virtual functions even if there is room in the cor=
responding area, and that prevent them to be inlined when used with small l=
ength.<br></div></blockquote><div><br>note that one is permitted to make hi=
s own streambuf implemenation as well. Another path that should be exhauste=
d before starting to think about a whole new library.&nbsp; I don't think t=
hat in my code I actually use these put/get functions - but I could be wron=
g, I forget.<br></div><div><br>I was responding to the suggestion that in m=
any cases they aren't convenient to use and any other alternative could dis=
pense with these.&nbsp; My view is that you don't have to use them and if y=
ou want to make your own "raw_ostream" it doesn't have to support them if y=
ou feel this way.&nbsp; My real point is that it's premature to think about=
 a new library when the possibilities of the current one haven't been exhau=
sted.&nbsp; It's also possible that attempts to make a "raw_i/ostream" clas=
s might work just fine except for some small thing that could be addressed =
with a small tweak to the current library - implementation of is_binary() i=
s would be an example.<br></div></blockquote><div><br>The performance tests=
 were designed to see what the cost of the <i>interface</i> is, not the und=
erlying implementation. The streambuf interface is sufficiently esoteric to=
 me that I don't really understand how to implement one, but if a basic_str=
ingbuf implementation (which should be nothing more than a wrapper around b=
asic_string) is an order of magnitude less efficient than just doing basic_=
string::push_back, then that's not a problem that's going to be solved with=
 a "small tweak."<br><br>The problem isn't basic_stringbuf; the problem is =
<i>basic_streambuf itself</i>. It's the virtual interface with how characte=
rs are written to the buffer that's causing the performance issue. You can'=
t fix that with a different version of basic_stringbuf.<br>&nbsp;<br></div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0=
..8ex;border-left:1px #ccc solid;padding-left:1ex">c) unfortunately, the str=
eambuf implements the codecvt interface.&nbsp; A performance hit and not a =
good match for binary i/o.&nbsp; So I made a custom codecvt facet which doe=
s nothing. Another performance improvement.<br></blockquote><div><br>Wouldn=
't imbuing locale::classic() enough? That's what I do on my binary stream b=
ut I've never though about measuring if there was a win in imbuing a custom=
 codecvt.<br></div></blockquote><div><br>lol - truth is I don't know the an=
swer to this. &nbsp; I did this because I thought it would make a differenc=
e.&nbsp; I likely concluded this by tracing into library code.&nbsp; It was=
 an easy fix so I implemented and forgot about it.<br><br>Too re-iterate my=
 point,<br><br>a) the main concern of the original post was that streams ha=
ve performance issues and that a new library might be needed to address thi=
s.<br><br>b) Another (secondary concern) was the interface.<br><br>c) My vi=
ew is that these ideas should be "Tested" by making some derivations/ehance=
ments to the current libraries to address these concerns.</div></blockquote=
><div><br>From the given performance tests, it would appear that "derivatio=
ns/ehancements(sic)" will be insufficient to resolve this problem. It's an =
interface problem, and you can't solve an interface problem by continuing t=
o use the same interface.<br><br></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;"><div>Now that we have things like variadic templates, there is muc=
h opportunity in this area.&nbsp; Boost is the perfect place to post any su=
ch enhancements and or derivations.&nbsp; <br><br>d) So it's premature to s=
tart the haggling over a stream replacement.<br><br>Robert Ramey<br></div><=
/blockquote>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_389_26181072.1353876765167--

.


Author: Rob Meijer <pibara@gmail.com>
Date: Sun, 25 Nov 2012 22:10:37 +0100
Raw View
--047d7bf0effe9abec104cf583f4c
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

Format strings and streams both suffer from the same 'pay for what you
won't use' symptoms IMO.
The problem being that both are apparently sufficiently complex that
'optimize' compiler options don't
do that much. That is, if for example you create a null streambuf subclass
with an overloaded overflow method like this:

typename traits::int_type overflow(typename traits::int_type c) { return c;
}

All the operator<< stuff will get invoked anyhow when you use an ostream
created from such a streambuf no matter how much you push the compiler to
optimize. IMHO if you want to address problems with streams, a proposal
that identifies what would be needed to help the compiler make operator<<
code melt away when such a null stream buffer is used.

The point is that the price of using streams is not really that high when
the stream is actually going somewhere, but is extremely high if the stream
is in fact a null stream.




2012/11/17 Jason McKesson <jmckesson@gmail.com>

>  The Iostreams library in C++ has a problem. We have real, reasonable,
> legitimate C++ professional, who like C++ and use modern C++ idioms,
> telling people to not use iostreams. This is not due to differing ideas o=
n
> C++ or C-in-classes-style development, but the simple practical realities
> of the situation.
>
> This kind of thing is indicative of a real problem in iostreams. In order
> to eventually solve that problem, we must first identify exactly what the
> problems are. This discussion should be focused on exactly that:
> identifying the problems with the library. Once we know what the real
> problems are, we can be certain that any new system that is proposed
> addresses them.
>
> Note that this is about problems within iostreams. This is not about a
> list of things you *wish* it could do. This is about what iostreams
> actually tries to do but fails at in some way. So stuff like async file I=
O
> doesn=92t go here, since iostreams doesn=92t try to provide that.
>
> Feel free to add to this list other flaws you see in iostreams. Or if you
> think that some of them are not real flaws, feel free to explain why.
>
> Performance
> This is the big one, generally the #1 reason why people suggest using
> C-standard file IO rather than iostreams.
>
> Oftentimes, when people defend iostreams performance, they will say
> something to the effect of, =93iostreams does far more than C-standard fi=
le
> IO.=94 And that=92s true. With iostreams, you have an extensible mechanis=
m for
> writing any type directly to a stream. You can =93easily=94 write new
> streambuf=92s that will allow you to (via runtime polymorphism) be able t=
o
> work with existing code, thus allowing you to leverage your file IO for
> other forms of IO. You could even use a network pipe as an input or outpu=
t
> stream.
>
> There=92s one real problem with this logic, and it is exactly why people
> suggest C-standard file IO. Iostreams violates a fundamental precept of
> C++: pay *only* for what you use.
>
> Consider this suite of benchmarks<http://stackoverflow.com/questions/4340=
396/does-the-c-standard-mandate-poor-performance-for-iostreams-or-am-i-just=
-deali>.
> This code doesn=92t do file IO; it writes directly to a string. All it=92=
s
> doing is measuring the time it takes to append 4-characters to a string. =
A
> lot. It uses a `char[]` as a useful control. It also tests the use of
> `vector<char>` (presumably `basic_string` would have similar results).
> Therefore, this is a solid test for the efficiency of the iostreams
> codebase itself.
>
> Obviously there will be some efficiency loss. But consider the numbers in
> the results.
>
> The ostringstream is more than full order of magnitude slower than the
> control. It=92s almost 100x in some cases. Note that it=92s not using << =
to
> write to the stream; it=92s using `ostream::write()`.
>
> Note that the vector<char> implementations are fairly comparable to the
> control, usually being around 1x-4x the speed. So clearly this is somethi=
ng
> in ostringstream.
>
> Now, you might say that one could use the stringbuf directly. And that wa=
s
> done. While it does improve performance over the ostringstream case
> substantially (generally half to a quarter the performance), it=92s still
> over 10x slower than the control or most vector<char> implementations.
>
> Why? The stringbuf operations ought to be a thin wrapper over std::string=
..
> After all, that=92s what was asked for.
>
> Where does this inefficiency come from? I haven=92t done any extensive
> profiling analysis, but my educated guesses are from two places: virtual
> function overhead and an interface that does too much.
>
> ostringstream is supposed to be able to be used as an ostream for
> runtime-polymorphism. But here=92s where the C++ maxim comes into play.
> Runtime-polymorphism is not being used here. Every function call should
> be able to be statically dispatched. And it is, but all of the virtual
> machinery comes from *within* ostringstream.
>
> This problem seems to come mostly from the fact that basic_ostream, which
> does most of the leg-work for ostringstream, has no specific knowledge of
> its stream type. Therefore it's always a virtual call. And it may be doin=
g
> many such virtual calls.
>
> You can achieve the same runtime polymorphism (being able to overload
> operator<< for any stream) by using a static set of stream classes, tight=
ly
> coupled to their specific streambufs, and a single =93anystream=94 type t=
hat
> those streams can be converted into. It would use std::function-style typ=
e
> erasure to remember the original type and feed function calls to it. It
> would use a single function call to initiate each write operation, rather
> than what appears to be many virtual calls within each write.
>
> Then, there=92s the fact that streambuf itself is overdesigned. stringbuf
> ought to be a simple interface wrapper around a std::string, but it=92s n=
ot.
> It=92s a complex thing. It has locale support of all things. Why? Isn=92t
> that something that should be handled at the stream level?
>
> This API has no way to get a low-level interface to a
> file/string/whatever. There=92s no way to just open a filebuf and blast t=
he
> file into some memory, or to shove some memory out of a filebuf. It will
> always employ the locale machinery even if you didn=92t ask for it. It wi=
ll
> always make these internal virtual calls, even if they are completely
> statically dispatched.
>
> With iostreams, you are paying for a lot of stuff that you don=92t
> frequently use. At the stream level, it makes sense that you=92re paying =
for
> certain machinery (though again, some way to say that you=92re not using =
some
> of it would be nice). At the buffer level, it does not, since that is the
> lowest level you=92re allowed to use.
>
> Utility
> While performance is the big issue, it=92s not the only one.
>
> The biggest selling point for iostreams is the ability to extend its
> formatted writing functionality. You can overload operator<< for various
> types and simply use them. You can=92t do that with fprintf. And thanks t=
o
> ADL, it will work just fine for classes in namespaces. You can create new
> streambuf types and even streams if you like. All relatively easily.
>
> Here=92s the problem, and it is admittedly one that is subjective: printf=
 is
> really nice syntax.
>
> It=92s very compact, for one. Once you understand the basic syntax of it,
> it=92s very easy to see what=92s going on. Especially for complex formatt=
ing.
> Just consider the physical size difference between these two:
>
> snprintf(..., =930x%08x=94, integer);
>
>  stream << "0x" << std::right << std::hex << std::setw(8) << iVal << std:=
:endl;
>
>  It may take a bit longer to become used to the printf version, but this
> is something you can easily look up in a reference.
>
> Plus, it makes it much easier to do translations on formatted strings. Yo=
u
> can look the pattern string up in a table that changes from language to
> language. This is rather more difficult in iostreams, though not
> impossible. Granted, pattern changes may not be enough, as some languages
> have different subject/verb/object grammars that would require reshufflin=
g
> patterns around. However, there are printf-style systems that do allow fo=
r
> reshuffling, whereas no such mechanism exists for iostream-style.
>
> C++ used the << method because the alternatives were less flexible.
> Boost.Format and other systems show that C++03 did not really have to use
> this mechanism to achieve the extensibility features that iostreams provi=
de.
>
> What do you think? Are there other issues in iostreams that need to be
> mentioned?
>
> --
>
>
>
>

--=20




--047d7bf0effe9abec104cf583f4c
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

Format strings and streams both suffer from the same &#39;pay for what you =
won&#39;t use&#39; symptoms IMO.<div>The problem being that both are appare=
ntly sufficiently complex that &#39;optimize&#39; compiler options don&#39;=
t=A0</div>
<div>do that much. That is, if for example you create a null streambuf subc=
lass with an overloaded overflow method like this:</div><div><br></div><div=
>typename traits::int_type overflow(typename traits::int_type c) { return c=
; }<br>
</div><div><br></div><div>All the operator&lt;&lt; stuff will get invoked a=
nyhow when you use an ostream created from such a streambuf no matter how m=
uch you push the compiler to optimize. IMHO if you want to address problems=
 with streams, a proposal that identifies what would be needed to help the =
compiler make=A0operator&lt;&lt; code melt away when such a null stream buf=
fer is used.</div>
<div><br></div><div>The point is that the price of using streams is not rea=
lly that high when the stream is actually going somewhere, but is extremely=
 high if the stream is in fact a null stream.=A0</div><div><br></div><div>
<br></div><div class=3D"gmail_extra"><br><br><div class=3D"gmail_quote">201=
2/11/17 Jason McKesson <span dir=3D"ltr">&lt;<a href=3D"mailto:jmckesson@gm=
ail.com" target=3D"_blank">jmckesson@gmail.com</a>&gt;</span><br><blockquot=
e class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc sol=
id;padding-left:1ex">

 =20

   =20
 =20
  <div bgcolor=3D"#FFFFFF" text=3D"#000000">
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">The Iostreams
      library in C++ has a problem. We have real, reasonable, legitimate
      C++ professional, who like C++ and use modern C++ idioms, telling
      people to not use iostreams. This is not due to differing ideas on
      C++ or C-in-classes-style development, but the simple practical
      realities of the situation.</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">This

      kind of thing is indicative of a real problem in iostreams. In
      order to eventually solve that problem, we must first identify
      exactly what the problems are. This discussion should be focused
      on exactly that: identifying the problems with the library. Once
      we know what the real problems are, we can be certain that any new
      system that is proposed addresses them.</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">Note
      that this is about problems </span><span style=3D"vertical-align:base=
line;font-variant:normal;font-style:italic;font-size:15px;background-color:=
transparent;text-decoration:none;font-family:Arial;font-weight:normal">with=
in</span><span style=3D"vertical-align:baseline;font-variant:normal;font-st=
yle:normal;font-size:15px;background-color:transparent;text-decoration:none=
;font-family:Arial;font-weight:normal">
      iostreams. This is not about a list of things you <i>wish</i> it
      could do. This is about what iostreams actually tries to do but
      fails at in some way. So stuff like async file IO doesn=92t go here,
      since iostreams doesn=92t try to provide that.</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">Feel

      free to add to this list other flaws you see in iostreams. Or if
      you think that some of them are not real flaws, feel free to
      explain why.</span><br>
    <p dir=3D"ltr"><span style=3D"font-size:32px;font-family:Georgia;color:=
#666666;background-color:transparent;font-weight:normal;font-style:italic;f=
ont-variant:normal;text-decoration:none;vertical-align:baseline">Performanc=
e</span></p>

    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">This
      is the big one, generally the #1 reason why people suggest using
      C-standard file IO rather than iostreams.</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">Oftentimes,

      when people defend iostreams performance, they will say something
      to the effect of, =93iostreams does far more than C-standard file
      IO.=94 And that=92s true. With iostreams, you have an extensible
      mechanism for writing any type directly to a stream. You can
      =93easily=94 write new streambuf=92s that will allow you to (via runt=
ime
      polymorphism) be able to work with existing code, thus allowing
      you to leverage your file IO for other forms of IO. You could even
      use a network pipe as an input or output stream.</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">There=92s

      one real problem with this logic, and it is exactly why people
      suggest C-standard file IO. Iostreams violates a fundamental
      precept of C++: pay <i>only</i> for what you </span><span style=3D"ve=
rtical-align:baseline;font-variant:normal;font-style:italic;font-size:15px;=
background-color:transparent;text-decoration:none;font-family:Arial;font-we=
ight:normal">use</span><span style=3D"vertical-align:baseline;font-variant:=
normal;font-style:normal;font-size:15px;background-color:transparent;text-d=
ecoration:none;font-family:Arial;font-weight:normal">.</span><br>

    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">Consider
    </span><a href=3D"http://stackoverflow.com/questions/4340396/does-the-c=
-standard-mandate-poor-performance-for-iostreams-or-am-i-just-deali" target=
=3D"_blank"><span style=3D"font-size:15px;font-family:Arial;color:#1155cc;b=
ackground-color:transparent;font-weight:normal;font-style:normal;font-varia=
nt:normal;text-decoration:underline;vertical-align:baseline">this
        suite of benchmarks</span></a><span style=3D"vertical-align:baselin=
e;font-variant:normal;font-style:normal;font-size:15px;background-color:tra=
nsparent;text-decoration:none;font-family:Arial;font-weight:normal">.
      This code doesn=92t do file IO; it writes directly to a string. All
      it=92s doing is measuring the time it takes to append 4-characters
      to a string. A lot. It uses a `char[]` as a useful control. It
      also tests the use of `vector&lt;char&gt;` (presumably
      `basic_string` would have similar results). Therefore, this is a
      solid test for the efficiency of the iostreams codebase itself.</span=
><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">Obviously
      there will be some efficiency loss. But consider the numbers in
      the results.</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">The
      ostringstream is more than </span><span style=3D"vertical-align:basel=
ine;font-variant:normal;font-style:italic;font-size:15px;background-color:t=
ransparent;text-decoration:none;font-family:Arial;font-weight:normal">full
      order of magnitude</span><span style=3D"vertical-align:baseline;font-=
variant:normal;font-style:normal;font-size:15px;background-color:transparen=
t;text-decoration:none;font-family:Arial;font-weight:normal">
      slower than the control. It=92s almost 100x in some cases. Note that
      it=92s not using &lt;&lt; to write to the stream; it=92s using
      `ostream::write()`.</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">Note

      that the vector&lt;char&gt; implementations are fairly comparable
      to the control, usually being around 1x-4x the speed. So clearly
      this is something in ostringstream.</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">Now,

      you might say that one could use the stringbuf directly. And that
      was done. While it does improve performance over the ostringstream
      case substantially (generally half to a quarter the performance),
      it=92s still over 10x slower than the control or most
      vector&lt;char&gt; implementations.</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">Why?
      The stringbuf operations ought to be a thin wrapper over
      std::string. After all, that=92s what was asked for.</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">Where

      does this inefficiency come from? I haven=92t done any extensive
      profiling analysis, but my educated guesses are from two places:
      virtual function overhead and an interface that does too much.</span>=
<br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">ostringstream

      is supposed to be able to be used as an ostream for
      runtime-polymorphism. But here=92s where the C++ maxim comes into
      play. Runtime-polymorphism is </span><span style=3D"vertical-align:ba=
seline;font-variant:normal;font-style:italic;font-size:15px;background-colo=
r:transparent;text-decoration:none;font-family:Arial;font-weight:normal">no=
t
      being used here</span><span style=3D"vertical-align:baseline;font-var=
iant:normal;font-style:normal;font-size:15px;background-color:transparent;t=
ext-decoration:none;font-family:Arial;font-weight:normal">.
      Every function call should be able to be statically dispatched.
      And it is, but all of the virtual machinery comes from <i>within</i>
      ostringstream.</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">This
      problem seems to come mostly from the fact that basic_ostream,
      which does most of the leg-work for ostringstream, has no specific
      knowledge of its stream type. Therefore it&#39;s always a virtual
      call. And it may be doing many such virtual calls.</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">You

      can achieve the same runtime polymorphism (being able to overload
      operator&lt;&lt; for any stream) by using a static set of stream
      classes, tightly coupled to their specific streambufs, and a
      single =93anystream=94 type that those streams can be converted into.
      It would use std::function-style type erasure to remember the
      original type and feed function calls to it. It would use a single
      function call to initiate each write operation, rather than what
      appears to be many virtual calls within each write.</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">Then,

      there=92s the fact that streambuf itself is overdesigned. stringbuf
      ought to be a simple interface wrapper around a std::string, but
      it=92s not. It=92s a complex thing. It has </span><span style=3D"vert=
ical-align:baseline;font-variant:normal;font-style:italic;font-size:15px;ba=
ckground-color:transparent;text-decoration:none;font-family:Arial;font-weig=
ht:normal">locale
      support</span><span style=3D"vertical-align:baseline;font-variant:nor=
mal;font-style:normal;font-size:15px;background-color:transparent;text-deco=
ration:none;font-family:Arial;font-weight:normal">
      of all things. Why? Isn=92t that something that should be handled at
      the stream level?</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">This

      API has no way to get a low-level interface to a
      file/string/whatever. There=92s no way to just open a filebuf and
      blast the file into some memory, or to shove some memory out of a
      filebuf. It will always employ the locale machinery even if you
      didn=92t ask for it. It will always make these internal virtual
      calls, even if they are completely statically dispatched.</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">With

      iostreams, you are paying for a lot of stuff that you don=92t
      frequently use. At the stream level, it makes sense that you=92re
      paying for certain machinery (though again, some way to say that
      you=92re not using some of it would be nice). At the buffer level,
      it does not, since that is the lowest level you=92re allowed to use.<=
/span><br>
    <p dir=3D"ltr"><span style=3D"font-size:32px;font-family:Georgia;color:=
#666666;background-color:transparent;font-weight:normal;font-style:italic;f=
ont-variant:normal;text-decoration:none;vertical-align:baseline">Utility</s=
pan></p>

    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">While
      performance is the big issue, it=92s not the only one.</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">The

      biggest selling point for iostreams is the ability to extend its
      formatted writing functionality. You can overload operator&lt;&lt;
      for various types and simply use them. You can=92t do that with
      fprintf. And thanks to ADL, it will work just fine for classes in
      namespaces. You can create new streambuf types and even streams if
      you like. All relatively easily.</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">Here=92s
      the problem, and it is admittedly one that is subjective: printf
      is really nice syntax.</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">It=92s

      very compact, for one. Once you understand the basic syntax of it,
      it=92s very easy to see what=92s going on. Especially for complex
      formatting. Just consider the physical size difference between
      these two:</span><br>
    <pre><tt><span style=3D"vertical-align:baseline;font-variant:normal;fon=
t-style:normal;font-size:15px;background-color:transparent;text-decoration:=
none;font-weight:normal">snprintf(..., =930x%08x=94, integer);</span></tt><=
/pre>

    <pre><tt><span style=3D"vertical-align:baseline;font-variant:normal;fon=
t-style:normal;font-size:15px;background-color:transparent;text-decoration:=
none;font-weight:normal"></span></tt></pre>
    <pre><tt><span style=3D"vertical-align:baseline;font-variant:normal;fon=
t-style:normal;font-size:15px;background-color:transparent;text-decoration:=
none;font-weight:normal">stream &lt;&lt; &quot;0x&quot; &lt;&lt; std::right=
 &lt;&lt; std::hex &lt;&lt; std::setw(8) &lt;&lt; iVal &lt;&lt; std::endl;<=
/span></tt></pre>

    <pre><span style=3D"vertical-align:baseline;font-variant:normal;font-st=
yle:normal;font-size:15px;background-color:transparent;text-decoration:none=
;font-family:Arial;font-weight:normal"></span></pre>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">It
      may take a bit longer to become used to the printf version, but
      this is something you can easily look up in a reference.</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">Plus,

      it makes it much easier to do translations on formatted strings.
      You can look the pattern string up in a table that changes from
      language to language. This is rather more difficult in iostreams,
      though not impossible. Granted, pattern changes may not be enough,
      as some languages have different subject/verb/object grammars that
      would require reshuffling patterns around. However, there are
      printf-style systems that do allow for reshuffling, whereas no
      such mechanism exists for iostream-style.</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal">C++

      used the &lt;&lt; method because the alternatives were less
      flexible. Boost.Format and other systems show that C++03 did not
      really have to use this mechanism to achieve the extensibility
      features that iostreams provide.</span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><br>
    <span style=3D"vertical-align:baseline;font-variant:normal;font-style:n=
ormal;font-size:15px;background-color:transparent;text-decoration:none;font=
-family:Arial;font-weight:normal"></span><span style=3D"vertical-align:base=
line;font-variant:normal;font-style:normal;font-size:15px;background-color:=
transparent;text-decoration:none;font-family:Arial;font-weight:normal">What
      do you think? Are there other issues in iostreams that need to be
      mentioned?</span><span class=3D"HOEnZb"><font color=3D"#888888"><br>
  </font></span></div><span class=3D"HOEnZb"><font color=3D"#888888">


<p></p>

-- <br>
=A0<br>
=A0<br>
=A0<br>
</font></span></blockquote></div><br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--047d7bf0effe9abec104cf583f4c--

.


Author: robertmacleranramey@gmail.com
Date: Sun, 25 Nov 2012 14:16:47 -0800 (PST)
Raw View
------=_Part_37_11476737.1353881807844
Content-Type: text/plain; charset=ISO-8859-1



On Sunday, November 25, 2012 12:52:45 PM UTC-8, Nicol Bolas wrote:

>
> From the given performance tests, it would appear that
> "derivations/ehancements(sic)" will be insufficient to resolve this problem.
>

I don't think the tests show that.


> It's an interface problem, and you can't solve an interface problem by
> continuing to use the same interface.
>

I guess that's where we disagree.  Of course without an alternative
interface to test it's really hard to know.

Robert Ramey

--




------=_Part_37_11476737.1353881807844
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br>On Sunday, November 25, 2012 12:52:45 PM UTC-8, Nicol Bolas wrote:<=
br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;=
border-left: 1px #ccc solid;padding-left: 1ex;"><div><br>From the given per=
formance tests, it would appear that "derivations/ehancements(sic)" will be=
 insufficient to resolve this problem.</div></blockquote><div><br>I don't t=
hink the tests show that.<br>&nbsp;</div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;"><div> It's an interface problem, and you can't solve an interfac=
e problem by continuing to use the same interface.<br></div></blockquote><d=
iv><br>I guess that's where we disagree.&nbsp; Of course without an alterna=
tive interface to test it's really hard to know.<br><br>Robert Ramey<br></d=
iv>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_37_11476737.1353881807844--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 25 Nov 2012 15:57:02 -0800 (PST)
Raw View
------=_Part_1_31746455.1353887822785
Content-Type: text/plain; charset=ISO-8859-1



On Sunday, November 25, 2012 2:16:48 PM UTC-8, robertmac...@gmail.com wrote:
>
>
>
> On Sunday, November 25, 2012 12:52:45 PM UTC-8, Nicol Bolas wrote:
>
>>
>> From the given performance tests, it would appear that
>> "derivations/ehancements(sic)" will be insufficient to resolve this problem.
>>
>
> I don't think the tests show that.
>

Well, how else can you explain it? vector::push_back is over 10x faster
than doing the equivalent task with basic_stringbuf directly when they are
doing the exact same thing. There are only two possible conclusions one
could draw from this:

1) two separate `basic_stringbuf` implementations were written by complete
morons.
2) the basic_stringbuf interface creates substantial inefficiencies.

#1 seems highly unlikely, since the same "complete morons" who wrote
`basic_stringbuf` also wrote `vector`. And again, it wasn't an isolated
incident: the two most popular implementations of the C++ standard library
(VC's library and GCC's libstdc++) have the exact same performance problem.
If there were a competitive implementation, odds are good that one of them
would have found it.

So how do you explain it?


> It's an interface problem, and you can't solve an interface problem by
>> continuing to use the same interface.
>>
>
> I guess that's where we disagree.  Of course without an alternative
> interface to test it's really hard to know.
>

It *was* tested against an alternate interface: `std::vector`. And
`char[]`, for that matter. It lost against both of them. Badly.

--




------=_Part_1_31746455.1353887822785
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br>On Sunday, November 25, 2012 2:16:48 PM UTC-8, robertmac...@gmail.c=
om wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br><br>On Sunday, No=
vember 25, 2012 12:52:45 PM UTC-8, Nicol Bolas wrote:<br><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div><br>From the given performance tests, it would =
appear that "derivations/ehancements(sic)" will be insufficient to resolve =
this problem.</div></blockquote><div><br>I don't think the tests show that.=
<br></div></blockquote><div><br>Well, how else can you explain it? vector::=
push_back is over 10x faster than doing the equivalent task with basic_stri=
ngbuf directly when they are doing the exact same thing. There are only two=
 possible conclusions one could draw from this:<br><br>1) two separate `bas=
ic_stringbuf` implementations were written by complete morons.<br>2) the ba=
sic_stringbuf interface creates substantial inefficiencies.<br><br>#1 seems=
 highly unlikely, since the same "complete morons" who wrote `basic_stringb=
uf` also wrote `vector`. And again, it wasn't an isolated incident: the two=
 most popular implementations of the C++ standard library (VC's library and=
 GCC's libstdc++) have the exact same performance problem. If there were a =
competitive implementation, odds are good that one of them would have found=
 it.<br><br>So how do you explain it?<br>&nbsp;</div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;"><blockquote class=3D"gmail_quote" style=3D"margin:0;=
margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div> It's a=
n interface problem, and you can't solve an interface problem by continuing=
 to use the same interface.<br></div></blockquote><div><br>I guess that's w=
here we disagree.&nbsp; Of course without an alternative interface to test =
it's really hard to know.<br></div></blockquote><div><br>It <i>was</i> test=
ed against an alternate interface: `std::vector`. And `char[]`, for that ma=
tter. It lost against both of them. Badly.</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_1_31746455.1353887822785--

.


Author: robertmacleranramey@gmail.com
Date: Sun, 25 Nov 2012 17:40:58 -0800 (PST)
Raw View
------=_Part_86_15446915.1353894058072
Content-Type: text/plain; charset=ISO-8859-1



On Sunday, November 25, 2012 3:57:03 PM UTC-8, Nicol Bolas wrote:
>
>
>
> On Sunday, November 25, 2012 2:16:48 PM UTC-8, robertmac...@gmail.comwrote:
>>
>>
>>
>> On Sunday, November 25, 2012 12:52:45 PM UTC-8, Nicol Bolas wrote:
>>
>>>
>>> From the given performance tests, it would appear that
>>> "derivations/ehancements(sic)" will be insufficient to resolve this problem.
>>>
>>
>> I don't think the tests show that.
>>
>
> Well, how else can you explain it? vector::push_back is over 10x faster
> than doing the equivalent task with basic_stringbuf directly when they are
> doing the exact same thing.
>

The stream implementation considers codeconvert, /r/n translation etc,
etc.  Even though this functionality isn't used.  string keeps track of the
length even though that functionality isn't used in the test.  char []
doesn't have to keep track of anything.  The tests show that the
implementation of stream is much slower for simple functionality than char
[].  This suggests that it might be worth spending some effort in the
implementation of streams when the extended functionality isn't needed.
That's what I was suggesting.

I haven't seen any proposals for alternative interface so I can't comment
on them.

Robert Ramey

--




------=_Part_86_15446915.1353894058072
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br>On Sunday, November 25, 2012 3:57:03 PM UTC-8, Nicol Bolas wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><br><br>On Sunday, November 25, =
2012 2:16:48 PM UTC-8, <a>robertmac...@gmail.com</a> wrote:<blockquote clas=
s=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc =
solid;padding-left:1ex"><br><br>On Sunday, November 25, 2012 12:52:45 PM UT=
C-8, Nicol Bolas wrote:<br><blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div><br=
>From the given performance tests, it would appear that "derivations/ehance=
ments(sic)" will be insufficient to resolve this problem.</div></blockquote=
><div><br>I don't think the tests show that.<br></div></blockquote><div><br=
>Well, how else can you explain it? vector::push_back is over 10x faster th=
an doing the equivalent task with basic_stringbuf directly when they are do=
ing the exact same thing. </div></blockquote><div><br>The stream implementa=
tion considers codeconvert, /r/n translation etc, etc.&nbsp; Even though th=
is functionality isn't used.&nbsp; string keeps track of the length even th=
ough that functionality isn't used in the test.&nbsp; char [] doesn't have =
to keep track of anything.&nbsp; The tests show that the implementation of =
stream is much slower for simple functionality than char [].&nbsp; This sug=
gests that it might be worth spending some effort in the implementation of =
streams when the extended functionality isn't needed.&nbsp; That's what I w=
as suggesting.<br><br>I haven't seen any proposals for alternative interfac=
e so I can't comment on them.<br><br>Robert Ramey<br><br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_86_15446915.1353894058072--

.


Author: Beman Dawes <bdawes@acm.org>
Date: Sun, 25 Nov 2012 21:03:01 -0500
Raw View
On Sun, Nov 25, 2012 at 12:24 PM,  <robertmacleranramey@gmail.com> wrote:
>
>
> On Sunday, November 25, 2012 9:09:22 AM UTC-8, Beman Dawes wrote:
>>
>> On Sun, Nov 25, 2012 at 11:26 AM,  <robertmac...@gmail.com> wrote:
>>
>> > a) The std::binary flag was necessary to avoid the i/o stream from
>> > munching
>> > characters.  Unfortunatly,  there is no way to inquire (e.g.
>> > i/ostream.is_binary() ) to determine how a stream has been opened so
>> > that
>> > certain user errors can be detected.
>>
>> Interesting point. I've also run into cases I wanted to detect binary
>> streams to improve error detection.
>>
>> If you write up an issue with the motivation for
>> i/ostream.is_binary(), and the suggested P/R, I'll champion it with
>> the LWG.
>
>
> what's a P/R? and where would one "write up" such an issue?

P/R == Proposed Resolution. What I'm suggesting is that this isn't a
big enough problem to merit its own paper, so a library issue is all
that is required. See http://isocpp.org/std/submit-a-library-issue for
how to submit one.

Also see http://cplusplus.github.com/LWG/lwg-active.html for sample issues.

--Beman

--




.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 25 Nov 2012 19:52:49 -0800 (PST)
Raw View
------=_Part_96_3749983.1353901969824
Content-Type: text/plain; charset=ISO-8859-1



On Sunday, November 25, 2012 5:40:58 PM UTC-8, robertmac...@gmail.com wrote:
>
>
>
> On Sunday, November 25, 2012 3:57:03 PM UTC-8, Nicol Bolas wrote:
>>
>>
>>
>> On Sunday, November 25, 2012 2:16:48 PM UTC-8, robertmac...@gmail.comwrote:
>>>
>>>
>>>
>>> On Sunday, November 25, 2012 12:52:45 PM UTC-8, Nicol Bolas wrote:
>>>
>>>>
>>>> From the given performance tests, it would appear that
>>>> "derivations/ehancements(sic)" will be insufficient to resolve this problem.
>>>>
>>>
>>> I don't think the tests show that.
>>>
>>
>> Well, how else can you explain it? vector::push_back is over 10x faster
>> than doing the equivalent task with basic_stringbuf directly when they are
>> doing the exact same thing.
>>
>
> The stream implementation considers codeconvert, /r/n translation etc, etc.
>

Does it? He used basic_stringbuf directly. While locale support is in
streambuf, any end-line translation is not.

Furthermore, that's part of the point. You can't just rip that stuff out,
because the system *requires* it. To remove it would be a
non-backwards-compatible change to a system that's been more or less stable
for over 14 years now. streambuf does locale and codecvt stuff; it can't *
not* do that without breaking people's code.

Breaking changes are allowed, but you generally need to show a serious need
for them, as well as a reason why it can't be done in a non-breaking way.
As well as doing a study of how widespread the breakage would be.

You're much more likely to get a proposal actually accepted if it doesn't
break things.

Even though this functionality isn't used.  string keeps track of the
> length even though that functionality isn't used in the test.  char []
> doesn't have to keep track of anything.  The tests show that the
> implementation of stream is much slower for simple functionality than char
> [].  This suggests that it might be worth spending some effort in the
> implementation of streams when the extended functionality isn't needed.
> That's what I was suggesting.
>
> I haven't seen any proposals for alternative interface so I can't comment
> on them.
>
> Robert Ramey
>
>

--




------=_Part_96_3749983.1353901969824
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br>On Sunday, November 25, 2012 5:40:58 PM UTC-8, robertmac...@gmail.c=
om wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br><br>On Sunday, No=
vember 25, 2012 3:57:03 PM UTC-8, Nicol Bolas wrote:<blockquote class=3D"gm=
ail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><br><br>On Sunday, November 25, 2012 2:16:48 PM UTC-8, <a>=
robertmac...@gmail.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><b=
r><br>On Sunday, November 25, 2012 12:52:45 PM UTC-8, Nicol Bolas wrote:<br=
><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div><br>From the given performanc=
e tests, it would appear that "derivations/ehancements(sic)" will be insuff=
icient to resolve this problem.</div></blockquote><div><br>I don't think th=
e tests show that.<br></div></blockquote><div><br>Well, how else can you ex=
plain it? vector::push_back is over 10x faster than doing the equivalent ta=
sk with basic_stringbuf directly when they are doing the exact same thing. =
</div></blockquote><div><br>The stream implementation considers codeconvert=
, /r/n translation etc, etc.</div></blockquote><div><br>Does it? He used ba=
sic_stringbuf directly. While locale support is in streambuf, any end-line =
translation is not.<br><br>Furthermore, that's part of the point. You can't=
 just rip that stuff out, because the system <i>requires</i> it. To remove =
it would be a non-backwards-compatible change to a system that's been more =
or less stable for over 14 years now. streambuf does locale and codecvt stu=
ff; it can't <i>not</i> do that without breaking people's code.<br><br>Brea=
king changes are allowed, but you generally need to show a serious need for=
 them, as well as a reason why it can't be done in a non-breaking way. As w=
ell as doing a study of how widespread the breakage would be.<br><br>You're=
 much more likely to get a proposal actually accepted if it doesn't break t=
hings.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>Even =
though this functionality isn't used.&nbsp; string keeps track of the lengt=
h even though that functionality isn't used in the test.&nbsp; char [] does=
n't have to keep track of anything.&nbsp; The tests show that the implement=
ation of stream is much slower for simple functionality than char [].&nbsp;=
 This suggests that it might be worth spending some effort in the implement=
ation of streams when the extended functionality isn't needed.&nbsp; That's=
 what I was suggesting.<br><br>I haven't seen any proposals for alternative=
 interface so I can't comment on them.<br><br>Robert Ramey<br><br></div></b=
lockquote>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_96_3749983.1353901969824--

.


Author: 0xcdcdcdcd@gmx.at
Date: Mon, 10 Dec 2012 05:45:39 -0800 (PST)
Raw View
------=_Part_14_20339018.1355147139659
Content-Type: text/plain; charset=ISO-8859-1

On Saturday, November 17, 2012 8:36:37 PM UTC+1, Nicol Bolas wrote:
>
>  The Iostreams library in C++ has a problem. We have real, reasonable,
> legitimate C++ professional, who like C++ and use modern C++ idioms,
> telling people to not use iostreams. ...
>

(Somehow I think this whole thread shopuld be moved to [ISO C++ Standard -
Discussion ] but while we're here ...)

I assume that many have felt the pain of IOstreams at some point, and I
have recently found a nice question on SO:
What serious alternatives exist for the IOStream library? (besides cstdio)<http://stackoverflow.com/questions/6171360/what-serious-alternatives-exist-for-the-iostream-library-besides-cstdio>-
http://stackoverflow.com/q/6171360/321013

There's really two points I want to highlight from there:

1) quoting the OP: "[iostreams is] ... [e]ntirely too complicated to a
client. If you use only what comes with the standard library it's great,
but attempting to extend things is next to impossible. I read the entire
"Standard C++ IOStreams and Locales" book -- the only book seemingly
available on the topic -- *twice* -- and I still don't know what's going
on."

2) The mentioned FastFormat library - While the FastFormat library has it's
quirks, and I never used it in production, it's at least one serious
attempt to implement something.


--




------=_Part_14_20339018.1355147139659
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On Saturday, November 17, 2012 8:36:37 PM UTC+1, Nicol Bolas wrote:<blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;">
 =20

   =20
 =20
  <div bgcolor=3D"#FFFFFF" text=3D"#000000">
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">The Iostreams
      library in C++ has a problem. We have real, reasonable, legitimate
      C++ professional, who like C++ and use modern C++ idioms, telling
      people to not use iostreams. ...</span></div></blockquote><div><br><s=
pan style=3D""><span><span id=3D"f-tl" role=3D"heading" class=3D"GEAVBTLCF5=
B GEAVBTLCIJB">(Somehow I think this whole thread shopuld be moved to [ISO =
C++ Standard - Discussion</span></span></span> ] but while we're here ...)<=
br><br>I assume that many have felt the pain of IOstreams at some point, an=
d I have recently found a nice question on SO:<br><h1 itemprop=3D"name"><a =
href=3D"http://stackoverflow.com/questions/6171360/what-serious-alternative=
s-exist-for-the-iostream-library-besides-cstdio" class=3D"question-hyperlin=
k">What serious alternatives exist for the IOStream library? (besides cstdi=
o)</a> - <br></h1><a href=3D"http://stackoverflow.com/q/6171360/321013">htt=
p://stackoverflow.com/q/6171360/321013</a><br><br>There's really two points=
 I want to highlight from there:<br><br>1) quoting the OP: "[iostreams is] =
.... [e]ntirely too complicated to a client. If you use only what comes with=
=20
the standard library it's great, but attempting to extend things is next
 to impossible. I read the entire "Standard C++ IOStreams and Locales"=20
book -- the only book seemingly available on the topic -- <em>twice</em> --=
 and I still don't know what's going on."<br><br>2) The mentioned FastForma=
t library - While the FastFormat library has it's quirks, and I never used =
it in production, it's at least one serious attempt to implement something.=
<br><br><br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_14_20339018.1355147139659--

.


Author: naesten@gmail.com
Date: Sat, 14 Dec 2013 18:27:56 -0800 (PST)
Raw View
------=_Part_639_20246695.1387074476179
Content-Type: text/plain; charset=ISO-8859-1

On Saturday, November 24, 2012 3:14:11 PM UTC-5, Jean-Marc Bourguet wrote:
>
> See what happened with the proposition to remove trigraphs.
>

What proposal?  (And what was done wrong?)  I've been thinking of trying to
propose that they at least be (optionally) disabled by default.  (Perhaps
with an interim period in which they just be deprecated by default, though
it seems rather as though they effectively are already.  There would
probably have to be a special "#pragma" to enable them, with an alternate
"??=pragma" spelling despite trigraphs being disabled.)

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_639_20246695.1387074476179
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Saturday, November 24, 2012 3:14:11 PM UTC-5, Jean-Marc=
 Bourguet wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">See what=20
happened with the proposition to remove trigraphs.<br></blockquote><div><br=
>What proposal?&nbsp; (And what was done wrong?)&nbsp; I've been thinking o=
f trying to propose that they at least be (optionally) disabled by default.=
&nbsp; (Perhaps with an interim period in which they just be deprecated by =
default, though it seems rather as though they effectively are already.&nbs=
p; There would probably have to be a special "#pragma" to enable them, with=
 an alternate "??=3Dpragma" spelling despite trigraphs being disabled.)<br>=
</div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_639_20246695.1387074476179--

.


Author: euloanty@live.com
Date: Sun, 15 Dec 2013 07:38:12 -0800 (PST)
Raw View
------=_Part_991_30836367.1387121892703
Content-Type: text/plain; charset=ISO-8859-1

YES.
Iostreams is failure.This is right.

But cstdio is much more rubbish. I can't use it to read many things
correctly.
For example, how could I read std::time_t correctly? Use what? "%d"? "%u"?
"%llu"? "%lld"? "%"PRIu32?

I support that we should make a new IO Library.

About efficiency, I'd say cstdio and iostream are all rubbish. I only use
0.15s to read 10000000 numbers by "fread" on Linux, but fscanf uses 1s
and std::ifstream uses 0.95s.
And I know many cstdio function uses sync. That's very slow.

Before we do that, concept and concept polymorphism should be done first. I
don't think a library that needs object-oriented is good. We can use
concept programming to change them. Of course we need constexpr. I hate the
polymorphism-based object-oriented.


ofstream is faster than cstdio. fout<<s; is twice faster than
fprintf(fout,"%d",s);

In my opinion many IO operations don't need locale, and most of
the IO states can be remarked as constexpr . And I hate locale and sync.

All our iostates must be known as constexpr, except nsetw.

This is right:
ncout<<nfixed<<nsetw(3)<<s;
But this is wrong:
ncout<<nfixed<<nsetw(3);
ncout<<s;
Of course, directly output is right:
ncout<<s;
All the io-states must be known first.

This is right.
int s(3);
ncout.printf("%",s);
But this is wrong:
int s(3);
ncout.printf("%d",s);

This is right:
double s(3);
ncout.printf("%",nfixed<<nsetw(3)<<s);
But this is wrong:
double s(3);
ncout.printf("%.3f",s);

The ncout.printf() returns ncout itself not a int!!!!
so we can write:
(ncout.printf("%",nfixed<<nsetw(3)<<s)<<3.4).printf("%",525);

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_991_30836367.1387121892703
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>YES. </div><div>Iostreams is failure.This is right.</=
div><div><br></div><div>But cstdio is much&nbsp;more rubbish. I can't use i=
t to read&nbsp;many&nbsp;things correctly.<br>For example, how could I read=
 std::time_t correctly? Use what? "%d"? "%u"? "%llu"? "%lld"? "%"PRIu32?</d=
iv><div><br></div><div>I support that we should&nbsp;make a new&nbsp;IO Lib=
rary.</div><div><br></div><div>About efficiency, I'd&nbsp;say cstdio and io=
stream are all rubbish. I only use 0.15s to read 10000000 numbers&nbsp;by&n=
bsp;"fread"&nbsp;on Linux, but&nbsp;fscanf&nbsp;uses 1s and&nbsp;std::ifstr=
eam uses 0.95s.</div><div>And I know many cstdio function uses sync. That's=
 very slow.</div><div><br></div><div><font color=3D"#00ff00">Before we do t=
hat, concept and concept polymorphism should be done first. I don't think a=
 library that needs object-oriented is good. We can use concept programming=
&nbsp;to change them. Of course we need constexpr. I hate&nbsp;the polymorp=
hism-based&nbsp;object-oriented.</font></div><div><font color=3D"#00ff00"><=
br></font></div><div><br></div><div>ofstream is faster than cstdio. fout&lt=
;&lt;s; is twice faster than fprintf(fout,"%d",s);</div><div><br></div><div=
>In my opinion&nbsp;many&nbsp;IO operations&nbsp;don't need locale, and&nbs=
p;most&nbsp;of the&nbsp;IO&nbsp;states can be remarked as constexpr . And I=
 hate locale and sync.</div><div><br></div><div>All our iostates must be kn=
own as constexpr, except nsetw.</div><div><br></div><div>This is right:</di=
v><div>ncout&lt;&lt;nfixed&lt;&lt;nsetw(3)&lt;&lt;s;</div><div>But this is =
wrong:</div><div>ncout&lt;&lt;nfixed&lt;&lt;nsetw(3);</div><div>ncout&lt;&l=
t;s;</div><div><div>Of course,&nbsp;directly output&nbsp;is right:</div><di=
v>ncout&lt;&lt;s;</div></div><div>All the io-states must be known first.</d=
iv><div><br></div><div>This is right.</div><div>int s(3);</div><div>ncout.p=
rintf("%",s);</div><div>But this is wrong:</div><div>int s(3);</div><div>nc=
out.printf("%d",s);</div><div><br></div><div>This is right:</div><div>doubl=
e&nbsp;s(3);</div><div>ncout.printf("%",nfixed&lt;&lt;nsetw(3)&lt;&lt;s);</=
div><div>But this is wrong:</div><div>double s(3);</div><div>ncout.printf("=
%.3f",s);</div><div><br></div><div>The ncout.printf() returns ncout itself =
not a int!!!!</div><div>so we can write:</div><div>(ncout.printf("%",nfixed=
&lt;&lt;nsetw(3)&lt;&lt;s)&lt;&lt;3.4).printf("%",525);</div><div><br></div=
></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_991_30836367.1387121892703--

.


Author: euloanty@live.com
Date: Sun, 15 Dec 2013 08:09:02 -0800 (PST)
Raw View
------=_Part_994_3265583.1387123742082
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

I am sorry:
"This is right:
ncout<<nfixed<<nsetw(3)<<s;"
is poor too.

ncout<<(nfixed<<nsetw(3)<<s);
That's ok!!

=E5=9C=A8 2012=E5=B9=B411=E6=9C=8818=E6=97=A5=E6=98=9F=E6=9C=9F=E6=97=A5UTC=
+8=E4=B8=8A=E5=8D=883=E6=97=B636=E5=88=8637=E7=A7=92=EF=BC=8CNicol Bolas=E5=
=86=99=E9=81=93=EF=BC=9A

>  The Iostreams library in C++ has a problem. We have real, reasonable,=20
> legitimate C++ professional, who like C++ and use modern C++ idioms,=20
> telling people to not use iostreams. This is not due to differing ideas o=
n=20
> C++ or C-in-classes-style development, but the simple practical realities=
=20
> of the situation.
>
> This kind of thing is indicative of a real problem in iostreams. In order=
=20
> to eventually solve that problem, we must first identify exactly what the=
=20
> problems are. This discussion should be focused on exactly that:=20
> identifying the problems with the library. Once we know what the real=20
> problems are, we can be certain that any new system that is proposed=20
> addresses them.
>
> Note that this is about problems within iostreams. This is not about a=20
> list of things you *wish* it could do. This is about what iostreams=20
> actually tries to do but fails at in some way. So stuff like async file I=
O=20
> doesn=E2=80=99t go here, since iostreams doesn=E2=80=99t try to provide t=
hat.
>
> Feel free to add to this list other flaws you see in iostreams. Or if you=
=20
> think that some of them are not real flaws, feel free to explain why.
>
> Performance
> This is the big one, generally the #1 reason why people suggest using=20
> C-standard file IO rather than iostreams.
>
> Oftentimes, when people defend iostreams performance, they will say=20
> something to the effect of, =E2=80=9Ciostreams does far more than C-stand=
ard file=20
> IO.=E2=80=9D And that=E2=80=99s true. With iostreams, you have an extensi=
ble mechanism for=20
> writing any type directly to a stream. You can =E2=80=9Ceasily=E2=80=9D w=
rite new=20
> streambuf=E2=80=99s that will allow you to (via runtime polymorphism) be =
able to=20
> work with existing code, thus allowing you to leverage your file IO for=
=20
> other forms of IO. You could even use a network pipe as an input or outpu=
t=20
> stream.
>
> There=E2=80=99s one real problem with this logic, and it is exactly why p=
eople=20
> suggest C-standard file IO. Iostreams violates a fundamental precept of=
=20
> C++: pay *only* for what you use.
>
> Consider this suite of benchmarks<http://stackoverflow.com/questions/4340=
396/does-the-c-standard-mandate-poor-performance-for-iostreams-or-am-i-just=
-deali>.=20
> This code doesn=E2=80=99t do file IO; it writes directly to a string. All=
 it=E2=80=99s=20
> doing is measuring the time it takes to append 4-characters to a string. =
A=20
> lot. It uses a `char[]` as a useful control. It also tests the use of=20
> `vector<char>` (presumably `basic_string` would have similar results).=20
> Therefore, this is a solid test for the efficiency of the iostreams=20
> codebase itself.
>
> Obviously there will be some efficiency loss. But consider the numbers in=
=20
> the results.
>
> The ostringstream is more than full order of magnitude slower than the=20
> control. It=E2=80=99s almost 100x in some cases. Note that it=E2=80=99s n=
ot using << to=20
> write to the stream; it=E2=80=99s using `ostream::write()`.
>
> Note that the vector<char> implementations are fairly comparable to the=
=20
> control, usually being around 1x-4x the speed. So clearly this is somethi=
ng=20
> in ostringstream.
>
> Now, you might say that one could use the stringbuf directly. And that wa=
s=20
> done. While it does improve performance over the ostringstream case=20
> substantially (generally half to a quarter the performance), it=E2=80=99s=
 still=20
> over 10x slower than the control or most vector<char> implementations.
>
> Why? The stringbuf operations ought to be a thin wrapper over std::string=
..=20
> After all, that=E2=80=99s what was asked for.
>
> Where does this inefficiency come from? I haven=E2=80=99t done any extens=
ive=20
> profiling analysis, but my educated guesses are from two places: virtual=
=20
> function overhead and an interface that does too much.
>
> ostringstream is supposed to be able to be used as an ostream for=20
> runtime-polymorphism. But here=E2=80=99s where the C++ maxim comes into p=
lay.=20
> Runtime-polymorphism is not being used here. Every function call should=
=20
> be able to be statically dispatched. And it is, but all of the virtual=20
> machinery comes from *within* ostringstream.
>
> This problem seems to come mostly from the fact that basic_ostream, which=
=20
> does most of the leg-work for ostringstream, has no specific knowledge of=
=20
> its stream type. Therefore it's always a virtual call. And it may be doin=
g=20
> many such virtual calls.
>
> You can achieve the same runtime polymorphism (being able to overload=20
> operator<< for any stream) by using a static set of stream classes, tight=
ly=20
> coupled to their specific streambufs, and a single =E2=80=9Canystream=E2=
=80=9D type that=20
> those streams can be converted into. It would use std::function-style typ=
e=20
> erasure to remember the original type and feed function calls to it. It=
=20
> would use a single function call to initiate each write operation, rather=
=20
> than what appears to be many virtual calls within each write.
>
> Then, there=E2=80=99s the fact that streambuf itself is overdesigned. str=
ingbuf=20
> ought to be a simple interface wrapper around a std::string, but it=E2=80=
=99s not.=20
> It=E2=80=99s a complex thing. It has locale support of all things. Why? I=
sn=E2=80=99t=20
> that something that should be handled at the stream level?
>
> This API has no way to get a low-level interface to a=20
> file/string/whatever. There=E2=80=99s no way to just open a filebuf and b=
last the=20
> file into some memory, or to shove some memory out of a filebuf. It will=
=20
> always employ the locale machinery even if you didn=E2=80=99t ask for it.=
 It will=20
> always make these internal virtual calls, even if they are completely=20
> statically dispatched.
>
> With iostreams, you are paying for a lot of stuff that you don=E2=80=99t=
=20
> frequently use. At the stream level, it makes sense that you=E2=80=99re p=
aying for=20
> certain machinery (though again, some way to say that you=E2=80=99re not =
using some=20
> of it would be nice). At the buffer level, it does not, since that is the=
=20
> lowest level you=E2=80=99re allowed to use.
>
> Utility
> While performance is the big issue, it=E2=80=99s not the only one.
>
> The biggest selling point for iostreams is the ability to extend its=20
> formatted writing functionality. You can overload operator<< for various=
=20
> types and simply use them. You can=E2=80=99t do that with fprintf. And th=
anks to=20
> ADL, it will work just fine for classes in namespaces. You can create new=
=20
> streambuf types and even streams if you like. All relatively easily.
>
> Here=E2=80=99s the problem, and it is admittedly one that is subjective: =
printf is=20
> really nice syntax.
>
> It=E2=80=99s very compact, for one. Once you understand the basic syntax =
of it,=20
> it=E2=80=99s very easy to see what=E2=80=99s going on. Especially for com=
plex formatting.=20
> Just consider the physical size difference between these two:
>
> snprintf(..., =E2=80=9C0x%08x=E2=80=9D, integer);
>
>  stream << "0x" << std::right << std::hex << std::setw(8) << iVal << std:=
:endl;
>
>  It may take a bit longer to become used to the printf version, but this=
=20
> is something you can easily look up in a reference.
>
> Plus, it makes it much easier to do translations on formatted strings. Yo=
u=20
> can look the pattern string up in a table that changes from language to=
=20
> language. This is rather more difficult in iostreams, though not=20
> impossible. Granted, pattern changes may not be enough, as some languages=
=20
> have different subject/verb/object grammars that would require reshufflin=
g=20
> patterns around. However, there are printf-style systems that do allow fo=
r=20
> reshuffling, whereas no such mechanism exists for iostream-style.
>
> C++ used the << method because the alternatives were less flexible.=20
> Boost.Format and other systems show that C++03 did not really have to use=
=20
> this mechanism to achieve the extensibility features that iostreams provi=
de.
>
> What do you think? Are there other issues in iostreams that need to be=20
> mentioned?
> =20

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_994_3265583.1387123742082
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>I am sorry:</div><div>"This is right:</div><div>ncout=
&lt;&lt;nfixed&lt;&lt;nsetw(3)&lt;&lt;s;"</div><div>is poor too.</div><div>=
<br></div><div>ncout&lt;&lt;(nfixed&lt;&lt;nsetw(3)&lt;&lt;s);</div><div>Th=
at's ok!!<br><br>=E5=9C=A8 2012=E5=B9=B411=E6=9C=8818=E6=97=A5=E6=98=9F=E6=
=9C=9F=E6=97=A5UTC+8=E4=B8=8A=E5=8D=883=E6=97=B636=E5=88=8637=E7=A7=92=EF=
=BC=8CNicol Bolas=E5=86=99=E9=81=93=EF=BC=9A</div><blockquote class=3D"gmai=
l_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left=
-color: rgb(204, 204, 204); border-left-width: 1px; border-left-style: soli=
d;">
 =20

   =20
 =20
  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">The =
Iostreams
      library in C++ has a problem. We have real, reasonable, legitimate
      C++ professional, who like C++ and use modern C++ idioms, telling
      people to not use iostreams. This is not due to differing ideas on
      C++ or C-in-classes-style development, but the simple practical
      realities of the situation.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">This

      kind of thing is indicative of a real problem in iostreams. In
      order to eventually solve that problem, we must first identify
      exactly what the problems are. This discussion should be focused
      on exactly that: identifying the problems with the library. Once
      we know what the real problems are, we can be certain that any new
      system that is proposed addresses them.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Note
      that this is about problems </span><span style=3D"color: rgb(0, 0, 0)=
; font-family: Arial; font-size: 15px; font-style: italic; font-variant: no=
rmal; font-weight: normal; text-decoration: none; vertical-align: baseline;=
 background-color: transparent;">within</span><span style=3D"color: rgb(0, =
0, 0); font-family: Arial; font-size: 15px; font-style: normal; font-varian=
t: normal; font-weight: normal; text-decoration: none; vertical-align: base=
line; background-color: transparent;">
      iostreams. This is not about a list of things you <i>wish</i> it
      could do. This is about what iostreams actually tries to do but
      fails at in some way. So stuff like async file IO doesn=E2=80=99t go =
here,
      since iostreams doesn=E2=80=99t try to provide that.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Feel

      free to add to this list other flaws you see in iostreams. Or if
      you think that some of them are not real flaws, feel free to
      explain why.</span><br>
    <p dir=3D"ltr"><span style=3D"color: rgb(102, 102, 102); font-family: G=
eorgia; font-size: 32px; font-style: italic; font-variant: normal; font-wei=
ght: normal; text-decoration: none; vertical-align: baseline; background-co=
lor: transparent;">Performance</span></p>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">This
      is the big one, generally the #1 reason why people suggest using
      C-standard file IO rather than iostreams.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Ofte=
ntimes,

      when people defend iostreams performance, they will say something
      to the effect of, =E2=80=9Ciostreams does far more than C-standard fi=
le
      IO.=E2=80=9D And that=E2=80=99s true. With iostreams, you have an ext=
ensible
      mechanism for writing any type directly to a stream. You can
      =E2=80=9Ceasily=E2=80=9D write new streambuf=E2=80=99s that will allo=
w you to (via runtime
      polymorphism) be able to work with existing code, thus allowing
      you to leverage your file IO for other forms of IO. You could even
      use a network pipe as an input or output stream.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Ther=
e=E2=80=99s

      one real problem with this logic, and it is exactly why people
      suggest C-standard file IO. Iostreams violates a fundamental
      precept of C++: pay <i>only</i> for what you </span><span style=3D"co=
lor: rgb(0, 0, 0); font-family: Arial; font-size: 15px; font-style: italic;=
 font-variant: normal; font-weight: normal; text-decoration: none; vertical=
-align: baseline; background-color: transparent;">use</span><span style=3D"=
color: rgb(0, 0, 0); font-family: Arial; font-size: 15px; font-style: norma=
l; font-variant: normal; font-weight: normal; text-decoration: none; vertic=
al-align: baseline; background-color: transparent;">.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Cons=
ider
    </span><a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75htt=
p%3A%2F%2Fstackoverflow.com%2Fquestions%2F4340396%2Fdoes-the-c-standard-man=
date-poor-performance-for-iostreams-or-am-i-just-deali\46sa\75D\46sntz\0751=
\46usg\75AFQjCNFGm4Xsoek6kyzy5OpZ33R9EM5ShA';return true;" onclick=3D"this.=
href=3D'http://www.google.com/url?q\75http%3A%2F%2Fstackoverflow.com%2Fques=
tions%2F4340396%2Fdoes-the-c-standard-mandate-poor-performance-for-iostream=
s-or-am-i-just-deali\46sa\75D\46sntz\0751\46usg\75AFQjCNFGm4Xsoek6kyzy5OpZ3=
3R9EM5ShA';return true;" href=3D"http://stackoverflow.com/questions/4340396=
/does-the-c-standard-mandate-poor-performance-for-iostreams-or-am-i-just-de=
ali" target=3D"_blank"><span style=3D"color: rgb(17, 85, 204); font-family:=
 Arial; font-size: 15px; font-style: normal; font-variant: normal; font-wei=
ght: normal; text-decoration: underline; vertical-align: baseline; backgrou=
nd-color: transparent;">this
        suite of benchmarks</span></a><span style=3D"color: rgb(0, 0, 0); f=
ont-family: Arial; font-size: 15px; font-style: normal; font-variant: norma=
l; font-weight: normal; text-decoration: none; vertical-align: baseline; ba=
ckground-color: transparent;">.
      This code doesn=E2=80=99t do file IO; it writes directly to a string.=
 All
      it=E2=80=99s doing is measuring the time it takes to append 4-charact=
ers
      to a string. A lot. It uses a `char[]` as a useful control. It
      also tests the use of `vector&lt;char&gt;` (presumably
      `basic_string` would have similar results). Therefore, this is a
      solid test for the efficiency of the iostreams codebase itself.</span=
><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Obvi=
ously
      there will be some efficiency loss. But consider the numbers in
      the results.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">The
      ostringstream is more than </span><span style=3D"color: rgb(0, 0, 0);=
 font-family: Arial; font-size: 15px; font-style: italic; font-variant: nor=
mal; font-weight: normal; text-decoration: none; vertical-align: baseline; =
background-color: transparent;">full
      order of magnitude</span><span style=3D"color: rgb(0, 0, 0); font-fam=
ily: Arial; font-size: 15px; font-style: normal; font-variant: normal; font=
-weight: normal; text-decoration: none; vertical-align: baseline; backgroun=
d-color: transparent;">
      slower than the control. It=E2=80=99s almost 100x in some cases. Note=
 that
      it=E2=80=99s not using &lt;&lt; to write to the stream; it=E2=80=99s =
using
      `ostream::write()`.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Note

      that the vector&lt;char&gt; implementations are fairly comparable
      to the control, usually being around 1x-4x the speed. So clearly
      this is something in ostringstream.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Now,

      you might say that one could use the stringbuf directly. And that
      was done. While it does improve performance over the ostringstream
      case substantially (generally half to a quarter the performance),
      it=E2=80=99s still over 10x slower than the control or most
      vector&lt;char&gt; implementations.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Why?
      The stringbuf operations ought to be a thin wrapper over
      std::string. After all, that=E2=80=99s what was asked for.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Wher=
e

      does this inefficiency come from? I haven=E2=80=99t done any extensiv=
e
      profiling analysis, but my educated guesses are from two places:
      virtual function overhead and an interface that does too much.</span>=
<br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">ostr=
ingstream

      is supposed to be able to be used as an ostream for
      runtime-polymorphism. But here=E2=80=99s where the C++ maxim comes in=
to
      play. Runtime-polymorphism is </span><span style=3D"color: rgb(0, 0, =
0); font-family: Arial; font-size: 15px; font-style: italic; font-variant: =
normal; font-weight: normal; text-decoration: none; vertical-align: baselin=
e; background-color: transparent;">not
      being used here</span><span style=3D"color: rgb(0, 0, 0); font-family=
: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-we=
ight: normal; text-decoration: none; vertical-align: baseline; background-c=
olor: transparent;">.
      Every function call should be able to be statically dispatched.
      And it is, but all of the virtual machinery comes from <i>within</i>
      ostringstream.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">This
      problem seems to come mostly from the fact that basic_ostream,
      which does most of the leg-work for ostringstream, has no specific
      knowledge of its stream type. Therefore it's always a virtual
      call. And it may be doing many such virtual calls.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">You

      can achieve the same runtime polymorphism (being able to overload
      operator&lt;&lt; for any stream) by using a static set of stream
      classes, tightly coupled to their specific streambufs, and a
      single =E2=80=9Canystream=E2=80=9D type that those streams can be con=
verted into.
      It would use std::function-style type erasure to remember the
      original type and feed function calls to it. It would use a single
      function call to initiate each write operation, rather than what
      appears to be many virtual calls within each write.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Then=
,

      there=E2=80=99s the fact that streambuf itself is overdesigned. strin=
gbuf
      ought to be a simple interface wrapper around a std::string, but
      it=E2=80=99s not. It=E2=80=99s a complex thing. It has </span><span s=
tyle=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px; font-styl=
e: italic; font-variant: normal; font-weight: normal; text-decoration: none=
; vertical-align: baseline; background-color: transparent;">locale
      support</span><span style=3D"color: rgb(0, 0, 0); font-family: Arial;=
 font-size: 15px; font-style: normal; font-variant: normal; font-weight: no=
rmal; text-decoration: none; vertical-align: baseline; background-color: tr=
ansparent;">
      of all things. Why? Isn=E2=80=99t that something that should be handl=
ed at
      the stream level?</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">This

      API has no way to get a low-level interface to a
      file/string/whatever. There=E2=80=99s no way to just open a filebuf a=
nd
      blast the file into some memory, or to shove some memory out of a
      filebuf. It will always employ the locale machinery even if you
      didn=E2=80=99t ask for it. It will always make these internal virtual
      calls, even if they are completely statically dispatched.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">With

      iostreams, you are paying for a lot of stuff that you don=E2=80=99t
      frequently use. At the stream level, it makes sense that you=E2=80=99=
re
      paying for certain machinery (though again, some way to say that
      you=E2=80=99re not using some of it would be nice). At the buffer lev=
el,
      it does not, since that is the lowest level you=E2=80=99re allowed to=
 use.</span><br>
    <p dir=3D"ltr"><span style=3D"color: rgb(102, 102, 102); font-family: G=
eorgia; font-size: 32px; font-style: italic; font-variant: normal; font-wei=
ght: normal; text-decoration: none; vertical-align: baseline; background-co=
lor: transparent;">Utility</span></p>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Whil=
e
      performance is the big issue, it=E2=80=99s not the only one.</span><b=
r>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">The

      biggest selling point for iostreams is the ability to extend its
      formatted writing functionality. You can overload operator&lt;&lt;
      for various types and simply use them. You can=E2=80=99t do that with
      fprintf. And thanks to ADL, it will work just fine for classes in
      namespaces. You can create new streambuf types and even streams if
      you like. All relatively easily.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Here=
=E2=80=99s
      the problem, and it is admittedly one that is subjective: printf
      is really nice syntax.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">It=
=E2=80=99s

      very compact, for one. Once you understand the basic syntax of it,
      it=E2=80=99s very easy to see what=E2=80=99s going on. Especially for=
 complex
      formatting. Just consider the physical size difference between
      these two:</span><br>
    <pre><tt><span style=3D"color: rgb(0, 0, 0); font-size: 15px; font-styl=
e: normal; font-variant: normal; font-weight: normal; text-decoration: none=
; vertical-align: baseline; background-color: transparent;">snprintf(..., =
=E2=80=9C0x%08x=E2=80=9D, integer);</span></tt></pre>
    <pre><tt><span style=3D"color: rgb(0, 0, 0); font-size: 15px; font-styl=
e: normal; font-variant: normal; font-weight: normal; text-decoration: none=
; vertical-align: baseline; background-color: transparent;"></span></tt></p=
re>
    <pre><tt><span style=3D"color: rgb(0, 0, 0); font-size: 15px; font-styl=
e: normal; font-variant: normal; font-weight: normal; text-decoration: none=
; vertical-align: baseline; background-color: transparent;">stream &lt;&lt;=
 "0x" &lt;&lt; std::right &lt;&lt; std::hex &lt;&lt; std::setw(8) &lt;&lt; =
iVal &lt;&lt; std::endl;</span></tt></pre>
    <pre><span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size:=
 15px; font-style: normal; font-variant: normal; font-weight: normal; text-=
decoration: none; vertical-align: baseline; background-color: transparent;"=
></span></pre>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">It
      may take a bit longer to become used to the printf version, but
      this is something you can easily look up in a reference.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Plus=
,

      it makes it much easier to do translations on formatted strings.
      You can look the pattern string up in a table that changes from
      language to language. This is rather more difficult in iostreams,
      though not impossible. Granted, pattern changes may not be enough,
      as some languages have different subject/verb/object grammars that
      would require reshuffling patterns around. However, there are
      printf-style systems that do allow for reshuffling, whereas no
      such mechanism exists for iostream-style.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">C++

      used the &lt;&lt; method because the alternatives were less
      flexible. Boost.Format and other systems show that C++03 did not
      really have to use this mechanism to achieve the extensibility
      features that iostreams provide.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px;=
 font-style: normal; font-variant: normal; font-weight: normal; text-decora=
tion: none; vertical-align: baseline; background-color: transparent;">What
      do you think? Are there other issues in iostreams that need to be
      mentioned?</span><br>
  </div>

</blockquote></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_994_3265583.1387123742082--

.


Author: Jean-Marc Bourguet <jm.bourguet@gmail.com>
Date: Mon, 16 Dec 2013 00:33:12 -0800 (PST)
Raw View
------=_Part_1390_28296287.1387182792110
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Le dimanche 15 d=E9cembre 2013 03:27:56 UTC+1, nae...@gmail.com a =E9crit :
>
> On Saturday, November 24, 2012 3:14:11 PM UTC-5, Jean-Marc Bourguet wrote=
:
>>
>> See what happened with the proposition to remove trigraphs.
>>
>
> What proposal?  (And what was done wrong?)  I've been thinking of trying=
=20
> to propose that they at least be (optionally) disabled by default. =20
> (Perhaps with an interim period in which they just be deprecated by=20
> default, though it seems rather as though they effectively are already. =
=20
> There would probably have to be a special "#pragma" to enable them, with =
an=20
> alternate "??=3Dpragma" spelling despite trigraphs being disabled.)
>

There already have been tentatives (IIRC correctly, even an adoption which=
=20
has then been reversed).  The latest paper I've found with a quick search=
=20
is http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3062.pdf  If=20
you really want to do something, I suggest that you track those, check the=
=20
meeting notes and see with those which were involved what could be done.

--=20
Jean-Marc

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_1390_28296287.1387182792110
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Le dimanche 15 d=E9cembre 2013 03:27:56 UTC+1, nae...@gmai=
l.com a =E9crit&nbsp;:<blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr">On Saturday, November 24, 2012 3:14:11 PM UTC-5, Jean-Marc Bourgue=
t wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">See what=20
happened with the proposition to remove trigraphs.<br></blockquote><div><br=
>What proposal?&nbsp; (And what was done wrong?)&nbsp; I've been thinking o=
f trying to propose that they at least be (optionally) disabled by default.=
&nbsp; (Perhaps with an interim period in which they just be deprecated by =
default, though it seems rather as though they effectively are already.&nbs=
p; There would probably have to be a special "#pragma" to enable them, with=
 an alternate "??=3Dpragma" spelling despite trigraphs being disabled.)<br>=
</div></div></blockquote><div><br></div><div>There already have been tentat=
ives (IIRC correctly, even an adoption which has then been reversed). &nbsp=
;The latest paper I've found with a quick search is&nbsp;<a href=3D"http://=
www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3062.pdf">http://www.open=
-std.org/jtc1/sc22/wg21/docs/papers/2010/n3062.pdf</a>&nbsp; If you really =
want to do something, I suggest that you track those, check the meeting not=
es and see with those which were involved what could be done.</div><div><br=
></div><div>--&nbsp;</div><div>Jean-Marc</div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1390_28296287.1387182792110--

.


Author: fritzpoll <fred.pollard@gmail.com>
Date: Sun, 12 Jan 2014 09:44:03 -0800 (PST)
Raw View
------=_Part_2125_17884145.1389548644039
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

I have used iostreams in C++ since I was a beginner programmer and even now=
=20
am using it in commercial projects.  I agree with many of the sentiments=20
expressed in the original post, particularly regarding performance.  The=20
main problem as I see it (and there seems to be some agreement in the posts=
=20
above) is that iostreams attempts to do too much - it is doing I/O and=20
formatting and localisation all in one package.  In a way, for beginners,=
=20
this is great, but the mechanics of the interface and interdependencies=20
that this introduces makes deviation from simple use a daunting task.  Even=
=20
now, 15 years on from my first C++ program, I'm "frightened" of cajoling=20
iostreams to do anything complicated.

That said, it is all very well to complain and compile a list of=20
grievances, but we need a) some solutions and b) a sample implementation of=
=20
the same.  I think the answer in a new library would be to take the=20
functionality of iostreams and split it up, so that you have something like=
:

   - streams classes that are sources and/or sinks - these conceptually=20
   simply stream byte data from one place to another.  So a file stream wou=
ld=20
   simply take in the data provided and write out the data into the file, a=
=20
   string stream would do the same but store it in a string, etc.  As now,=
=20
   you'd have separate classes relating to different source/sink types.  Th=
ese=20
   would all inherit from a single base class, largely to account for the u=
se=20
   case where one may wish to store pointers to multiple streams of differe=
nt=20
   types in a container to loop over during processing.
   - More string formatting functions.  C++11 extended the <string> header=
=20
   to include conversions from most primitives into a string/wstring, but=
=20
   further formatting functions could be included by default - these would =
=20
   need to be written for unicode types as well, I suspect.  I'm not sure=
=20
   exactly how to start with the list of functionality required to replicat=
e=20
   what one can achieve with iostreams, but perhaps other can offer guidanc=
e.
  =20
Other aspects such as Unicode/Localisation should be dealt with by other=20
libraries - it doesn't seem like it should be the purpose of a stream to do=
=20
this, and not every user of the streaming library should have to pay the=20
cost by default, as at present.  It seems perverse at the moment that one=
=20
can improve the performance of iostreams only by introducing more complex=
=20
code - the inverse of the more typical equation where more code =3D> more=
=20
functionality.

If we can pin down/agree a more suitable interface, I'm certainly happy to=
=20
help provide a sample implementation for testing and improvement.  My ideas=
=20
above can be discarded if they are not appropriate - I'm not wedded to=20
them, but I thought they might provide a hook for criticism!
On Saturday, November 17, 2012 7:36:37 PM UTC, Nicol Bolas wrote:
>
>  The Iostreams library in C++ has a problem. We have real, reasonable,=20
> legitimate C++ professional, who like C++ and use modern C++ idioms,=20
> telling people to not use iostreams. This is not due to differing ideas o=
n=20
> C++ or C-in-classes-style development, but the simple practical realities=
=20
> of the situation.
>
> This kind of thing is indicative of a real problem in iostreams. In order=
=20
> to eventually solve that problem, we must first identify exactly what the=
=20
> problems are. This discussion should be focused on exactly that:=20
> identifying the problems with the library. Once we know what the real=20
> problems are, we can be certain that any new system that is proposed=20
> addresses them.
>
> Note that this is about problems within iostreams. This is not about a=20
> list of things you *wish* it could do. This is about what iostreams=20
> actually tries to do but fails at in some way. So stuff like async file I=
O=20
> doesn=92t go here, since iostreams doesn=92t try to provide that.
>
> Feel free to add to this list other flaws you see in iostreams. Or if you=
=20
> think that some of them are not real flaws, feel free to explain why.
>
> Performance
> This is the big one, generally the #1 reason why people suggest using=20
> C-standard file IO rather than iostreams.
>
> Oftentimes, when people defend iostreams performance, they will say=20
> something to the effect of, =93iostreams does far more than C-standard fi=
le=20
> IO.=94 And that=92s true. With iostreams, you have an extensible mechanis=
m for=20
> writing any type directly to a stream. You can =93easily=94 write new=20
> streambuf=92s that will allow you to (via runtime polymorphism) be able t=
o=20
> work with existing code, thus allowing you to leverage your file IO for=
=20
> other forms of IO. You could even use a network pipe as an input or outpu=
t=20
> stream.
>
> There=92s one real problem with this logic, and it is exactly why people=
=20
> suggest C-standard file IO. Iostreams violates a fundamental precept of=
=20
> C++: pay *only* for what you use.
>
> Consider this suite of benchmarks<http://stackoverflow.com/questions/4340=
396/does-the-c-standard-mandate-poor-performance-for-iostreams-or-am-i-just=
-deali>.=20
> This code doesn=92t do file IO; it writes directly to a string. All it=92=
s=20
> doing is measuring the time it takes to append 4-characters to a string. =
A=20
> lot. It uses a `char[]` as a useful control. It also tests the use of=20
> `vector<char>` (presumably `basic_string` would have similar results).=20
> Therefore, this is a solid test for the efficiency of the iostreams=20
> codebase itself.
>
> Obviously there will be some efficiency loss. But consider the numbers in=
=20
> the results.
>
> The ostringstream is more than full order of magnitude slower than the=20
> control. It=92s almost 100x in some cases. Note that it=92s not using << =
to=20
> write to the stream; it=92s using `ostream::write()`.
>
> Note that the vector<char> implementations are fairly comparable to the=
=20
> control, usually being around 1x-4x the speed. So clearly this is somethi=
ng=20
> in ostringstream.
>
> Now, you might say that one could use the stringbuf directly. And that wa=
s=20
> done. While it does improve performance over the ostringstream case=20
> substantially (generally half to a quarter the performance), it=92s still=
=20
> over 10x slower than the control or most vector<char> implementations.
>
> Why? The stringbuf operations ought to be a thin wrapper over std::string=
..=20
> After all, that=92s what was asked for.
>
> Where does this inefficiency come from? I haven=92t done any extensive=20
> profiling analysis, but my educated guesses are from two places: virtual=
=20
> function overhead and an interface that does too much.
>
> ostringstream is supposed to be able to be used as an ostream for=20
> runtime-polymorphism. But here=92s where the C++ maxim comes into play.=
=20
> Runtime-polymorphism is not being used here. Every function call should=
=20
> be able to be statically dispatched. And it is, but all of the virtual=20
> machinery comes from *within* ostringstream.
>
> This problem seems to come mostly from the fact that basic_ostream, which=
=20
> does most of the leg-work for ostringstream, has no specific knowledge of=
=20
> its stream type. Therefore it's always a virtual call. And it may be doin=
g=20
> many such virtual calls.
>
> You can achieve the same runtime polymorphism (being able to overload=20
> operator<< for any stream) by using a static set of stream classes, tight=
ly=20
> coupled to their specific streambufs, and a single =93anystream=94 type t=
hat=20
> those streams can be converted into. It would use std::function-style typ=
e=20
> erasure to remember the original type and feed function calls to it. It=
=20
> would use a single function call to initiate each write operation, rather=
=20
> than what appears to be many virtual calls within each write.
>
> Then, there=92s the fact that streambuf itself is overdesigned. stringbuf=
=20
> ought to be a simple interface wrapper around a std::string, but it=92s n=
ot.=20
> It=92s a complex thing. It has locale support of all things. Why? Isn=92t=
=20
> that something that should be handled at the stream level?
>
> This API has no way to get a low-level interface to a=20
> file/string/whatever. There=92s no way to just open a filebuf and blast t=
he=20
> file into some memory, or to shove some memory out of a filebuf. It will=
=20
> always employ the locale machinery even if you didn=92t ask for it. It wi=
ll=20
> always make these internal virtual calls, even if they are completely=20
> statically dispatched.
>
> With iostreams, you are paying for a lot of stuff that you don=92t=20
> frequently use. At the stream level, it makes sense that you=92re paying =
for=20
> certain machinery (though again, some way to say that you=92re not using =
some=20
> of it would be nice). At the buffer level, it does not, since that is the=
=20
> lowest level you=92re allowed to use.
>
> Utility
> While performance is the big issue, it=92s not the only one.
>
> The biggest selling point for iostreams is the ability to extend its=20
> formatted writing functionality. You can overload operator<< for various=
=20
> types and simply use them. You can=92t do that with fprintf. And thanks t=
o=20
> ADL, it will work just fine for classes in namespaces. You can create new=
=20
> streambuf types and even streams if you like. All relatively easily.
>
> Here=92s the problem, and it is admittedly one that is subjective: printf=
 is=20
> really nice syntax.
>
> It=92s very compact, for one. Once you understand the basic syntax of it,=
=20
> it=92s very easy to see what=92s going on. Especially for complex formatt=
ing.=20
> Just consider the physical size difference between these two:
>
> snprintf(..., =930x%08x=94, integer);
>
>  stream << "0x" << std::right << std::hex << std::setw(8) << iVal << std:=
:endl;
>
>  It may take a bit longer to become used to the printf version, but this=
=20
> is something you can easily look up in a reference.
>
> Plus, it makes it much easier to do translations on formatted strings. Yo=
u=20
> can look the pattern string up in a table that changes from language to=
=20
> language. This is rather more difficult in iostreams, though not=20
> impossible. Granted, pattern changes may not be enough, as some languages=
=20
> have different subject/verb/object grammars that would require reshufflin=
g=20
> patterns around. However, there are printf-style systems that do allow fo=
r=20
> reshuffling, whereas no such mechanism exists for iostream-style.
>
> C++ used the << method because the alternatives were less flexible.=20
> Boost.Format and other systems show that C++03 did not really have to use=
=20
> this mechanism to achieve the extensibility features that iostreams provi=
de.
>
> What do you think? Are there other issues in iostreams that need to be=20
> mentioned?
> =20

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_2125_17884145.1389548644039
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I have used iostreams in C++ since I was a beginner progra=
mmer and even now am using it in commercial projects.&nbsp; I agree with ma=
ny of the sentiments expressed in the original post, particularly regarding=
 performance.&nbsp; The main problem as I see it (and there seems to be som=
e agreement in the posts above) is that iostreams attempts to do too much -=
 it is doing I/O and formatting and localisation all in one package.&nbsp; =
In a way, for beginners, this is great, but the mechanics of the interface =
and interdependencies that this introduces makes deviation from simple use =
a daunting task.&nbsp; Even now, 15 years on from my first C++ program, I'm=
 "frightened" of cajoling iostreams to do anything complicated.<br><br>That=
 said, it is all very well to complain and compile a list of grievances, bu=
t we need a) some solutions and b) a sample implementation of the same.&nbs=
p; I think the answer in a new library would be to take the functionality o=
f iostreams and split it up, so that you have something like:<br><ul><li>st=
reams classes that are sources and/or sinks - these conceptually simply str=
eam byte data from one place to another.&nbsp; So a file stream would simpl=
y take in the data provided and write out the data into the file, a string =
stream would do the same but store it in a string, etc.&nbsp; As now, you'd=
 have separate classes relating to different source/sink types.&nbsp; These=
 would all inherit from a single base class, largely to account for the use=
 case where one may wish to store pointers to multiple streams of different=
 types in a container to loop over during processing.</li><li>More string f=
ormatting functions.&nbsp; C++11 extended the &lt;string&gt; header to incl=
ude conversions from most primitives into a string/wstring, but further for=
matting functions could be included by default - these would&nbsp; need to =
be written for unicode types as well, I suspect.&nbsp; I'm not sure exactly=
 how to start with the list of functionality required to replicate what one=
 can achieve with iostreams, but perhaps other can offer guidance.<br></li>=
</ul><p>Other aspects such as Unicode/Localisation should be dealt with by =
other libraries - it doesn't seem like it should be the purpose of a stream=
 to do this, and not every user of the streaming library should have to pay=
 the cost by default, as at present.&nbsp; It seems perverse at the moment =
that one can improve the performance of iostreams only by introducing more =
complex code - the inverse of the more typical equation where more code =3D=
&gt; more functionality.</p><p>If we can pin down/agree a more suitable int=
erface, I'm certainly happy to help provide a sample implementation for tes=
ting and improvement.&nbsp; My ideas above can be discarded if they are not=
 appropriate - I'm not wedded to them, but I thought they might provide a h=
ook for criticism!<br></p>On Saturday, November 17, 2012 7:36:37 PM UTC, Ni=
col Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
 =20

   =20
 =20
  <div bgcolor=3D"#FFFFFF" text=3D"#000000">
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">The Iostreams
      library in C++ has a problem. We have real, reasonable, legitimate
      C++ professional, who like C++ and use modern C++ idioms, telling
      people to not use iostreams. This is not due to differing ideas on
      C++ or C-in-classes-style development, but the simple practical
      realities of the situation.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">This

      kind of thing is indicative of a real problem in iostreams. In
      order to eventually solve that problem, we must first identify
      exactly what the problems are. This discussion should be focused
      on exactly that: identifying the problems with the library. Once
      we know what the real problems are, we can be certain that any new
      system that is proposed addresses them.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Note
      that this is about problems </span><span style=3D"font-size:15px;font=
-family:Arial;color:#000000;background-color:transparent;font-weight:normal=
;font-style:italic;font-variant:normal;text-decoration:none;vertical-align:=
baseline">within</span><span style=3D"font-size:15px;font-family:Arial;colo=
r:#000000;background-color:transparent;font-weight:normal;font-style:normal=
;font-variant:normal;text-decoration:none;vertical-align:baseline">
      iostreams. This is not about a list of things you <i>wish</i> it
      could do. This is about what iostreams actually tries to do but
      fails at in some way. So stuff like async file IO doesn=92t go here,
      since iostreams doesn=92t try to provide that.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Feel

      free to add to this list other flaws you see in iostreams. Or if
      you think that some of them are not real flaws, feel free to
      explain why.</span><br>
    <p dir=3D"ltr"><span style=3D"font-size:32px;font-family:Georgia;color:=
#666666;background-color:transparent;font-weight:normal;font-style:italic;f=
ont-variant:normal;text-decoration:none;vertical-align:baseline">Performanc=
e</span></p>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">This
      is the big one, generally the #1 reason why people suggest using
      C-standard file IO rather than iostreams.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Oftentimes,

      when people defend iostreams performance, they will say something
      to the effect of, =93iostreams does far more than C-standard file
      IO.=94 And that=92s true. With iostreams, you have an extensible
      mechanism for writing any type directly to a stream. You can
      =93easily=94 write new streambuf=92s that will allow you to (via runt=
ime
      polymorphism) be able to work with existing code, thus allowing
      you to leverage your file IO for other forms of IO. You could even
      use a network pipe as an input or output stream.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">There=92s

      one real problem with this logic, and it is exactly why people
      suggest C-standard file IO. Iostreams violates a fundamental
      precept of C++: pay <i>only</i> for what you </span><span style=3D"fo=
nt-size:15px;font-family:Arial;color:#000000;background-color:transparent;f=
ont-weight:normal;font-style:italic;font-variant:normal;text-decoration:non=
e;vertical-align:baseline">use</span><span style=3D"font-size:15px;font-fam=
ily:Arial;color:#000000;background-color:transparent;font-weight:normal;fon=
t-style:normal;font-variant:normal;text-decoration:none;vertical-align:base=
line">.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Consider
    </span><a href=3D"http://stackoverflow.com/questions/4340396/does-the-c=
-standard-mandate-poor-performance-for-iostreams-or-am-i-just-deali" target=
=3D"_blank" onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fstackoverflow.com%2Fquestions%2F4340396%2Fdoes-the-c-standard-manda=
te-poor-performance-for-iostreams-or-am-i-just-deali\46sa\75D\46sntz\0751\4=
6usg\75AFQjCNFGm4Xsoek6kyzy5OpZ33R9EM5ShA';return true;" onclick=3D"this.hr=
ef=3D'http://www.google.com/url?q\75http%3A%2F%2Fstackoverflow.com%2Fquesti=
ons%2F4340396%2Fdoes-the-c-standard-mandate-poor-performance-for-iostreams-=
or-am-i-just-deali\46sa\75D\46sntz\0751\46usg\75AFQjCNFGm4Xsoek6kyzy5OpZ33R=
9EM5ShA';return true;"><span style=3D"font-size:15px;font-family:Arial;colo=
r:#1155cc;background-color:transparent;font-weight:normal;font-style:normal=
;font-variant:normal;text-decoration:underline;vertical-align:baseline">thi=
s
        suite of benchmarks</span></a><span style=3D"font-size:15px;font-fa=
mily:Arial;color:#000000;background-color:transparent;font-weight:normal;fo=
nt-style:normal;font-variant:normal;text-decoration:none;vertical-align:bas=
eline">.
      This code doesn=92t do file IO; it writes directly to a string. All
      it=92s doing is measuring the time it takes to append 4-characters
      to a string. A lot. It uses a `char[]` as a useful control. It
      also tests the use of `vector&lt;char&gt;` (presumably
      `basic_string` would have similar results). Therefore, this is a
      solid test for the efficiency of the iostreams codebase itself.</span=
><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Obviously
      there will be some efficiency loss. But consider the numbers in
      the results.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">The
      ostringstream is more than </span><span style=3D"font-size:15px;font-=
family:Arial;color:#000000;background-color:transparent;font-weight:normal;=
font-style:italic;font-variant:normal;text-decoration:none;vertical-align:b=
aseline">full
      order of magnitude</span><span style=3D"font-size:15px;font-family:Ar=
ial;color:#000000;background-color:transparent;font-weight:normal;font-styl=
e:normal;font-variant:normal;text-decoration:none;vertical-align:baseline">
      slower than the control. It=92s almost 100x in some cases. Note that
      it=92s not using &lt;&lt; to write to the stream; it=92s using
      `ostream::write()`.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Note

      that the vector&lt;char&gt; implementations are fairly comparable
      to the control, usually being around 1x-4x the speed. So clearly
      this is something in ostringstream.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Now,

      you might say that one could use the stringbuf directly. And that
      was done. While it does improve performance over the ostringstream
      case substantially (generally half to a quarter the performance),
      it=92s still over 10x slower than the control or most
      vector&lt;char&gt; implementations.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Why?
      The stringbuf operations ought to be a thin wrapper over
      std::string. After all, that=92s what was asked for.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Where

      does this inefficiency come from? I haven=92t done any extensive
      profiling analysis, but my educated guesses are from two places:
      virtual function overhead and an interface that does too much.</span>=
<br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">ostringstream

      is supposed to be able to be used as an ostream for
      runtime-polymorphism. But here=92s where the C++ maxim comes into
      play. Runtime-polymorphism is </span><span style=3D"font-size:15px;fo=
nt-family:Arial;color:#000000;background-color:transparent;font-weight:norm=
al;font-style:italic;font-variant:normal;text-decoration:none;vertical-alig=
n:baseline">not
      being used here</span><span style=3D"font-size:15px;font-family:Arial=
;color:#000000;background-color:transparent;font-weight:normal;font-style:n=
ormal;font-variant:normal;text-decoration:none;vertical-align:baseline">.
      Every function call should be able to be statically dispatched.
      And it is, but all of the virtual machinery comes from <i>within</i>
      ostringstream.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">This
      problem seems to come mostly from the fact that basic_ostream,
      which does most of the leg-work for ostringstream, has no specific
      knowledge of its stream type. Therefore it's always a virtual
      call. And it may be doing many such virtual calls.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">You

      can achieve the same runtime polymorphism (being able to overload
      operator&lt;&lt; for any stream) by using a static set of stream
      classes, tightly coupled to their specific streambufs, and a
      single =93anystream=94 type that those streams can be converted into.
      It would use std::function-style type erasure to remember the
      original type and feed function calls to it. It would use a single
      function call to initiate each write operation, rather than what
      appears to be many virtual calls within each write.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Then,

      there=92s the fact that streambuf itself is overdesigned. stringbuf
      ought to be a simple interface wrapper around a std::string, but
      it=92s not. It=92s a complex thing. It has </span><span style=3D"font=
-size:15px;font-family:Arial;color:#000000;background-color:transparent;fon=
t-weight:normal;font-style:italic;font-variant:normal;text-decoration:none;=
vertical-align:baseline">locale
      support</span><span style=3D"font-size:15px;font-family:Arial;color:#=
000000;background-color:transparent;font-weight:normal;font-style:normal;fo=
nt-variant:normal;text-decoration:none;vertical-align:baseline">
      of all things. Why? Isn=92t that something that should be handled at
      the stream level?</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">This

      API has no way to get a low-level interface to a
      file/string/whatever. There=92s no way to just open a filebuf and
      blast the file into some memory, or to shove some memory out of a
      filebuf. It will always employ the locale machinery even if you
      didn=92t ask for it. It will always make these internal virtual
      calls, even if they are completely statically dispatched.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">With

      iostreams, you are paying for a lot of stuff that you don=92t
      frequently use. At the stream level, it makes sense that you=92re
      paying for certain machinery (though again, some way to say that
      you=92re not using some of it would be nice). At the buffer level,
      it does not, since that is the lowest level you=92re allowed to use.<=
/span><br>
    <p dir=3D"ltr"><span style=3D"font-size:32px;font-family:Georgia;color:=
#666666;background-color:transparent;font-weight:normal;font-style:italic;f=
ont-variant:normal;text-decoration:none;vertical-align:baseline">Utility</s=
pan></p>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">While
      performance is the big issue, it=92s not the only one.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">The

      biggest selling point for iostreams is the ability to extend its
      formatted writing functionality. You can overload operator&lt;&lt;
      for various types and simply use them. You can=92t do that with
      fprintf. And thanks to ADL, it will work just fine for classes in
      namespaces. You can create new streambuf types and even streams if
      you like. All relatively easily.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Here=92s
      the problem, and it is admittedly one that is subjective: printf
      is really nice syntax.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">It=92s

      very compact, for one. Once you understand the basic syntax of it,
      it=92s very easy to see what=92s going on. Especially for complex
      formatting. Just consider the physical size difference between
      these two:</span><br>
    <pre><tt><span style=3D"font-size:15px;color:rgb(0,0,0);background-colo=
r:transparent;font-weight:normal;font-style:normal;font-variant:normal;text=
-decoration:none;vertical-align:baseline">snprintf(..., =930x%08x=94, integ=
er);</span></tt></pre>
    <pre><tt><span style=3D"font-size:15px;color:rgb(0,0,0);background-colo=
r:transparent;font-weight:normal;font-style:normal;font-variant:normal;text=
-decoration:none;vertical-align:baseline"></span></tt></pre>
    <pre><tt><span style=3D"font-size:15px;color:rgb(0,0,0);background-colo=
r:transparent;font-weight:normal;font-style:normal;font-variant:normal;text=
-decoration:none;vertical-align:baseline">stream &lt;&lt; "0x" &lt;&lt; std=
::right &lt;&lt; std::hex &lt;&lt; std::setw(8) &lt;&lt; iVal &lt;&lt; std:=
:endl;</span></tt></pre>
    <pre><span style=3D"font-size:15px;font-family:Arial;color:#000000;back=
ground-color:transparent;font-weight:normal;font-style:normal;font-variant:=
normal;text-decoration:none;vertical-align:baseline"></span></pre>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">It
      may take a bit longer to become used to the printf version, but
      this is something you can easily look up in a reference.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">Plus,

      it makes it much easier to do translations on formatted strings.
      You can look the pattern string up in a table that changes from
      language to language. This is rather more difficult in iostreams,
      though not impossible. Granted, pattern changes may not be enough,
      as some languages have different subject/verb/object grammars that
      would require reshuffling patterns around. However, there are
      printf-style systems that do allow for reshuffling, whereas no
      such mechanism exists for iostream-style.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline">C++

      used the &lt;&lt; method because the alternatives were less
      flexible. Boost.Format and other systems show that C++03 did not
      really have to use this mechanism to achieve the extensibility
      features that iostreams provide.</span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><br>
    <span style=3D"font-size:15px;font-family:Arial;color:#000000;backgroun=
d-color:transparent;font-weight:normal;font-style:normal;font-variant:norma=
l;text-decoration:none;vertical-align:baseline"></span><span style=3D"font-=
size:15px;font-family:Arial;color:#000000;background-color:transparent;font=
-weight:normal;font-style:normal;font-variant:normal;text-decoration:none;v=
ertical-align:baseline">What
      do you think? Are there other issues in iostreams that need to be
      mentioned?</span><br>
  </div>

</blockquote></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_2125_17884145.1389548644039--

.


Author: wsdwsd <euloanty@live.com>
Date: Mon, 13 Jan 2014 04:50:13 +0000
Raw View
--_5D7AAC03-FA37-4270-B9E6-ACA7D783C76A_
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8

I agree with you. I have make a simple ifstream for a sample and I have fou=
nd a way to deal with iomanip. If you need, please email me.






Sent from Windows Mail





From: fritzpoll
Sent: =E2=80=8EMonday=E2=80=8E, =E2=80=8EJanuary=E2=80=8E =E2=80=8E13=E2=80=
=8E, =E2=80=8E2014 =E2=80=8E1=E2=80=8E:=E2=80=8E44=E2=80=8E =E2=80=8EAM
To: std-proposals@isocpp.org





I have used iostreams in C++ since I was a beginner programmer and even now=
 am using it in commercial projects.  I agree with many of the sentiments e=
xpressed in the original post, particularly regarding performance.  The mai=
n problem as I see it (and there seems to be some agreement in the posts ab=
ove) is that iostreams attempts to do too much - it is doing I/O and format=
ting and localisation all in one package.  In a way, for beginners, this is=
 great, but the mechanics of the interface and interdependencies that this =
introduces makes deviation from simple use a daunting task.  Even now, 15 y=
ears on from my first C++ program, I'm "frightened" of cajoling iostreams t=
o do anything complicated.

That said, it is all very well to complain and compile a list of grievances=
, but we need a) some solutions and b) a sample implementation of the same.=
  I think the answer in a new library would be to take the functionality of=
 iostreams and split it up, so that you have something like:
streams classes that are sources and/or sinks - these conceptually simply s=
tream byte data from one place to another.  So a file stream would simply t=
ake in the data provided and write out the data into the file, a string str=
eam would do the same but store it in a string, etc.  As now, you'd have se=
parate classes relating to different source/sink types.  These would all in=
herit from a single base class, largely to account for the use case where o=
ne may wish to store pointers to multiple streams of different types in a c=
ontainer to loop over during processing.
More string formatting functions.  C++11 extended the <string> header to in=
clude conversions from most primitives into a string/wstring, but further f=
ormatting functions could be included by default - these would  need to be =
written for unicode types as well, I suspect.  I'm not sure exactly how to =
start with the list of functionality required to replicate what one can ach=
ieve with iostreams, but perhaps other can offer guidance.


Other aspects such as Unicode/Localisation should be dealt with by other li=
braries - it doesn't seem like it should be the purpose of a stream to do t=
his, and not every user of the streaming library should have to pay the cos=
t by default, as at present.  It seems perverse at the moment that one can =
improve the performance of iostreams only by introducing more complex code =
- the inverse of the more typical equation where more code =3D> more functi=
onality.

If we can pin down/agree a more suitable interface, I'm certainly happy to =
help provide a sample implementation for testing and improvement.  My ideas=
 above can be discarded if they are not appropriate - I'm not wedded to the=
m, but I thought they might provide a hook for criticism!

On Saturday, November 17, 2012 7:36:37 PM UTC, Nicol Bolas wrote:

The Iostreams library in C++ has a problem. We have real, reasonable, legit=
imate C++ professional, who like C++ and use modern C++ idioms, telling peo=
ple to not use iostreams. This is not due to differing ideas on C++ or C-in=
-classes-style development, but the simple practical realities of the situa=
tion.

This kind of thing is indicative of a real problem in iostreams. In order t=
o eventually solve that problem, we must first identify exactly what the pr=
oblems are. This discussion should be focused on exactly that: identifying =
the problems with the library. Once we know what the real problems are, we =
can be certain that any new system that is proposed addresses them.

Note that this is about problems within iostreams. This is not about a list=
 of things you wish it could do. This is about what iostreams actually trie=
s to do but fails at in some way. So stuff like async file IO doesn=E2=80=
=99t go here, since iostreams doesn=E2=80=99t try to provide that.

Feel free to add to this list other flaws you see in iostreams. Or if you t=
hink that some of them are not real flaws, feel free to explain why.

Performance
This is the big one, generally the #1 reason why people suggest using C-sta=
ndard file IO rather than iostreams.

Oftentimes, when people defend iostreams performance, they will say somethi=
ng to the effect of, =E2=80=9Ciostreams does far more than C-standard file =
IO.=E2=80=9D And that=E2=80=99s true. With iostreams, you have an extensibl=
e mechanism for writing any type directly to a stream. You can =E2=80=9Ceas=
ily=E2=80=9D write new streambuf=E2=80=99s that will allow you to (via runt=
ime polymorphism) be able to work with existing code, thus allowing you to =
leverage your file IO for other forms of IO. You could even use a network p=
ipe as an input or output stream.

There=E2=80=99s one real problem with this logic, and it is exactly why peo=
ple suggest C-standard file IO. Iostreams violates a fundamental precept of=
 C++: pay only for what you use.

Consider this suite of benchmarks. This code doesn=E2=80=99t do file IO; it=
 writes directly to a string. All it=E2=80=99s doing is measuring the time =
it takes to append 4-characters to a string. A lot. It uses a `char[]` as a=
 useful control. It also tests the use of `vector<char>` (presumably `basic=
_string` would have similar results). Therefore, this is a solid test for t=
he efficiency of the iostreams codebase itself.

Obviously there will be some efficiency loss. But consider the numbers in t=
he results.

The ostringstream is more than full order of magnitude slower than the cont=
rol. It=E2=80=99s almost 100x in some cases. Note that it=E2=80=99s not usi=
ng << to write to the stream; it=E2=80=99s using `ostream::write()`.

Note that the vector<char> implementations are fairly comparable to the con=
trol, usually being around 1x-4x the speed. So clearly this is something in=
 ostringstream.

Now, you might say that one could use the stringbuf directly. And that was =
done. While it does improve performance over the ostringstream case substan=
tially (generally half to a quarter the performance), it=E2=80=99s still ov=
er 10x slower than the control or most vector<char> implementations.

Why? The stringbuf operations ought to be a thin wrapper over std::string. =
After all, that=E2=80=99s what was asked for.

Where does this inefficiency come from? I haven=E2=80=99t done any extensiv=
e profiling analysis, but my educated guesses are from two places: virtual =
function overhead and an interface that does too much.

ostringstream is supposed to be able to be used as an ostream for runtime-p=
olymorphism. But here=E2=80=99s where the C++ maxim comes into play. Runtim=
e-polymorphism is not being used here. Every function call should be able t=
o be statically dispatched. And it is, but all of the virtual machinery com=
es from within ostringstream.

This problem seems to come mostly from the fact that basic_ostream, which d=
oes most of the leg-work for ostringstream, has no specific knowledge of it=
s stream type. Therefore it's always a virtual call. And it may be doing ma=
ny such virtual calls.

You can achieve the same runtime polymorphism (being able to overload opera=
tor<< for any stream) by using a static set of stream classes, tightly coup=
led to their specific streambufs, and a single =E2=80=9Canystream=E2=80=9D =
type that those streams can be converted into. It would use std::function-s=
tyle type erasure to remember the original type and feed function calls to =
it. It would use a single function call to initiate each write operation, r=
ather than what appears to be many virtual calls within each write.

Then, there=E2=80=99s the fact that streambuf itself is overdesigned. strin=
gbuf ought to be a simple interface wrapper around a std::string, but it=E2=
=80=99s not. It=E2=80=99s a complex thing. It has locale support of all thi=
ngs. Why? Isn=E2=80=99t that something that should be handled at the stream=
 level?

This API has no way to get a low-level interface to a file/string/whatever.=
 There=E2=80=99s no way to just open a filebuf and blast the file into some=
 memory, or to shove some memory out of a filebuf. It will always employ th=
e locale machinery even if you didn=E2=80=99t ask for it. It will always ma=
ke these internal virtual calls, even if they are completely statically dis=
patched.

With iostreams, you are paying for a lot of stuff that you don=E2=80=99t fr=
equently use. At the stream level, it makes sense that you=E2=80=99re payin=
g for certain machinery (though again, some way to say that you=E2=80=99re =
not using some of it would be nice). At the buffer level, it does not, sinc=
e that is the lowest level you=E2=80=99re allowed to use.

Utility
While performance is the big issue, it=E2=80=99s not the only one.

The biggest selling point for iostreams is the ability to extend its format=
ted writing functionality. You can overload operator<< for various types an=
d simply use them. You can=E2=80=99t do that with fprintf. And thanks to AD=
L, it will work just fine for classes in namespaces. You can create new str=
eambuf types and even streams if you like. All relatively easily.

Here=E2=80=99s the problem, and it is admittedly one that is subjective: pr=
intf is really nice syntax.

It=E2=80=99s very compact, for one. Once you understand the basic syntax of=
 it, it=E2=80=99s very easy to see what=E2=80=99s going on. Especially for =
complex formatting. Just consider the physical size difference between thes=
e two:
snprintf(..., =E2=80=9C0x%08x=E2=80=9D, integer);

stream << "0x" << std::right << std::hex << std::setw(8) << iVal << std::en=
dl;

It may take a bit longer to become used to the printf version, but this is =
something you can easily look up in a reference.

Plus, it makes it much easier to do translations on formatted strings. You =
can look the pattern string up in a table that changes from language to lan=
guage. This is rather more difficult in iostreams, though not impossible. G=
ranted, pattern changes may not be enough, as some languages have different=
 subject/verb/object grammars that would require reshuffling patterns aroun=
d. However, there are printf-style systems that do allow for reshuffling, w=
hereas no such mechanism exists for iostream-style.

C++ used the << method because the alternatives were less flexible. Boost.F=
ormat and other systems show that C++03 did not really have to use this mec=
hanism to achieve the extensibility features that iostreams provide.

What do you think? Are there other issues in iostreams that need to be ment=
ioned?

--=20
=20
---=20
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this topic, visit https://groups.google.com/a/isocpp.or=
g/d/topic/std-proposals/bMzBAHgb5_o/unsubscribe.
To unsubscribe from this group and all its topics, send an email to std-pro=
posals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--_5D7AAC03-FA37-4270-B9E6-ACA7D783C76A_
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8


<html>
<head>
<meta name=3D"generator" content=3D"Windows Mail 17.5.9600.20315">
<style data-externalstyle=3D"true"><!--
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph {
margin-top:0in;
margin-right:0in;
margin-bottom:0in;
margin-left:.5in;
margin-bottom:.0001pt;
}
p.MsoNormal, li.MsoNormal, div.MsoNormal {
margin:0in;
margin-bottom:.0001pt;
}
p.MsoListParagraphCxSpFirst, li.MsoListParagraphCxSpFirst, div.MsoListParag=
raphCxSpFirst,=20
p.MsoListParagraphCxSpMiddle, li.MsoListParagraphCxSpMiddle, div.MsoListPar=
agraphCxSpMiddle,=20
p.MsoListParagraphCxSpLast, li.MsoListParagraphCxSpLast, div.MsoListParagra=
phCxSpLast {
margin-top:0in;
margin-right:0in;
margin-bottom:0in;
margin-left:.5in;
margin-bottom:.0001pt;
line-height:115%;
}
--></style></head>
<body dir=3D"ltr">
<div data-externalstyle=3D"false" dir=3D"ltr" style=3D"font-family: 'Calibr=
i', 'Microsoft YaHei UI', 'Segoe UI', 'Meiryo', 'Microsoft JhengHei UI', 'M=
algun Gothic', 'sans-serif';font-size:12pt;"><div style=3D"color: rgb(0, 0,=
 0);">I agree with&nbsp;you. I have make a simple ifstream for a sample and=
 I have found a way to deal with&nbsp;iomanip. If you need, please email me=
..<br></div><div style=3D"color: rgb(0, 0, 0);" data-signatureblock=3D"true"=
><div style=3D"color: rgb(0, 0, 0);"><br></div><div style=3D"color: rgb(0, =
0, 0);">Sent from Windows Mail</div><div style=3D"color: rgb(0, 0, 0);"><br=
></div></div><div style=3D"padding-top: 5px; border-top-color: rgb(229, 229=
, 229); border-top-width: 1px; border-top-style: solid;"><div><font face=3D=
" 'Calibri', 'Microsoft YaHei UI', 'Segoe UI', 'Meiryo', 'Microsoft JhengHe=
i UI', 'Malgun Gothic', 'sans-serif'" style=3D'line-height: 15pt; letter-sp=
acing: 0.02em; font-family: "Calibri", "Microsoft YaHei UI", "Segoe UI", "M=
eiryo", "Microsoft JhengHei UI", "Malgun Gothic", "sans-serif"; font-size: =
12pt;'><b>From:</b>&nbsp;<a href=3D"mailto:fred.pollard@gmail.com" target=
=3D"_parent">fritzpoll</a><br><b>Sent:</b>&nbsp;=E2=80=8EMonday=E2=80=8E, =
=E2=80=8EJanuary=E2=80=8E =E2=80=8E13=E2=80=8E, =E2=80=8E2014 =E2=80=8E1=E2=
=80=8E:=E2=80=8E44=E2=80=8E =E2=80=8EAM<br><b>To:</b>&nbsp;<a href=3D"mailt=
o:std-proposals@isocpp.org" target=3D"_parent">std-proposals@isocpp.org</a>=
</font></div></div><div><br></div><div dir=3D""><div dir=3D"ltr">I have use=
d iostreams in C++ since I was a beginner programmer and even now am using =
it in commercial projects.&nbsp; I agree with many of the sentiments expres=
sed in the original post, particularly regarding performance.&nbsp; The mai=
n problem as I see it (and there seems to be some agreement in the posts ab=
ove) is that iostreams attempts to do too much - it is doing I/O and format=
ting and localisation all in one package.&nbsp; In a way, for beginners, th=
is is great, but the mechanics of the interface and interdependencies that =
this introduces makes deviation from simple use a daunting task.&nbsp; Even=
 now, 15 years on from my first C++ program, I'm "frightened" of cajoling i=
ostreams to do anything complicated.<br><br>That said, it is all very well =
to complain and compile a list of grievances, but we need a) some solutions=
 and b) a sample implementation of the same.&nbsp; I think the answer in a =
new library would be to take the functionality of iostreams and split it up=
, so that you have something like:<br><ul style=3D"padding-top: 0px; paddin=
g-bottom: 0px; margin-top: 0px; margin-bottom: 0px; list-style-type: disc;"=
><li>streams classes that are sources and/or sinks - these conceptually sim=
ply stream byte data from one place to another.&nbsp; So a file stream woul=
d simply take in the data provided and write out the data into the file, a =
string stream would do the same but store it in a string, etc.&nbsp; As now=
, you'd have separate classes relating to different source/sink types.&nbsp=
; These would all inherit from a single base class, largely to account for =
the use case where one may wish to store pointers to multiple streams of di=
fferent types in a container to loop over during processing.</li><li>More s=
tring formatting functions.&nbsp; C++11 extended the &lt;string&gt; header =
to include conversions from most primitives into a string/wstring, but furt=
her formatting functions could be included by default - these would&nbsp; n=
eed to be written for unicode types as well, I suspect.&nbsp; I'm not sure =
exactly how to start with the list of functionality required to replicate w=
hat one can achieve with iostreams, but perhaps other can offer guidance.<b=
r></li></ul><p>Other aspects such as Unicode/Localisation should be dealt w=
ith by other libraries - it doesn't seem like it should be the purpose of a=
 stream to do this, and not every user of the streaming library should have=
 to pay the cost by default, as at present.&nbsp; It seems perverse at the =
moment that one can improve the performance of iostreams only by introducin=
g more complex code - the inverse of the more typical equation where more c=
ode =3D&gt; more functionality.</p><p>If we can pin down/agree a more suita=
ble interface, I'm certainly happy to help provide a sample implementation =
for testing and improvement.&nbsp; My ideas above can be discarded if they =
are not appropriate - I'm not wedded to them, but I thought they might prov=
ide a hook for criticism!<br></p>On Saturday, November 17, 2012 7:36:37 PM =
UTC, Nicol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204);=
 border-left-width: 1px; border-left-style: solid;">
 =20

   =20
 =20
  <div>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">The =
Iostreams
      library in C++ has a problem. We have real, reasonable, legitimate
      C++ professional, who like C++ and use modern C++ idioms, telling
      people to not use iostreams. This is not due to differing ideas on
      C++ or C-in-classes-style development, but the simple practical
      realities of the situation.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">This

      kind of thing is indicative of a real problem in iostreams. In
      order to eventually solve that problem, we must first identify
      exactly what the problems are. This discussion should be focused
      on exactly that: identifying the problems with the library. Once
      we know what the real problems are, we can be certain that any new
      system that is proposed addresses them.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Note
      that this is about problems </span><span style=3D"color: rgb(0, 0, 0)=
; font-family: Arial; font-size: 15px; font-style: italic; font-variant: no=
rmal; font-weight: normal; text-decoration: none; vertical-align: baseline;=
 background-color: transparent;">within</span><span style=3D"color: rgb(0, =
0, 0); font-family: Arial; font-size: 15px; font-style: normal; font-varian=
t: normal; font-weight: normal; text-decoration: none; vertical-align: base=
line; background-color: transparent;">
      iostreams. This is not about a list of things you <i>wish</i> it
      could do. This is about what iostreams actually tries to do but
      fails at in some way. So stuff like async file IO doesn=E2=80=99t go =
here,
      since iostreams doesn=E2=80=99t try to provide that.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Feel

      free to add to this list other flaws you see in iostreams. Or if
      you think that some of them are not real flaws, feel free to
      explain why.</span><br>
    <p dir=3D"ltr"><span style=3D"color: rgb(102, 102, 102); font-family: G=
eorgia; font-size: 32px; font-style: italic; font-variant: normal; font-wei=
ght: normal; text-decoration: none; vertical-align: baseline; background-co=
lor: transparent;">Performance</span></p>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">This
      is the big one, generally the #1 reason why people suggest using
      C-standard file IO rather than iostreams.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Ofte=
ntimes,

      when people defend iostreams performance, they will say something
      to the effect of, =E2=80=9Ciostreams does far more than C-standard fi=
le
      IO.=E2=80=9D And that=E2=80=99s true. With iostreams, you have an ext=
ensible
      mechanism for writing any type directly to a stream. You can
      =E2=80=9Ceasily=E2=80=9D write new streambuf=E2=80=99s that will allo=
w you to (via runtime
      polymorphism) be able to work with existing code, thus allowing
      you to leverage your file IO for other forms of IO. You could even
      use a network pipe as an input or output stream.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Ther=
e=E2=80=99s

      one real problem with this logic, and it is exactly why people
      suggest C-standard file IO. Iostreams violates a fundamental
      precept of C++: pay <i>only</i> for what you </span><span style=3D"co=
lor: rgb(0, 0, 0); font-family: Arial; font-size: 15px; font-style: italic;=
 font-variant: normal; font-weight: normal; text-decoration: none; vertical=
-align: baseline; background-color: transparent;">use</span><span style=3D"=
color: rgb(0, 0, 0); font-family: Arial; font-size: 15px; font-style: norma=
l; font-variant: normal; font-weight: normal; text-decoration: none; vertic=
al-align: baseline; background-color: transparent;">.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Cons=
ider
    </span><a href=3D"http://stackoverflow.com/questions/4340396/does-the-c=
-standard-mandate-poor-performance-for-iostreams-or-am-i-just-deali" target=
=3D"_parent"><span style=3D"color: rgb(17, 85, 204); font-family: Arial; fo=
nt-size: 15px; font-style: normal; font-variant: normal; font-weight: norma=
l; text-decoration: underline; vertical-align: baseline; background-color: =
transparent;">this
        suite of benchmarks</span></a><span style=3D"color: rgb(0, 0, 0); f=
ont-family: Arial; font-size: 15px; font-style: normal; font-variant: norma=
l; font-weight: normal; text-decoration: none; vertical-align: baseline; ba=
ckground-color: transparent;">.
      This code doesn=E2=80=99t do file IO; it writes directly to a string.=
 All
      it=E2=80=99s doing is measuring the time it takes to append 4-charact=
ers
      to a string. A lot. It uses a `char[]` as a useful control. It
      also tests the use of `vector&lt;char&gt;` (presumably
      `basic_string` would have similar results). Therefore, this is a
      solid test for the efficiency of the iostreams codebase itself.</span=
><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Obvi=
ously
      there will be some efficiency loss. But consider the numbers in
      the results.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">The
      ostringstream is more than </span><span style=3D"color: rgb(0, 0, 0);=
 font-family: Arial; font-size: 15px; font-style: italic; font-variant: nor=
mal; font-weight: normal; text-decoration: none; vertical-align: baseline; =
background-color: transparent;">full
      order of magnitude</span><span style=3D"color: rgb(0, 0, 0); font-fam=
ily: Arial; font-size: 15px; font-style: normal; font-variant: normal; font=
-weight: normal; text-decoration: none; vertical-align: baseline; backgroun=
d-color: transparent;">
      slower than the control. It=E2=80=99s almost 100x in some cases. Note=
 that
      it=E2=80=99s not using &lt;&lt; to write to the stream; it=E2=80=99s =
using
      `ostream::write()`.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Note

      that the vector&lt;char&gt; implementations are fairly comparable
      to the control, usually being around 1x-4x the speed. So clearly
      this is something in ostringstream.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Now,

      you might say that one could use the stringbuf directly. And that
      was done. While it does improve performance over the ostringstream
      case substantially (generally half to a quarter the performance),
      it=E2=80=99s still over 10x slower than the control or most
      vector&lt;char&gt; implementations.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Why?
      The stringbuf operations ought to be a thin wrapper over
      std::string. After all, that=E2=80=99s what was asked for.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Wher=
e

      does this inefficiency come from? I haven=E2=80=99t done any extensiv=
e
      profiling analysis, but my educated guesses are from two places:
      virtual function overhead and an interface that does too much.</span>=
<br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">ostr=
ingstream

      is supposed to be able to be used as an ostream for
      runtime-polymorphism. But here=E2=80=99s where the C++ maxim comes in=
to
      play. Runtime-polymorphism is </span><span style=3D"color: rgb(0, 0, =
0); font-family: Arial; font-size: 15px; font-style: italic; font-variant: =
normal; font-weight: normal; text-decoration: none; vertical-align: baselin=
e; background-color: transparent;">not
      being used here</span><span style=3D"color: rgb(0, 0, 0); font-family=
: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-we=
ight: normal; text-decoration: none; vertical-align: baseline; background-c=
olor: transparent;">.
      Every function call should be able to be statically dispatched.
      And it is, but all of the virtual machinery comes from <i>within</i>
      ostringstream.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">This
      problem seems to come mostly from the fact that basic_ostream,
      which does most of the leg-work for ostringstream, has no specific
      knowledge of its stream type. Therefore it's always a virtual
      call. And it may be doing many such virtual calls.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">You

      can achieve the same runtime polymorphism (being able to overload
      operator&lt;&lt; for any stream) by using a static set of stream
      classes, tightly coupled to their specific streambufs, and a
      single =E2=80=9Canystream=E2=80=9D type that those streams can be con=
verted into.
      It would use std::function-style type erasure to remember the
      original type and feed function calls to it. It would use a single
      function call to initiate each write operation, rather than what
      appears to be many virtual calls within each write.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Then=
,

      there=E2=80=99s the fact that streambuf itself is overdesigned. strin=
gbuf
      ought to be a simple interface wrapper around a std::string, but
      it=E2=80=99s not. It=E2=80=99s a complex thing. It has </span><span s=
tyle=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px; font-styl=
e: italic; font-variant: normal; font-weight: normal; text-decoration: none=
; vertical-align: baseline; background-color: transparent;">locale
      support</span><span style=3D"color: rgb(0, 0, 0); font-family: Arial;=
 font-size: 15px; font-style: normal; font-variant: normal; font-weight: no=
rmal; text-decoration: none; vertical-align: baseline; background-color: tr=
ansparent;">
      of all things. Why? Isn=E2=80=99t that something that should be handl=
ed at
      the stream level?</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">This

      API has no way to get a low-level interface to a
      file/string/whatever. There=E2=80=99s no way to just open a filebuf a=
nd
      blast the file into some memory, or to shove some memory out of a
      filebuf. It will always employ the locale machinery even if you
      didn=E2=80=99t ask for it. It will always make these internal virtual
      calls, even if they are completely statically dispatched.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">With

      iostreams, you are paying for a lot of stuff that you don=E2=80=99t
      frequently use. At the stream level, it makes sense that you=E2=80=99=
re
      paying for certain machinery (though again, some way to say that
      you=E2=80=99re not using some of it would be nice). At the buffer lev=
el,
      it does not, since that is the lowest level you=E2=80=99re allowed to=
 use.</span><br>
    <p dir=3D"ltr"><span style=3D"color: rgb(102, 102, 102); font-family: G=
eorgia; font-size: 32px; font-style: italic; font-variant: normal; font-wei=
ght: normal; text-decoration: none; vertical-align: baseline; background-co=
lor: transparent;">Utility</span></p>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Whil=
e
      performance is the big issue, it=E2=80=99s not the only one.</span><b=
r>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">The

      biggest selling point for iostreams is the ability to extend its
      formatted writing functionality. You can overload operator&lt;&lt;
      for various types and simply use them. You can=E2=80=99t do that with
      fprintf. And thanks to ADL, it will work just fine for classes in
      namespaces. You can create new streambuf types and even streams if
      you like. All relatively easily.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Here=
=E2=80=99s
      the problem, and it is admittedly one that is subjective: printf
      is really nice syntax.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">It=
=E2=80=99s

      very compact, for one. Once you understand the basic syntax of it,
      it=E2=80=99s very easy to see what=E2=80=99s going on. Especially for=
 complex
      formatting. Just consider the physical size difference between
      these two:</span><br>
    <pre><tt><span style=3D"color: rgb(0, 0, 0); font-size: 15px; font-styl=
e: normal; font-variant: normal; font-weight: normal; text-decoration: none=
; vertical-align: baseline; background-color: transparent;">snprintf(..., =
=E2=80=9C0x%08x=E2=80=9D, integer);</span></tt></pre>
    <pre><tt><span style=3D"color: rgb(0, 0, 0); font-size: 15px; font-styl=
e: normal; font-variant: normal; font-weight: normal; text-decoration: none=
; vertical-align: baseline; background-color: transparent;"></span></tt></p=
re>
    <pre><tt><span style=3D"color: rgb(0, 0, 0); font-size: 15px; font-styl=
e: normal; font-variant: normal; font-weight: normal; text-decoration: none=
; vertical-align: baseline; background-color: transparent;">stream &lt;&lt;=
 "0x" &lt;&lt; std::right &lt;&lt; std::hex &lt;&lt; std::setw(8) &lt;&lt; =
iVal &lt;&lt; std::endl;</span></tt></pre>
    <pre><span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size:=
 15px; font-style: normal; font-variant: normal; font-weight: normal; text-=
decoration: none; vertical-align: baseline; background-color: transparent;"=
></span></pre>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">It
      may take a bit longer to become used to the printf version, but
      this is something you can easily look up in a reference.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">Plus=
,

      it makes it much easier to do translations on formatted strings.
      You can look the pattern string up in a table that changes from
      language to language. This is rather more difficult in iostreams,
      though not impossible. Granted, pattern changes may not be enough,
      as some languages have different subject/verb/object grammars that
      would require reshuffling patterns around. However, there are
      printf-style systems that do allow for reshuffling, whereas no
      such mechanism exists for iostream-style.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;">C++

      used the &lt;&lt; method because the alternatives were less
      flexible. Boost.Format and other systems show that C++03 did not
      really have to use this mechanism to achieve the extensibility
      features that iostreams provide.</span><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><br>
    <span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px=
; font-style: normal; font-variant: normal; font-weight: normal; text-decor=
ation: none; vertical-align: baseline; background-color: transparent;"></sp=
an><span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: 15px;=
 font-style: normal; font-variant: normal; font-weight: normal; text-decora=
tion: none; vertical-align: baseline; background-color: transparent;">What
      do you think? Are there other issues in iostreams that need to be
      mentioned?</span><br>
  </div>

</blockquote></div>

<p></p>

-- <br>
&nbsp;<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/bMzBAHgb5_o/unsubscribe" target=3D"_pare=
nt">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/bMzBAHgb5_=
o/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to std-pro=
posals+unsubscribe@isocpp.org.<br>
To post to this group, send email to std-proposals@isocpp.org.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_parent">http://groups.google.com/a/isocpp.org/gr=
oup/std-proposals/</a>.<br>
</div></div>
</body>
</html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--_5D7AAC03-FA37-4270-B9E6-ACA7D783C76A_--

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Mon, 13 Jan 2014 15:29:22 -0800 (PST)
Raw View
------=_Part_769_16151387.1389655762433
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

I like your ideas! In wxWidgets toolkit there has been a layering of low=20
level (typical file read/write functionality) and formatting streams on top=
=20
of these for a long time, which provides some lessons on what to do/not do.

When it comes to formatting I think there is fruitful middle ground between=
=20
printf and operator<< + manipulators, now that we have variadic templates.=
=20
A recent suggestion offered a type safe printf-like formatter but still=20
stuck to the printf formatting system with %<pars><letter> where the letter=
=20
now has to match the type deduced from the template parameter. This is=20
unnecessary redundancy: As the type is known the <letter> part is not=20
necessary! This leaves the <pars> part open for customization for different=
=20
data types, if we can just find out where they end (this is one of the=20
roles of the <letter> part). Here is one possibility:

Each inserted value is written like this: %<name>|<pars>%

The name can be as simple as a digit or (preferrably) more descriptive.=20
<pars> can be anything but some discipline is suggested... The | is omitted=
=20
if there are no pars.

The reason for mandating a name is two-fold: Firstly to still be able to=20
use %% as an escape for a % character. Secondly to allow translation where=
=20
the translated string has the inserts in another order. This is very common=
=20
for instance when translating between English and French. A prerequisite=20
for this to work is that the formatting function has access to both the=20
untranslated and translated strings so it can match the inserts in the=20
original string with the arguments that follow and rearrange them=20
appropriately.

To implement the type specific parameters the formatting function supplies=
=20
the <pars> part as a string_view to an overloaded string to_string(T&,=20
string_view pars). This function is the one to overload for your custom=20
data types, which then can have a completely separate notion of parameters=
=20
from the arithmetic types.

I have implemented this in a real project which has been using this=20
successfully for the last five years or so, but of course there are lots of=
=20
other ways to do this once you notice that the type specifier is no longer=
=20
needed.

BTW: If static members were allowed in lambdas this could be used to parse=
=20
the format string once and for all and implement translation (using an=20
enclosing macro), For some reason static data has been prohibited in=20
lambdas, unfortunately.

Den m=E5ndagen den 13:e januari 2014 kl. 05:50:13 UTC+1 skrev wsdwsd:
>
>  I agree with you. I have make a simple ifstream for a sample and I have=
=20
> found a way to deal with iomanip. If you need, please email me.
>
> Sent from Windows Mail
>
> *From:* fritzpoll <javascript:>
> *Sent:* Monday, January 13, 2014 1:44 AM
> *To:* std-pr...@isocpp.org <javascript:>
>
> I have used iostreams in C++ since I was a beginner programmer and even=
=20
> now am using it in commercial projects.  I agree with many of the=20
> sentiments expressed in the original post, particularly regarding=20
> performance.  The main problem as I see it (and there seems to be some=20
> agreement in the posts above) is that iostreams attempts to do too much -=
=20
> it is doing I/O and formatting and localisation all in one package.  In a=
=20
> way, for beginners, this is great, but the mechanics of the interface and=
=20
> interdependencies that this introduces makes deviation from simple use a=
=20
> daunting task.  Even now, 15 years on from my first C++ program, I'm=20
> "frightened" of cajoling iostreams to do anything complicated.
>
> That said, it is all very well to complain and compile a list of=20
> grievances, but we need a) some solutions and b) a sample implementation =
of=20
> the same.  I think the answer in a new library would be to take the=20
> functionality of iostreams and split it up, so that you have something li=
ke:
>
>    - streams classes that are sources and/or sinks - these conceptually=
=20
>    simply stream byte data from one place to another.  So a file stream w=
ould=20
>    simply take in the data provided and write out the data into the file,=
 a=20
>    string stream would do the same but store it in a string, etc.  As now=
,=20
>    you'd have separate classes relating to different source/sink types.  =
These=20
>    would all inherit from a single base class, largely to account for the=
 use=20
>    case where one may wish to store pointers to multiple streams of diffe=
rent=20
>    types in a container to loop over during processing.
>    - More string formatting functions.  C++11 extended the <string>=20
>    header to include conversions from most primitives into a string/wstri=
ng,=20
>    but further formatting functions could be included by default - these=
=20
>    would  need to be written for unicode types as well, I suspect.  I'm n=
ot=20
>    sure exactly how to start with the list of functionality required to=
=20
>    replicate what one can achieve with iostreams, but perhaps other can o=
ffer=20
>    guidance.
>   =20
> Other aspects such as Unicode/Localisation should be dealt with by other=
=20
> libraries - it doesn't seem like it should be the purpose of a stream to =
do=20
> this, and not every user of the streaming library should have to pay the=
=20
> cost by default, as at present.  It seems perverse at the moment that one=
=20
> can improve the performance of iostreams only by introducing more complex=
=20
> code - the inverse of the more typical equation where more code =3D> more=
=20
> functionality.
>
> If we can pin down/agree a more suitable interface, I'm certainly happy t=
o=20
> help provide a sample implementation for testing and improvement.  My ide=
as=20
> above can be discarded if they are not appropriate - I'm not wedded to=20
> them, but I thought they might provide a hook for criticism!
> On Saturday, November 17, 2012 7:36:37 PM UTC, Nicol Bolas wrote:
>>
>>  The Iostreams library in C++ has a problem. We have real, reasonable,=
=20
>> legitimate C++ professional, who like C++ and use modern C++ idioms,=20
>> telling people to not use iostreams. This is not due to differing ideas =
on=20
>> C++ or C-in-classes-style development, but the simple practical realitie=
s=20
>> of the situation.
>>
>> This kind of thing is indicative of a real problem in iostreams. In orde=
r=20
>> to eventually solve that problem, we must first identify exactly what th=
e=20
>> problems are. This discussion should be focused on exactly that:=20
>> identifying the problems with the library. Once we know what the real=20
>> problems are, we can be certain that any new system that is proposed=20
>> addresses them.
>>
>> Note that this is about problems within iostreams. This is not about a=
=20
>> list of things you *wish* it could do. This is about what iostreams=20
>> actually tries to do but fails at in some way. So stuff like async file =
IO=20
>> doesn=92t go here, since iostreams doesn=92t try to provide that.
>>
>> Feel free to add to this list other flaws you see in iostreams. Or if yo=
u=20
>> think that some of them are not real flaws, feel free to explain why.
>>
>> Performance
>> This is the big one, generally the #1 reason why people suggest using=20
>> C-standard file IO rather than iostreams.
>>
>> Oftentimes, when people defend iostreams performance, they will say=20
>> something to the effect of, =93iostreams does far more than C-standard f=
ile=20
>> IO.=94 And that=92s true. With iostreams, you have an extensible mechani=
sm for=20
>> writing any type directly to a stream. You can =93easily=94 write new=20
>> streambuf=92s that will allow you to (via runtime polymorphism) be able =
to=20
>> work with existing code, thus allowing you to leverage your file IO for=
=20
>> other forms of IO. You could even use a network pipe as an input or outp=
ut=20
>> stream.
>>
>> There=92s one real problem with this logic, and it is exactly why people=
=20
>> suggest C-standard file IO. Iostreams violates a fundamental precept of=
=20
>> C++: pay *only* for what you use.
>>
>> Consider this suite of benchmarks<http://stackoverflow.com/questions/434=
0396/does-the-c-standard-mandate-poor-performance-for-iostreams-or-am-i-jus=
t-deali>.=20
>> This code doesn=92t do file IO; it writes directly to a string. All it=
=92s=20
>> doing is measuring the time it takes to append 4-characters to a string.=
 A=20
>> lot. It uses a `char[]` as a useful control. It also tests the use of=20
>> `vector<char>` (presumably `basic_string` would have similar results).=
=20
>> Therefore, this is a solid test for the efficiency of the iostreams=20
>> codebase itself.
>>
>> Obviously there will be some efficiency loss. But consider the numbers i=
n=20
>> the results.
>>
>> The ostringstream is more than full order of magnitude slower than the=
=20
>> control. It=92s almost 100x in some cases. Note that it=92s not using <<=
 to=20
>> write to the stream; it=92s using `ostream::write()`.
>>
>> Note that the vector<char> implementations are fairly comparable to the=
=20
>> control, usually being around 1x-4x the speed. So clearly this is someth=
ing=20
>> in ostringstream.
>>
>> Now, you might say that one could use the stringbuf directly. And that=
=20
>> was done. While it does improve performance over the ostringstream case=
=20
>> substantially (generally half to a quarter the performance), it=92s stil=
l=20
>> over 10x slower than the control or most vector<char> implementations.
>>
>> Why? The stringbuf operations ought to be a thin wrapper over=20
>> std::string. After all, that=92s what was asked for.
>>
>> Where does this inefficiency come from? I haven=92t done any extensive=
=20
>> profiling analysis, but my educated guesses are from two places: virtual=
=20
>> function overhead and an interface that does too much.
>>
>> ostringstream is supposed to be able to be used as an ostream for=20
>> runtime-polymorphism. But here=92s where the C++ maxim comes into play.=
=20
>> Runtime-polymorphism is not being used here. Every function call should=
=20
>> be able to be statically dispatched. And it is, but all of the virtual=
=20
>> machinery comes from *within* ostringstream.
>>
>> This problem seems to come mostly from the fact that basic_ostream, whic=
h=20
>> does most of the leg-work for ostringstream, has no specific knowledge o=
f=20
>> its stream type. Therefore it's always a virtual call. And it may be doi=
ng=20
>> many such virtual calls.
>>
>> You can achieve the same runtime polymorphism (being able to overload=20
>> operator<< for any stream) by using a static set of stream classes, tigh=
tly=20
>> coupled to their specific streambufs, and a single =93anystream=94 type =
that=20
>> those streams can be converted into. It would use std::function-style ty=
pe=20
>> erasure to remember the original type and feed function calls to it. It=
=20
>> would use a single function call to initiate each write operation, rathe=
r=20
>> than what appears to be many virtual calls within each write.
>>
>> Then, there=92s the fact that streambuf itself is overdesigned. stringbu=
f=20
>> ought to be a simple interface wrapper around a std::string, but it=92s =
not.=20
>> It=92s a complex thing. It has locale support of all things. Why? Isn=92=
t=20
>> that something that should be handled at the stream level?
>>
>> This API has no way to get a low-level interface to a=20
>> file/string/whatever. There=92s no way to just open a filebuf and blast =
the=20
>> file into some memory, or to shove some memory out of a filebuf. It will=
=20
>> always employ the locale machinery even if you didn=92t ask for it. It w=
ill=20
>> always make these internal virtual calls, even if they are completely=20
>> statically dispatched.
>>
>> With iostreams, you are paying for a lot of stuff that you don=92t=20
>> frequently use. At the stream level, it makes sense that you=92re paying=
 for=20
>> certain machinery (though again, some way to say that you=92re not using=
 some=20
>> of it would be nice). At the buffer level, it does not, since that is th=
e=20
>> lowest level you=92re allowed to use.
>>
>> Utility
>> While performance is the big issue, it=92s not the only one.
>>
>> The biggest selling point for iostreams is the ability to extend its=20
>> formatted writing functionality. You can overload operator<< for various=
=20
>> types and simply use them. You can=92t do that with fprintf. And thanks =
to=20
>> ADL, it will work just fine for classes in namespaces. You can create ne=
w=20
>> streambuf types and even streams if you like. All relatively easily.
>>
>> Here=92s the problem, and it is admittedly one that is subjective: print=
f=20
>> is really nice syntax.
>>
>> It=92s very compact, for one. Once you understand the basic syntax of it=
,=20
>> it=92s very easy to see what=92s going on. Especially for complex format=
ting.=20
>> Just consider the physical size difference between these two:
>>
>> snprintf(..., =930x%08x=94, integer);
>>
>>  stream << "0x" << std::right << std::hex << std::setw(8) << iVal << std=
::endl;
>>
>>  It may take a bit longer to become used to the printf version, but this=
=20
>> is something you can easily look up in a reference.
>>
>> Plus, it makes it much easier to do translations on formatted strings.=
=20
>> You can look the pattern string up in a table that changes from language=
 to=20
>> language. This is rather more difficult in iostreams, though not=20
>> impossible. Granted, pattern changes may not be enough, as some language=
s=20
>> have different subject/verb/object grammars that would require reshuffli=
ng=20
>> patterns around. However, there are printf-style systems that do allow f=
or=20
>> reshuffling, whereas no such mechanism exists for iostream-style.
>>
>> C++ used the << method because the alternatives were less flexible.=20
>> Boost.Format and other systems show that C++03 did not really have to us=
e=20
>> this mechanism to achieve the extensibility features that iostreams prov=
ide.
>>
>> What do you think? Are there other issues in iostreams that need to be=
=20
>> mentioned?
>> =20
>  --=20
> =20
> ---=20
> You received this message because you are subscribed to a topic in the=20
> Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this topic, visit=20
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/bMzBAHgb5_o/=
unsubscribe
> .
> To unsubscribe from this group and all its topics, send an email to=20
> std-proposal...@isocpp.org <javascript:>.
> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
> Visit this group at=20
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
> =20

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_769_16151387.1389655762433
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>I like your ideas! In wxWidgets toolkit there has bee=
n a layering of low level (typical file read/write functionality) and forma=
tting streams on top of these for a long time, which provides some lessons =
on what to do/not do.<br></div><div><br></div><div>When it comes to formatt=
ing I think there is fruitful middle ground between printf and operator&lt;=
&lt; + manipulators, now that we have variadic templates. A recent suggesti=
on offered a type safe printf-like formatter but still stuck to the printf =
formatting system with %&lt;pars&gt;&lt;letter&gt; where the letter now has=
 to match the type deduced from the template parameter. This is unnecessary=
 redundancy: As the type is known the &lt;letter&gt; part is not necessary!=
 This leaves the &lt;pars&gt; part open for customization for different dat=
a types, if we can just find out where they end (this is one of the roles o=
f the &lt;letter&gt; part). Here is one possibility:</div><div><br></div><d=
iv>Each inserted value is written like this: %&lt;name&gt;|&lt;pars&gt;%</d=
iv><div><br></div><div>The name can be as simple as a digit or (preferrably=
) more descriptive. &lt;pars&gt; can be anything but some discipline is sug=
gested... The | is omitted if there are no pars.</div><div><br></div><div>T=
he reason for mandating a name is two-fold: Firstly to still be able to use=
 %% as an escape for a % character. Secondly to allow translation where the=
 translated string has the inserts in another order. This is very common fo=
r instance when translating between English and French. A prerequisite for =
this to work is that the formatting function has access to both the untrans=
lated and translated strings so it can match the inserts in the original st=
ring with the arguments that follow and rearrange them appropriately.</div>=
<div><br></div><div>To implement the type specific parameters the formattin=
g function supplies the &lt;pars&gt; part as a string_view to an overloaded=
 string to_string(T&amp;, string_view pars). This function is the one to ov=
erload for your custom data types, which then can have a completely separat=
e notion of parameters from the arithmetic types.</div><div><br></div><div>=
I have implemented this in a real project which has been using this success=
fully for the last five years or so, but of course there are lots of other =
ways to do this once you notice that the type specifier is no longer needed=
..</div><div><br></div><div>BTW: If static members were allowed in lambdas t=
his could be used to parse the format string once and for all and implement=
 translation (using an enclosing macro), For some reason static data has be=
en prohibited in lambdas, unfortunately.<br><br>Den m=E5ndagen den 13:e jan=
uari 2014 kl. 05:50:13 UTC+1 skrev wsdwsd:<blockquote class=3D"gmail_quote"=
 style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-=
left: 1ex;">




<div dir=3D"ltr">
<div dir=3D"ltr" style=3D"font-family:'Calibri','Microsoft YaHei UI','Segoe=
 UI','Meiryo','Microsoft JhengHei UI','Malgun Gothic','sans-serif';font-siz=
e:12pt"><div style=3D"color:rgb(0,0,0)">I agree with&nbsp;you. I have make =
a simple ifstream for a sample and I have found a way to deal with&nbsp;iom=
anip. If you need, please email me.<br></div><div style=3D"color:rgb(0,0,0)=
"><div style=3D"color:rgb(0,0,0)"><br></div><div style=3D"color:rgb(0,0,0)"=
>Sent from Windows Mail</div><div style=3D"color:rgb(0,0,0)"><br></div></di=
v><div style=3D"padding-top:5px;border-top-color:rgb(229,229,229);border-to=
p-width:1px;border-top-style:solid"><div><font face=3D" 'Calibri', 'Microso=
ft YaHei UI', 'Segoe UI', 'Meiryo', 'Microsoft JhengHei UI', 'Malgun Gothic=
', 'sans-serif'" style=3D"line-height:15pt;letter-spacing:0.02em;font-famil=
y:&quot;Calibri&quot;,&quot;Microsoft YaHei UI&quot;,&quot;Segoe UI&quot;,&=
quot;Meiryo&quot;,&quot;Microsoft JhengHei UI&quot;,&quot;Malgun Gothic&quo=
t;,&quot;sans-serif&quot;;font-size:12pt"><b>From:</b>&nbsp;<a href=3D"java=
script:" target=3D"_blank" gdf-obfuscated-mailto=3D"bobTkf_DWFoJ" onmousedo=
wn=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'javas=
cript:';return true;">fritzpoll</a><br><b>Sent:</b>&nbsp;Monday, January 13=
, 2014 1:44 AM<br><b>To:</b>&nbsp;<a href=3D"javascript:" target=3D"_blank"=
 gdf-obfuscated-mailto=3D"bobTkf_DWFoJ" onmousedown=3D"this.href=3D'javascr=
ipt:';return true;" onclick=3D"this.href=3D'javascript:';return true;">std-=
pr...@isocpp.org</a></font></div></div><div><br></div><div dir=3D""><div di=
r=3D"ltr">I have used iostreams in C++ since I was a beginner programmer an=
d even now am using it in commercial projects.&nbsp; I agree with many of t=
he sentiments expressed in the original post, particularly regarding perfor=
mance.&nbsp; The main problem as I see it (and there seems to be some agree=
ment in the posts above) is that iostreams attempts to do too much - it is =
doing I/O and formatting and localisation all in one package.&nbsp; In a wa=
y, for beginners, this is great, but the mechanics of the interface and int=
erdependencies that this introduces makes deviation from simple use a daunt=
ing task.&nbsp; Even now, 15 years on from my first C++ program, I'm "frigh=
tened" of cajoling iostreams to do anything complicated.<br><br>That said, =
it is all very well to complain and compile a list of grievances, but we ne=
ed a) some solutions and b) a sample implementation of the same.&nbsp; I th=
ink the answer in a new library would be to take the functionality of iostr=
eams and split it up, so that you have something like:<br><ul style=3D"padd=
ing-top:0px;padding-bottom:0px;margin-top:0px;margin-bottom:0px;list-style-=
type:disc"><li>streams classes that are sources and/or sinks - these concep=
tually simply stream byte data from one place to another.&nbsp; So a file s=
tream would simply take in the data provided and write out the data into th=
e file, a string stream would do the same but store it in a string, etc.&nb=
sp; As now, you'd have separate classes relating to different source/sink t=
ypes.&nbsp; These would all inherit from a single base class, largely to ac=
count for the use case where one may wish to store pointers to multiple str=
eams of different types in a container to loop over during processing.</li>=
<li>More string formatting functions.&nbsp; C++11 extended the &lt;string&g=
t; header to include conversions from most primitives into a string/wstring=
, but further formatting functions could be included by default - these wou=
ld&nbsp; need to be written for unicode types as well, I suspect.&nbsp; I'm=
 not sure exactly how to start with the list of functionality required to r=
eplicate what one can achieve with iostreams, but perhaps other can offer g=
uidance.<br></li></ul><p>Other aspects such as Unicode/Localisation should =
be dealt with by other libraries - it doesn't seem like it should be the pu=
rpose of a stream to do this, and not every user of the streaming library s=
hould have to pay the cost by default, as at present.&nbsp; It seems perver=
se at the moment that one can improve the performance of iostreams only by =
introducing more complex code - the inverse of the more typical equation wh=
ere more code =3D&gt; more functionality.</p><p>If we can pin down/agree a =
more suitable interface, I'm certainly happy to help provide a sample imple=
mentation for testing and improvement.&nbsp; My ideas above can be discarde=
d if they are not appropriate - I'm not wedded to them, but I thought they =
might provide a hook for criticism!<br></p>On Saturday, November 17, 2012 7=
:36:37 PM UTC, Nicol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D=
"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,20=
4);border-left-width:1px;border-left-style:solid">
 =20

   =20
 =20
  <div>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">The Iostreams
      library in C++ has a problem. We have real, reasonable, legitimate
      C++ professional, who like C++ and use modern C++ idioms, telling
      people to not use iostreams. This is not due to differing ideas on
      C++ or C-in-classes-style development, but the simple practical
      realities of the situation.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">This

      kind of thing is indicative of a real problem in iostreams. In
      order to eventually solve that problem, we must first identify
      exactly what the problems are. This discussion should be focused
      on exactly that: identifying the problems with the library. Once
      we know what the real problems are, we can be certain that any new
      system that is proposed addresses them.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Note
      that this is about problems </span><span style=3D"color:rgb(0,0,0);fo=
nt-family:Arial;font-size:15px;font-style:italic;font-variant:normal;font-w=
eight:normal;text-decoration:none;vertical-align:baseline;background-color:=
transparent">within</span><span style=3D"color:rgb(0,0,0);font-family:Arial=
;font-size:15px;font-style:normal;font-variant:normal;font-weight:normal;te=
xt-decoration:none;vertical-align:baseline;background-color:transparent">
      iostreams. This is not about a list of things you <i>wish</i> it
      could do. This is about what iostreams actually tries to do but
      fails at in some way. So stuff like async file IO doesn=92t go here,
      since iostreams doesn=92t try to provide that.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Feel

      free to add to this list other flaws you see in iostreams. Or if
      you think that some of them are not real flaws, feel free to
      explain why.</span><br>
    <p dir=3D"ltr"><span style=3D"color:rgb(102,102,102);font-family:Georgi=
a;font-size:32px;font-style:italic;font-variant:normal;font-weight:normal;t=
ext-decoration:none;vertical-align:baseline;background-color:transparent">P=
erformance</span></p>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">This
      is the big one, generally the #1 reason why people suggest using
      C-standard file IO rather than iostreams.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Oftentimes,

      when people defend iostreams performance, they will say something
      to the effect of, =93iostreams does far more than C-standard file
      IO.=94 And that=92s true. With iostreams, you have an extensible
      mechanism for writing any type directly to a stream. You can
      =93easily=94 write new streambuf=92s that will allow you to (via runt=
ime
      polymorphism) be able to work with existing code, thus allowing
      you to leverage your file IO for other forms of IO. You could even
      use a network pipe as an input or output stream.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">There=92s

      one real problem with this logic, and it is exactly why people
      suggest C-standard file IO. Iostreams violates a fundamental
      precept of C++: pay <i>only</i> for what you </span><span style=3D"co=
lor:rgb(0,0,0);font-family:Arial;font-size:15px;font-style:italic;font-vari=
ant:normal;font-weight:normal;text-decoration:none;vertical-align:baseline;=
background-color:transparent">use</span><span style=3D"color:rgb(0,0,0);fon=
t-family:Arial;font-size:15px;font-style:normal;font-variant:normal;font-we=
ight:normal;text-decoration:none;vertical-align:baseline;background-color:t=
ransparent">.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Consider
    </span><a href=3D"http://stackoverflow.com/questions/4340396/does-the-c=
-standard-mandate-poor-performance-for-iostreams-or-am-i-just-deali" target=
=3D"_blank" onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fstackoverflow.com%2Fquestions%2F4340396%2Fdoes-the-c-standard-manda=
te-poor-performance-for-iostreams-or-am-i-just-deali\46sa\75D\46sntz\0751\4=
6usg\75AFQjCNFGm4Xsoek6kyzy5OpZ33R9EM5ShA';return true;" onclick=3D"this.hr=
ef=3D'http://www.google.com/url?q\75http%3A%2F%2Fstackoverflow.com%2Fquesti=
ons%2F4340396%2Fdoes-the-c-standard-mandate-poor-performance-for-iostreams-=
or-am-i-just-deali\46sa\75D\46sntz\0751\46usg\75AFQjCNFGm4Xsoek6kyzy5OpZ33R=
9EM5ShA';return true;"><span style=3D"color:rgb(17,85,204);font-family:Aria=
l;font-size:15px;font-style:normal;font-variant:normal;font-weight:normal;t=
ext-decoration:underline;vertical-align:baseline;background-color:transpare=
nt">this
        suite of benchmarks</span></a><span style=3D"color:rgb(0,0,0);font-=
family:Arial;font-size:15px;font-style:normal;font-variant:normal;font-weig=
ht:normal;text-decoration:none;vertical-align:baseline;background-color:tra=
nsparent">.
      This code doesn=92t do file IO; it writes directly to a string. All
      it=92s doing is measuring the time it takes to append 4-characters
      to a string. A lot. It uses a `char[]` as a useful control. It
      also tests the use of `vector&lt;char&gt;` (presumably
      `basic_string` would have similar results). Therefore, this is a
      solid test for the efficiency of the iostreams codebase itself.</span=
><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Obviously
      there will be some efficiency loss. But consider the numbers in
      the results.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">The
      ostringstream is more than </span><span style=3D"color:rgb(0,0,0);fon=
t-family:Arial;font-size:15px;font-style:italic;font-variant:normal;font-we=
ight:normal;text-decoration:none;vertical-align:baseline;background-color:t=
ransparent">full
      order of magnitude</span><span style=3D"color:rgb(0,0,0);font-family:=
Arial;font-size:15px;font-style:normal;font-variant:normal;font-weight:norm=
al;text-decoration:none;vertical-align:baseline;background-color:transparen=
t">
      slower than the control. It=92s almost 100x in some cases. Note that
      it=92s not using &lt;&lt; to write to the stream; it=92s using
      `ostream::write()`.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Note

      that the vector&lt;char&gt; implementations are fairly comparable
      to the control, usually being around 1x-4x the speed. So clearly
      this is something in ostringstream.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Now,

      you might say that one could use the stringbuf directly. And that
      was done. While it does improve performance over the ostringstream
      case substantially (generally half to a quarter the performance),
      it=92s still over 10x slower than the control or most
      vector&lt;char&gt; implementations.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Why?
      The stringbuf operations ought to be a thin wrapper over
      std::string. After all, that=92s what was asked for.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Where

      does this inefficiency come from? I haven=92t done any extensive
      profiling analysis, but my educated guesses are from two places:
      virtual function overhead and an interface that does too much.</span>=
<br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">ostringstream

      is supposed to be able to be used as an ostream for
      runtime-polymorphism. But here=92s where the C++ maxim comes into
      play. Runtime-polymorphism is </span><span style=3D"color:rgb(0,0,0);=
font-family:Arial;font-size:15px;font-style:italic;font-variant:normal;font=
-weight:normal;text-decoration:none;vertical-align:baseline;background-colo=
r:transparent">not
      being used here</span><span style=3D"color:rgb(0,0,0);font-family:Ari=
al;font-size:15px;font-style:normal;font-variant:normal;font-weight:normal;=
text-decoration:none;vertical-align:baseline;background-color:transparent">=
..
      Every function call should be able to be statically dispatched.
      And it is, but all of the virtual machinery comes from <i>within</i>
      ostringstream.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">This
      problem seems to come mostly from the fact that basic_ostream,
      which does most of the leg-work for ostringstream, has no specific
      knowledge of its stream type. Therefore it's always a virtual
      call. And it may be doing many such virtual calls.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">You

      can achieve the same runtime polymorphism (being able to overload
      operator&lt;&lt; for any stream) by using a static set of stream
      classes, tightly coupled to their specific streambufs, and a
      single =93anystream=94 type that those streams can be converted into.
      It would use std::function-style type erasure to remember the
      original type and feed function calls to it. It would use a single
      function call to initiate each write operation, rather than what
      appears to be many virtual calls within each write.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Then,

      there=92s the fact that streambuf itself is overdesigned. stringbuf
      ought to be a simple interface wrapper around a std::string, but
      it=92s not. It=92s a complex thing. It has </span><span style=3D"colo=
r:rgb(0,0,0);font-family:Arial;font-size:15px;font-style:italic;font-varian=
t:normal;font-weight:normal;text-decoration:none;vertical-align:baseline;ba=
ckground-color:transparent">locale
      support</span><span style=3D"color:rgb(0,0,0);font-family:Arial;font-=
size:15px;font-style:normal;font-variant:normal;font-weight:normal;text-dec=
oration:none;vertical-align:baseline;background-color:transparent">
      of all things. Why? Isn=92t that something that should be handled at
      the stream level?</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">This

      API has no way to get a low-level interface to a
      file/string/whatever. There=92s no way to just open a filebuf and
      blast the file into some memory, or to shove some memory out of a
      filebuf. It will always employ the locale machinery even if you
      didn=92t ask for it. It will always make these internal virtual
      calls, even if they are completely statically dispatched.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">With

      iostreams, you are paying for a lot of stuff that you don=92t
      frequently use. At the stream level, it makes sense that you=92re
      paying for certain machinery (though again, some way to say that
      you=92re not using some of it would be nice). At the buffer level,
      it does not, since that is the lowest level you=92re allowed to use.<=
/span><br>
    <p dir=3D"ltr"><span style=3D"color:rgb(102,102,102);font-family:Georgi=
a;font-size:32px;font-style:italic;font-variant:normal;font-weight:normal;t=
ext-decoration:none;vertical-align:baseline;background-color:transparent">U=
tility</span></p>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">While
      performance is the big issue, it=92s not the only one.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">The

      biggest selling point for iostreams is the ability to extend its
      formatted writing functionality. You can overload operator&lt;&lt;
      for various types and simply use them. You can=92t do that with
      fprintf. And thanks to ADL, it will work just fine for classes in
      namespaces. You can create new streambuf types and even streams if
      you like. All relatively easily.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Here=92s
      the problem, and it is admittedly one that is subjective: printf
      is really nice syntax.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">It=92s

      very compact, for one. Once you understand the basic syntax of it,
      it=92s very easy to see what=92s going on. Especially for complex
      formatting. Just consider the physical size difference between
      these two:</span><br>
    <pre><tt><span style=3D"color:rgb(0,0,0);font-size:15px;font-style:norm=
al;font-variant:normal;font-weight:normal;text-decoration:none;vertical-ali=
gn:baseline;background-color:transparent">snprintf(..., =930x%08x=94, integ=
er);</span></tt></pre>
    <pre><tt><span style=3D"color:rgb(0,0,0);font-size:15px;font-style:norm=
al;font-variant:normal;font-weight:normal;text-decoration:none;vertical-ali=
gn:baseline;background-color:transparent"></span></tt></pre>
    <pre><tt><span style=3D"color:rgb(0,0,0);font-size:15px;font-style:norm=
al;font-variant:normal;font-weight:normal;text-decoration:none;vertical-ali=
gn:baseline;background-color:transparent">stream &lt;&lt; "0x" &lt;&lt; std=
::right &lt;&lt; std::hex &lt;&lt; std::setw(8) &lt;&lt; iVal &lt;&lt; std:=
:endl;</span></tt></pre>
    <pre><span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;f=
ont-style:normal;font-variant:normal;font-weight:normal;text-decoration:non=
e;vertical-align:baseline;background-color:transparent"></span></pre>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">It
      may take a bit longer to become used to the printf version, but
      this is something you can easily look up in a reference.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Plus,

      it makes it much easier to do translations on formatted strings.
      You can look the pattern string up in a table that changes from
      language to language. This is rather more difficult in iostreams,
      though not impossible. Granted, pattern changes may not be enough,
      as some languages have different subject/verb/object grammars that
      would require reshuffling patterns around. However, there are
      printf-style systems that do allow for reshuffling, whereas no
      such mechanism exists for iostream-style.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">C++

      used the &lt;&lt; method because the alternatives were less
      flexible. Boost.Format and other systems show that C++03 did not
      really have to use this mechanism to achieve the extensibility
      features that iostreams provide.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><span style=3D"co=
lor:rgb(0,0,0);font-family:Arial;font-size:15px;font-style:normal;font-vari=
ant:normal;font-weight:normal;text-decoration:none;vertical-align:baseline;=
background-color:transparent">What
      do you think? Are there other issues in iostreams that need to be
      mentioned?</span><br>
  </div>

</blockquote></div>

<p></p>

-- <br>
&nbsp;<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/bMzBAHgb5_o/unsubscribe" target=3D"_blan=
k" onmousedown=3D"this.href=3D'https://groups.google.com/a/isocpp.org/d/top=
ic/std-proposals/bMzBAHgb5_o/unsubscribe';return true;" onclick=3D"this.hre=
f=3D'https://groups.google.com/a/isocpp.org/d/topic/std-proposals/bMzBAHgb5=
_o/unsubscribe';return true;">https://groups.google.com/a/<wbr>isocpp.org/d=
/topic/std-<wbr>proposals/bMzBAHgb5_o/<wbr>unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"bobTkf_DWFoJ" o=
nmousedown=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=
=3D'javascript:';return true;">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"bobTkf_DWFoJ" onmousedown=3D"this.href=3D'java=
script:';return true;" onclick=3D"this.href=3D'javascript:';return true;">s=
td-pr...@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank" onmousedown=3D"this.href=3D'http://groups=
..google.com/a/isocpp.org/group/std-proposals/';return true;" onclick=3D"thi=
s.href=3D'http://groups.google.com/a/isocpp.org/group/std-proposals/';retur=
n true;">http://groups.google.com/a/<wbr>isocpp.org/group/std-<wbr>proposal=
s/</a>.<br>
</div></div>
</div>

</blockquote></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_769_16151387.1389655762433--

.


Author: fritzpoll <fred.pollard@gmail.com>
Date: Mon, 13 Jan 2014 23:18:51 -0800 (PST)
Raw View
------=_Part_254_30430604.1389683931111
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

In my scribbling, I've got a few ideas for the formatting, given that that=
=20
the "streams" are now conceptually just copying bytes from one place to=20
another.

   - Essentially your idea - a format function that takes certain=20
   parameters and produces a string/wstring to be passed through to the str=
eam
   - A set of chainable functions (or method chains) to format a value into=
=20
   a string (so you get something like format_string(f).set_precision(5, 2)=
)

The first has more common semantics from other languages, so that would be=
=20
more of an advantage.  The disadvantage is that it is still possible to=20
pass in parameters that are not valid for a given type ("%5.2" on a char,=
=20
for example)

The second can provide the type checking for given methods, so that one can=
=20
only invoke them on the correct type (by templating format_string, above)=
=20
but feels a little more cumbersome and perhaps too unfamiliar. =20

On Monday, January 13, 2014 11:29:22 PM UTC, Bengt Gustafsson wrote:

> I like your ideas! In wxWidgets toolkit there has been a layering of low=
=20
> level (typical file read/write functionality) and formatting streams on t=
op=20
> of these for a long time, which provides some lessons on what to do/not d=
o.
>
> When it comes to formatting I think there is fruitful middle ground=20
> between printf and operator<< + manipulators, now that we have variadic=
=20
> templates. A recent suggestion offered a type safe printf-like formatter=
=20
> but still stuck to the printf formatting system with %<pars><letter> wher=
e=20
> the letter now has to match the type deduced from the template parameter.=
=20
> This is unnecessary redundancy: As the type is known the <letter> part is=
=20
> not necessary! This leaves the <pars> part open for customization for=20
> different data types, if we can just find out where they end (this is one=
=20
> of the roles of the <letter> part). Here is one possibility:
>
> Each inserted value is written like this: %<name>|<pars>%
>
> The name can be as simple as a digit or (preferrably) more descriptive.=
=20
> <pars> can be anything but some discipline is suggested... The | is omitt=
ed=20
> if there are no pars.
>
> The reason for mandating a name is two-fold: Firstly to still be able to=
=20
> use %% as an escape for a % character. Secondly to allow translation wher=
e=20
> the translated string has the inserts in another order. This is very comm=
on=20
> for instance when translating between English and French. A prerequisite=
=20
> for this to work is that the formatting function has access to both the=
=20
> untranslated and translated strings so it can match the inserts in the=20
> original string with the arguments that follow and rearrange them=20
> appropriately.
>
> To implement the type specific parameters the formatting function supplie=
s=20
> the <pars> part as a string_view to an overloaded string to_string(T&,=20
> string_view pars). This function is the one to overload for your custom=
=20
> data types, which then can have a completely separate notion of parameter=
s=20
> from the arithmetic types.
>
> I have implemented this in a real project which has been using this=20
> successfully for the last five years or so, but of course there are lots =
of=20
> other ways to do this once you notice that the type specifier is no longe=
r=20
> needed.
>
> BTW: If static members were allowed in lambdas this could be used to pars=
e=20
> the format string once and for all and implement translation (using an=20
> enclosing macro), For some reason static data has been prohibited in=20
> lambdas, unfortunately.
>
> Den m=C3=A5ndagen den 13:e januari 2014 kl. 05:50:13 UTC+1 skrev wsdwsd:
>>
>>  I agree with you. I have make a simple ifstream for a sample and I have=
=20
>> found a way to deal with iomanip. If you need, please email me.
>>
>> Sent from Windows Mail
>>
>> *From:* fritzpoll
>> *Sent:* =E2=80=8EMonday=E2=80=8E, =E2=80=8EJanuary=E2=80=8E =E2=80=8E13=
=E2=80=8E, =E2=80=8E2014 =E2=80=8E1=E2=80=8E:=E2=80=8E44=E2=80=8E =E2=80=8E=
AM
>> *To:* std-pr...@isocpp.org
>>
>> I have used iostreams in C++ since I was a beginner programmer and even=
=20
>> now am using it in commercial projects.  I agree with many of the=20
>> sentiments expressed in the original post, particularly regarding=20
>> performance.  The main problem as I see it (and there seems to be some=
=20
>> agreement in the posts above) is that iostreams attempts to do too much =
-=20
>> it is doing I/O and formatting and localisation all in one package.  In =
a=20
>> way, for beginners, this is great, but the mechanics of the interface an=
d=20
>> interdependencies that this introduces makes deviation from simple use a=
=20
>> daunting task.  Even now, 15 years on from my first C++ program, I'm=20
>> "frightened" of cajoling iostreams to do anything complicated.
>>
>> That said, it is all very well to complain and compile a list of=20
>> grievances, but we need a) some solutions and b) a sample implementation=
 of=20
>> the same.  I think the answer in a new library would be to take the=20
>> functionality of iostreams and split it up, so that you have something l=
ike:
>>
>>    - streams classes that are sources and/or sinks - these conceptually=
=20
>>    simply stream byte data from one place to another.  So a file stream =
would=20
>>    simply take in the data provided and write out the data into the file=
, a=20
>>    string stream would do the same but store it in a string, etc.  As no=
w,=20
>>    you'd have separate classes relating to different source/sink types. =
 These=20
>>    would all inherit from a single base class, largely to account for th=
e use=20
>>    case where one may wish to store pointers to multiple streams of diff=
erent=20
>>    types in a container to loop over during processing.
>>    - More string formatting functions.  C++11 extended the <string>=20
>>    header to include conversions from most primitives into a string/wstr=
ing,=20
>>    but further formatting functions could be included by default - these=
=20
>>    would  need to be written for unicode types as well, I suspect.  I'm =
not=20
>>    sure exactly how to start with the list of functionality required to=
=20
>>    replicate what one can achieve with iostreams, but perhaps other can =
offer=20
>>    guidance.
>>   =20
>> Other aspects such as Unicode/Localisation should be dealt with by other=
=20
>> libraries - it doesn't seem like it should be the purpose of a stream to=
 do=20
>> this, and not every user of the streaming library should have to pay the=
=20
>> cost by default, as at present.  It seems perverse at the moment that on=
e=20
>> can improve the performance of iostreams only by introducing more comple=
x=20
>> code - the inverse of the more typical equation where more code =3D> mor=
e=20
>> functionality.
>>
>> If we can pin down/agree a more suitable interface, I'm certainly happy=
=20
>> to help provide a sample implementation for testing and improvement.  My=
=20
>> ideas above can be discarded if they are not appropriate - I'm not wedde=
d=20
>> to them, but I thought they might provide a hook for criticism!
>> On Saturday, November 17, 2012 7:36:37 PM UTC, Nicol Bolas wrote:
>>>
>>>  The Iostreams library in C++ has a problem. We have real, reasonable,=
=20
>>> legitimate C++ professional, who like C++ and use modern C++ idioms,=20
>>> telling people to not use iostreams. This is not due to differing ideas=
 on=20
>>> C++ or C-in-classes-style development, but the simple practical realiti=
es=20
>>> of the situation.
>>>
>>> This kind of thing is indicative of a real problem in iostreams. In=20
>>> order to eventually solve that problem, we must first identify exactly =
what=20
>>> the problems are. This discussion should be focused on exactly that:=20
>>> identifying the problems with the library. Once we know what the real=
=20
>>> problems are, we can be certain that any new system that is proposed=20
>>> addresses them.
>>>
>>> Note that this is about problems within iostreams. This is not about a=
=20
>>> list of things you *wish* it could do. This is about what iostreams=20
>>> actually tries to do but fails at in some way. So stuff like async file=
 IO=20
>>> doesn=E2=80=99t go here, since iostreams doesn=E2=80=99t try to provide=
 that.
>>>
>>> Feel free to add to this list other flaws you see in iostreams. Or if=
=20
>>> you think that some of them are not real flaws, feel free to explain wh=
y.
>>>
>>> Performance
>>> This is the big one, generally the #1 reason why people suggest using=
=20
>>> C-standard file IO rather than iostreams.
>>>
>>> Oftentimes, when people defend iostreams performance, they will say=20
>>> something to the effect of, =E2=80=9Ciostreams does far more than C-sta=
ndard file=20
>>> IO.=E2=80=9D And that=E2=80=99s true. With iostreams, you have an exten=
sible mechanism for=20
>>> writing any type directly to a stream. You can =E2=80=9Ceasily=E2=80=9D=
 write new=20
>>> streambuf=E2=80=99s that will allow you to (via runtime polymorphism) b=
e able to=20
>>> work with existing code, thus allowing you to leverage your file IO for=
=20
>>> other forms of IO. You could even use a network pipe as an input or out=
put=20
>>> stream.
>>>
>>> There=E2=80=99s one real problem with this logic, and it is exactly why=
 people=20
>>> suggest C-standard file IO. Iostreams violates a fundamental precept of=
=20
>>> C++: pay *only* for what you use.
>>>
>>> Consider this suite of benchmarks<http://stackoverflow.com/questions/43=
40396/does-the-c-standard-mandate-poor-performance-for-iostreams-or-am-i-ju=
st-deali>.=20
>>> This code doesn=E2=80=99t do file IO; it writes directly to a string. A=
ll it=E2=80=99s=20
>>> doing is measuring the time it takes to append 4-characters to a string=
.. A=20
>>> lot. It uses a `char[]` as a useful control. It also tests the use of=
=20
>>> `vector<char>` (presumably `basic_string` would have similar results).=
=20
>>> Therefore, this is a solid test for the efficiency of the iostreams=20
>>> codebase itself.
>>>
>>> Obviously there will be some efficiency loss. But consider the numbers=
=20
>>> in the results.
>>>
>>> The ostringstream is more than full order of magnitude slower than the=
=20
>>> control. It=E2=80=99s almost 100x in some cases. Note that it=E2=80=99s=
 not using << to=20
>>> write to the stream; it=E2=80=99s using `ostream::write()`.
>>>
>>> Note that the vector<char> implementations are fairly comparable to the=
=20
>>> control, usually being around 1x-4x the speed. So clearly this is somet=
hing=20
>>> in ostringstream.
>>>
>>> Now, you might say that one could use the stringbuf directly. And that=
=20
>>> was done. While it does improve performance over the ostringstream case=
=20
>>> substantially (generally half to a quarter the performance), it=E2=80=
=99s still=20
>>> over 10x slower than the control or most vector<char> implementations.
>>>
>>> Why? The stringbuf operations ought to be a thin wrapper over=20
>>> std::string. After all, that=E2=80=99s what was asked for.
>>>
>>> Where does this inefficiency come from? I haven=E2=80=99t done any exte=
nsive=20
>>> profiling analysis, but my educated guesses are from two places: virtua=
l=20
>>> function overhead and an interface that does too much.
>>>
>>> ostringstream is supposed to be able to be used as an ostream for=20
>>> runtime-polymorphism. But here=E2=80=99s where the C++ maxim comes into=
 play.=20
>>> Runtime-polymorphism is not being used here. Every function call should=
=20
>>> be able to be statically dispatched. And it is, but all of the virtual=
=20
>>> machinery comes from *within* ostringstream.
>>>
>>> This problem seems to come mostly from the fact that basic_ostream,=20
>>> which does most of the leg-work for ostringstream, has no specific=20
>>> knowledge of its stream type. Therefore it's always a virtual call. And=
 it=20
>>> may be doing many such virtual calls.
>>>
>>> You can achieve the same runtime polymorphism (being able to overload=
=20
>>> operator<< for any stream) by using a static set of stream classes, tig=
htly=20
>>> coupled to their specific streambufs, and a single =E2=80=9Canystream=
=E2=80=9D type that=20
>>> those streams can be converted into. It would use std::function-style t=
ype=20
>>> erasure to remember the original type and feed function calls to it. It=
=20
>>> would use a single function call to initiate each write operation, rath=
er=20
>>> than what appears to be many virtual calls within each write.
>>>
>>> Then, there=E2=80=99s the fact that streambuf itself is overdesigned. s=
tringbuf=20
>>> ought to be a simple interface wrapper around a std::string, but it=E2=
=80=99s not.=20
>>> It=E2=80=99s a complex thing. It has locale support of all things. Why?=
 Isn=E2=80=99t=20
>>> that something that should be handled at the stream level?
>>>
>>> This API has no way to get a low-level interface to a=20
>>> file/string/whatever. There=E2=80=99s no way to just open a filebuf and=
 blast the=20
>>> file into some memory, or to shove some memory out of a filebuf. It wil=
l=20
>>> always employ the locale machinery even if you didn=E2=80=99t ask for i=
t. It will=20
>>> always make these internal virtual calls, even if they are completely=
=20
>>> statically dispatched.
>>>
>>> With iostreams, you are paying for a lot of stuff that you don=E2=80=99=
t=20
>>> frequently use. At the stream level, it makes sense that you=E2=80=99re=
 paying for=20
>>> certain machinery (though again, some way to say that you=E2=80=99re no=
t using some=20
>>> of it would be nice). At the buffer level, it does not, since that is t=
he=20
>>> lowest level you=E2=80=99re allowed to use.
>>>
>>> Utility
>>> While performance is the big issue, it=E2=80=99s not the only one.
>>>
>>> The biggest selling point for iostreams is the ability to extend its=20
>>> formatted writing functionality. You can overload operator<< for variou=
s=20
>>> types and simply use them. You can=E2=80=99t do that with fprintf. And =
thanks to=20
>>> ADL, it will work just fine for classes in namespaces. You can create n=
ew=20
>>> streambuf types and even streams if you like. All relatively easily.
>>>
>>> Here=E2=80=99s the problem, and it is admittedly one that is subjective=
: printf=20
>>> is really nice syntax.
>>>
>>> It=E2=80=99s very compact, for one. Once you understand the basic synta=
x of it,=20
>>> it=E2=80=99s very easy to see what=E2=80=99s going on. Especially for c=
omplex formatting.=20
>>> Just consider the physical size difference between these two:
>>>
>>> snprintf(..., =E2=80=9C0x%08x=E2=80=9D, integer);
>>>
>>>  stream << "0x" << std::right << std::hex << std::setw(8) << iVal << st=
d::endl;
>>>
>>>  It may take a bit longer to become used to the printf version, but=20
>>> this is something you can easily look up in a reference.
>>>
>>> Plus, it makes it much easier to do translations on formatted strings.=
=20
>>> You can look the pattern string up in a table that changes from languag=
e to=20
>>> language. This is rather more difficult in iostreams, though not=20
>>> impossible. Granted, pattern changes may not be enough, as some languag=
es=20
>>> have different subject/verb/object grammars that would require reshuffl=
ing=20
>>> patterns around. However, there are printf-style systems that do allow =
for=20
>>> reshuffling, whereas no such mechanism exists for iostream-style.
>>>
>>> C++ used the << method because the alternatives were less flexible.=20
>>> Boost.Format and other systems show that C++03 did not really have to u=
se=20
>>> this mechanism to achieve the extensibility features that iostreams pro=
vide.
>>>
>>> What do you think? Are there other issues in iostreams that need to be=
=20
>>> mentioned?
>>> =20
>>  --=20
>> =20
>> ---=20
>> You received this message because you are subscribed to a topic in the=
=20
>> Google Groups "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this topic, visit=20
>> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/bMzBAHgb5_o=
/unsubscribe
>> .
>> To unsubscribe from this group and all its topics, send an email to=20
>> std-proposal...@isocpp.org.
>> To post to this group, send email to std-pr...@isocpp.org.
>> Visit this group at=20
>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>> =20
>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_254_30430604.1389683931111
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">In my scribbling, I've got a few ideas for the formatting,=
 given that that the "streams" are now conceptually just copying bytes from=
 one place to another.<br><ul><li>Essentially your idea - a format function=
 that takes certain parameters and produces a string/wstring to be passed t=
hrough to the stream</li><li>A set of chainable functions (or method chains=
) to format a value into a string (so you get something like format_string(=
f).set_precision(5, 2))</li></ul><p>The first has more common semantics fro=
m other languages, so that would be more of an advantage.&nbsp; The disadva=
ntage is that it is still possible to pass in parameters that are not valid=
 for a given type ("%5.2" on a char, for example)</p><p>The second can prov=
ide the type checking for given methods, so that one can only invoke them o=
n the correct type (by templating format_string, above) but feels a little =
more cumbersome and perhaps too unfamiliar.&nbsp; <br></p><p>On Monday, Jan=
uary 13, 2014 11:29:22 PM UTC, Bengt Gustafsson wrote:</p><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr"><div>I like your ideas! In wxW=
idgets toolkit there has been a layering of low level (typical file read/wr=
ite functionality) and formatting streams on top of these for a long time, =
which provides some lessons on what to do/not do.<br></div><div><br></div><=
div>When it comes to formatting I think there is fruitful middle ground bet=
ween printf and operator&lt;&lt; + manipulators, now that we have variadic =
templates. A recent suggestion offered a type safe printf-like formatter bu=
t still stuck to the printf formatting system with %&lt;pars&gt;&lt;letter&=
gt; where the letter now has to match the type deduced from the template pa=
rameter. This is unnecessary redundancy: As the type is known the &lt;lette=
r&gt; part is not necessary! This leaves the &lt;pars&gt; part open for cus=
tomization for different data types, if we can just find out where they end=
 (this is one of the roles of the &lt;letter&gt; part). Here is one possibi=
lity:</div><div><br></div><div>Each inserted value is written like this: %&=
lt;name&gt;|&lt;pars&gt;%</div><div><br></div><div>The name can be as simpl=
e as a digit or (preferrably) more descriptive. &lt;pars&gt; can be anythin=
g but some discipline is suggested... The | is omitted if there are no pars=
..</div><div><br></div><div>The reason for mandating a name is two-fold: Fir=
stly to still be able to use %% as an escape for a % character. Secondly to=
 allow translation where the translated string has the inserts in another o=
rder. This is very common for instance when translating between English and=
 French. A prerequisite for this to work is that the formatting function ha=
s access to both the untranslated and translated strings so it can match th=
e inserts in the original string with the arguments that follow and rearran=
ge them appropriately.</div><div><br></div><div>To implement the type speci=
fic parameters the formatting function supplies the &lt;pars&gt; part as a =
string_view to an overloaded string to_string(T&amp;, string_view pars). Th=
is function is the one to overload for your custom data types, which then c=
an have a completely separate notion of parameters from the arithmetic type=
s.</div><div><br></div><div>I have implemented this in a real project which=
 has been using this successfully for the last five years or so, but of cou=
rse there are lots of other ways to do this once you notice that the type s=
pecifier is no longer needed.</div><div><br></div><div>BTW: If static membe=
rs were allowed in lambdas this could be used to parse the format string on=
ce and for all and implement translation (using an enclosing macro), For so=
me reason static data has been prohibited in lambdas, unfortunately.<br><br=
>Den m=C3=A5ndagen den 13:e januari 2014 kl. 05:50:13 UTC+1 skrev wsdwsd:<b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex">




<div dir=3D"ltr">
<div dir=3D"ltr" style=3D"font-family:'Calibri','Microsoft YaHei UI','Segoe=
 UI','Meiryo','Microsoft JhengHei UI','Malgun Gothic','sans-serif';font-siz=
e:12pt"><div style=3D"color:rgb(0,0,0)">I agree with&nbsp;you. I have make =
a simple ifstream for a sample and I have found a way to deal with&nbsp;iom=
anip. If you need, please email me.<br></div><div style=3D"color:rgb(0,0,0)=
"><div style=3D"color:rgb(0,0,0)"><br></div><div style=3D"color:rgb(0,0,0)"=
>Sent from Windows Mail</div><div style=3D"color:rgb(0,0,0)"><br></div></di=
v><div style=3D"padding-top:5px;border-top-color:rgb(229,229,229);border-to=
p-width:1px;border-top-style:solid"><div><font style=3D"line-height:15pt;le=
tter-spacing:0.02em;font-family:&quot;Calibri&quot;,&quot;Microsoft YaHei U=
I&quot;,&quot;Segoe UI&quot;,&quot;Meiryo&quot;,&quot;Microsoft JhengHei UI=
&quot;,&quot;Malgun Gothic&quot;,&quot;sans-serif&quot;;font-size:12pt" fac=
e=3D" 'Calibri', 'Microsoft YaHei UI', 'Segoe UI', 'Meiryo', 'Microsoft Jhe=
ngHei UI', 'Malgun Gothic', 'sans-serif'"><b>From:</b>&nbsp;<a>fritzpoll</a=
><br><b>Sent:</b>&nbsp;=E2=80=8EMonday=E2=80=8E, =E2=80=8EJanuary=E2=80=8E =
=E2=80=8E13=E2=80=8E, =E2=80=8E2014 =E2=80=8E1=E2=80=8E:=E2=80=8E44=E2=80=
=8E =E2=80=8EAM<br><b>To:</b>&nbsp;<a>std-pr...@isocpp.org</a></font></div>=
</div><div><br></div><div dir=3D""><div dir=3D"ltr">I have used iostreams i=
n C++ since I was a beginner programmer and even now am using it in commerc=
ial projects.&nbsp; I agree with many of the sentiments expressed in the or=
iginal post, particularly regarding performance.&nbsp; The main problem as =
I see it (and there seems to be some agreement in the posts above) is that =
iostreams attempts to do too much - it is doing I/O and formatting and loca=
lisation all in one package.&nbsp; In a way, for beginners, this is great, =
but the mechanics of the interface and interdependencies that this introduc=
es makes deviation from simple use a daunting task.&nbsp; Even now, 15 year=
s on from my first C++ program, I'm "frightened" of cajoling iostreams to d=
o anything complicated.<br><br>That said, it is all very well to complain a=
nd compile a list of grievances, but we need a) some solutions and b) a sam=
ple implementation of the same.&nbsp; I think the answer in a new library w=
ould be to take the functionality of iostreams and split it up, so that you=
 have something like:<br><ul style=3D"padding-top:0px;padding-bottom:0px;ma=
rgin-top:0px;margin-bottom:0px;list-style-type:disc"><li>streams classes th=
at are sources and/or sinks - these conceptually simply stream byte data fr=
om one place to another.&nbsp; So a file stream would simply take in the da=
ta provided and write out the data into the file, a string stream would do =
the same but store it in a string, etc.&nbsp; As now, you'd have separate c=
lasses relating to different source/sink types.&nbsp; These would all inher=
it from a single base class, largely to account for the use case where one =
may wish to store pointers to multiple streams of different types in a cont=
ainer to loop over during processing.</li><li>More string formatting functi=
ons.&nbsp; C++11 extended the &lt;string&gt; header to include conversions =
from most primitives into a string/wstring, but further formatting function=
s could be included by default - these would&nbsp; need to be written for u=
nicode types as well, I suspect.&nbsp; I'm not sure exactly how to start wi=
th the list of functionality required to replicate what one can achieve wit=
h iostreams, but perhaps other can offer guidance.<br></li></ul><p>Other as=
pects such as Unicode/Localisation should be dealt with by other libraries =
- it doesn't seem like it should be the purpose of a stream to do this, and=
 not every user of the streaming library should have to pay the cost by def=
ault, as at present.&nbsp; It seems perverse at the moment that one can imp=
rove the performance of iostreams only by introducing more complex code - t=
he inverse of the more typical equation where more code =3D&gt; more functi=
onality.</p><p>If we can pin down/agree a more suitable interface, I'm cert=
ainly happy to help provide a sample implementation for testing and improve=
ment.&nbsp; My ideas above can be discarded if they are not appropriate - I=
'm not wedded to them, but I thought they might provide a hook for criticis=
m!<br></p>On Saturday, November 17, 2012 7:36:37 PM UTC, Nicol Bolas wrote:=
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding=
-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-l=
eft-style:solid">
 =20

   =20
 =20
  <div>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">The Iostreams
      library in C++ has a problem. We have real, reasonable, legitimate
      C++ professional, who like C++ and use modern C++ idioms, telling
      people to not use iostreams. This is not due to differing ideas on
      C++ or C-in-classes-style development, but the simple practical
      realities of the situation.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">This

      kind of thing is indicative of a real problem in iostreams. In
      order to eventually solve that problem, we must first identify
      exactly what the problems are. This discussion should be focused
      on exactly that: identifying the problems with the library. Once
      we know what the real problems are, we can be certain that any new
      system that is proposed addresses them.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Note
      that this is about problems </span><span style=3D"color:rgb(0,0,0);fo=
nt-family:Arial;font-size:15px;font-style:italic;font-variant:normal;font-w=
eight:normal;text-decoration:none;vertical-align:baseline;background-color:=
transparent">within</span><span style=3D"color:rgb(0,0,0);font-family:Arial=
;font-size:15px;font-style:normal;font-variant:normal;font-weight:normal;te=
xt-decoration:none;vertical-align:baseline;background-color:transparent">
      iostreams. This is not about a list of things you <i>wish</i> it
      could do. This is about what iostreams actually tries to do but
      fails at in some way. So stuff like async file IO doesn=E2=80=99t go =
here,
      since iostreams doesn=E2=80=99t try to provide that.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Feel

      free to add to this list other flaws you see in iostreams. Or if
      you think that some of them are not real flaws, feel free to
      explain why.</span><br>
    <p dir=3D"ltr"><span style=3D"color:rgb(102,102,102);font-family:Georgi=
a;font-size:32px;font-style:italic;font-variant:normal;font-weight:normal;t=
ext-decoration:none;vertical-align:baseline;background-color:transparent">P=
erformance</span></p>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">This
      is the big one, generally the #1 reason why people suggest using
      C-standard file IO rather than iostreams.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Oftentimes,

      when people defend iostreams performance, they will say something
      to the effect of, =E2=80=9Ciostreams does far more than C-standard fi=
le
      IO.=E2=80=9D And that=E2=80=99s true. With iostreams, you have an ext=
ensible
      mechanism for writing any type directly to a stream. You can
      =E2=80=9Ceasily=E2=80=9D write new streambuf=E2=80=99s that will allo=
w you to (via runtime
      polymorphism) be able to work with existing code, thus allowing
      you to leverage your file IO for other forms of IO. You could even
      use a network pipe as an input or output stream.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">There=E2=80=99s

      one real problem with this logic, and it is exactly why people
      suggest C-standard file IO. Iostreams violates a fundamental
      precept of C++: pay <i>only</i> for what you </span><span style=3D"co=
lor:rgb(0,0,0);font-family:Arial;font-size:15px;font-style:italic;font-vari=
ant:normal;font-weight:normal;text-decoration:none;vertical-align:baseline;=
background-color:transparent">use</span><span style=3D"color:rgb(0,0,0);fon=
t-family:Arial;font-size:15px;font-style:normal;font-variant:normal;font-we=
ight:normal;text-decoration:none;vertical-align:baseline;background-color:t=
ransparent">.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Consider
    </span><a href=3D"http://stackoverflow.com/questions/4340396/does-the-c=
-standard-mandate-poor-performance-for-iostreams-or-am-i-just-deali" target=
=3D"_blank" onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fstackoverflow.com%2Fquestions%2F4340396%2Fdoes-the-c-standard-manda=
te-poor-performance-for-iostreams-or-am-i-just-deali\46sa\75D\46sntz\0751\4=
6usg\75AFQjCNFGm4Xsoek6kyzy5OpZ33R9EM5ShA';return true;" onclick=3D"this.hr=
ef=3D'http://www.google.com/url?q\75http%3A%2F%2Fstackoverflow.com%2Fquesti=
ons%2F4340396%2Fdoes-the-c-standard-mandate-poor-performance-for-iostreams-=
or-am-i-just-deali\46sa\75D\46sntz\0751\46usg\75AFQjCNFGm4Xsoek6kyzy5OpZ33R=
9EM5ShA';return true;"><span style=3D"color:rgb(17,85,204);font-family:Aria=
l;font-size:15px;font-style:normal;font-variant:normal;font-weight:normal;t=
ext-decoration:underline;vertical-align:baseline;background-color:transpare=
nt">this
        suite of benchmarks</span></a><span style=3D"color:rgb(0,0,0);font-=
family:Arial;font-size:15px;font-style:normal;font-variant:normal;font-weig=
ht:normal;text-decoration:none;vertical-align:baseline;background-color:tra=
nsparent">.
      This code doesn=E2=80=99t do file IO; it writes directly to a string.=
 All
      it=E2=80=99s doing is measuring the time it takes to append 4-charact=
ers
      to a string. A lot. It uses a `char[]` as a useful control. It
      also tests the use of `vector&lt;char&gt;` (presumably
      `basic_string` would have similar results). Therefore, this is a
      solid test for the efficiency of the iostreams codebase itself.</span=
><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Obviously
      there will be some efficiency loss. But consider the numbers in
      the results.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">The
      ostringstream is more than </span><span style=3D"color:rgb(0,0,0);fon=
t-family:Arial;font-size:15px;font-style:italic;font-variant:normal;font-we=
ight:normal;text-decoration:none;vertical-align:baseline;background-color:t=
ransparent">full
      order of magnitude</span><span style=3D"color:rgb(0,0,0);font-family:=
Arial;font-size:15px;font-style:normal;font-variant:normal;font-weight:norm=
al;text-decoration:none;vertical-align:baseline;background-color:transparen=
t">
      slower than the control. It=E2=80=99s almost 100x in some cases. Note=
 that
      it=E2=80=99s not using &lt;&lt; to write to the stream; it=E2=80=99s =
using
      `ostream::write()`.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Note

      that the vector&lt;char&gt; implementations are fairly comparable
      to the control, usually being around 1x-4x the speed. So clearly
      this is something in ostringstream.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Now,

      you might say that one could use the stringbuf directly. And that
      was done. While it does improve performance over the ostringstream
      case substantially (generally half to a quarter the performance),
      it=E2=80=99s still over 10x slower than the control or most
      vector&lt;char&gt; implementations.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Why?
      The stringbuf operations ought to be a thin wrapper over
      std::string. After all, that=E2=80=99s what was asked for.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Where

      does this inefficiency come from? I haven=E2=80=99t done any extensiv=
e
      profiling analysis, but my educated guesses are from two places:
      virtual function overhead and an interface that does too much.</span>=
<br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">ostringstream

      is supposed to be able to be used as an ostream for
      runtime-polymorphism. But here=E2=80=99s where the C++ maxim comes in=
to
      play. Runtime-polymorphism is </span><span style=3D"color:rgb(0,0,0);=
font-family:Arial;font-size:15px;font-style:italic;font-variant:normal;font=
-weight:normal;text-decoration:none;vertical-align:baseline;background-colo=
r:transparent">not
      being used here</span><span style=3D"color:rgb(0,0,0);font-family:Ari=
al;font-size:15px;font-style:normal;font-variant:normal;font-weight:normal;=
text-decoration:none;vertical-align:baseline;background-color:transparent">=
..
      Every function call should be able to be statically dispatched.
      And it is, but all of the virtual machinery comes from <i>within</i>
      ostringstream.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">This
      problem seems to come mostly from the fact that basic_ostream,
      which does most of the leg-work for ostringstream, has no specific
      knowledge of its stream type. Therefore it's always a virtual
      call. And it may be doing many such virtual calls.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">You

      can achieve the same runtime polymorphism (being able to overload
      operator&lt;&lt; for any stream) by using a static set of stream
      classes, tightly coupled to their specific streambufs, and a
      single =E2=80=9Canystream=E2=80=9D type that those streams can be con=
verted into.
      It would use std::function-style type erasure to remember the
      original type and feed function calls to it. It would use a single
      function call to initiate each write operation, rather than what
      appears to be many virtual calls within each write.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Then,

      there=E2=80=99s the fact that streambuf itself is overdesigned. strin=
gbuf
      ought to be a simple interface wrapper around a std::string, but
      it=E2=80=99s not. It=E2=80=99s a complex thing. It has </span><span s=
tyle=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-style:italic=
;font-variant:normal;font-weight:normal;text-decoration:none;vertical-align=
:baseline;background-color:transparent">locale
      support</span><span style=3D"color:rgb(0,0,0);font-family:Arial;font-=
size:15px;font-style:normal;font-variant:normal;font-weight:normal;text-dec=
oration:none;vertical-align:baseline;background-color:transparent">
      of all things. Why? Isn=E2=80=99t that something that should be handl=
ed at
      the stream level?</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">This

      API has no way to get a low-level interface to a
      file/string/whatever. There=E2=80=99s no way to just open a filebuf a=
nd
      blast the file into some memory, or to shove some memory out of a
      filebuf. It will always employ the locale machinery even if you
      didn=E2=80=99t ask for it. It will always make these internal virtual
      calls, even if they are completely statically dispatched.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">With

      iostreams, you are paying for a lot of stuff that you don=E2=80=99t
      frequently use. At the stream level, it makes sense that you=E2=80=99=
re
      paying for certain machinery (though again, some way to say that
      you=E2=80=99re not using some of it would be nice). At the buffer lev=
el,
      it does not, since that is the lowest level you=E2=80=99re allowed to=
 use.</span><br>
    <p dir=3D"ltr"><span style=3D"color:rgb(102,102,102);font-family:Georgi=
a;font-size:32px;font-style:italic;font-variant:normal;font-weight:normal;t=
ext-decoration:none;vertical-align:baseline;background-color:transparent">U=
tility</span></p>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">While
      performance is the big issue, it=E2=80=99s not the only one.</span><b=
r>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">The

      biggest selling point for iostreams is the ability to extend its
      formatted writing functionality. You can overload operator&lt;&lt;
      for various types and simply use them. You can=E2=80=99t do that with
      fprintf. And thanks to ADL, it will work just fine for classes in
      namespaces. You can create new streambuf types and even streams if
      you like. All relatively easily.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Here=E2=80=99s
      the problem, and it is admittedly one that is subjective: printf
      is really nice syntax.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">It=E2=80=99s

      very compact, for one. Once you understand the basic syntax of it,
      it=E2=80=99s very easy to see what=E2=80=99s going on. Especially for=
 complex
      formatting. Just consider the physical size difference between
      these two:</span><br>
    <pre><tt><span style=3D"color:rgb(0,0,0);font-size:15px;font-style:norm=
al;font-variant:normal;font-weight:normal;text-decoration:none;vertical-ali=
gn:baseline;background-color:transparent">snprintf(..., =E2=80=9C0x%08x=E2=
=80=9D, integer);</span></tt></pre>
    <pre><tt><span style=3D"color:rgb(0,0,0);font-size:15px;font-style:norm=
al;font-variant:normal;font-weight:normal;text-decoration:none;vertical-ali=
gn:baseline;background-color:transparent"></span></tt></pre>
    <pre><tt><span style=3D"color:rgb(0,0,0);font-size:15px;font-style:norm=
al;font-variant:normal;font-weight:normal;text-decoration:none;vertical-ali=
gn:baseline;background-color:transparent">stream &lt;&lt; "0x" &lt;&lt; std=
::right &lt;&lt; std::hex &lt;&lt; std::setw(8) &lt;&lt; iVal &lt;&lt; std:=
:endl;</span></tt></pre>
    <pre><span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;f=
ont-style:normal;font-variant:normal;font-weight:normal;text-decoration:non=
e;vertical-align:baseline;background-color:transparent"></span></pre>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">It
      may take a bit longer to become used to the printf version, but
      this is something you can easily look up in a reference.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">Plus,

      it makes it much easier to do translations on formatted strings.
      You can look the pattern string up in a table that changes from
      language to language. This is rather more difficult in iostreams,
      though not impossible. Granted, pattern changes may not be enough,
      as some languages have different subject/verb/object grammars that
      would require reshuffling patterns around. However, there are
      printf-style systems that do allow for reshuffling, whereas no
      such mechanism exists for iostream-style.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent">C++

      used the &lt;&lt; method because the alternatives were less
      flexible. Boost.Format and other systems show that C++03 did not
      really have to use this mechanism to achieve the extensibility
      features that iostreams provide.</span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><br>
    <span style=3D"color:rgb(0,0,0);font-family:Arial;font-size:15px;font-s=
tyle:normal;font-variant:normal;font-weight:normal;text-decoration:none;ver=
tical-align:baseline;background-color:transparent"></span><span style=3D"co=
lor:rgb(0,0,0);font-family:Arial;font-size:15px;font-style:normal;font-vari=
ant:normal;font-weight:normal;text-decoration:none;vertical-align:baseline;=
background-color:transparent">What
      do you think? Are there other issues in iostreams that need to be
      mentioned?</span><br>
  </div>

</blockquote></div>

<p></p>

-- <br>
&nbsp;<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/bMzBAHgb5_o/unsubscribe" target=3D"_blan=
k" onmousedown=3D"this.href=3D'https://groups.google.com/a/isocpp.org/d/top=
ic/std-proposals/bMzBAHgb5_o/unsubscribe';return true;" onclick=3D"this.hre=
f=3D'https://groups.google.com/a/isocpp.org/d/topic/std-proposals/bMzBAHgb5=
_o/unsubscribe';return true;">https://groups.google.com/a/<wbr>isocpp.org/d=
/topic/std-<wbr>proposals/bMzBAHgb5_o/<wbr>unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a>std-=
proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a>std-pr...@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank" onmousedown=3D"this.href=3D'http://groups=
..google.com/a/isocpp.org/group/std-proposals/';return true;" onclick=3D"thi=
s.href=3D'http://groups.google.com/a/isocpp.org/group/std-proposals/';retur=
n true;">http://groups.google.com/a/<wbr>isocpp.org/group/std-<wbr>proposal=
s/</a>.<br>
</div></div>
</div>

</blockquote></div></div></blockquote></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_254_30430604.1389683931111--

.


Author: fritzpoll <fred.pollard@gmail.com>
Date: Mon, 13 Jan 2014 23:48:51 -0800 (PST)
Raw View
I missed your reference to variadic templates. I presume this would be for compile time string parsing?  In which case, although potentially complex to implement, a fast type safe version is possible I suppose.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Mon, 13 Jan 2014 23:56:06 -0800
Raw View
--001a11330af2b4a6d604efe988ee
Content-Type: text/plain; charset=UTF-8

Or just for accepting the printf style arguments in a safer way. E.g.

format(sink, "foo %0 bar %1", 21, 42);

could be expressed as

template<typename Sink, typename... Args>
void format(Sink& output, char const* spec, Args... args)
{
   // ....
}

fastformat has a similar API.

Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal


On Mon, Jan 13, 2014 at 11:48 PM, fritzpoll <fred.pollard@gmail.com> wrote:

> I missed your reference to variadic templates. I presume this would be for
> compile time string parsing?  In which case, although potentially complex
> to implement, a fast type safe version is possible I suppose.
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a11330af2b4a6d604efe988ee
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><div><div>Or just for accepting the printf style argu=
ments in a safer way. E.g.<br><br></div>format(sink, &quot;foo %0 bar %1&qu=
ot;, 21, 42);<br><br></div>could be expressed as<br><br></div><div>template=
&lt;typename Sink, typename... Args&gt;<br>

</div><div>void format(Sink&amp; output, char const* spec, Args... args)<br=
>{<br>=C2=A0=C2=A0 // ....<br>}<br><br></div><div>fastformat has a similar =
API.<br></div></div><div class=3D"gmail_extra"><br clear=3D"all"><div><div =
dir=3D"ltr">

<div>Billy O&#39;Neal</div><div><a href=3D"https://bitbucket.org/BillyONeal=
/" target=3D"_blank">https://github.com/BillyONeal/</a></div><div><a href=
=3D"http://stackoverflow.com/users/82320/billy-oneal" target=3D"_blank">htt=
p://stackoverflow.com/users/82320/billy-oneal</a></div>

</div></div>
<br><br><div class=3D"gmail_quote">On Mon, Jan 13, 2014 at 11:48 PM, fritzp=
oll <span dir=3D"ltr">&lt;<a href=3D"mailto:fred.pollard@gmail.com" target=
=3D"_blank">fred.pollard@gmail.com</a>&gt;</span> wrote:<br><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pa=
dding-left:1ex">

I missed your reference to variadic templates. I presume this would be for =
compile time string parsing? =C2=A0In which case, although potentially comp=
lex to implement, a fast type safe version is possible I suppose.<br>
<span class=3D"HOEnZb"><font color=3D"#888888"><br>
--<br>
<br>
---<br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">std-propo=
sals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</font></span></blockquote></div><br></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a11330af2b4a6d604efe988ee--

.


Author: fritzpoll <fred.pollard@gmail.com>
Date: Tue, 14 Jan 2014 10:39:55 -0800 (PST)
Raw View
------=_Part_412_5367894.1389724795727
Content-Type: text/plain; charset=UTF-8

I do need to dig through FastFormat and see how it is implemented, because
it seems very powerful considering it uses no TMP.

Aside from type-safety, are there any arguments against using a format
string?  The only other one I'm aware of is the notion that it is another
sub-language that one needs to get a reference for.  To my mind, though,
that argument could just as easily apply to any library, including the
present IOStreams.



On Tuesday, January 14, 2014 7:56:06 AM UTC, Billy O'Neal wrote:
>
> Or just for accepting the printf style arguments in a safer way. E.g.
>
> format(sink, "foo %0 bar %1", 21, 42);
>
> could be expressed as
>
> template<typename Sink, typename... Args>
> void format(Sink& output, char const* spec, Args... args)
> {
>    // ....
> }
>
> fastformat has a similar API.
>
> Billy O'Neal
> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
> http://stackoverflow.com/users/82320/billy-oneal
>
>
> On Mon, Jan 13, 2014 at 11:48 PM, fritzpoll <fred.p...@gmail.com<javascript:>
> > wrote:
>
>> I missed your reference to variadic templates. I presume this would be
>> for compile time string parsing?  In which case, although potentially
>> complex to implement, a fast type safe version is possible I suppose.
>>
>> --
>>
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to std-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> Visit this group at
>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>
>
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_412_5367894.1389724795727
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I do need to dig through FastFormat and see how it is impl=
emented, because it seems very powerful considering it uses no TMP.<br><br>=
Aside from type-safety, are there any arguments against using a format stri=
ng?&nbsp; The only other one I'm aware of is the notion that it is another =
sub-language that one needs to get a reference for.&nbsp; To my mind, thoug=
h, that argument could just as easily apply to any library, including the p=
resent IOStreams.<br><br><br><br>On Tuesday, January 14, 2014 7:56:06 AM UT=
C, Billy O'Neal wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div><div><div>Or just for accepting the printf style arguments in=
 a safer way. E.g.<br><br></div>format(sink, "foo %0 bar %1", 21, 42);<br><=
br></div>could be expressed as<br><br></div><div>template&lt;typename Sink,=
 typename... Args&gt;<br>

</div><div>void format(Sink&amp; output, char const* spec, Args... args)<br=
>{<br>&nbsp;&nbsp; // ....<br>}<br><br></div><div>fastformat has a similar =
API.<br></div></div><div><br clear=3D"all"><div><div dir=3D"ltr">

<div>Billy O'Neal</div><div><a href=3D"https://bitbucket.org/BillyONeal/" t=
arget=3D"_blank" onmousedown=3D"this.href=3D'https://www.google.com/url?q\7=
5https%3A%2F%2Fbitbucket.org%2FBillyONeal%2F\46sa\75D\46sntz\0751\46usg\75A=
FQjCNEUaaIry0cea0l0vX6ztWgwQ7_4Lg';return true;" onclick=3D"this.href=3D'ht=
tps://www.google.com/url?q\75https%3A%2F%2Fbitbucket.org%2FBillyONeal%2F\46=
sa\75D\46sntz\0751\46usg\75AFQjCNEUaaIry0cea0l0vX6ztWgwQ7_4Lg';return true;=
">https://github.com/BillyONeal/</a></div><div><a href=3D"http://stackoverf=
low.com/users/82320/billy-oneal" target=3D"_blank" onmousedown=3D"this.href=
=3D'http://www.google.com/url?q\75http%3A%2F%2Fstackoverflow.com%2Fusers%2F=
82320%2Fbilly-oneal\46sa\75D\46sntz\0751\46usg\75AFQjCNHY_gA133vyg0yY-U2PNM=
VA8cCSBg';return true;" onclick=3D"this.href=3D'http://www.google.com/url?q=
\75http%3A%2F%2Fstackoverflow.com%2Fusers%2F82320%2Fbilly-oneal\46sa\75D\46=
sntz\0751\46usg\75AFQjCNHY_gA133vyg0yY-U2PNMVA8cCSBg';return true;">http://=
stackoverflow.com/<wbr>users/82320/billy-oneal</a></div>

</div></div>
<br><br><div class=3D"gmail_quote">On Mon, Jan 13, 2014 at 11:48 PM, fritzp=
oll <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obf=
uscated-mailto=3D"pWVNoKVuBHUJ" onmousedown=3D"this.href=3D'javascript:';re=
turn true;" onclick=3D"this.href=3D'javascript:';return true;">fred.p...@gm=
ail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D=
"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

I missed your reference to variadic templates. I presume this would be for =
compile time string parsing? &nbsp;In which case, although potentially comp=
lex to implement, a fast type safe version is possible I suppose.<br>
<span><font color=3D"#888888"><br>
--<br>
<br>
---<br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
pWVNoKVuBHUJ" onmousedown=3D"this.href=3D'javascript:';return true;" onclic=
k=3D"this.href=3D'javascript:';return true;">std-proposal...@<wbr>isocpp.or=
g</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"pWVNoKVuBHUJ" onmousedown=3D"this.href=3D'java=
script:';return true;" onclick=3D"this.href=3D'javascript:';return true;">s=
td-pr...@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank" onmousedown=3D"this.href=3D'http://groups=
..google.com/a/isocpp.org/group/std-proposals/';return true;" onclick=3D"thi=
s.href=3D'http://groups.google.com/a/isocpp.org/group/std-proposals/';retur=
n true;">http://groups.google.com/a/<wbr>isocpp.org/group/std-<wbr>proposal=
s/</a>.<br>
</font></span></blockquote></div><br></div>
</blockquote></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_412_5367894.1389724795727--

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Tue, 14 Jan 2014 14:26:42 -0800 (PST)
Raw View
------=_Part_4227_20594025.1389738402057
Content-Type: text/plain; charset=UTF-8

I was thinking of Billy's use of variadic templates, to let the formatting
function know the types.

It is correct that it is possible to pass incorrect formatting parameters
for the type without this being noticed at compile time. However, the
verbosity of your other variant is very similar to that of iostream
manipulators and those seem to be too hard to write for most programmers,
who instead go with classic printf.

Fastformat is fast because you provide it with the destination string or
stream as the first parameter. This allows the formatting to go on without
having to create temporary string objects just to immediately send them to
the stream.

As we are thinking about standard features it would be natural to use a
concept for the destination so that different destinations adhering to the
concept (basically a push_back() or something).

FastFormat does not seem to process any formatting parameters, just
argument numbers. My worry is that if we put the formatting stuff with the
values to format as fritzpoll suggests the whole new feature will be
disregarded as it is too far from printf. I think it has a value to be able
to look at just the formatting string and get an idea of how the output
string will look. Some languages even provide "Value: ###.##" notation to
set the number of digits (maybe Cobol?), which is very illustrative.

From a performance standpoint we have different drawbacks in each solution:
For printf and other formatters with format strings you have to parse the
string itself to find the % clauses for each call. For
the chained modifiers case you'd have to perform many more function calls,
and it is tempting to create the output of string_format() as a string
which is then inserted in the formatting string, which incurs a further
heap alloation of this string. A more clever implementation may have
srting_format() be a temporary object which for instance could have an
operator<< with an ostream to the left and which renders the formatted
value directly onto the stream. Building this object could be slow or fast
depending on compiler quality.

What I would like is a possibility to do the parsing of format strings and
the corresponding checking of formatting parameter/type compatiblity once
and for all, at the latest at program start. However, this does not seem to
be possible today. The closest we get is a function static object which can
do the parsing and format parameter checking once and for all, but not
until the message is really to be created. I have tried this approach in
one application and it got really ugly when applied to error messages:
Instead of the real error message you often got an error regarding type
mismatching (as errors are often hard to provoke it is also hard to get the
error message formatting tested). What is needed is a file static object
declared inside a function (or even better, inside and expression). Scary!

Den tisdagen den 14:e januari 2014 kl. 19:39:55 UTC+1 skrev fritzpoll:

I do need to dig through FastFormat and see how it is implemented, because
> it seems very powerful considering it uses no TMP.
>
> Aside from type-safety, are there any arguments against using a format
> string?  The only other one I'm aware of is the notion that it is another
> sub-language that one needs to get a reference for.  To my mind, though,
> that argument could just as easily apply to any library, including the
> present IOStreams.
>
>
>
> On Tuesday, January 14, 2014 7:56:06 AM UTC, Billy O'Neal wrote:
>>
>> Or just for accepting the printf style arguments in a safer way. E.g.
>>
>> format(sink, "foo %0 bar %1", 21, 42);
>>
>> could be expressed as
>>
>> template<typename Sink, typename... Args>
>> void format(Sink& output, char const* spec, Args... args)
>> {
>>    // ....
>> }
>>
>> fastformat has a similar API.
>>
>> Billy O'Neal
>> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
>> http://stackoverflow.com/users/82320/billy-oneal
>>
>>
>> On Mon, Jan 13, 2014 at 11:48 PM, fritzpoll <fred.p...@gmail.com> wrote:
>>
>>> I missed your reference to variadic templates. I presume this would be
>>> for compile time string parsing?  In which case, although potentially
>>> complex to implement, a fast type safe version is possible I suppose.
>>>
>>> --
>>>
>>> ---
>>> You received this message because you are subscribed to the Google
>>> Groups "ISO C++ Standard - Future Proposals" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to std-proposal...@isocpp.org.
>>> To post to this group, send email to std-pr...@isocpp.org.
>>> Visit this group at
>>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>>
>>
>>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_4227_20594025.1389738402057
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I was thinking of Billy's use of variadic templates, to le=
t the formatting function know the types.<div><br></div><div>It is correct =
that it is possible to pass incorrect formatting parameters for the type wi=
thout this being noticed at compile time. However, the verbosity of your ot=
her variant is very similar to that of iostream manipulators and those seem=
 to be too hard to write for most programmers, who instead go with classic =
printf.</div><div><br></div><div>Fastformat is fast because you provide it =
with the destination string or stream as the first parameter. This allows t=
he formatting to go on without having to create temporary string objects ju=
st to immediately send them to the stream.</div><div><br></div><div>As we a=
re thinking about standard features it would be natural to use a concept fo=
r the destination so that different destinations adhering to the concept (b=
asically a push_back() or something).</div><div><br></div><div>FastFormat d=
oes not seem to process any formatting parameters, just argument numbers. M=
y worry is that if we put the formatting stuff with the values to format as=
 fritzpoll suggests the whole new feature will be disregarded as it is too =
far from printf. I think it has a value to be able to look at just the form=
atting string and get an idea of how the output string will look. Some lang=
uages even provide "Value: ###.##" notation to set the number of digits (ma=
ybe Cobol?), which is very illustrative.</div><div><br></div><div>From a pe=
rformance standpoint we have different drawbacks in each solution: For prin=
tf and other formatters with format strings you have to parse the string it=
self to find the % clauses for each call. For&nbsp;<br>the chained modifier=
s case you'd have to perform many more function calls, and it is tempting t=
o create the output of string_format() as a string which is then inserted i=
n the formatting string, which incurs a further heap alloation of this stri=
ng. A more clever implementation may have srting_format() be a temporary ob=
ject which for instance could have an operator&lt;&lt; with an ostream to t=
he left and which renders the formatted value directly onto the stream. Bui=
lding this object could be slow or fast depending on compiler quality.</div=
><div><br></div><div>What I would like is a possibility to do the parsing o=
f format strings and the corresponding checking of formatting parameter/typ=
e compatiblity once and for all, at the latest at program start. However, t=
his does not seem to be possible today. The closest we get is a function st=
atic object which can do the parsing and format parameter checking once and=
 for all, but not until the message is really to be created. I have tried t=
his approach in one application and it got really ugly when applied to erro=
r messages: Instead of the real error message you often got an error regard=
ing type mismatching (as errors are often hard to provoke it is also hard t=
o get the error message formatting tested). What is needed is a file static=
 object declared inside a function (or even better, inside and expression).=
 Scary!</div><div><br></div><div>Den tisdagen den 14:e januari 2014 kl. 19:=
39:55 UTC+1 skrev fritzpoll:</div><div><br><blockquote class=3D"gmail_quote=
" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding=
-left: 1ex;"><div dir=3D"ltr">I do need to dig through FastFormat and see h=
ow it is implemented, because it seems very powerful considering it uses no=
 TMP.<br><br>Aside from type-safety, are there any arguments against using =
a format string?&nbsp; The only other one I'm aware of is the notion that i=
t is another sub-language that one needs to get a reference for.&nbsp; To m=
y mind, though, that argument could just as easily apply to any library, in=
cluding the present IOStreams.<br><br><br><br>On Tuesday, January 14, 2014 =
7:56:06 AM UTC, Billy O'Neal wrote:<blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div dir=3D"ltr"><div><div><div>Or just for accepting the printf style arg=
uments in a safer way. E.g.<br><br></div>format(sink, "foo %0 bar %1", 21, =
42);<br><br></div>could be expressed as<br><br></div><div>template&lt;typen=
ame Sink, typename... Args&gt;<br>

</div><div>void format(Sink&amp; output, char const* spec, Args... args)<br=
>{<br>&nbsp;&nbsp; // ....<br>}<br><br></div><div>fastformat has a similar =
API.<br></div></div><div><br clear=3D"all"><div><div dir=3D"ltr">

<div>Billy O'Neal</div><div><a href=3D"https://bitbucket.org/BillyONeal/" t=
arget=3D"_blank" onmousedown=3D"this.href=3D'https://www.google.com/url?q\7=
5https%3A%2F%2Fbitbucket.org%2FBillyONeal%2F\46sa\75D\46sntz\0751\46usg\75A=
FQjCNEUaaIry0cea0l0vX6ztWgwQ7_4Lg';return true;" onclick=3D"this.href=3D'ht=
tps://www.google.com/url?q\75https%3A%2F%2Fbitbucket.org%2FBillyONeal%2F\46=
sa\75D\46sntz\0751\46usg\75AFQjCNEUaaIry0cea0l0vX6ztWgwQ7_4Lg';return true;=
">https://github.com/BillyONeal/</a></div><div><a href=3D"http://stackoverf=
low.com/users/82320/billy-oneal" target=3D"_blank" onmousedown=3D"this.href=
=3D'http://www.google.com/url?q\75http%3A%2F%2Fstackoverflow.com%2Fusers%2F=
82320%2Fbilly-oneal\46sa\75D\46sntz\0751\46usg\75AFQjCNHY_gA133vyg0yY-U2PNM=
VA8cCSBg';return true;" onclick=3D"this.href=3D'http://www.google.com/url?q=
\75http%3A%2F%2Fstackoverflow.com%2Fusers%2F82320%2Fbilly-oneal\46sa\75D\46=
sntz\0751\46usg\75AFQjCNHY_gA133vyg0yY-U2PNMVA8cCSBg';return true;">http://=
stackoverflow.com/<wbr>users/82320/billy-oneal</a></div>

</div></div>
<br><br><div class=3D"gmail_quote">On Mon, Jan 13, 2014 at 11:48 PM, fritzp=
oll <span dir=3D"ltr">&lt;<a>fred.p...@gmail.com</a>&gt;</span> wrote:<br><=
blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px=
 #ccc solid;padding-left:1ex">

I missed your reference to variadic templates. I presume this would be for =
compile time string parsing? &nbsp;In which case, although potentially comp=
lex to implement, a fast type safe version is possible I suppose.<br>
<span><font color=3D"#888888"><br>
--<br>
<br>
---<br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a>std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a>std-pr...@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank" onmousedown=3D"this.href=3D'http://groups=
..google.com/a/isocpp.org/group/std-proposals/';return true;" onclick=3D"thi=
s.href=3D'http://groups.google.com/a/isocpp.org/group/std-proposals/';retur=
n true;">http://groups.google.com/a/<wbr>isocpp.org/group/std-<wbr>proposal=
s/</a>.<br>
</font></span></blockquote></div><br></div>
</blockquote></div></blockquote></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_4227_20594025.1389738402057--

.


Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Tue, 14 Jan 2014 15:30:10 -0800
Raw View
--001a11332d16261f4404eff69517
Content-Type: text/plain; charset=UTF-8

> It is correct that it is possible to pass incorrect formatting parameters
for the type without this being noticed at compile time.

I don't see this as a problem. The reason printf's behavior is bad here is
that an incorrect string results in undefined behavior at run time. With a
variadic template function, if the string is invalid, the program can go to
std::terminate() rather than incur undefined behavior. (This is no
different than e.g. passing a null pointer to an API documented to require
a pointer to data)

Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal


On Tue, Jan 14, 2014 at 2:26 PM, Bengt Gustafsson <
bengt.gustafsson@beamways.com> wrote:

> I was thinking of Billy's use of variadic templates, to let the formatting
> function know the types.
>
> It is correct that it is possible to pass incorrect formatting parameters
> for the type without this being noticed at compile time. However, the
> verbosity of your other variant is very similar to that of iostream
> manipulators and those seem to be too hard to write for most programmers,
> who instead go with classic printf.
>
> Fastformat is fast because you provide it with the destination string or
> stream as the first parameter. This allows the formatting to go on without
> having to create temporary string objects just to immediately send them to
> the stream.
>
> As we are thinking about standard features it would be natural to use a
> concept for the destination so that different destinations adhering to the
> concept (basically a push_back() or something).
>
> FastFormat does not seem to process any formatting parameters, just
> argument numbers. My worry is that if we put the formatting stuff with the
> values to format as fritzpoll suggests the whole new feature will be
> disregarded as it is too far from printf. I think it has a value to be able
> to look at just the formatting string and get an idea of how the output
> string will look. Some languages even provide "Value: ###.##" notation to
> set the number of digits (maybe Cobol?), which is very illustrative.
>
> From a performance standpoint we have different drawbacks in each
> solution: For printf and other formatters with format strings you have to
> parse the string itself to find the % clauses for each call. For
> the chained modifiers case you'd have to perform many more function calls,
> and it is tempting to create the output of string_format() as a string
> which is then inserted in the formatting string, which incurs a further
> heap alloation of this string. A more clever implementation may have
> srting_format() be a temporary object which for instance could have an
> operator<< with an ostream to the left and which renders the formatted
> value directly onto the stream. Building this object could be slow or fast
> depending on compiler quality.
>
> What I would like is a possibility to do the parsing of format strings and
> the corresponding checking of formatting parameter/type compatiblity once
> and for all, at the latest at program start. However, this does not seem to
> be possible today. The closest we get is a function static object which can
> do the parsing and format parameter checking once and for all, but not
> until the message is really to be created. I have tried this approach in
> one application and it got really ugly when applied to error messages:
> Instead of the real error message you often got an error regarding type
> mismatching (as errors are often hard to provoke it is also hard to get the
> error message formatting tested). What is needed is a file static object
> declared inside a function (or even better, inside and expression). Scary!
>
> Den tisdagen den 14:e januari 2014 kl. 19:39:55 UTC+1 skrev fritzpoll:
>
> I do need to dig through FastFormat and see how it is implemented, because
>> it seems very powerful considering it uses no TMP.
>>
>> Aside from type-safety, are there any arguments against using a format
>> string?  The only other one I'm aware of is the notion that it is another
>> sub-language that one needs to get a reference for.  To my mind, though,
>> that argument could just as easily apply to any library, including the
>> present IOStreams.
>>
>>
>>
>> On Tuesday, January 14, 2014 7:56:06 AM UTC, Billy O'Neal wrote:
>>>
>>> Or just for accepting the printf style arguments in a safer way. E.g.
>>>
>>> format(sink, "foo %0 bar %1", 21, 42);
>>>
>>> could be expressed as
>>>
>>> template<typename Sink, typename... Args>
>>> void format(Sink& output, char const* spec, Args... args)
>>> {
>>>    // ....
>>> }
>>>
>>> fastformat has a similar API.
>>>
>>> Billy O'Neal
>>> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
>>> http://stackoverflow.com/users/82320/billy-oneal
>>>
>>>
>>> On Mon, Jan 13, 2014 at 11:48 PM, fritzpoll <fred.p...@gmail.com> wrote:
>>>
>>>> I missed your reference to variadic templates. I presume this would be
>>>> for compile time string parsing?  In which case, although potentially
>>>> complex to implement, a fast type safe version is possible I suppose.
>>>>
>>>> --
>>>>
>>>> ---
>>>> You received this message because you are subscribed to the Google
>>>> Groups "ISO C++ Standard - Future Proposals" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>> an email to std-proposal...@isocpp.org.
>>>> To post to this group, send email to std-pr...@isocpp.org.
>>>> Visit this group at http://groups.google.com/a/isocpp.org/group/std-
>>>> proposals/.
>>>>
>>>
>>>  --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a11332d16261f4404eff69517
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>&gt; It is correct that it is possible to pass incorr=
ect formatting parameters for the type without this being noticed at compil=
e time.</div><div><br></div><div>I don&#39;t see this as a problem. The rea=
son printf&#39;s behavior is bad here is that an incorrect string results i=
n undefined behavior at run time. With a variadic template function, if the=
 string is invalid, the program can go to std::terminate() rather than incu=
r undefined behavior. (This is no different than e.g. passing a null pointe=
r to an API documented to require a pointer to data)</div>

</div><div class=3D"gmail_extra"><br clear=3D"all"><div><div dir=3D"ltr"><d=
iv>Billy O&#39;Neal</div><div><a href=3D"https://bitbucket.org/BillyONeal/"=
 target=3D"_blank">https://github.com/BillyONeal/</a></div><div><a href=3D"=
http://stackoverflow.com/users/82320/billy-oneal" target=3D"_blank">http://=
stackoverflow.com/users/82320/billy-oneal</a></div>

</div></div>
<br><br><div class=3D"gmail_quote">On Tue, Jan 14, 2014 at 2:26 PM, Bengt G=
ustafsson <span dir=3D"ltr">&lt;<a href=3D"mailto:bengt.gustafsson@beamways=
..com" target=3D"_blank">bengt.gustafsson@beamways.com</a>&gt;</span> wrote:=
<br>

<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">I was thinking of Billy&#39=
;s use of variadic templates, to let the formatting function know the types=
..<div>

<br></div><div>It is correct that it is possible to pass incorrect formatti=
ng parameters for the type without this being noticed at compile time. Howe=
ver, the verbosity of your other variant is very similar to that of iostrea=
m manipulators and those seem to be too hard to write for most programmers,=
 who instead go with classic printf.</div>

<div><br></div><div>Fastformat is fast because you provide it with the dest=
ination string or stream as the first parameter. This allows the formatting=
 to go on without having to create temporary string objects just to immedia=
tely send them to the stream.</div>

<div><br></div><div>As we are thinking about standard features it would be =
natural to use a concept for the destination so that different destinations=
 adhering to the concept (basically a push_back() or something).</div>
<div>
<br></div><div>FastFormat does not seem to process any formatting parameter=
s, just argument numbers. My worry is that if we put the formatting stuff w=
ith the values to format as fritzpoll suggests the whole new feature will b=
e disregarded as it is too far from printf. I think it has a value to be ab=
le to look at just the formatting string and get an idea of how the output =
string will look. Some languages even provide &quot;Value: ###.##&quot; not=
ation to set the number of digits (maybe Cobol?), which is very illustrativ=
e.</div>

<div><br></div><div>From a performance standpoint we have different drawbac=
ks in each solution: For printf and other formatters with format strings yo=
u have to parse the string itself to find the % clauses for each call. For=
=C2=A0<br>

the chained modifiers case you&#39;d have to perform many more function cal=
ls, and it is tempting to create the output of string_format() as a string =
which is then inserted in the formatting string, which incurs a further hea=
p alloation of this string. A more clever implementation may have srting_fo=
rmat() be a temporary object which for instance could have an operator&lt;&=
lt; with an ostream to the left and which renders the formatted value direc=
tly onto the stream. Building this object could be slow or fast depending o=
n compiler quality.</div>

<div><br></div><div>What I would like is a possibility to do the parsing of=
 format strings and the corresponding checking of formatting parameter/type=
 compatiblity once and for all, at the latest at program start. However, th=
is does not seem to be possible today. The closest we get is a function sta=
tic object which can do the parsing and format parameter checking once and =
for all, but not until the message is really to be created. I have tried th=
is approach in one application and it got really ugly when applied to error=
 messages: Instead of the real error message you often got an error regardi=
ng type mismatching (as errors are often hard to provoke it is also hard to=
 get the error message formatting tested). What is needed is a file static =
object declared inside a function (or even better, inside and expression). =
Scary!</div>

<div><br></div><div>Den tisdagen den 14:e januari 2014 kl. 19:39:55 UTC+1 s=
krev fritzpoll:</div><div><br><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);=
border-left-width:1px;border-left-style:solid">

<div dir=3D"ltr">I do need to dig through FastFormat and see how it is impl=
emented, because it seems very powerful considering it uses no TMP.<br><br>=
Aside from type-safety, are there any arguments against using a format stri=
ng?=C2=A0 The only other one I&#39;m aware of is the notion that it is anot=
her sub-language that one needs to get a reference for.=C2=A0 To my mind, t=
hough, that argument could just as easily apply to any library, including t=
he present IOStreams.<br>

<br><br><br>On Tuesday, January 14, 2014 7:56:06 AM UTC, Billy O&#39;Neal w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;pa=
dding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;bor=
der-left-style:solid">

<div dir=3D"ltr"><div><div><div>Or just for accepting the printf style argu=
ments in a safer way. E.g.<br><br></div>format(sink, &quot;foo %0 bar %1&qu=
ot;, 21, 42);<br><br></div>could be expressed as<br><br></div><div>template=
&lt;typename Sink, typename... Args&gt;<br>



</div><div>void format(Sink&amp; output, char const* spec, Args... args)<br=
>{<br>=C2=A0=C2=A0 // ....<br>}<br><br></div><div>fastformat has a similar =
API.<br></div></div><div><br clear=3D"all"><div><div dir=3D"ltr">

<div>Billy O&#39;Neal</div><div><a href=3D"https://bitbucket.org/BillyONeal=
/" target=3D"_blank">https://github.com/BillyONeal/</a></div><div><a href=
=3D"http://stackoverflow.com/users/82320/billy-oneal" target=3D"_blank">htt=
p://stackoverflow.com/<u></u>users/82320/billy-oneal</a></div>



</div></div>
<br><br><div class=3D"gmail_quote">On Mon, Jan 13, 2014 at 11:48 PM, fritzp=
oll <span dir=3D"ltr">&lt;<a>fred.p...@gmail.com</a>&gt;</span> wrote:<br><=
blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-=
left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-le=
ft-style:solid">



I missed your reference to variadic templates. I presume this would be for =
compile time string parsing? =C2=A0In which case, although potentially comp=
lex to implement, a fast type safe version is possible I suppose.<span clas=
s=3D"HOEnZb"><font color=3D"#888888"><br>


<span><font color=3D"#888888"><br>
--<br>
<br>
---<br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a>std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a>std-pr...@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/<u></u>isocpp.=
org/group/std-<u></u>proposals/</a>.<br>
</font></span></font></span></blockquote></div><span class=3D"HOEnZb"><font=
 color=3D"#888888"><br></font></span></div><span class=3D"HOEnZb"><font col=
or=3D"#888888">
</font></span></blockquote></div></blockquote></div></div><span class=3D"HO=
EnZb"><font color=3D"#888888">

<p></p>

-- <br>
=C2=A0<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</font></span></blockquote></div><br></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a11332d16261f4404eff69517--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Tue, 14 Jan 2014 17:50:46 -0600
Raw View
--001a11c3841a42166e04eff6df49
Content-Type: text/plain; charset=ISO-8859-1

On 14 January 2014 12:39, fritzpoll <fred.pollard@gmail.com> wrote:

> Aside from type-safety, are there any arguments against using a format
> string?


Good:  it shows how the line is being laid out.
Bad:  It is visually separate from the objects being formatted.

Not that there is necessarily a good way to split that up, as line layout
is sometimes tied to object formatting...

--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a11c3841a42166e04eff6df49
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra">On 14 January 2014 12:39, fritz=
poll <span dir=3D"ltr">&lt;<a href=3D"mailto:fred.pollard@gmail.com" target=
=3D"_blank">fred.pollard@gmail.com</a>&gt;</span> wrote:<br><div class=3D"g=
mail_quote">

<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">Aside from type-safety, are there any argume=
nts against using a format string?</blockquote></div><br>Good: =A0it shows =
how the line is being laid out.</div>

<div class=3D"gmail_extra">Bad: =A0It is visually separate from the objects=
 being formatted.</div><div class=3D"gmail_extra"><br></div><div class=3D"g=
mail_extra">Not that there is necessarily a good way to split that up, as l=
ine layout is sometimes tied to object formatting...<br clear=3D"all">

<div><br></div>-- <br>=A0Nevin &quot;:-)&quot; Liber=A0 &lt;mailto:<a href=
=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com=
</a>&gt;=A0 (847) 691-1404
</div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a11c3841a42166e04eff6df49--

.


Author: Miro Knejp <miro@knejp.de>
Date: Wed, 15 Jan 2014 03:58:31 +0100
Raw View
> streams classes that are sources and/or sinks - these conceptually
> simply stream byte data from one place to another.  So a file stream
> would simply take in the data provided and write out the data into the
> file, a string stream would do the same but store it in a string,
> etc.  As now, you'd have separate classes relating to different
> source/sink types. These would all inherit from a single base class,
> largely to account for the use case where one may wish to store
> pointers to multiple streams of different types in a container to loop
> over during processing.
This separation already exists: streambufs act as raw byte sources/sinks
whereas streams do the formatting. basic_streambuf has protected virtual
members, allthough there is no separation between source/sink buffers.
basic_filebuf overrides these to provide file access. Boost.Iostreams
provides it's own subclasses of basic_streambuf to integrate it's device
model to std streams.

> > It is correct that it is possible to pass incorrect formatting
> parameters for the type without this being noticed at compile time.
>
> I don't see this as a problem. The reason printf's behavior is bad
> here is that an incorrect string results in undefined behavior at run
> time. With a variadic template function, if the string is invalid, the
> program can go to std::terminate() rather than incur undefined
> behavior. (This is no different than e.g. passing a null pointer to an
> API documented to require a pointer to data)
std::terminate() might be a bit harsh, but signaling some kind of error
is certainly preferable to UB. In the projects I have worked on
printf-like format strings were mostly only used in the UI localization.
Especially important for positional parameters when substrings have
different positions in a sentence in different languages (which sadly is
not part of the current standard). If the translator somehow manages to
mess up the format strings I'd rather have a recoverable state (and for
example fallback to the English/neutral one) than a terminate.

A revival of iostream definitely needs to natively supporte some kind of
format string, simply because it's very novice friendly compared to the
current stream manipulators (besides a whole lot of typing!). Positional
arguments and locales are a must if the formatting is to be considered
for i18n at all. Having locale names forced to comply with one of the
other ISO standards would be nice, too but that's off topic.

I also like the idea of "compiling" format strings at runtime into a
re-usable object to improve efficiency for repeated invokations similar
to regex objects.

I don't think deciding on the actual grammar used for the formatting is
of much relevance until a design for the actual interface and I/O
interoperability exists. The grammar is then only a detail (if done
correctly the interface doesn't depend on the format syntax). I do like
the way .NET can pass the relevant format substrings to the object's
ToString() method so it can control it's own formatting. A
concept/ADL-based interface/filter to allow such a mechanism could prove
very flexible.


--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Tue, 14 Jan 2014 23:01:32 -0800 (PST)
Raw View
------=_Part_12_5986417.1389769292743
Content-Type: text/plain; charset=UTF-8

While streambuf exists its API is so non-intuitive that it is seldom used
as a "file" object in itself. I would like to see a new "bytestream" type
of object with nice read and write methods and the features you would
expect from a file, similar to the functions available for a C FILE*.

The bytestream class hierarchy should be the logical choice when reading
and writing binary files.

An iostream-like class hiearchy could be layered on top, much like the
relationship between iostream and streambuf today. But as we don't want too
much statefulness (persistent hex and precision for instance, is very error
prone) this class would be rather empty, the only thing I could think of is
a locale which acts as a default when formatting does not prescribe
something else (on a per facet basis, probably). Maybe line ending features
would also be a suitable property for this level. The different subclasses
for different types of bytestreams I think are still appropriate as having
to create two objects to do formatted output (as in wxWidgets) is tedious.
For user defined bytestreams implementing a corresponding formatted stream
subclass would be optional.

---

Pre-compilation of format strings is interesting but as I wrote before, we
would want this to take place when the program starts to avoid nasty
surprises when a seldom occuring error message is to be formatted. This
would however require a core language change... In the mean time we could
design a system where the simple usage creates a temporary "compiled format
string" object each time formatting is performed, while it is also possible
to explicitly create one in file static memory to get the faster
performance and program start checking. This could be done like this:

template<typename... Ts> class Formatter {
public:
    Formatter(const char* fmtstring);      // Use this ctor to create a
static formatter
    template<typename Sink> Sink& Format(Sink& dest, Ts&&... args);
};

// This function does the inline formatting
template<typename Sink, typename... Ts> Sink& Format(Sink& dest, const
char* fmtstring, Ts&&... args)
{
    Formatter<Ts...> fmt(fmtstring);
    fmt.Format(dest, args...);
    return dest;
}

Note that the Formatter ctor can do both argument checking and
pre-compilation of the string. Three usage levels are supported:

// Global formatter
static Formatter<int, float> my_error_message("Illegal value {1p2} at
offset {0h}");

void f()
{
    if (error)
       my_error_message.Format(cout, offset, value);

// Function static formatter which compiles its contents and checks
parameters at first call.
    static Formatter<MyClass>
}

Den onsdagen den 15:e januari 2014 kl. 03:58:31 UTC+1 skrev Miro Knejp:
>
> > streams classes that are sources and/or sinks - these conceptually
> > simply stream byte data from one place to another.  So a file stream
> > would simply take in the data provided and write out the data into the
> > file, a string stream would do the same but store it in a string,
> > etc.  As now, you'd have separate classes relating to different
> > source/sink types. These would all inherit from a single base class,
> > largely to account for the use case where one may wish to store
> > pointers to multiple streams of different types in a container to loop
> > over during processing.
> This separation already exists: streambufs act as raw byte sources/sinks
> whereas streams do the formatting. basic_streambuf has protected virtual
> members, allthough there is no separation between source/sink buffers.
> basic_filebuf overrides these to provide file access. Boost.Iostreams
> provides it's own subclasses of basic_streambuf to integrate it's device
> model to std streams.
>
> > > It is correct that it is possible to pass incorrect formatting
> > parameters for the type without this being noticed at compile time.
> >
> > I don't see this as a problem. The reason printf's behavior is bad
> > here is that an incorrect string results in undefined behavior at run
> > time. With a variadic template function, if the string is invalid, the
> > program can go to std::terminate() rather than incur undefined
> > behavior. (This is no different than e.g. passing a null pointer to an
> > API documented to require a pointer to data)
> std::terminate() might be a bit harsh, but signaling some kind of error
> is certainly preferable to UB. In the projects I have worked on
> printf-like format strings were mostly only used in the UI localization.
> Especially important for positional parameters when substrings have
> different positions in a sentence in different languages (which sadly is
> not part of the current standard). If the translator somehow manages to
> mess up the format strings I'd rather have a recoverable state (and for
> example fallback to the English/neutral one) than a terminate.
>
> A revival of iostream definitely needs to natively supporte some kind of
> format string, simply because it's very novice friendly compared to the
> current stream manipulators (besides a whole lot of typing!). Positional
> arguments and locales are a must if the formatting is to be considered
> for i18n at all. Having locale names forced to comply with one of the
> other ISO standards would be nice, too but that's off topic.
>
> I also like the idea of "compiling" format strings at runtime into a
> re-usable object to improve efficiency for repeated invokations similar
> to regex objects.
>
> I don't think deciding on the actual grammar used for the formatting is
> of much relevance until a design for the actual interface and I/O
> interoperability exists. The grammar is then only a detail (if done
> correctly the interface doesn't depend on the format syntax). I do like
> the way .NET can pass the relevant format substrings to the object's
> ToString() method so it can control it's own formatting. A
> concept/ADL-based interface/filter to allow such a mechanism could prove
> very flexible.
>
>
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_12_5986417.1389769292743
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">While streambuf exists its API is so non-intuitive that it=
 is seldom used as a "file" object in itself. I would like to see a new "by=
testream" type of object with nice read and write methods and the features =
you would expect from a file, similar to the functions available for a C FI=
LE*.<div><br></div><div>The bytestream class hierarchy should be the logica=
l choice when reading and writing binary files.</div><div><br></div><div>An=
 iostream-like class hiearchy could be layered on top, much like the relati=
onship between iostream and streambuf today. But as we don't want too much =
statefulness (persistent hex and precision for instance, is very error pron=
e) this class would be rather empty, the only thing I could think of is a l=
ocale which acts as a default when formatting does not prescribe something =
else (on a per facet basis, probably). Maybe line ending features would als=
o be a suitable property for this level. The different subclasses for diffe=
rent types of bytestreams I think are still appropriate as having to create=
 two objects to do formatted output (as in wxWidgets) is tedious. For user =
defined bytestreams implementing a corresponding formatted stream subclass =
would be optional.</div><div><br></div><div>---</div><div><br></div><div>Pr=
e-compilation of format strings is interesting but as I wrote before, we wo=
uld want this to take place when the program starts to avoid nasty surprise=
s when a seldom occuring error message is to be formatted. This would howev=
er require a core language change... In the mean time we could design a sys=
tem where the simple usage creates a temporary "compiled format string" obj=
ect each time formatting is performed, while it is also possible to explici=
tly create one in file static memory to get the faster performance and prog=
ram start checking. This could be done like this:</div><div><br></div><div>=
template&lt;typename... Ts&gt; class Formatter {</div><div>public:</div><di=
v>&nbsp; &nbsp; Formatter(const char* fmtstring); &nbsp; &nbsp; &nbsp;// Us=
e this ctor to create a static formatter</div><div>&nbsp; &nbsp; template&l=
t;typename Sink&gt; Sink&amp; Format(Sink&amp; dest, Ts&amp;&amp;... args);=
</div><div>};</div><div><br></div><div>// This function does the inline for=
matting</div><div>template&lt;typename Sink, typename... Ts&gt; Sink&amp; F=
ormat(Sink&amp; dest, const char* fmtstring, Ts&amp;&amp;... args)</div><di=
v>{</div><div>&nbsp; &nbsp; Formatter&lt;Ts...&gt; fmt(fmtstring);</div><di=
v>&nbsp; &nbsp; fmt.Format(dest, args...);</div><div>&nbsp; &nbsp; return d=
est;</div><div>}</div><div><br></div><div>Note that the Formatter ctor can =
do both argument checking and pre-compilation of the string. Three usage le=
vels are supported:</div><div><br></div><div>// Global formatter</div><div>=
static Formatter&lt;int, float&gt; my_error_message("Illegal value {1p2} at=
 offset {0h}");</div><div><br></div><div>void f()</div><div>{</div><div>&nb=
sp; &nbsp; if (error)</div><div>&nbsp; &nbsp; &nbsp; &nbsp;my_error_message=
..Format(cout, offset, value);</div><div><br></div><div>// Function static f=
ormatter which compiles its contents and checks parameters at first call.</=
div><div>&nbsp; &nbsp; static Formatter&lt;MyClass&gt;&nbsp;</div><div>}</d=
iv><div><br>Den onsdagen den 15:e januari 2014 kl. 03:58:31 UTC+1 skrev Mir=
o Knejp:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;">&gt; streams classes t=
hat are sources and/or sinks - these conceptually=20
<br>&gt; simply stream byte data from one place to another. &nbsp;So a file=
 stream=20
<br>&gt; would simply take in the data provided and write out the data into=
 the=20
<br>&gt; file, a string stream would do the same but store it in a string,=
=20
<br>&gt; etc. &nbsp;As now, you'd have separate classes relating to differe=
nt=20
<br>&gt; source/sink types. These would all inherit from a single base clas=
s,=20
<br>&gt; largely to account for the use case where one may wish to store=20
<br>&gt; pointers to multiple streams of different types in a container to =
loop=20
<br>&gt; over during processing.
<br>This separation already exists: streambufs act as raw byte sources/sink=
s=20
<br>whereas streams do the formatting. basic_streambuf has protected virtua=
l=20
<br>members, allthough there is no separation between source/sink buffers.=
=20
<br>basic_filebuf overrides these to provide file access. Boost.Iostreams=
=20
<br>provides it's own subclasses of basic_streambuf to integrate it's devic=
e=20
<br>model to std streams.
<br>
<br>&gt; &gt; It is correct that it is possible to pass incorrect formattin=
g=20
<br>&gt; parameters for the type without this being noticed at compile time=
..
<br>&gt;
<br>&gt; I don't see this as a problem. The reason printf's behavior is bad=
=20
<br>&gt; here is that an incorrect string results in undefined behavior at =
run=20
<br>&gt; time. With a variadic template function, if the string is invalid,=
 the=20
<br>&gt; program can go to std::terminate() rather than incur undefined=20
<br>&gt; behavior. (This is no different than e.g. passing a null pointer t=
o an=20
<br>&gt; API documented to require a pointer to data)
<br>std::terminate() might be a bit harsh, but signaling some kind of error=
=20
<br>is certainly preferable to UB. In the projects I have worked on=20
<br>printf-like format strings were mostly only used in the UI localization=
..=20
<br>Especially important for positional parameters when substrings have=20
<br>different positions in a sentence in different languages (which sadly i=
s=20
<br>not part of the current standard). If the translator somehow manages to=
=20
<br>mess up the format strings I'd rather have a recoverable state (and for=
=20
<br>example fallback to the English/neutral one) than a terminate.
<br>
<br>A revival of iostream definitely needs to natively supporte some kind o=
f=20
<br>format string, simply because it's very novice friendly compared to the=
=20
<br>current stream manipulators (besides a whole lot of typing!). Positiona=
l=20
<br>arguments and locales are a must if the formatting is to be considered=
=20
<br>for i18n at all. Having locale names forced to comply with one of the=
=20
<br>other ISO standards would be nice, too but that's off topic.
<br>
<br>I also like the idea of "compiling" format strings at runtime into a=20
<br>re-usable object to improve efficiency for repeated invokations similar=
=20
<br>to regex objects.
<br>
<br>I don't think deciding on the actual grammar used for the formatting is=
=20
<br>of much relevance until a design for the actual interface and I/O=20
<br>interoperability exists. The grammar is then only a detail (if done=20
<br>correctly the interface doesn't depend on the format syntax). I do like=
=20
<br>the way .NET can pass the relevant format substrings to the object's=20
<br>ToString() method so it can control it's own formatting. A=20
<br>concept/ADL-based interface/filter to allow such a mechanism could prov=
e=20
<br>very flexible.
<br>
<br>
<br></blockquote></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_12_5986417.1389769292743--

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Tue, 14 Jan 2014 23:46:56 -0800 (PST)
Raw View
------=_Part_1967_16412530.1389772016803
Content-Type: text/plain; charset=UTF-8

Sorry, I accdentaly sent that too soon. Here's the completed example:


// Global formatter, checked at program start.
static Formatter<int, float> my_error_message("Illegal value {1p2} at
offset {0h}");

void f()
{
    if (error)
       my_error_message.Format(cout, offset, value);

// Function static formatter which compiles its contents and checks
parameters at first call.
    static Formatter<MyClass> local_fmt("Value: {0xyz}");

    vector<MyClass> data;
    for (auto& d : data)
       local_fmt.Format(cout, d) << endl;

   // On the spot formatting
   Format(cout, "Total count {0}\n", data.size());
}

When inspecting this code you can notice:

- If Formatter::Format was replaced by Formatter::operator() it would look
nicer.
- the const char* above should maybe be a template par to allow for more
format string types, at least whcar_t* but maybe strings too.
- A possibility to do cout << Format(...) << endl; would look more like
what C++ pgogrammers are used to. This would mean reformulation like this:

template<typename... Ts> FormatterWithValues<Ts...> Format(const char*
fmtstring, Ts&&... vs);

template<typename Dest, typename... Ts> Dest& operator<<(Dest& dest, const
FormatterWithValues<Ts...>& fmt) { return fmt.Format(dest); }

Where FormatterWithValues is a wrapper which contains a Formatter and a
tuple of referens to vs which its Format() then applies to the contained
Formatter so that the stream is actually available when formatting occurs .
A good compiler is required to be able to generate decent code from such
constructs...

- To be able to test if formatting parameters are ok for their types before
actually doing the formatting and to complete the pre-compilation a class
template for individual parameter's formatting is logical:

template<typename T> DataFormatter {
public:
     DataFormatter();
     void Parse(string_view pars);   // Throw if pars are illegal. Some
specific exception class probably needed.
     template<typename Dest> void Format(Dest& dest, const T& src);
};

DataFormatter is then specialized for each type to format. The Parse()
method stores its result in members specific for each specialization.

Given this it should be possible to define that Formatter has a
std::tuple<DataFormatter<Ts>...> member and create a loop to give each
formatter its formatting pars when parsing the format string. I see two
problems with this approach: As the DataFormatters are stored in a tuple
you can't get at them using runtime indexing. This can be solved by
template metaprogramming but that's going to increase compile times alot.
The other problem is if the same {0} number occurs twice in the format
string with different parameters, then DataFormatter for the 0:th argument
has two different formatting parameter sets which prevents precalculation.
Maybe this should be UB (with implementations probably formatting according
to the second parameter set for both mentions of 0).

- If this was combined with a built in support for translation the
formatting parameters could be kept in the original  string. I.e. the
Formatter would always see the original string and compile itself using it,
but then ask the central translation facility for the translation, possibly
given the locale of the stream. It would even be possible to use the
formatting parameters of the original string as default while also allowing
per-language customization.

While allowing Format(ostream&) is tautological (ostream already does
similar formatting) I think this is an important feature for code
migration, the concept for Dest parameter could just contain the put() and
write() methods of ostream. This allows other Dest types to easily be
created.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_1967_16412530.1389772016803
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Sorry, I accdentaly sent that too soon. Here's the complet=
ed example:<div><br></div><div><br></div><div><div>// Global formatter, che=
cked at program start.</div><div>static Formatter&lt;int, float&gt; my_erro=
r_message("Illegal value {1p2} at offset {0h}");</div><div><br></div><div>v=
oid f()</div><div>{</div><div>&nbsp; &nbsp; if (error)</div><div>&nbsp; &nb=
sp; &nbsp; &nbsp;my_error_message.Format(cout, offset, value);</div><div><b=
r></div><div>// Function static formatter which compiles its contents and c=
hecks parameters at first call.</div><div>&nbsp; &nbsp; static Formatter&lt=
;MyClass&gt; local_fmt("Value: {0xyz}");</div><div><br></div><div>&nbsp; &n=
bsp; vector&lt;MyClass&gt; data;</div><div>&nbsp; &nbsp; for (auto&amp; d :=
 data)</div><div>&nbsp; &nbsp; &nbsp; &nbsp;local_fmt.Format(cout, d) &lt;&=
lt; endl;</div><div><br></div><div>&nbsp; &nbsp;// On the spot formatting</=
div><div>&nbsp; &nbsp;Format(cout, "Total count {0}\n", data.size());</div>=
<div>}</div><div><br></div><div>When inspecting this code you can notice:</=
div><div><br></div><div>- If Formatter::Format was replaced by Formatter::o=
perator() it would look nicer.</div><div>- the const char* above should may=
be be a template par to allow for more format string types, at least whcar_=
t* but maybe strings too.</div><div>- A possibility to do cout &lt;&lt; For=
mat(...) &lt;&lt; endl; would look more like what C++ pgogrammers are used =
to. This would mean reformulation like this:</div><div><br></div><div>templ=
ate&lt;typename... Ts&gt; FormatterWithValues&lt;Ts...&gt; Format(const cha=
r* fmtstring, Ts&amp;&amp;... vs);</div><div><br></div><div>template&lt;typ=
ename Dest, typename... Ts&gt; Dest&amp; operator&lt;&lt;(Dest&amp; dest, c=
onst FormatterWithValues&lt;Ts...&gt;&amp; fmt) { return fmt.Format(dest); =
}</div><div><br></div><div>Where FormatterWithValues is a wrapper which con=
tains a Formatter and a tuple of referens to vs which its Format() then app=
lies to the contained Formatter so that the stream is actually available wh=
en formatting occurs . A good compiler is required to be able to generate d=
ecent code from such constructs...</div><div><br></div><div>- To be able to=
 test if formatting parameters are ok for their types before actually doing=
 the formatting and to complete the pre-compilation a class template for in=
dividual parameter's formatting is logical:</div><div><br></div><div>templa=
te&lt;typename T&gt; DataFormatter {</div><div>public:</div><div>&nbsp; &nb=
sp; &nbsp;DataFormatter();</div><div>&nbsp; &nbsp; &nbsp;void Parse(string_=
view pars); &nbsp; // Throw if pars are illegal. Some specific exception cl=
ass probably needed.</div><div>&nbsp; &nbsp; &nbsp;template&lt;typename Des=
t&gt; void Format(Dest&amp; dest, const T&amp; src);</div><div>};</div><div=
><br></div><div>DataFormatter is then specialized for each type to format. =
The Parse() method stores its result in members specific for each specializ=
ation.</div><div><br></div><div>Given this it should be possible to define =
that Formatter has a std::tuple&lt;DataFormatter&lt;Ts&gt;...&gt; member an=
d create a loop to give each formatter its formatting pars when parsing the=
 format string. I see two problems with this approach: As the DataFormatter=
s are stored in a tuple you can't get at them using runtime indexing. This =
can be solved by template metaprogramming but that's going to increase comp=
ile times alot. The other problem is if the same {0} number occurs twice in=
 the format string with different parameters, then DataFormatter for the 0:=
th argument has two different formatting parameter sets which prevents prec=
alculation. Maybe this should be UB (with implementations probably formatti=
ng according to the second parameter set for both mentions of 0).</div><div=
><br></div><div>- If this was combined with a built in support for translat=
ion the formatting parameters could be kept in the original &nbsp;string. I=
..e. the Formatter would always see the original string and compile itself u=
sing it, but then ask the central translation facility for the translation,=
 possibly given the locale of the stream. It would even be possible to use =
the formatting parameters of the original string as default while also allo=
wing per-language customization.</div></div><div><br></div><div>While allow=
ing Format(ostream&amp;) is tautological (ostream already does similar form=
atting) I think this is an important feature for code migration, the concep=
t for Dest parameter could just contain the put() and write() methods of os=
tream. This allows other Dest types to easily be created.</div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1967_16412530.1389772016803--

.


Author: Miro Knejp <miro@knejp.de>
Date: Wed, 15 Jan 2014 13:37:10 +0100
Raw View
> While streambuf exists its API is so non-intuitive that it is seldom
> used as a "file" object in itself. I would like to see a new
> "bytestream" type of object with nice read and write methods and the
> features you would expect from a file, similar to the functions
> available for a C FILE*.
Agreed.
>
> Pre-compilation of format strings is interesting but as I wrote
> before, we would want this to take place when the program starts to
> avoid nasty surprises when a seldom occuring error message is to be
> formatted. This would however require a core language change... In the
> mean time we could design a system where the simple usage creates a
> temporary "compiled format string" object each time formatting is
> performed, while it is also possible to explicitly create one in file
> static memory to get the faster performance and program start checking.
Just to make sure we are talking about the same thing: with
"precompiled" I mean a representation of a format string created at
runtime which is more efficient to execute repeatedly than to parse the
format string every single time.

Having said that, I would rather not have the compiler guesstimate
whether or not to create some static format object at startup if I don't
explicitly tell it to. I see the use case the same as with <regex>. If I
know I am going to format the same message over and over and over again
I want to be able to create an object from a (external) source string,
put it somewhere safe and reuse it. If however a certain string is
formatted rarely an easy to use inline version would be preferred.
Regarding error messages: if your error strings are hardcoded anyway it
should be possible to wrap the error creating/throwing parts in
functions and write tests for them. I don't see how this requires any
special treatment. So besides the "compiler does some magic for me" part
I think we are on the same track.

Though for the sake of consistency with the overall design of the
standard library, i.e. not formatting using object methods but a
free-standing overload (makes it easier to integrate in templated code):

template<class... Args, class CharT, classTraits = /*...*/, class
Allocator = /*...*/>
class basic_formatter
{
     formatter(...) { } // Various overloads to accept string sources,
does the "precompilation"

     basic_string</*...*/> operator() (const Args&...); // For use as
functor
};

template<typename... Ts> using formatter = basic_formatter<Ts..., char>;

template<typename... Ts, /*...*/> basic_string</*...*/> format(const
basic_formatter<Ts..., /*...*/>&, const Ts&... args);

// Various overloads to accept string sources instead of formatters.
// These could create a temporary formatter object, or (if more
efficient) do the formatting directly (e.g. to avoid unnecessary
allocations which would be required by the formatter to store state)
template<typename... Ts> string format(const /*...*/&, const Ts&... args);

I hope this looks reasonable. I left out interoperability with iostreams
for now since we're looking for a replacement anyway. But adding a
streambuf/bytestream/whatever sink in front of the format object would
allow a direct write which might need less allocations.

For the formatting of the individual values the formatter would the call
into user/system provided functions avaiable in several overloads,
depending on how throroughly the type can be formatted:

string format_value([appender&, ]const MyValueType& v[, string_view
options]);

Stuff in brackets [ ] specifies optional arguments. The optional
"options" parameter can forward format options form the format string to
the formatting function and is empty if none were present. The format
options could as well from format arguments.

The exact nature of "appender" needs to be specified. It could be a
streambuf/bytestream/sink that either writes to the formatter's internal
buffer or directly to a device and would of course be write-only. Maybe
a simple OutputIterator would suffice. Though it would be advantageous
if it supported block-writing, then it is based on a custom concept. If
the passed in format options are somehow invalid or the formatting
cannot be done throwing an exception would probably be the most
intuitive solution (or maybe <optional>? <expected>?).

If more than one overload is present the program is ill-formed.

For the "precompilation" aspect a second helper is needed. My idea is to
have similar functions to those above but instead of producing values
they return function objects with the format_options possibly baked in
if present.

template<class MyValueType>
     std::function<string([appender&, ]const MyValueType&[,
string_view])> value_formatter([string_view format_options]);

Again, stuff in brackets [ ] is optional and if more than one overload
exists the programm is ill-formed.

The return type of value_formatter may not necessarily be a
std::function but this way it is easier to showcase. As long as it is a
type where the three functor overloads can be distinguished (using
concepts?) everything is fine and the formatter should be able to pick
the correct code path. The functional signatures can optionally also
contain an additinal string_view argument for the formatting options
just in case they cannot be pre-baked (or were provided as format
arguments) and need to be re-evaluated at each formatting invokation. If
none of such overloads exists precompilation for this entity is disabled
and format_value is called instead on every execution. For absolute
completeness there could even be an allocator argument to use for the
function object if heap allocation is required.

To summarize, the design as presented here (which I'm sure has flaws and
can be imporoved) allows to add "to_string" capabilities to classes in a
non-instrusive way compatible with a new printf-like interface with
compile time type checking and it provides a mechanism to enable the
"precompilation" phase for types where repeated parsing of format
arguments (or the format string itself) may be inefficient. It enables
the precompilation of multiple instances of the same positonal argument
with different format options (e.g. "{0:XXXX} bla {0:HH:mm:ss}" using
..NET syntax as example) without conflicts because each precompiled
argument receives its own function object. All names were of course
chosen spontaneously and are open to bikeshedding.

I didn't go into detail about the bytestream/sink topic as I think those
should be two separate proposals.

I believe this design is very flexible and has the potential of being
efficient. Allthough compilation times might suffer.
But please, feel free to tear it apart :)

P.S.: An example for flexibility: Assume you want an int to be printed
in a special way with custom format options the standard doesn't support
for 'int'. A simple tag struct and format function is all you need to
make this happen:

struct MyFormattedInt { MyFormattedInt(int i) : i(i); int i; }; //
Constructor not explicit by design

string format_value(const MyFormattedInt& v, string_view options)
{
      return /* do something fancy with "pretty" ints */;
}

formatter<int, MyFormattedInt> fmt{"{0:00} {1:pretty}"};
format(fmt, 1, 1);

Note that at the point of calling format() no special manipulator or
other intrusive marker is necessary for enabling the pretty print.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Wed, 15 Jan 2014 11:26:12 -0800 (PST)
Raw View
------=_Part_5027_14809783.1389813972092
Content-Type: text/plain; charset=UTF-8


>
> > Pre-compilation of format strings is interesting but as I wrote
> > before, we would want this to take place when the program starts to
> > avoid nasty surprises when a seldom occuring error message is to be
> > formatted. This would however require a core language change... In the
> > mean time we could design a system where the simple usage creates a
> > temporary "compiled format string" object each time formatting is
> > performed, while it is also possible to explicitly create one in file
> > static memory to get the faster performance and program start checking.
> Just to make sure we are talking about the same thing: with
> "precompiled" I mean a representation of a format string created at
> runtime which is more efficient to execute repeatedly than to parse the
> format string every single time.
>
Agreed.

>
> Having said that, I would rather not have the compiler guesstimate
> whether or not to create some static format object at startup if I don't
> explicitly tell it to. I see the use case the same as with <regex>. If I
> know I am going to format the same message over and over and over again
> I want to be able to create an object from a (external) source string,
> put it somewhere safe and reuse it. If however a certain string is
> formatted rarely an easy to use inline version would be preferred.
>
As of now there is no language construct to be able to force static memory
with program start initiation inside a function.
However, I still would wish for such a possibility. Mainly to be able to
collect all translatable strings in a program without displaying them,
but as a spin off format parameters could be checked for validity for their
data types and optionally precompiled, although I agree that consuming
memory
for the compiled result could be overdoing it.


> Regarding error messages: if your error strings are hardcoded anyway it
> should be possible to wrap the error creating/throwing parts in
> functions and write tests for them. I don't see how this requires any
> special treatment. So besides the "compiler does some magic for me" part
> I think we are on the same track.
>
I don't know what you mean with hardcoded. I want the untranslated text to
be visible at the point of use. Subdividing into a static object in global
(or namespace) scope and its use at the point of error detection
increases the risk for outdated message strings and is tedious to code.
Without a new language feature you have to select between having the error
text in the right place and format string verification at program start.
I'm not talking about magic especially designed for this feature of course,
but a general possibility to separate visiblity and lifetime of local
variables.

As for your long example below it is very similar to my ideas, except that
I don't like to have to customize two things in parallel to get the
precompilation functionality. I think we're homing in on something good
here...

One additional feature that we could think about is formatter repositories.
That is, to be able to define multiple sets of formatters so that the same
C++ type can be associated with different formatter types in different
parts of the application, and for different types of output streams. Just
having the overload/template specialization mechanism available is not so
scalable for large applications. It is however unclear which level of
performance we are aiming for, is it for instance obvious that everything
is templated or could a virtual method interface be used.

I'm currently preparing a first implementation sketch (compilable!) to get
some hands on experience. I will post it here when finished.


>
> Though for the sake of consistency with the overall design of the
> standard library, i.e. not formatting using object methods but a
> free-standing overload (makes it easier to integrate in templated code):
>
> template<class... Args, class CharT, classTraits = /*...*/, class
> Allocator = /*...*/>
> class basic_formatter
> {
>      formatter(...) { } // Various overloads to accept string sources,
> does the "precompilation"
>
>      basic_string</*...*/> operator() (const Args&...); // For use as
> functor
> };
>
> template<typename... Ts> using formatter = basic_formatter<Ts..., char>;
>
> template<typename... Ts, /*...*/> basic_string</*...*/> format(const
> basic_formatter<Ts..., /*...*/>&, const Ts&... args);
>
> // Various overloads to accept string sources instead of formatters.
> // These could create a temporary formatter object, or (if more
> efficient) do the formatting directly (e.g. to avoid unnecessary
> allocations which would be required by the formatter to store state)
> template<typename... Ts> string format(const /*...*/&, const Ts&... args);
>
> I hope this looks reasonable. I left out interoperability with iostreams
> for now since we're looking for a replacement anyway. But adding a
> streambuf/bytestream/whatever sink in front of the format object would
> allow a direct write which might need less allocations.
>
> For the formatting of the individual values the formatter would the call
> into user/system provided functions avaiable in several overloads,
> depending on how throroughly the type can be formatted:
>
> string format_value([appender&, ]const MyValueType& v[, string_view
> options]);
>
> Stuff in brackets [ ] specifies optional arguments. The optional
> "options" parameter can forward format options form the format string to
> the formatting function and is empty if none were present. The format
> options could as well from format arguments.
>
> The exact nature of "appender" needs to be specified. It could be a
> streambuf/bytestream/sink that either writes to the formatter's internal
> buffer or directly to a device and would of course be write-only. Maybe
> a simple OutputIterator would suffice. Though it would be advantageous
> if it supported block-writing, then it is based on a custom concept. If
> the passed in format options are somehow invalid or the formatting
> cannot be done throwing an exception would probably be the most
> intuitive solution (or maybe <optional>? <expected>?).
>
> If more than one overload is present the program is ill-formed.
>
> For the "precompilation" aspect a second helper is needed. My idea is to
> have similar functions to those above but instead of producing values
> they return function objects with the format_options possibly baked in
> if present.
>
> template<class MyValueType>
>      std::function<string([appender&, ]const MyValueType&[,
> string_view])> value_formatter([string_view format_options]);
>
> Again, stuff in brackets [ ] is optional and if more than one overload
> exists the programm is ill-formed.
>
> The return type of value_formatter may not necessarily be a
> std::function but this way it is easier to showcase. As long as it is a
> type where the three functor overloads can be distinguished (using
> concepts?) everything is fine and the formatter should be able to pick
> the correct code path. The functional signatures can optionally also
> contain an additinal string_view argument for the formatting options
> just in case they cannot be pre-baked (or were provided as format
> arguments) and need to be re-evaluated at each formatting invokation. If
> none of such overloads exists precompilation for this entity is disabled
> and format_value is called instead on every execution. For absolute
> completeness there could even be an allocator argument to use for the
> function object if heap allocation is required.
>
> To summarize, the design as presented here (which I'm sure has flaws and
> can be imporoved) allows to add "to_string" capabilities to classes in a
> non-instrusive way compatible with a new printf-like interface with
> compile time type checking and it provides a mechanism to enable the
> "precompilation" phase for types where repeated parsing of format
> arguments (or the format string itself) may be inefficient. It enables
> the precompilation of multiple instances of the same positonal argument
> with different format options (e.g. "{0:XXXX} bla {0:HH:mm:ss}" using
> .NET syntax as example) without conflicts because each precompiled
> argument receives its own function object. All names were of course
> chosen spontaneously and are open to bikeshedding.
>
> I didn't go into detail about the bytestream/sink topic as I think those
> should be two separate proposals.
>
> I believe this design is very flexible and has the potential of being
> efficient. Allthough compilation times might suffer.
> But please, feel free to tear it apart :)
>
> P.S.: An example for flexibility: Assume you want an int to be printed
> in a special way with custom format options the standard doesn't support
> for 'int'. A simple tag struct and format function is all you need to
> make this happen:
>
> struct MyFormattedInt { MyFormattedInt(int i) : i(i); int i; }; //
> Constructor not explicit by design
>
> string format_value(const MyFormattedInt& v, string_view options)
> {
>       return /* do something fancy with "pretty" ints */;
> }
>
> formatter<int, MyFormattedInt> fmt{"{0:00} {1:pretty}"};
> format(fmt, 1, 1);
>
> Note that at the point of calling format() no special manipulator or
> other intrusive marker is necessary for enabling the pretty print.
>
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_5027_14809783.1389813972092
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">&gt; Pre-comp=
ilation of format strings is interesting but as I wrote=20
<br>&gt; before, we would want this to take place when the program starts t=
o=20
<br>&gt; avoid nasty surprises when a seldom occuring error message is to b=
e=20
<br>&gt; formatted. This would however require a core language change... In=
 the=20
<br>&gt; mean time we could design a system where the simple usage creates =
a=20
<br>&gt; temporary "compiled format string" object each time formatting is=
=20
<br>&gt; performed, while it is also possible to explicitly create one in f=
ile=20
<br>&gt; static memory to get the faster performance and program start chec=
king.
<br>Just to make sure we are talking about the same thing: with=20
<br>"precompiled" I mean a representation of a format string created at=20
<br>runtime which is more efficient to execute repeatedly than to parse the=
=20
<br>format string every single time.
<br></blockquote><div>Agreed.&nbsp;</div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;">
<br>Having said that, I would rather not have the compiler guesstimate=20
<br>whether or not to create some static format object at startup if I don'=
t=20
<br>explicitly tell it to. I see the use case the same as with &lt;regex&gt=
;. If I=20
<br>know I am going to format the same message over and over and over again=
=20
<br>I want to be able to create an object from a (external) source string,=
=20
<br>put it somewhere safe and reuse it. If however a certain string is=20
<br>formatted rarely an easy to use inline version would be preferred.<br><=
/blockquote><div>As of now there is no language construct to be able to for=
ce static memory with program start initiation inside a function.</div><div=
>However, I still would wish for such a possibility. Mainly to be able to c=
ollect all translatable strings in a program without displaying them,&nbsp;=
</div><div>but as a spin off format parameters could be checked for validit=
y for their data types and optionally precompiled, although I agree that co=
nsuming memory</div><div>for the compiled result could be overdoing it.</di=
v><div>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Regarding e=
rror messages: if your error strings are hardcoded anyway it=20
<br>should be possible to wrap the error creating/throwing parts in=20
<br>functions and write tests for them. I don't see how this requires any=
=20
<br>special treatment. So besides the "compiler does some magic for me" par=
t=20
<br>I think we are on the same track.<br></blockquote><div>I don't know wha=
t you mean with hardcoded. I want the untranslated text to be visible at th=
e point of use. Subdividing into a static object in global (or namespace) s=
cope and its use at the point of error detection</div><div>increases the ri=
sk for outdated message strings and is tedious to code. Without a new langu=
age feature you have to select between having the error text in the right p=
lace and format string verification at program start.</div><div>I'm not tal=
king about magic especially designed for this feature of course, but a gene=
ral possibility to separate visiblity and lifetime of local variables.</div=
><div><br></div><div>As for your long example below it is very similar to m=
y ideas, except that I don't like to have to customize two things in parall=
el to get the precompilation functionality. I think we're homing in on some=
thing good here...</div><div><br></div><div>One additional feature that we =
could think about is formatter repositories. That is, to be able to define =
multiple sets of formatters so that the same C++ type can be associated wit=
h different formatter types in different parts of the application, and for =
different types of output streams. Just having the overload/template specia=
lization mechanism available is not so scalable for large applications. It =
is however unclear which level of performance we are aiming for, is it for =
instance obvious that everything is templated or could a virtual method int=
erface be used.</div><div><br></div><div>I'm currently preparing a first im=
plementation sketch (compilable!) to get some hands on experience. I will p=
ost it here when finished.</div><div>&nbsp;</div><blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;">
<br>Though for the sake of consistency with the overall design of the=20
<br>standard library, i.e. not formatting using object methods but a=20
<br>free-standing overload (makes it easier to integrate in templated code)=
:
<br>
<br>template&lt;class... Args, class CharT, classTraits =3D /*...*/, class=
=20
<br>Allocator =3D /*...*/&gt;
<br>class basic_formatter
<br>{
<br>&nbsp; &nbsp; &nbsp;formatter(...) { } // Various overloads to accept s=
tring sources,=20
<br>does the "precompilation"
<br>
<br>&nbsp; &nbsp; &nbsp;basic_string&lt;/*...*/&gt; operator() (const Args&=
amp;...); // For use as=20
<br>functor
<br>};
<br>
<br>template&lt;typename... Ts&gt; using formatter =3D basic_formatter&lt;T=
s..., char&gt;;
<br>
<br>template&lt;typename... Ts, /*...*/&gt; basic_string&lt;/*...*/&gt; for=
mat(const=20
<br>basic_formatter&lt;Ts..., /*...*/&gt;&amp;, const Ts&amp;... args);
<br>
<br>// Various overloads to accept string sources instead of formatters.
<br>// These could create a temporary formatter object, or (if more=20
<br>efficient) do the formatting directly (e.g. to avoid unnecessary=20
<br>allocations which would be required by the formatter to store state)
<br>template&lt;typename... Ts&gt; string format(const /*...*/&amp;, const =
Ts&amp;... args);
<br>
<br>I hope this looks reasonable. I left out interoperability with iostream=
s=20
<br>for now since we're looking for a replacement anyway. But adding a=20
<br>streambuf/bytestream/whatever sink in front of the format object would=
=20
<br>allow a direct write which might need less allocations.
<br>
<br>For the formatting of the individual values the formatter would the cal=
l=20
<br>into user/system provided functions avaiable in several overloads,=20
<br>depending on how throroughly the type can be formatted:
<br>
<br>string format_value([appender&amp;, ]const MyValueType&amp; v[, string_=
view=20
<br>options]);
<br>
<br>Stuff in brackets [ ] specifies optional arguments. The optional=20
<br>"options" parameter can forward format options form the format string t=
o=20
<br>the formatting function and is empty if none were present. The format=
=20
<br>options could as well from format arguments.
<br>
<br>The exact nature of "appender" needs to be specified. It could be a=20
<br>streambuf/bytestream/sink that either writes to the formatter's interna=
l=20
<br>buffer or directly to a device and would of course be write-only. Maybe=
=20
<br>a simple OutputIterator would suffice. Though it would be advantageous=
=20
<br>if it supported block-writing, then it is based on a custom concept. If=
=20
<br>the passed in format options are somehow invalid or the formatting=20
<br>cannot be done throwing an exception would probably be the most=20
<br>intuitive solution (or maybe &lt;optional&gt;? &lt;expected&gt;?).
<br>
<br>If more than one overload is present the program is ill-formed.
<br>
<br>For the "precompilation" aspect a second helper is needed. My idea is t=
o=20
<br>have similar functions to those above but instead of producing values=
=20
<br>they return function objects with the format_options possibly baked in=
=20
<br>if present.
<br>
<br>template&lt;class MyValueType&gt;
<br>&nbsp; &nbsp; &nbsp;std::function&lt;string([<wbr>appender&amp;, ]const=
 MyValueType&amp;[,=20
<br>string_view])&gt; value_formatter([string_view format_options]);
<br>
<br>Again, stuff in brackets [ ] is optional and if more than one overload=
=20
<br>exists the programm is ill-formed.
<br>
<br>The return type of value_formatter may not necessarily be a=20
<br>std::function but this way it is easier to showcase. As long as it is a=
=20
<br>type where the three functor overloads can be distinguished (using=20
<br>concepts?) everything is fine and the formatter should be able to pick=
=20
<br>the correct code path. The functional signatures can optionally also=20
<br>contain an additinal string_view argument for the formatting options=20
<br>just in case they cannot be pre-baked (or were provided as format=20
<br>arguments) and need to be re-evaluated at each formatting invokation. I=
f=20
<br>none of such overloads exists precompilation for this entity is disable=
d=20
<br>and format_value is called instead on every execution. For absolute=20
<br>completeness there could even be an allocator argument to use for the=
=20
<br>function object if heap allocation is required.
<br>
<br>To summarize, the design as presented here (which I'm sure has flaws an=
d=20
<br>can be imporoved) allows to add "to_string" capabilities to classes in =
a=20
<br>non-instrusive way compatible with a new printf-like interface with=20
<br>compile time type checking and it provides a mechanism to enable the=20
<br>"precompilation" phase for types where repeated parsing of format=20
<br>arguments (or the format string itself) may be inefficient. It enables=
=20
<br>the precompilation of multiple instances of the same positonal argument=
=20
<br>with different format options (e.g. "{0:XXXX} bla {0:HH:mm:ss}" using=
=20
<br>.NET syntax as example) without conflicts because each precompiled=20
<br>argument receives its own function object. All names were of course=20
<br>chosen spontaneously and are open to bikeshedding.
<br>
<br>I didn't go into detail about the bytestream/sink topic as I think thos=
e=20
<br>should be two separate proposals.
<br>
<br>I believe this design is very flexible and has the potential of being=
=20
<br>efficient. Allthough compilation times might suffer.
<br>But please, feel free to tear it apart :)
<br>
<br>P.S.: An example for flexibility: Assume you want an int to be printed=
=20
<br>in a special way with custom format options the standard doesn't suppor=
t=20
<br>for 'int'. A simple tag struct and format function is all you need to=
=20
<br>make this happen:
<br>
<br>struct MyFormattedInt { MyFormattedInt(int i) : i(i); int i; }; //=20
<br>Constructor not explicit by design
<br>
<br>string format_value(const MyFormattedInt&amp; v, string_view options)
<br>{
<br>&nbsp; &nbsp; &nbsp; return /* do something fancy with "pretty" ints */=
;
<br>}
<br>
<br>formatter&lt;int, MyFormattedInt&gt; fmt{"{0:00} {1:pretty}"};
<br>format(fmt, 1, 1);
<br>
<br>Note that at the point of calling format() no special manipulator or=20
<br>other intrusive marker is necessary for enabling the pretty print.
<br>
<br></blockquote></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_5027_14809783.1389813972092--

.


Author: Bjorn Reese <breese@mail1.stofanet.dk>
Date: Thu, 16 Jan 2014 10:00:07 +0100
Raw View
On 01/14/2014 12:29 AM, Bengt Gustafsson wrote:

> Each inserted value is written like this: %<name>|<pars>%

There are precendents for this kind of formatting syntax. A decade ago
such extensions were added to several printf libraries (e.g. [1,2].)

[1] http://sourceforge.net/p/ctrio/git/ci/master/tree/doc/doc_register.h
[2] http://www.and.org/vstr/#cust-fmt

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: fritzpoll <fred.pollard@gmail.com>
Date: Fri, 17 Jan 2014 14:41:31 -0800 (PST)
Raw View
------=_Part_81_11727382.1389998491790
Content-Type: text/plain; charset=UTF-8

I also think that a new library should have at its core a "bytestream" type
of object, which simply emits into its sink the representation of the
object it is passed.

So for example, one can envision code like the following:

file_bytestream f("test.fil");
float value = 7.5f;

f << value;        //four bytes representing the floating point value 7.5
are written to test.fil

Note that I have deliberately used the input/output operator here, since,
although the standard at present indicates that this is formatted I/O (as
distinct from the unformatted I/O of write() and read() in IOStreams), it
always seemed odd to me that the syntactic sugar of something being fed
into the stream was the preserve of only text streams.  Don't worry about
it - it's not a significant issue!  This could, I think be implemented
relatively easily using a templated operator function that simply takes the
address of the function and the size of the type and write it into the
appropriate sink.

Something like (not syntax checked):

template<typename T>
bytestream& operator<<(bytestream& st, const T value)
{

return st.write(value);

}
..
..
..
//somewhere in file_bytestream as a member function...code is wrong, but
hopefully intent is clear
template<typename T>
file_bytestream& write(T& value)
{

auto ad = &value;

char* recast = static_cast<char*>(ad);

fwrite(recast, sizeof(char), sizeof(T), this->pFile);  //pFile is some
internal FILE* pointer

return *this;

}

To handle user-defined types, users could overload the << operator to make
a series of calls to write() on the bytestream and write out appropriately
(types encapsulating pointers are an obvious off-the-top-of-my-head
example).  A textstream-type class would essentially use a bytestream, but
would simply format the bytes appropriately before emitting them.  So for
example, a file_textstream class might encapsulate a file_bytestream class
as a member (called 'fbs' in the example below) and then redefine its <<
operator in this kind of fashion:

file_textstream& operator<<(file_textstream& txt, const float value)
{

txt.fbs.write(std::to_string(value));   //need a wstring equivalent

}

A separate operator would then be define to act on objects returned by the
formatting functions being described by others:

file_textstream& operator<<(file_textstream& txt, const
*format_function_type* value);

This is not perfectly thought through (I'm writing this while I wait for a
plane and it is late!), but I hope it gives the idea of a layered approach
that will only make a client of the library use the functionality that it
needs.  The stream operators themselves should in principle compile down to
the underlying C calls, so giving a C++-like interface with associated
safety and type-checking, but with (hopefully) limited overhead.

Naturally, formatting the text in a more complicated manner (using the
format functions earlier in the thread) will introduce an overhead, but not
necessarily any more than in any other language, and crucially one only
pays for it if one needs the functionality.

Sorry for the poor implementations above - I haven't a compiler to hand and
am in haste.  Hopefully they are sufficiently illustrative!


On Wednesday, January 15, 2014 12:37:10 PM UTC, Miro Knejp wrote:
>
>
> > While streambuf exists its API is so non-intuitive that it is seldom
> > used as a "file" object in itself. I would like to see a new
> > "bytestream" type of object with nice read and write methods and the
> > features you would expect from a file, similar to the functions
> > available for a C FILE*.
> Agreed.
> >
> > Pre-compilation of format strings is interesting but as I wrote
> > before, we would want this to take place when the program starts to
> > avoid nasty surprises when a seldom occuring error message is to be
> > formatted. This would however require a core language change... In the
> > mean time we could design a system where the simple usage creates a
> > temporary "compiled format string" object each time formatting is
> > performed, while it is also possible to explicitly create one in file
> > static memory to get the faster performance and program start checking.
> Just to make sure we are talking about the same thing: with
> "precompiled" I mean a representation of a format string created at
> runtime which is more efficient to execute repeatedly than to parse the
> format string every single time.
>
> Having said that, I would rather not have the compiler guesstimate
> whether or not to create some static format object at startup if I don't
> explicitly tell it to. I see the use case the same as with <regex>. If I
> know I am going to format the same message over and over and over again
> I want to be able to create an object from a (external) source string,
> put it somewhere safe and reuse it. If however a certain string is
> formatted rarely an easy to use inline version would be preferred.
> Regarding error messages: if your error strings are hardcoded anyway it
> should be possible to wrap the error creating/throwing parts in
> functions and write tests for them. I don't see how this requires any
> special treatment. So besides the "compiler does some magic for me" part
> I think we are on the same track.
>
> Though for the sake of consistency with the overall design of the
> standard library, i.e. not formatting using object methods but a
> free-standing overload (makes it easier to integrate in templated code):
>
> template<class... Args, class CharT, classTraits = /*...*/, class
> Allocator = /*...*/>
> class basic_formatter
> {
>      formatter(...) { } // Various overloads to accept string sources,
> does the "precompilation"
>
>      basic_string</*...*/> operator() (const Args&...); // For use as
> functor
> };
>
> template<typename... Ts> using formatter = basic_formatter<Ts..., char>;
>
> template<typename... Ts, /*...*/> basic_string</*...*/> format(const
> basic_formatter<Ts..., /*...*/>&, const Ts&... args);
>
> // Various overloads to accept string sources instead of formatters.
> // These could create a temporary formatter object, or (if more
> efficient) do the formatting directly (e.g. to avoid unnecessary
> allocations which would be required by the formatter to store state)
> template<typename... Ts> string format(const /*...*/&, const Ts&... args);
>
> I hope this looks reasonable. I left out interoperability with iostreams
> for now since we're looking for a replacement anyway. But adding a
> streambuf/bytestream/whatever sink in front of the format object would
> allow a direct write which might need less allocations.
>
> For the formatting of the individual values the formatter would the call
> into user/system provided functions avaiable in several overloads,
> depending on how throroughly the type can be formatted:
>
> string format_value([appender&, ]const MyValueType& v[, string_view
> options]);
>
> Stuff in brackets [ ] specifies optional arguments. The optional
> "options" parameter can forward format options form the format string to
> the formatting function and is empty if none were present. The format
> options could as well from format arguments.
>
> The exact nature of "appender" needs to be specified. It could be a
> streambuf/bytestream/sink that either writes to the formatter's internal
> buffer or directly to a device and would of course be write-only. Maybe
> a simple OutputIterator would suffice. Though it would be advantageous
> if it supported block-writing, then it is based on a custom concept. If
> the passed in format options are somehow invalid or the formatting
> cannot be done throwing an exception would probably be the most
> intuitive solution (or maybe <optional>? <expected>?).
>
> If more than one overload is present the program is ill-formed.
>
> For the "precompilation" aspect a second helper is needed. My idea is to
> have similar functions to those above but instead of producing values
> they return function objects with the format_options possibly baked in
> if present.
>
> template<class MyValueType>
>      std::function<string([appender&, ]const MyValueType&[,
> string_view])> value_formatter([string_view format_options]);
>
> Again, stuff in brackets [ ] is optional and if more than one overload
> exists the programm is ill-formed.
>
> The return type of value_formatter may not necessarily be a
> std::function but this way it is easier to showcase. As long as it is a
> type where the three functor overloads can be distinguished (using
> concepts?) everything is fine and the formatter should be able to pick
> the correct code path. The functional signatures can optionally also
> contain an additinal string_view argument for the formatting options
> just in case they cannot be pre-baked (or were provided as format
> arguments) and need to be re-evaluated at each formatting invokation. If
> none of such overloads exists precompilation for this entity is disabled
> and format_value is called instead on every execution. For absolute
> completeness there could even be an allocator argument to use for the
> function object if heap allocation is required.
>
> To summarize, the design as presented here (which I'm sure has flaws and
> can be imporoved) allows to add "to_string" capabilities to classes in a
> non-instrusive way compatible with a new printf-like interface with
> compile time type checking and it provides a mechanism to enable the
> "precompilation" phase for types where repeated parsing of format
> arguments (or the format string itself) may be inefficient. It enables
> the precompilation of multiple instances of the same positonal argument
> with different format options (e.g. "{0:XXXX} bla {0:HH:mm:ss}" using
> .NET syntax as example) without conflicts because each precompiled
> argument receives its own function object. All names were of course
> chosen spontaneously and are open to bikeshedding.
>
> I didn't go into detail about the bytestream/sink topic as I think those
> should be two separate proposals.
>
> I believe this design is very flexible and has the potential of being
> efficient. Allthough compilation times might suffer.
> But please, feel free to tear it apart :)
>
> P.S.: An example for flexibility: Assume you want an int to be printed
> in a special way with custom format options the standard doesn't support
> for 'int'. A simple tag struct and format function is all you need to
> make this happen:
>
> struct MyFormattedInt { MyFormattedInt(int i) : i(i); int i; }; //
> Constructor not explicit by design
>
> string format_value(const MyFormattedInt& v, string_view options)
> {
>       return /* do something fancy with "pretty" ints */;
> }
>
> formatter<int, MyFormattedInt> fmt{"{0:00} {1:pretty}"};
> format(fmt, 1, 1);
>
> Note that at the point of calling format() no special manipulator or
> other intrusive marker is necessary for enabling the pretty print.
>
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_81_11727382.1389998491790
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I also think that a new library should have at its core a =
"bytestream" type of object, which simply emits into its sink the represent=
ation of the object it is passed.<div><br></div><div>So for example, one ca=
n envision code like the following:</div><div><br></div><div>file_bytestrea=
m f("test.fil");</div><div>float value =3D 7.5f;</div><div><br></div><div>f=
 &lt;&lt; value; &nbsp; &nbsp; &nbsp; &nbsp;//four bytes representing the f=
loating point value 7.5 are written to test.fil</div><div><br></div><div>No=
te that I have deliberately used the input/output operator here, since, alt=
hough the standard at present indicates that this is formatted I/O (as dist=
inct from the unformatted I/O of write() and read() in IOStreams), it alway=
s seemed odd to me that the syntactic sugar of something being fed into the=
 stream was the preserve of only text streams. &nbsp;Don't worry about it -=
 it's not a significant issue! &nbsp;This could, I think be implemented rel=
atively easily using a templated operator function that simply takes the ad=
dress of the function and the size of the type and write it into the approp=
riate sink.</div><div><br></div><div>Something like (not syntax checked):</=
div><div><br></div><div>template&lt;typename T&gt;</div><div>bytestream&amp=
; operator&lt;&lt;(bytestream&amp; st, const T value)</div><div>{</div><div=
><blockquote style=3D"margin: 0 0 0 40px; border: none; padding: 0px;">retu=
rn st.write(value);</blockquote><div>}</div><div>.<br></div><div>.</div><di=
v>.</div><div>//somewhere in file_bytestream as a member function...code is=
 wrong, but hopefully intent is clear</div><div>template&lt;typename T&gt;<=
/div><div>file_bytestream&amp; write(T&amp; value)</div></div><div>{</div><=
div><blockquote style=3D"margin: 0 0 0 40px; border: none; padding: 0px;"><=
div>auto ad =3D &amp;value;</div></blockquote></div><blockquote style=3D"ma=
rgin: 0 0 0 40px; border: none; padding: 0px;"><div><div>char* recast =3D s=
tatic_cast&lt;char*&gt;(ad);</div></div></blockquote><blockquote style=3D"m=
argin: 0 0 0 40px; border: none; padding: 0px;"><div>fwrite(recast, sizeof(=
char), sizeof(T), this-&gt;pFile); &nbsp;//pFile is some internal FILE* poi=
nter</div></blockquote><blockquote style=3D"margin: 0 0 0 40px; border: non=
e; padding: 0px;"><div>return *this;</div></blockquote><div>}</div><div><br=
></div><div>To handle user-defined types, users could overload the &lt;&lt;=
 operator to make a series of calls to write() on the bytestream and write =
out appropriately (types encapsulating pointers are an obvious off-the-top-=
of-my-head example). &nbsp;A textstream-type class would essentially use a =
bytestream, but would simply format the bytes appropriately before emitting=
 them. &nbsp;So for example, a file_textstream class might encapsulate a fi=
le_bytestream class as a member (called 'fbs' in the example below) and the=
n redefine its &lt;&lt; operator in this kind of fashion:</div><div><br></d=
iv><div>file_textstream&amp; operator&lt;&lt;(file_textstream&amp; txt, con=
st float value)</div><div>{</div><div><blockquote style=3D"margin: 0 0 0 40=
px; border: none; padding: 0px;"><div>txt.fbs.write(std::to_string(value));=
 &nbsp; //need a wstring equivalent</div></blockquote></div><div>}</div><di=
v><br></div><div>A separate operator would then be define to act on objects=
 returned by the formatting functions being described by others:</div><div>=
<br></div><div>file_textstream&amp; operator&lt;&lt;(file_textstream&amp; t=
xt, const <i>format_function_type</i>&nbsp;value);</div><div><br></div><div=
>This is not perfectly thought through (I'm writing this while I wait for a=
 plane and it is late!), but I hope it gives the idea of a layered approach=
 that will only make a client of the library use the functionality that it =
needs. &nbsp;The stream operators themselves should in principle compile do=
wn to the underlying C calls, so giving a C++-like interface with associate=
d safety and type-checking, but with (hopefully) limited overhead. &nbsp;</=
div><div><br></div><div>Naturally, formatting the text in a more complicate=
d manner (using the format functions earlier in the thread) will introduce =
an overhead, but not necessarily any more than in any other language, and c=
rucially one only pays for it if one needs the functionality.</div><div><br=
></div><div>Sorry for the poor implementations above - I haven't a compiler=
 to hand and am in haste. &nbsp;Hopefully they are sufficiently illustrativ=
e!</div><div><br></div><div><br>On Wednesday, January 15, 2014 12:37:10 PM =
UTC, Miro Knejp wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>&gt; While streambuf exists its API is so non-intuitive that it is seld=
om=20
<br>&gt; used as a "file" object in itself. I would like to see a new=20
<br>&gt; "bytestream" type of object with nice read and write methods and t=
he=20
<br>&gt; features you would expect from a file, similar to the functions=20
<br>&gt; available for a C FILE*.
<br>Agreed.
<br>&gt;
<br>&gt; Pre-compilation of format strings is interesting but as I wrote=20
<br>&gt; before, we would want this to take place when the program starts t=
o=20
<br>&gt; avoid nasty surprises when a seldom occuring error message is to b=
e=20
<br>&gt; formatted. This would however require a core language change... In=
 the=20
<br>&gt; mean time we could design a system where the simple usage creates =
a=20
<br>&gt; temporary "compiled format string" object each time formatting is=
=20
<br>&gt; performed, while it is also possible to explicitly create one in f=
ile=20
<br>&gt; static memory to get the faster performance and program start chec=
king.
<br>Just to make sure we are talking about the same thing: with=20
<br>"precompiled" I mean a representation of a format string created at=20
<br>runtime which is more efficient to execute repeatedly than to parse the=
=20
<br>format string every single time.
<br>
<br>Having said that, I would rather not have the compiler guesstimate=20
<br>whether or not to create some static format object at startup if I don'=
t=20
<br>explicitly tell it to. I see the use case the same as with &lt;regex&gt=
;. If I=20
<br>know I am going to format the same message over and over and over again=
=20
<br>I want to be able to create an object from a (external) source string,=
=20
<br>put it somewhere safe and reuse it. If however a certain string is=20
<br>formatted rarely an easy to use inline version would be preferred.=20
<br>Regarding error messages: if your error strings are hardcoded anyway it=
=20
<br>should be possible to wrap the error creating/throwing parts in=20
<br>functions and write tests for them. I don't see how this requires any=
=20
<br>special treatment. So besides the "compiler does some magic for me" par=
t=20
<br>I think we are on the same track.
<br>
<br>Though for the sake of consistency with the overall design of the=20
<br>standard library, i.e. not formatting using object methods but a=20
<br>free-standing overload (makes it easier to integrate in templated code)=
:
<br>
<br>template&lt;class... Args, class CharT, classTraits =3D /*...*/, class=
=20
<br>Allocator =3D /*...*/&gt;
<br>class basic_formatter
<br>{
<br>&nbsp; &nbsp; &nbsp;formatter(...) { } // Various overloads to accept s=
tring sources,=20
<br>does the "precompilation"
<br>
<br>&nbsp; &nbsp; &nbsp;basic_string&lt;/*...*/&gt; operator() (const Args&=
amp;...); // For use as=20
<br>functor
<br>};
<br>
<br>template&lt;typename... Ts&gt; using formatter =3D basic_formatter&lt;T=
s..., char&gt;;
<br>
<br>template&lt;typename... Ts, /*...*/&gt; basic_string&lt;/*...*/&gt; for=
mat(const=20
<br>basic_formatter&lt;Ts..., /*...*/&gt;&amp;, const Ts&amp;... args);
<br>
<br>// Various overloads to accept string sources instead of formatters.
<br>// These could create a temporary formatter object, or (if more=20
<br>efficient) do the formatting directly (e.g. to avoid unnecessary=20
<br>allocations which would be required by the formatter to store state)
<br>template&lt;typename... Ts&gt; string format(const /*...*/&amp;, const =
Ts&amp;... args);
<br>
<br>I hope this looks reasonable. I left out interoperability with iostream=
s=20
<br>for now since we're looking for a replacement anyway. But adding a=20
<br>streambuf/bytestream/whatever sink in front of the format object would=
=20
<br>allow a direct write which might need less allocations.
<br>
<br>For the formatting of the individual values the formatter would the cal=
l=20
<br>into user/system provided functions avaiable in several overloads,=20
<br>depending on how throroughly the type can be formatted:
<br>
<br>string format_value([appender&amp;, ]const MyValueType&amp; v[, string_=
view=20
<br>options]);
<br>
<br>Stuff in brackets [ ] specifies optional arguments. The optional=20
<br>"options" parameter can forward format options form the format string t=
o=20
<br>the formatting function and is empty if none were present. The format=
=20
<br>options could as well from format arguments.
<br>
<br>The exact nature of "appender" needs to be specified. It could be a=20
<br>streambuf/bytestream/sink that either writes to the formatter's interna=
l=20
<br>buffer or directly to a device and would of course be write-only. Maybe=
=20
<br>a simple OutputIterator would suffice. Though it would be advantageous=
=20
<br>if it supported block-writing, then it is based on a custom concept. If=
=20
<br>the passed in format options are somehow invalid or the formatting=20
<br>cannot be done throwing an exception would probably be the most=20
<br>intuitive solution (or maybe &lt;optional&gt;? &lt;expected&gt;?).
<br>
<br>If more than one overload is present the program is ill-formed.
<br>
<br>For the "precompilation" aspect a second helper is needed. My idea is t=
o=20
<br>have similar functions to those above but instead of producing values=
=20
<br>they return function objects with the format_options possibly baked in=
=20
<br>if present.
<br>
<br>template&lt;class MyValueType&gt;
<br>&nbsp; &nbsp; &nbsp;std::function&lt;string([<wbr>appender&amp;, ]const=
 MyValueType&amp;[,=20
<br>string_view])&gt; value_formatter([string_view format_options]);
<br>
<br>Again, stuff in brackets [ ] is optional and if more than one overload=
=20
<br>exists the programm is ill-formed.
<br>
<br>The return type of value_formatter may not necessarily be a=20
<br>std::function but this way it is easier to showcase. As long as it is a=
=20
<br>type where the three functor overloads can be distinguished (using=20
<br>concepts?) everything is fine and the formatter should be able to pick=
=20
<br>the correct code path. The functional signatures can optionally also=20
<br>contain an additinal string_view argument for the formatting options=20
<br>just in case they cannot be pre-baked (or were provided as format=20
<br>arguments) and need to be re-evaluated at each formatting invokation. I=
f=20
<br>none of such overloads exists precompilation for this entity is disable=
d=20
<br>and format_value is called instead on every execution. For absolute=20
<br>completeness there could even be an allocator argument to use for the=
=20
<br>function object if heap allocation is required.
<br>
<br>To summarize, the design as presented here (which I'm sure has flaws an=
d=20
<br>can be imporoved) allows to add "to_string" capabilities to classes in =
a=20
<br>non-instrusive way compatible with a new printf-like interface with=20
<br>compile time type checking and it provides a mechanism to enable the=20
<br>"precompilation" phase for types where repeated parsing of format=20
<br>arguments (or the format string itself) may be inefficient. It enables=
=20
<br>the precompilation of multiple instances of the same positonal argument=
=20
<br>with different format options (e.g. "{0:XXXX} bla {0:HH:mm:ss}" using=
=20
<br>.NET syntax as example) without conflicts because each precompiled=20
<br>argument receives its own function object. All names were of course=20
<br>chosen spontaneously and are open to bikeshedding.
<br>
<br>I didn't go into detail about the bytestream/sink topic as I think thos=
e=20
<br>should be two separate proposals.
<br>
<br>I believe this design is very flexible and has the potential of being=
=20
<br>efficient. Allthough compilation times might suffer.
<br>But please, feel free to tear it apart :)
<br>
<br>P.S.: An example for flexibility: Assume you want an int to be printed=
=20
<br>in a special way with custom format options the standard doesn't suppor=
t=20
<br>for 'int'. A simple tag struct and format function is all you need to=
=20
<br>make this happen:
<br>
<br>struct MyFormattedInt { MyFormattedInt(int i) : i(i); int i; }; //=20
<br>Constructor not explicit by design
<br>
<br>string format_value(const MyFormattedInt&amp; v, string_view options)
<br>{
<br>&nbsp; &nbsp; &nbsp; return /* do something fancy with "pretty" ints */=
;
<br>}
<br>
<br>formatter&lt;int, MyFormattedInt&gt; fmt{"{0:00} {1:pretty}"};
<br>format(fmt, 1, 1);
<br>
<br>Note that at the point of calling format() no special manipulator or=20
<br>other intrusive marker is necessary for enabling the pretty print.
<br>
<br></blockquote></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_81_11727382.1389998491790--

.


Author: Miro Knejp <miro@knejp.de>
Date: Sat, 18 Jan 2014 00:04:18 +0100
Raw View
> I also think that a new library should have at its core a "bytestream"
> type of object, which simply emits into its sink the representation of
> the object it is passed.
>
> So for example, one can envision code like the following:
>
> file_bytestream f("test.fil");
> float value = 7.5f;
>
> f << value;        //four bytes representing the floating point value
> 7.5 are written to test.fil
I use a custom unformatted iomanip for these use cases.
ostream << unformatted(7.5f);
istream >> unformatted(afloat);
reads/writes the byte representation using the read/write methods.
A static_assert fails if T is not a POD type. Exceptions are
vectors/strings/arrays where instead value_type must be a POD and it
writes/reads the content instead of the object itself.

Not having to do this for every single invokation using dedicated
unformatted binary streams would be nice though.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: fritzpoll <fred.pollard@gmail.com>
Date: Fri, 17 Jan 2014 15:27:17 -0800 (PST)
Raw View
------=_Part_89_29363358.1390001237877
Content-Type: text/plain; charset=UTF-8

Yes, it's sort of in keeping with the philosophy that you shouldn't need to
do something comlicated to achieve a simple result.  Although that
statement is perhaps more subjective than I think!

On Friday, January 17, 2014 11:04:18 PM UTC, Miro Knejp wrote:
>
>
> > I also think that a new library should have at its core a "bytestream"
> > type of object, which simply emits into its sink the representation of
> > the object it is passed.
> >
> > So for example, one can envision code like the following:
> >
> > file_bytestream f("test.fil");
> > float value = 7.5f;
> >
> > f << value;        //four bytes representing the floating point value
> > 7.5 are written to test.fil
> I use a custom unformatted iomanip for these use cases.
> ostream << unformatted(7.5f);
> istream >> unformatted(afloat);
> reads/writes the byte representation using the read/write methods.
> A static_assert fails if T is not a POD type. Exceptions are
> vectors/strings/arrays where instead value_type must be a POD and it
> writes/reads the content instead of the object itself.
>
> Not having to do this for every single invokation using dedicated
> unformatted binary streams would be nice though.
>
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_89_29363358.1390001237877
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Yes, it's sort of in keeping with the philosophy that you =
shouldn't need to do something comlicated to achieve a simple result. &nbsp=
;Although that statement is perhaps more subjective than I think!<br><br>On=
 Friday, January 17, 2014 11:04:18 PM UTC, Miro Knejp wrote:<blockquote cla=
ss=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #=
ccc solid;padding-left: 1ex;">
<br>&gt; I also think that a new library should have at its core a "bytestr=
eam"=20
<br>&gt; type of object, which simply emits into its sink the representatio=
n of=20
<br>&gt; the object it is passed.
<br>&gt;
<br>&gt; So for example, one can envision code like the following:
<br>&gt;
<br>&gt; file_bytestream f("test.fil");
<br>&gt; float value =3D 7.5f;
<br>&gt;
<br>&gt; f &lt;&lt; value; &nbsp; &nbsp; &nbsp; &nbsp;//four bytes represen=
ting the floating point value=20
<br>&gt; 7.5 are written to test.fil
<br>I use a custom unformatted iomanip for these use cases.
<br>ostream &lt;&lt; unformatted(7.5f);
<br>istream &gt;&gt; unformatted(afloat);
<br>reads/writes the byte representation using the read/write methods.
<br>A static_assert fails if T is not a POD type. Exceptions are=20
<br>vectors/strings/arrays where instead value_type must be a POD and it=20
<br>writes/reads the content instead of the object itself.
<br>
<br>Not having to do this for every single invokation using dedicated=20
<br>unformatted binary streams would be nice though.
<br>
<br></blockquote></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_89_29363358.1390001237877--

.


Author: masse.nicolas@gmail.com
Date: Fri, 17 Jan 2014 15:52:18 -0800 (PST)
Raw View
------=_Part_87_1324132.1390002738748
Content-Type: text/plain; charset=UTF-8

Hi all.
For the things of parsing the format string only once, I do believe the
simplest solution woul be to add some classes wich are able to contains the
formatting parameters.
For example, in .Net the NumberFormatInfo<http://msdn.microsoft.com/fr-fr/library/system.globalization.numberformatinfo.numberformatinfo%28v=vs.110%29.aspx>class contains all the necessary information in order to format a number.
Then you could add a method or a ctor in order to get an object from a
string reprsentation of the format.
For example :

string format_price(double price, locale loc = std::locale()) //I'll
explain later why I put a std::locale here
{
    static auto format = std::numeric_format(".2");//say that the prices
should be formatted using 2 digits for the decimal part. Note that the
formatting syntax still need to be defined
    return to_string(price, format, loc);//I assume here that such an
overload of the to_string method exists.
}

The same could be achived by doing this :

std::numeric_format get_price_format()
{
    std::numeric_format format;
    format.decimal_digits = 2;
    return format;
}

string format_price(double price, locale loc = std::locale())
{
    static auto format = get_price_format();
    return to_string(price, format, loc);
}

Note that I separate the notion of formatting and the notion of locales on
purpose.
The idea beyond this is that they define different things.
Basically:
- the format will defined wich part of the data should be represented (and
how).
  For example :
    * the decimal part should be represented using the first 2 digit
    * a date should be represented with the day-of-the-month first
(represented as a numeric value), the the month (using a full string
representation), then the year (using 4 digit)

- the locale will define wich char or string must be used for each part.
  For example :
    * the decimal separator to be used must be a dot. ('.')
    * the name of the months are the strings "january", "february", ...if
you're using an english locale for example.

Now, another tought:
It seems than this topic is speaking of 2 differents things:
- Adding another way to provide iostream facilities
- Adding another way to provide formatting facilities
While those 2 are complementary, I think they are differents subject. Then
my question is :
What about creating a new topic about formatting facilities? (and keep this
one for iostream facilities)

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_87_1324132.1390002738748
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi all.<br>For the things of parsing the format string onl=
y once, I do believe the simplest solution woul be to add some classes wich=
 are able to contains the formatting parameters.<br>For example, in .Net th=
e <a href=3D"http://msdn.microsoft.com/fr-fr/library/system.globalization.n=
umberformatinfo.numberformatinfo%28v=3Dvs.110%29.aspx">NumberFormatInfo</a>=
 class contains all the necessary information in order to format a number.<=
br>Then you could add a method or a ctor in order to get an object from a s=
tring reprsentation of the format.<br>For example :<br><div class=3D"pretty=
print" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187=
, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-word;=
"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color:=
 #008;" class=3D"styled-by-prettify">string</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> format_price</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">double</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> price</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> locale loc </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">locale</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">())</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">//I'll explain later why I p=
ut a std::locale here </span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">static</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> format </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">numeric_format</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
80;" class=3D"styled-by-prettify">".2"</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">);</span><span style=3D"color: #800;" class=3D"=
styled-by-prettify">//say that the prices should be formatted using 2 digit=
s for the decimal part. Note that the formatting syntax still need to be de=
fined</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&=
nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">return</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
to_string</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">price</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> format</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> loc</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">);</span><span style=3D"color: #800;" clas=
s=3D"styled-by-prettify">//I assume here that such an overload of the to_st=
ring method exists.</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></=
span></div></code></div><br>The same could be achived by doing this :<br><b=
r><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250);=
 border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; =
word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpretty=
print"><span style=3D"color: #000;" class=3D"styled-by-prettify">std</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">numeric_format get_price_=
format</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; std</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">numeric_format format</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; form=
at</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">decimal_digits </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #066;" class=3D"styled-by-prettify">2</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color:=
 #008;" class=3D"styled-by-prettify">return</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> format</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">string</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 format_price</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">double=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> price</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> locale loc </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">locale</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">())</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">static</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> f=
ormat </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> get_price_=
format</span><span style=3D"color: #660;" class=3D"styled-by-prettify">();<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; =
&nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">ret=
urn</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> to_str=
ing</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">price</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> format</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> loc</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span></div></code></div><br>Note that I separate the notion of =
formatting and the notion of locales on purpose.<br>The idea beyond this is=
 that they define different things. <br>Basically: <br>- the format will de=
fined wich part of the data should be represented (and how). <br>&nbsp; For=
 example : <br>&nbsp;&nbsp;&nbsp; * the decimal part should be represented =
using the first 2 digit<br>&nbsp;&nbsp;&nbsp; * a date should be represente=
d with the day-of-the-month first (represented as a numeric value), the the=
 month (using a full string representation), then the year (using 4 digit)<=
br><br>- the locale will define wich char or string must be used for each p=
art.<br>&nbsp; For example : <br>&nbsp;&nbsp;&nbsp; * the decimal separator=
 to be used must be a dot. ('.')<br>&nbsp;&nbsp;&nbsp; * the name of the mo=
nths are the strings "january", "february", ...if you're using an english l=
ocale for example.<br><br>Now, another tought:<br>It seems than this topic =
is speaking of 2 differents things:<br>- Adding another way to provide iost=
ream facilities<br>- Adding another way to provide formatting facilities<br=
>While those 2 are complementary, I think they are differents subject. Then=
 my question is :<br>What about creating a new topic about formatting facil=
ities? (and keep this one for  iostream facilities)<br><br></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_87_1324132.1390002738748--

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Fri, 17 Jan 2014 16:36:57 -0800 (PST)
Raw View
------=_Part_210_25604155.1390005417522
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

I'm still working on my compilable codebase for this.

I'm however basically on the same page as you, except that I specified a=20
DataFormatter template which both contains the parameters, the parsing of=
=20
the parameters from string form and the actual formatting of the value of=
=20
type T.

This template is then specialized for each T, including, as desired, user=
=20
defined types.

The advantage is that as there is only one template name you can do much=20
more within the surrounding formatter template without having to resort to=
=20
using heap memory and virtual methods (which I don't).

I'm getting really close to working code but I was hit by a nasty bug,=20
possibly a compiler bug.

I think that the two subjects of a low level stream and a formatting=20
facility will ultimately be two different proposals, but in this stage I=20
think we need to keep the discussion in one place to see the=20
interdependencies and requirements more clearly. I'm also thinking that we=
=20
need an intermediate level which basically holds the locale and maybe the=
=20
line ending mode, as ostream already has this while it seems to be=20
unnecessary baggage for a new binary file class. I think that it would be=
=20
nice if this intermediate object held a "formatter set" that is, a=20
container of formatters for diferent types. It is however beyond me how to=
=20
get this without introducing things that slow the process down consiredably=
=20
such as searching a data structure for a formatter for typeid(T). Maybe a=
=20
template template parameter which defaults to 'DataFormatter' but that only=
=20
offers compile time specialization.=20

Den l=C3=B6rdagen den 18:e januari 2014 kl. 00:52:18 UTC+1 skrev=20
masse....@gmail.com:
>
> Hi all.
> For the things of parsing the format string only once, I do believe the=
=20
> simplest solution woul be to add some classes wich are able to contains t=
he=20
> formatting parameters.
> For example, in .Net the NumberFormatInfo<http://msdn.microsoft.com/fr-fr=
/library/system.globalization.numberformatinfo.numberformatinfo%28v=3Dvs.11=
0%29.aspx>class contains all the necessary information in order to format a=
 number.
> Then you could add a method or a ctor in order to get an object from a=20
> string reprsentation of the format.
> For example :
>
> string format_price(double price, locale loc =3D std::locale()) //I'll=20
> explain later why I put a std::locale here=20
> {
>     static auto format =3D std::numeric_format(".2");//say that the price=
s=20
> should be formatted using 2 digits for the decimal part. Note that the=20
> formatting syntax still need to be defined
>     return to_string(price, format, loc);//I assume here that such an=20
> overload of the to_string method exists.
> }
>
> The same could be achived by doing this :
>
> std::numeric_format get_price_format()
> {
>     std::numeric_format format;
>     format.decimal_digits =3D 2;
>     return format;
> }
>
> string format_price(double price, locale loc =3D std::locale())
> {
>     static auto format =3D get_price_format();
>     return to_string(price, format, loc);
> }
>
> Note that I separate the notion of formatting and the notion of locales o=
n=20
> purpose.
> The idea beyond this is that they define different things.=20
> Basically:=20
> - the format will defined wich part of the data should be represented (an=
d=20
> how).=20
>   For example :=20
>     * the decimal part should be represented using the first 2 digit
>     * a date should be represented with the day-of-the-month first=20
> (represented as a numeric value), the the month (using a full string=20
> representation), then the year (using 4 digit)
>
> - the locale will define wich char or string must be used for each part.
>   For example :=20
>     * the decimal separator to be used must be a dot. ('.')
>     * the name of the months are the strings "january", "february", ...if=
=20
> you're using an english locale for example.
>
> Now, another tought:
> It seems than this topic is speaking of 2 differents things:
> - Adding another way to provide iostream facilities
> - Adding another way to provide formatting facilities
> While those 2 are complementary, I think they are differents subject. The=
n=20
> my question is :
> What about creating a new topic about formatting facilities? (and keep=20
> this one for iostream facilities)
>
>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_210_25604155.1390005417522
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I'm still working on my compilable codebase for this.<div>=
<br></div><div>I'm however basically on the same page as you, except that I=
 specified a DataFormatter template which both contains the parameters, the=
 parsing of the parameters from string form and the actual formatting of th=
e value of type T.</div><div><br></div><div>This template is then specializ=
ed for each T, including, as desired, user defined types.</div><div><br></d=
iv><div>The advantage is that as there is only one template name you can do=
 much more within the surrounding formatter template without having to reso=
rt to using heap memory and virtual methods (which I don't).</div><div><br>=
</div><div>I'm getting really close to working code but I was hit by a nast=
y bug, possibly a compiler bug.</div><div><br></div><div>I think that the t=
wo subjects of a low level stream and a formatting facility will ultimately=
 be two different proposals, but in this stage I think we need to keep the =
discussion in one place to see the interdependencies and requirements more =
clearly. I'm also thinking that we need an intermediate level which basical=
ly holds the locale and maybe the line ending mode, as ostream already has =
this while it seems to be unnecessary baggage for a new binary file class. =
I think that it would be nice if this intermediate object held a "formatter=
 set" that is, a container of formatters for diferent types. It is however =
beyond me how to get this without introducing things that slow the process =
down consiredably such as searching a data structure for a formatter for ty=
peid(T). Maybe a template template parameter which defaults to 'DataFormatt=
er' but that only offers compile time specialization.&nbsp;</div><div><div>=
<br>Den l=C3=B6rdagen den 18:e januari 2014 kl. 00:52:18 UTC+1 skrev masse.=
....@gmail.com:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
>Hi all.<br>For the things of parsing the format string only once, I do bel=
ieve the simplest solution woul be to add some classes wich are able to con=
tains the formatting parameters.<br>For example, in .Net the <a href=3D"htt=
p://msdn.microsoft.com/fr-fr/library/system.globalization.numberformatinfo.=
numberformatinfo%28v=3Dvs.110%29.aspx" target=3D"_blank" onmousedown=3D"thi=
s.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fmsdn.microsoft.com%2Ff=
r-fr%2Flibrary%2Fsystem.globalization.numberformatinfo.numberformatinfo%252=
8v%3Dvs.110%2529.aspx\46sa\75D\46sntz\0751\46usg\75AFQjCNG7q0AGg2cpBKPq8H5K=
4QMXAmth4A';return true;" onclick=3D"this.href=3D'http://www.google.com/url=
?q\75http%3A%2F%2Fmsdn.microsoft.com%2Ffr-fr%2Flibrary%2Fsystem.globalizati=
on.numberformatinfo.numberformatinfo%2528v%3Dvs.110%2529.aspx\46sa\75D\46sn=
tz\0751\46usg\75AFQjCNG7q0AGg2cpBKPq8H5K4QMXAmth4A';return true;">NumberFor=
matInfo</a> class contains all the necessary information in order to format=
 a number.<br>Then you could add a method or a ctor in order to get an obje=
ct from a string reprsentation of the format.<br>For example :<br><div styl=
e=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border=
-style:solid;border-width:1px;word-wrap:break-word"><code><div><span style=
=3D"color:#000"><br></span><span style=3D"color:#008">string</span><span st=
yle=3D"color:#000"> format_price</span><span style=3D"color:#660">(</span><=
span style=3D"color:#008">double</span><span style=3D"color:#000"> price</s=
pan><span style=3D"color:#660">,</span><span style=3D"color:#000"> locale l=
oc </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> =
std</span><span style=3D"color:#660">::</span><span style=3D"color:#000">lo=
cale</span><span style=3D"color:#660">())</span><span style=3D"color:#000">=
 </span><span style=3D"color:#800">//I'll explain later why I put a std::lo=
cale here </span><span style=3D"color:#000"><br></span><span style=3D"color=
:#660">{</span><span style=3D"color:#000"><br>&nbsp; &nbsp; </span><span st=
yle=3D"color:#008">static</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#008">auto</span><span style=3D"color:#000"> format </span><sp=
an style=3D"color:#660">=3D</span><span style=3D"color:#000"> std</span><sp=
an style=3D"color:#660">::</span><span style=3D"color:#000">numeric_format<=
/span><span style=3D"color:#660">(</span><span style=3D"color:#080">".2"</s=
pan><span style=3D"color:#660">);</span><span style=3D"color:#800">//<wbr>s=
ay that the prices should be formatted using 2 digits for the decimal part.=
 Note that the formatting syntax still need to be defined</span><span style=
=3D"color:#000"><br>&nbsp; &nbsp; </span><span style=3D"color:#008">return<=
/span><span style=3D"color:#000"> to_string</span><span style=3D"color:#660=
">(</span><span style=3D"color:#000">price</span><span style=3D"color:#660"=
>,</span><span style=3D"color:#000"> format</span><span style=3D"color:#660=
">,</span><span style=3D"color:#000"> loc</span><span style=3D"color:#660">=
);</span><span style=3D"color:#800">//I assume here that such an overload o=
f the to_string method exists.</span><span style=3D"color:#000"><br></span>=
<span style=3D"color:#660">}</span><span style=3D"color:#000"><br></span></=
div></code></div><br>The same could be achived by doing this :<br><br><div =
style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bo=
rder-style:solid;border-width:1px;word-wrap:break-word"><code><div><span st=
yle=3D"color:#000">std</span><span style=3D"color:#660">::</span><span styl=
e=3D"color:#000">numeric_format get_price_format</span><span style=3D"color=
:#660">()</span><span style=3D"color:#000"><br></span><span style=3D"color:=
#660">{</span><span style=3D"color:#000"><br>&nbsp; &nbsp; std</span><span =
style=3D"color:#660">::</span><span style=3D"color:#000">numeric_format for=
mat</span><span style=3D"color:#660">;</span><span style=3D"color:#000"><br=
>&nbsp; &nbsp; format</span><span style=3D"color:#660">.</span><span style=
=3D"color:#000">decimal_digits </span><span style=3D"color:#660">=3D</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#066">2</span><span=
 style=3D"color:#660">;</span><span style=3D"color:#000"><br>&nbsp; &nbsp; =
</span><span style=3D"color:#008">return</span><span style=3D"color:#000"> =
format</span><span style=3D"color:#660">;</span><span style=3D"color:#000">=
<br></span><span style=3D"color:#660">}</span><span style=3D"color:#000"><b=
r><br></span><span style=3D"color:#008">string</span><span style=3D"color:#=
000"> format_price</span><span style=3D"color:#660">(</span><span style=3D"=
color:#008">double</span><span style=3D"color:#000"> price</span><span styl=
e=3D"color:#660">,</span><span style=3D"color:#000"> locale loc </span><spa=
n style=3D"color:#660">=3D</span><span style=3D"color:#000"> std</span><spa=
n style=3D"color:#660">::</span><span style=3D"color:#000">locale</span><sp=
an style=3D"color:#660">())</span><span style=3D"color:#000"><br></span><sp=
an style=3D"color:#660">{</span><span style=3D"color:#000"><br>&nbsp; &nbsp=
; </span><span style=3D"color:#008">static</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">auto</span><span style=3D"color:#000"> =
format </span><span style=3D"color:#660">=3D</span><span style=3D"color:#00=
0"> get_price_format</span><span style=3D"color:#660">();</span><span style=
=3D"color:#000"><br>&nbsp; &nbsp; </span><span style=3D"color:#008">return<=
/span><span style=3D"color:#000"> to_string</span><span style=3D"color:#660=
">(</span><span style=3D"color:#000">price</span><span style=3D"color:#660"=
>,</span><span style=3D"color:#000"> format</span><span style=3D"color:#660=
">,</span><span style=3D"color:#000"> loc</span><span style=3D"color:#660">=
);</span><span style=3D"color:#000"><br></span><span style=3D"color:#660">}=
</span><span style=3D"color:#000"><br></span></div></code></div><br>Note th=
at I separate the notion of formatting and the notion of locales on purpose=
..<br>The idea beyond this is that they define different things. <br>Basical=
ly: <br>- the format will defined wich part of the data should be represent=
ed (and how). <br>&nbsp; For example : <br>&nbsp;&nbsp;&nbsp; * the decimal=
 part should be represented using the first 2 digit<br>&nbsp;&nbsp;&nbsp; *=
 a date should be represented with the day-of-the-month first (represented =
as a numeric value), the the month (using a full string representation), th=
en the year (using 4 digit)<br><br>- the locale will define wich char or st=
ring must be used for each part.<br>&nbsp; For example : <br>&nbsp;&nbsp;&n=
bsp; * the decimal separator to be used must be a dot. ('.')<br>&nbsp;&nbsp=
;&nbsp; * the name of the months are the strings "january", "february", ...=
if you're using an english locale for example.<br><br>Now, another tought:<=
br>It seems than this topic is speaking of 2 differents things:<br>- Adding=
 another way to provide iostream facilities<br>- Adding another way to prov=
ide formatting facilities<br>While those 2 are complementary, I think they =
are differents subject. Then my question is :<br>What about creating a new =
topic about formatting facilities? (and keep this one for  iostream facilit=
ies)<br><br></div></blockquote></div></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_210_25604155.1390005417522--

.


Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Fri, 17 Jan 2014 16:57:49 -0800
Raw View
--001a1134a45c258b4a04f0342805
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

I don't think a template is the way to go here. While the potential
performance increase is there, I don't think that's the way we want to go
for the "general, default" library. Real programs often have localization
requirements, and if those values are burned in as template parameters you
can't go back later and fix this by changing the string.

If someone profiles and finds that they need faster formatting and don't
need localization, they can always fall back on a specialized library /
implementation.

Also take a look at .NET's Stream vs. StreamReader distinction -- and note
that today's stringstream is similar to .NETs StringReader. e.g. they have
2 completely separate trees which both can be overridden; at the formatted
and unformatted IO level. (Just don't repeat their mistake where the
formatted IO level takes ownership of the stream :) )

Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal


On Fri, Jan 17, 2014 at 4:36 PM, Bengt Gustafsson <
bengt.gustafsson@beamways.com> wrote:

> I'm still working on my compilable codebase for this.
>
> I'm however basically on the same page as you, except that I specified a
> DataFormatter template which both contains the parameters, the parsing of
> the parameters from string form and the actual formatting of the value of
> type T.
>
> This template is then specialized for each T, including, as desired, user
> defined types.
>
> The advantage is that as there is only one template name you can do much
> more within the surrounding formatter template without having to resort t=
o
> using heap memory and virtual methods (which I don't).
>
> I'm getting really close to working code but I was hit by a nasty bug,
> possibly a compiler bug.
>
> I think that the two subjects of a low level stream and a formatting
> facility will ultimately be two different proposals, but in this stage I
> think we need to keep the discussion in one place to see the
> interdependencies and requirements more clearly. I'm also thinking that w=
e
> need an intermediate level which basically holds the locale and maybe the
> line ending mode, as ostream already has this while it seems to be
> unnecessary baggage for a new binary file class. I think that it would be
> nice if this intermediate object held a "formatter set" that is, a
> container of formatters for diferent types. It is however beyond me how t=
o
> get this without introducing things that slow the process down consiredab=
ly
> such as searching a data structure for a formatter for typeid(T). Maybe a
> template template parameter which defaults to 'DataFormatter' but that on=
ly
> offers compile time specialization.
>
> Den l=C3=B6rdagen den 18:e januari 2014 kl. 00:52:18 UTC+1 skrev
> masse....@gmail.com:
>
>> Hi all.
>> For the things of parsing the format string only once, I do believe the
>> simplest solution woul be to add some classes wich are able to contains =
the
>> formatting parameters.
>> For example, in .Net the NumberFormatInfo<http://msdn.microsoft.com/fr-f=
r/library/system.globalization.numberformatinfo.numberformatinfo%28v=3Dvs.1=
10%29.aspx>class contains all the necessary information in order to format =
a number.
>> Then you could add a method or a ctor in order to get an object from a
>> string reprsentation of the format.
>> For example :
>>
>> string format_price(double price, locale loc =3D std::locale()) //I'll
>> explain later why I put a std::locale here
>> {
>>     static auto format =3D std::numeric_format(".2");//say that the pric=
es
>> should be formatted using 2 digits for the decimal part. Note that the
>> formatting syntax still need to be defined
>>     return to_string(price, format, loc);//I assume here that such an
>> overload of the to_string method exists.
>> }
>>
>> The same could be achived by doing this :
>>
>> std::numeric_format get_price_format()
>> {
>>     std::numeric_format format;
>>     format.decimal_digits =3D 2;
>>     return format;
>> }
>>
>> string format_price(double price, locale loc =3D std::locale())
>> {
>>     static auto format =3D get_price_format();
>>     return to_string(price, format, loc);
>> }
>>
>> Note that I separate the notion of formatting and the notion of locales
>> on purpose.
>> The idea beyond this is that they define different things.
>> Basically:
>> - the format will defined wich part of the data should be represented
>> (and how).
>>   For example :
>>     * the decimal part should be represented using the first 2 digit
>>     * a date should be represented with the day-of-the-month first
>> (represented as a numeric value), the the month (using a full string
>> representation), then the year (using 4 digit)
>>
>> - the locale will define wich char or string must be used for each part.
>>   For example :
>>     * the decimal separator to be used must be a dot. ('.')
>>     * the name of the months are the strings "january", "february", ...i=
f
>> you're using an english locale for example.
>>
>> Now, another tought:
>> It seems than this topic is speaking of 2 differents things:
>> - Adding another way to provide iostream facilities
>> - Adding another way to provide formatting facilities
>> While those 2 are complementary, I think they are differents subject.
>> Then my question is :
>> What about creating a new topic about formatting facilities? (and keep
>> this one for iostream facilities)
>>
>>  --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--001a1134a45c258b4a04f0342805
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>I don&#39;t think a template is the way to go here. W=
hile the potential performance increase is there, I don&#39;t think that&#3=
9;s the way we want to go for the &quot;general, default&quot; library. Rea=
l programs often have localization requirements, and if those values are bu=
rned in as template parameters you can&#39;t go back later and fix this by =
changing the string.</div>

<div><br></div><div>If someone profiles and finds that they need faster for=
matting and don&#39;t need localization, they can always fall back on a spe=
cialized library / implementation.</div><div><br></div><div>Also take a loo=
k at .NET&#39;s Stream vs. StreamReader distinction -- and note that today&=
#39;s stringstream is similar to .NETs StringReader. e.g. they have 2 compl=
etely separate trees which both can be overridden; at the formatted and unf=
ormatted IO level. (Just don&#39;t repeat their mistake where the formatted=
 IO level takes ownership of the stream :) )</div>

</div><div class=3D"gmail_extra"><br clear=3D"all"><div><div dir=3D"ltr"><d=
iv>Billy O&#39;Neal</div><div><a href=3D"https://bitbucket.org/BillyONeal/"=
 target=3D"_blank">https://github.com/BillyONeal/</a></div><div><a href=3D"=
http://stackoverflow.com/users/82320/billy-oneal" target=3D"_blank">http://=
stackoverflow.com/users/82320/billy-oneal</a></div>

</div></div>
<br><br><div class=3D"gmail_quote">On Fri, Jan 17, 2014 at 4:36 PM, Bengt G=
ustafsson <span dir=3D"ltr">&lt;<a href=3D"mailto:bengt.gustafsson@beamways=
..com" target=3D"_blank">bengt.gustafsson@beamways.com</a>&gt;</span> wrote:=
<br>

<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">I&#39;m still working on my=
 compilable codebase for this.<div><br></div><div>I&#39;m however basically=
 on the same page as you, except that I specified a DataFormatter template =
which both contains the parameters, the parsing of the parameters from stri=
ng form and the actual formatting of the value of type T.</div>

<div><br></div><div>This template is then specialized for each T, including=
, as desired, user defined types.</div><div><br></div><div>The advantage is=
 that as there is only one template name you can do much more within the su=
rrounding formatter template without having to resort to using heap memory =
and virtual methods (which I don&#39;t).</div>

<div><br></div><div>I&#39;m getting really close to working code but I was =
hit by a nasty bug, possibly a compiler bug.</div><div><br></div><div>I thi=
nk that the two subjects of a low level stream and a formatting facility wi=
ll ultimately be two different proposals, but in this stage I think we need=
 to keep the discussion in one place to see the interdependencies and requi=
rements more clearly. I&#39;m also thinking that we need an intermediate le=
vel which basically holds the locale and maybe the line ending mode, as ost=
ream already has this while it seems to be unnecessary baggage for a new bi=
nary file class. I think that it would be nice if this intermediate object =
held a &quot;formatter set&quot; that is, a container of formatters for dif=
erent types. It is however beyond me how to get this without introducing th=
ings that slow the process down consiredably such as searching a data struc=
ture for a formatter for typeid(T). Maybe a template template parameter whi=
ch defaults to &#39;DataFormatter&#39; but that only offers compile time sp=
ecialization.=C2=A0</div>

<div><div><br>Den l=C3=B6rdagen den 18:e januari 2014 kl. 00:52:18 UTC+1 sk=
rev <a href=3D"mailto:masse....@gmail.com" target=3D"_blank">masse....@gmai=
l.com</a>:<div><div class=3D"h5"><blockquote class=3D"gmail_quote" style=3D=
"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,20=
4);border-left-width:1px;border-left-style:solid">

<div dir=3D"ltr">Hi all.<br>For the things of parsing the format string onl=
y once, I do believe the simplest solution woul be to add some classes wich=
 are able to contains the formatting parameters.<br>For example, in .Net th=
e <a href=3D"http://msdn.microsoft.com/fr-fr/library/system.globalization.n=
umberformatinfo.numberformatinfo%28v=3Dvs.110%29.aspx" target=3D"_blank">Nu=
mberFormatInfo</a> class contains all the necessary information in order to=
 format a number.<br>

Then you could add a method or a ctor in order to get an object from a stri=
ng reprsentation of the format.<br>For example :<br><div style=3D"border:1p=
x solid rgb(187,187,187);background-color:rgb(250,250,250)"><code><div><spa=
n><br>

</span><span style=3D"color:rgb(0,0,136)">string</span><span> format_price<=
/span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb=
(0,0,136)">double</span><span> price</span><span style=3D"color:rgb(102,102=
,0)">,</span><span> locale loc </span><span style=3D"color:rgb(102,102,0)">=
=3D</span><span> std</span><span style=3D"color:rgb(102,102,0)">::</span><s=
pan>locale</span><span style=3D"color:rgb(102,102,0)">())</span><span> </sp=
an><span style=3D"color:rgb(136,0,0)">//I&#39;ll explain later why I put a =
std::locale here </span><span><br>

</span><span style=3D"color:rgb(102,102,0)">{</span><span><br>=C2=A0 =C2=A0=
 </span><span style=3D"color:rgb(0,0,136)">static</span><span> </span><span=
 style=3D"color:rgb(0,0,136)">auto</span><span> format </span><span style=
=3D"color:rgb(102,102,0)">=3D</span><span> std</span><span style=3D"color:r=
gb(102,102,0)">::</span><span>numeric_format</span><span style=3D"color:rgb=
(102,102,0)">(</span><span style=3D"color:rgb(0,136,0)">&quot;.2&quot;</spa=
n><span style=3D"color:rgb(102,102,0)">);</span><span style=3D"color:rgb(13=
6,0,0)">//<u></u>say that the prices should be formatted using 2 digits for=
 the decimal part. Note that the formatting syntax still need to be defined=
</span><span><br>

=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">return</span><span>=
 to_string</span><span style=3D"color:rgb(102,102,0)">(</span><span>price</=
span><span style=3D"color:rgb(102,102,0)">,</span><span> format</span><span=
 style=3D"color:rgb(102,102,0)">,</span><span> loc</span><span style=3D"col=
or:rgb(102,102,0)">);</span><span style=3D"color:rgb(136,0,0)">//I assume h=
ere that such an overload of the to_string method exists.</span><span><br>

</span><span style=3D"color:rgb(102,102,0)">}</span><span><br></span></div>=
</code></div><br>The same could be achived by doing this :<br><br><div styl=
e=3D"border:1px solid rgb(187,187,187);background-color:rgb(250,250,250)">
<code><div>
<span>std</span><span style=3D"color:rgb(102,102,0)">::</span><span>numeric=
_format get_price_format</span><span style=3D"color:rgb(102,102,0)">()</spa=
n><span><br></span><span style=3D"color:rgb(102,102,0)">{</span><span><br>=
=C2=A0 =C2=A0 std</span><span style=3D"color:rgb(102,102,0)">::</span><span=
>numeric_format format</span><span style=3D"color:rgb(102,102,0)">;</span><=
span><br>

=C2=A0 =C2=A0 format</span><span style=3D"color:rgb(102,102,0)">.</span><sp=
an>decimal_digits </span><span style=3D"color:rgb(102,102,0)">=3D</span><sp=
an> </span><span style=3D"color:rgb(0,102,102)">2</span><span style=3D"colo=
r:rgb(102,102,0)">;</span><span><br>

=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">return</span><span>=
 format</span><span style=3D"color:rgb(102,102,0)">;</span><span><br></span=
><span style=3D"color:rgb(102,102,0)">}</span><span><br><br></span><span st=
yle=3D"color:rgb(0,0,136)">string</span><span> format_price</span><span sty=
le=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,136)">doub=
le</span><span> price</span><span style=3D"color:rgb(102,102,0)">,</span><s=
pan> locale loc </span><span style=3D"color:rgb(102,102,0)">=3D</span><span=
> std</span><span style=3D"color:rgb(102,102,0)">::</span><span>locale</spa=
n><span style=3D"color:rgb(102,102,0)">())</span><span><br>

</span><span style=3D"color:rgb(102,102,0)">{</span><span><br>=C2=A0 =C2=A0=
 </span><span style=3D"color:rgb(0,0,136)">static</span><span> </span><span=
 style=3D"color:rgb(0,0,136)">auto</span><span> format </span><span style=
=3D"color:rgb(102,102,0)">=3D</span><span> get_price_format</span><span sty=
le=3D"color:rgb(102,102,0)">();</span><span><br>

=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">return</span><span>=
 to_string</span><span style=3D"color:rgb(102,102,0)">(</span><span>price</=
span><span style=3D"color:rgb(102,102,0)">,</span><span> format</span><span=
 style=3D"color:rgb(102,102,0)">,</span><span> loc</span><span style=3D"col=
or:rgb(102,102,0)">);</span><span><br>

</span><span style=3D"color:rgb(102,102,0)">}</span><span><br></span></div>=
</code></div><br>Note that I separate the notion of formatting and the noti=
on of locales on purpose.<br>The idea beyond this is that they define diffe=
rent things. <br>

Basically: <br>- the format will defined wich part of the data should be re=
presented (and how). <br>=C2=A0 For example : <br>=C2=A0=C2=A0=C2=A0 * the =
decimal part should be represented using the first 2 digit<br>=C2=A0=C2=A0=
=C2=A0 * a date should be represented with the day-of-the-month first (repr=
esented as a numeric value), the the month (using a full string representat=
ion), then the year (using 4 digit)<br>

<br>- the locale will define wich char or string must be used for each part=
..<br>=C2=A0 For example : <br>=C2=A0=C2=A0=C2=A0 * the decimal separator to=
 be used must be a dot. (&#39;.&#39;)<br>=C2=A0=C2=A0=C2=A0 * the name of t=
he months are the strings &quot;january&quot;, &quot;february&quot;, ...if =
you&#39;re using an english locale for example.<br>

<br>Now, another tought:<br>It seems than this topic is speaking of 2 diffe=
rents things:<br>- Adding another way to provide iostream facilities<br>- A=
dding another way to provide formatting facilities<br>While those 2 are com=
plementary, I think they are differents subject. Then my question is :<br>

What about creating a new topic about formatting facilities? (and keep this=
 one for  iostream facilities)<br><br></div></blockquote></div></div></div>=
</div></div><div class=3D"HOEnZb"><div class=3D"h5">

<p></p>

-- <br>
=C2=A0<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a1134a45c258b4a04f0342805--

.


Author: Miro Knejp <miro@knejp.de>
Date: Sat, 18 Jan 2014 06:31:07 +0100
Raw View
So I was toying around with my concept for the past days and uploaded my
progress:
https://github.com/mknejp/std-format

I hope the readme is a sufficient description of my take on the problem.
There are still several TODOs and open issues and the implementation
certainly is neither perfect nor the most efficient, but it works and
hopefully serves as a starting proof of concept. It's at least capable
of formatting its own error messages ;)

Am 18.01.2014 01:57, schrieb Billy O'Neal:
> I don't think a template is the way to go here. While the potential
> performance increase is there, I don't think that's the way we want to
> go for the "general, default" library. Real programs often have
> localization requirements, and if those values are burned in as
> template parameters you can't go back later and fix this by changing
> the string.
>
Could you elaborate on where you see templates as a problem for
localization? At least in my approach everything that controls the
formatting of the output comes from dynamic content, including the
ordering of the parameters and how they should be printed.

It allows for things like

format(localized_string, "Harry", 30, "nerd"); // types are string, int,
string
"His name is {0}, he's {1} years old and a {2}." => "His name is Harry,
he's 30 years old and a nerd."
"A {1} years old {2} called {0} entered the bar. He was the only {2}
there." => "A 30 years old nerd called Harry entered the bar. He was the
only nerd there."
"{0} the {2} had his {1:ord} birthday." => "Harry the nerd had his 30th
birthday."
The last example assumes there is a "ord" format flag making ordinal
numbers (based on the locale, thus en: 30th, de: 30., fr: 30e?)

The only  thing fixed with templates at compile time is the type of the
arguments: string, int, string. If you were, for example, to change the
second paramter to a "Age" class and have a to_string(const Age&,
string_view) method (or other supported overload) in the right scope it
uses that for printing instead and the conversion rules of the type are
completely under control of the implementer. The string_view argument
would be "ord", i.e. the entire content between the colon and closing brace.

Is there something I'm missing?

P.S.: Please keep in mind the syntax is just for demonstration purpose
and experimentation

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Fri, 17 Jan 2014 23:40:10 -0800
Raw View
--001a1136987415381d04f039c742
Content-Type: text/plain; charset=UTF-8

Ah, that's fine. I thought you were proposing something whereby things like
field widths / arg positions would be put in as nontype template parameters.

Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal


On Fri, Jan 17, 2014 at 9:31 PM, Miro Knejp <miro@knejp.de> wrote:

> So I was toying around with my concept for the past days and uploaded my
> progress:
> https://github.com/mknejp/std-format
>
> I hope the readme is a sufficient description of my take on the problem.
> There are still several TODOs and open issues and the implementation
> certainly is neither perfect nor the most efficient, but it works and
> hopefully serves as a starting proof of concept. It's at least capable of
> formatting its own error messages ;)
>
> Am 18.01.2014 01:57, schrieb Billy O'Neal:
>
>  I don't think a template is the way to go here. While the potential
>> performance increase is there, I don't think that's the way we want to go
>> for the "general, default" library. Real programs often have localization
>> requirements, and if those values are burned in as template parameters you
>> can't go back later and fix this by changing the string.
>>
>>  Could you elaborate on where you see templates as a problem for
> localization? At least in my approach everything that controls the
> formatting of the output comes from dynamic content, including the ordering
> of the parameters and how they should be printed.
>
> It allows for things like
>
> format(localized_string, "Harry", 30, "nerd"); // types are string, int,
> string
> "His name is {0}, he's {1} years old and a {2}." => "His name is Harry,
> he's 30 years old and a nerd."
> "A {1} years old {2} called {0} entered the bar. He was the only {2}
> there." => "A 30 years old nerd called Harry entered the bar. He was the
> only nerd there."
> "{0} the {2} had his {1:ord} birthday." => "Harry the nerd had his 30th
> birthday."
> The last example assumes there is a "ord" format flag making ordinal
> numbers (based on the locale, thus en: 30th, de: 30., fr: 30e?)
>
> The only  thing fixed with templates at compile time is the type of the
> arguments: string, int, string. If you were, for example, to change the
> second paramter to a "Age" class and have a to_string(const Age&,
> string_view) method (or other supported overload) in the right scope it
> uses that for printing instead and the conversion rules of the type are
> completely under control of the implementer. The string_view argument would
> be "ord", i.e. the entire content between the colon and closing brace.
>
> Is there something I'm missing?
>
> P.S.: Please keep in mind the syntax is just for demonstration purpose and
> experimentation
>
>
> --
>
> --- You received this message because you are subscribed to the Google
> Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at http://groups.google.com/a/isocpp.org/group/std-
> proposals/.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a1136987415381d04f039c742
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Ah, that&#39;s fine. I thought you were proposing somethin=
g whereby things like field widths / arg positions would be put in as nonty=
pe template parameters.<br><div class=3D"gmail_extra"><br clear=3D"all"><di=
v><div dir=3D"ltr">

<div>Billy O&#39;Neal</div><div><a href=3D"https://bitbucket.org/BillyONeal=
/" target=3D"_blank">https://github.com/BillyONeal/</a></div><div>
<a href=3D"http://stackoverflow.com/users/82320/billy-oneal" target=3D"_bla=
nk">http://stackoverflow.com/users/82320/billy-oneal</a></div></div></div>
<br><br><div class=3D"gmail_quote">On Fri, Jan 17, 2014 at 9:31 PM, Miro Kn=
ejp <span dir=3D"ltr">&lt;<a href=3D"mailto:miro@knejp.de" target=3D"_blank=
">miro@knejp.de</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" =
style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(20=
4,204,204);border-left-width:1px;border-left-style:solid">


So I was toying around with my concept for the past days and uploaded my pr=
ogress:<br>
<a href=3D"https://github.com/mknejp/std-format" target=3D"_blank">https://=
github.com/mknejp/std-<u></u>format</a><br>
<br>
I hope the readme is a sufficient description of my take on the problem. Th=
ere are still several TODOs and open issues and the implementation certainl=
y is neither perfect nor the most efficient, but it works and hopefully ser=
ves as a starting proof of concept. It&#39;s at least capable of formatting=
 its own error messages ;)<br>



<br>
Am 18.01.2014 01:57, schrieb Billy O&#39;Neal:<div><br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding=
-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-l=
eft-style:solid">
I don&#39;t think a template is the way to go here. While the potential per=
formance increase is there, I don&#39;t think that&#39;s the way we want to=
 go for the &quot;general, default&quot; library. Real programs often have =
localization requirements, and if those values are burned in as template pa=
rameters you can&#39;t go back later and fix this by changing the string.<b=
r>



<br>
</blockquote></div>
Could you elaborate on where you see templates as a problem for localizatio=
n? At least in my approach everything that controls the formatting of the o=
utput comes from dynamic content, including the ordering of the parameters =
and how they should be printed.<br>



<br>
It allows for things like<br>
<br>
format(localized_string, &quot;Harry&quot;, 30, &quot;nerd&quot;); // types=
 are string, int, string<br>
&quot;His name is {0}, he&#39;s {1} years old and a {2}.&quot; =3D&gt; &quo=
t;His name is Harry, he&#39;s 30 years old and a nerd.&quot;<br>
&quot;A {1} years old {2} called {0} entered the bar. He was the only {2} t=
here.&quot; =3D&gt; &quot;A 30 years old nerd called Harry entered the bar.=
 He was the only nerd there.&quot;<br>
&quot;{0} the {2} had his {1:ord} birthday.&quot; =3D&gt; &quot;Harry the n=
erd had his 30th birthday.&quot;<br>
The last example assumes there is a &quot;ord&quot; format flag making ordi=
nal numbers (based on the locale, thus en: 30th, de: 30., fr: 30e?)<br>
<br>
The only =C2=A0thing fixed with templates at compile time is the type of th=
e arguments: string, int, string. If you were, for example, to change the s=
econd paramter to a &quot;Age&quot; class and have a to_string(const Age&am=
p;, string_view) method (or other supported overload) in the right scope it=
 uses that for printing instead and the conversion rules of the type are co=
mpletely under control of the implementer. The string_view argument would b=
e &quot;ord&quot;, i.e. the entire content between the colon and closing br=
ace.<br>



<br>
Is there something I&#39;m missing?<br>
<br>
P.S.: Please keep in mind the syntax is just for demonstration purpose and =
experimentation<div><div><br>
<br>
-- <br>
<br>
--- You received this message because you are subscribed to the Google Grou=
ps &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@<u></u>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/<u></u>isocpp.=
org/group/std-<u></u>proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a1136987415381d04f039c742--

.


Author: Bjorn Reese <breese@mail1.stofanet.dk>
Date: Sat, 18 Jan 2014 13:15:29 +0100
Raw View
On 01/18/2014 06:31 AM, Miro Knejp wrote:
> So I was toying around with my concept for the past days and uploaded my
> progress:
> https://github.com/mknejp/std-format

I have not seen any reference to N3716 in this discussion, so I use this
opportunity to point it out:

   http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3716.html

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Miro Knejp <miro@knejp.de>
Date: Sat, 18 Jan 2014 20:58:35 +0100
Raw View
Am 18.01.2014 13:15, schrieb Bjorn Reese:
> On 01/18/2014 06:31 AM, Miro Knejp wrote:
>> So I was toying around with my concept for the past days and uploaded my
>> progress:
>> https://github.com/mknejp/std-format
>
> I have not seen any reference to N3716 in this discussion, so I use this
> opportunity to point it out:
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3716.html
>
Well I don't think that just making "printf()" ostream-compatible really
cuts it. The syntax may be known and common in the C/C++ community but
is also very limited. I believe it would be a subpar solution. You are
restricted to the format flags baked into the printf() parser and there
is no way of customization or extensions. If however one considers at
least the possibility of dropping the "printf()" way of doing it and
goes for one that may be available in other languages/frameworks which
is well tested, documented and extensible than acceptance to adopt it
might be present.

Just a simple motivational example: printing a std::tm or
std::chrono::time_point:

putf("%$1.2d.%2$.2d.%3$.4d - %4$.2d:%5$.2d:%6$.2d", tm1.tm_day,
tm1.tm_mon, tm1.tm_year, tm1.tm_hours, tm1.tm_min, tm1.tm_sec);
putf("%2$.2d/%$1.2d/%3$.4d - %4$.2d:%5$.2d:%6$.2d", tm1.tm_day,
tm1.tm_mon, tm1.tm_year, tm1.tm_hours, tm1.tm_min, tm1.tm_sec);
putf("???", time_point1);
versus
format("{0:dd.MM.yyyy - HH:mm:ss}", tm1); // "18.01.2014 - 20:36:09"
format("{0:MMM/dd/yyyy - h:mm t}", time_point1); // "Jan/01/2014 - 8:36
pm" using locale to determine "Jan" and "pm"
format("{0:d}", tm) //  short date pattern: "1/18/2014" (en-US),
"18/01/2014" (fr-FR), "2014/01/18 (ja-JP)"

How long did it take to make sure the putf() syntax is correct? I'm
still not 100% certain if the output matches what I expect.

In the way my approach is currently implemented the part between ":" and
"}" is passed to the to_string method (if a suitable overload exists),
therefore the to_string(const time_point&, string_view flags) can do
it's own formatting and is not limited to the prebaked format flags of
printf(). This is how the .NET framework handles it and it has proven to
be very useful (and where I got the "{0:d}" example from) therefore I'm
using it as reference for now until someone complains or has a better
alternative.

I would treat putf() as a separate proposal for people who are forced to
deal with a large amount of existing printf() strings and want to add
type-safety to existing code without changing all their strings
(possibly translated into dozens of languages).


--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Farid Mehrabi <farid.mehrabi@gmail.com>
Date: Sat, 18 Jan 2014 12:01:59 -0800 (PST)
Raw View
------=_Part_702_19873854.1390075320311
Content-Type: text/plain; charset=UTF-8



On Tuesday, January 14, 2014 10:09:55 PM UTC+3:30, fritzpoll wrote:
>
> Aside from type-safety, are there any arguments against using a format
> string?  The only other one I'm aware of is the notion that it is another
> sub-language that one needs to get a reference for.  To my mind, though,
> that argument could just as easily apply to any library, including the
> present IOStreams.
>
>>
>> Extending this format string to user defined types is another issue; the
run-time nature of strings will postpone detetction of any mistake in
parsing a UDT format specifier to run-time. In the absence of compile-time
support for parsing strings I try to avoid format strings. I agree that
present IOStreams are not the best choice, but sticking to old style is
IMHO due to mental Inertia. A templated printf without formatting is good;
if one needs formatting, string converter functions can be applied on the
object before handing it to the printf. This also keeps the IO function
simpler and faster.

regards,
FM

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_702_19873854.1390075320311
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Tuesday, January 14, 2014 10:09:55 PM UTC+3:30,=
 fritzpoll wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr">Aside from type-safety, are there any arguments against using a format =
string?&nbsp; The only other one I'm aware of is the notion that it is anot=
her sub-language that one needs to get a reference for.&nbsp; To my mind, t=
hough, that argument could just as easily apply to any library, including t=
he present IOStreams.<br><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div><br><=
/div></blockquote></div></blockquote><div>Extending this format string to u=
ser defined types is another issue; the run-time nature of strings will pos=
tpone detetction of any mistake in parsing a UDT format specifier to run-ti=
me. In the absence of compile-time support for parsing strings I try to avo=
id format strings. I agree that present IOStreams are not the best choice, =
but sticking to old style is IMHO due to mental Inertia. A templated printf=
 without formatting is good; if one needs formatting, string converter func=
tions can be applied on the object before handing it to the printf. This al=
so keeps the IO function simpler and faster.</div><div><br></div><div>regar=
ds,</div><div>FM</div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_702_19873854.1390075320311--

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Sun, 19 Jan 2014 08:00:49 -0800 (PST)
Raw View
------=_Part_795_9285405.1390147249071
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Now I have made a prototype implementation of a formatting functionality=20
that allows precompilation of formatting parameters. It compiles with=20
VS2012 Nov CTP and plain VS2013, I haven't tested other compilers.=20
Download: www.beamways.com/file/formatter.zip.

To show the functionality here's the test function:

// Global formatter, checked at program start. This message
// demonstrates out of order inserts and type-specific parameters.
static Formatter<int, float> my_error_message("Illegal value {1p2} at=20
offset {0h}");


void test_format(std::ostream& out)
{
  bool error =3D false;
=20
// Excluded unrelated proposal here... see zipfile if interested.

  if (error)
    out << my_error_message(1, 3.15f); // Even though the error seldom=20
occurs we know that if it occurs the message is ok.


  // Function static formatter which compiles its contents and checks
  // parameters at first call of test_format().
  static Formatter<MyClass> local_fmt("Value: {0yxz}");


  std::vector<MyClass> data;
  data.emplace_back(1, 2, 3);
  data.emplace_back(4, 5, 6);
  data.emplace_back(17, 42, 4711);

  for (auto& d : data)
    out << local_fmt(d) << std::endl;


   // On the spot formatting (the cast is temporary due to lack of=20
specialization for size_t).
   out << Format("Total count {0}\n", int(data.size())) << std::endl;


   // Ok, lets see the error message anyway.
   string err =3D my_error_message(1, 3.15f); // Test the operator string o=
f=20
ValueHolder!
   out << err << std::endl;
}



The main features of this package is that in all cases above the stream is=
=20
made available to the core formatting function so no intermediate string=20
objects are created. Also there is no dynamic memory used for the=20
type-specific formatting objects or, typically, their parameters.

You can easily add formatters for any type, above uses a formatter for=20
MyClass (shown in the zipfile).

Basic architecture:

Formatter is a variadic class template which creates a suitable=20
DataFormatter object for each of its template parameters, and in its ctor=
=20
parses the format string and defers parsing of each insert's parameters to=
=20
the respective DataFormatter instance.

DataFormatter is a class template which is specialized to handle formatting=
=20
of each data type. It has a Format method which takes a outputs stream and=
=20
a T, and a parameter parsing function.

Format is a free function which takes a format string and a variadic set of=
=20
parameters. It returns a FormatterWithValues which contains the Formatter=
=20
and a tuple of references to the parameters. This is a helper object.

operator<< on a ostream (or bytestream in the future) and a=20
FormatterWithValues sends the kept references to the Formatter's format=20
function along with the ostream. This causes the Formatter to output the=20
literal parts of the format string intersperced with the result of the=20
formatting of the parameter values by the individual DataFormatters it=20
contains.

For the reused Formatter use case another helper called ValueHolder is=20
used. It is very similar to FormatterWithValues but refers to the Formatter=
=20
instead of containing it.


I noticed when writing this that there should be an operator string() on=20
FormatterWithValues to cater for the "string =3D Format("fmt", pars);" use=
=20
case. That's a simple addition.

Both the helper objects would benefit from a string operator auto()=20
declaration. This syntax was suggested in another thread to force=20
conversion to a certain type (in this string) when used as the initializer=
=20
for an auto variable. In this case it would prevent
dangling references to the parameter values that both of these objects run=
=20
the risk of creating today, if kept after the surrounding expression=20
finishes.

I think this design could act as a starting point for a very efficient and=
=20
flexible formatting facility which can hopefully be layered on top of both=
=20
a new type of bytestreams and, via some adapter, on ostream.

What I think is the most important missing feature is to be able to collect=
=20
sets of formatting objects and use different such sets in different=20
situation. I'm considering using DataFormatter as a defaulted template=20
template parameter. Then you would be able to
create your own set like this:

template<typename T> class MyFormatter : public DataFormatter<T> {
};

The inheritance defaults all formatting to DataFormatter but then you can=
=20
specialize it for the types you want special formatting for. Then you can=
=20
write, possibly:

cout << Format<MyFormatter>("formatstring", pars) << endl;


In some cases you would want formatting object selection to be more dynamic=
=20
than this, in which case you typically want to adorn the output stream with=
=20
an object controlling the formatting. I don't see that this can be done=20
within the same framework as it would require using heap memory for all the=
=20
individual DataFormatters. One path to explore would be to have a special=
=20
IndirectFormatter type which can be used to defer formatting object=20
selection to runtime. I think this is doable, but the problem is the=20
Format<IndirectFormatter>("msg") is rather heavy typing at each point of=20
use. A DFormat function or similar could help with this.


Den l=C3=B6rdagen den 18:e januari 2014 kl. 21:01:59 UTC+1 skrev Farid Mehr=
abi:
>
>
>
> On Tuesday, January 14, 2014 10:09:55 PM UTC+3:30, fritzpoll wrote:
>>
>> Aside from type-safety, are there any arguments against using a format=
=20
>> string?  The only other one I'm aware of is the notion that it is anothe=
r=20
>> sub-language that one needs to get a reference for.  To my mind, though,=
=20
>> that argument could just as easily apply to any library, including the=
=20
>> present IOStreams.
>>
>>>
>>> Extending this format string to user defined types is another issue; th=
e=20
> run-time nature of strings will postpone detetction of any mistake in=20
> parsing a UDT format specifier to run-time. In the absence of compile-tim=
e=20
> support for parsing strings I try to avoid format strings. I agree that=
=20
> present IOStreams are not the best choice, but sticking to old style is=
=20
> IMHO due to mental Inertia. A templated printf without formatting is good=
;=20
> if one needs formatting, string converter functions can be applied on the=
=20
> object before handing it to the printf. This also keeps the IO function=
=20
> simpler and faster.
>
> regards,
> FM
>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_795_9285405.1390147249071
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Now I have made a prototype implementation of a formatting=
 functionality that allows precompilation of formatting parameters. It comp=
iles with VS2012 Nov CTP and plain VS2013, I haven't tested other compilers=
.. Download:&nbsp;<a href=3D"http://www.beamways.com/file/formatter.zip">www=
..beamways.com/file/formatter.zip</a>.<div><br></div><div>To show the functi=
onality here's the test function:</div><div><br></div><div><div class=3D"pr=
ettyprint" style=3D"background-color: rgb(250, 250, 250); border: 1px solid=
 rgb(187, 187, 187); word-wrap: break-word;"><code class=3D"prettyprint"><d=
iv class=3D"subprettyprint"><span style=3D"color: #800;" class=3D"styled-by=
-prettify">// Global formatter, checked at program start. This message</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><spa=
n style=3D"color: #800;" class=3D"styled-by-prettify">// demonstrates out o=
f order inserts and type-specific parameters.</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">static</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styl=
ed-by-prettify">Formatter</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">int</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">float</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> my_error_message</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">"Illegal value {1p2} at offs=
et {0h}"</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br><b=
r></span><span style=3D"color: #008;" class=3D"styled-by-prettify">void</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> test_format</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">ostream</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">out</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nb=
sp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">bool</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> error </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">false</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br>&nbsp;<br></span><font color=3D"#880000">=
<span style=3D"color: #800;" class=3D"styled-by-prettify">// Excluded unrel=
ated proposal here... see zipfile if interested.</span></font><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><font color=
=3D"#000000"><span style=3D"color: #000;" class=3D"styled-by-prettify">&nbs=
p; </span></font><span style=3D"color: #008;" class=3D"styled-by-prettify">=
if</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">error</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">out</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> my_error_message</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><span style=3D"color: #066;" class=
=3D"styled-by-prettify">1</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">3.1=
5f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #800;" class=3D"styled-by-prettify">// Even though the error =
seldom occurs we know that if it occurs the message is ok.</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br><br><br>&nbsp; </span><=
span style=3D"color: #800;" class=3D"styled-by-prettify">// Function static=
 formatter which compiles its contents and checks</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>&nbsp; </span><span style=3D"col=
or: #800;" class=3D"styled-by-prettify">// parameters at first call of test=
_format().</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br>&nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>static</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #606;" class=3D"styled-by-prettify">Formatter</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><s=
pan style=3D"color: #606;" class=3D"styled-by-prettify">MyClass</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> local_fmt</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #080;" class=3D"styled-by-prettify">"Value: {0yxz}"</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br><br><br>&nbsp; std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">vector</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #606;" =
class=3D"styled-by-prettify">MyClass</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> data</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>&nbsp; data</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">emplace_back</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #066;" class=3D"styled-by-prettify">1</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #066;" class=3D"styled-by-prettify">2</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"styl=
ed-by-prettify">3</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br>&nbsp; data</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">empla=
ce_back</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span style=3D"color: #066;" class=3D"styled-by-prettify">4</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #066;" class=3D"styled-by-prettify">5</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by=
-prettify">6</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&n=
bsp; data</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">emplace_ba=
ck</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span>=
<span style=3D"color: #066;" class=3D"styled-by-prettify">17</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #066=
;" class=3D"styled-by-prettify">42</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-pret=
tify">4711</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=
&nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">for=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> d </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> data</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">out</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&l=
t;&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> loc=
al_fmt</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">d</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">endl</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br><br><br>&nbsp; &nbsp;</span><span style=3D"color: #800;" class=3D"s=
tyled-by-prettify">// On the spot formatting (the cast is temporary due to =
lack of specialization for size_t).</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>&nbsp; &nbsp;</span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">out</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">&lt;&lt;</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prett=
ify">Format</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>(</span><span style=3D"color: #080;" class=3D"styled-by-prettify">"Total c=
ount {0}\n"</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">data</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">size</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">()))</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">&lt;&lt;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">endl</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br><br><br>&nbsp; &nbsp;=
</span><span style=3D"color: #800;" class=3D"styled-by-prettify">// Ok, let=
s see the error message anyway.</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br>&nbsp; &nbsp;</span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">string</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> err </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> my_error_message</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">(</span><span style=3D"color: #066;" class=3D"styled-by-=
prettify">1</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #066;" class=3D"styled-by-prettify">3.15f</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #800;" class=3D"styled-by-prettify">// Test the operator string of ValueH=
older!</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
&nbsp; &nbsp;</span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">out</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> err </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">endl</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br><br><br></span></div></code></div><div><br></div><div>The main=
 features of this package is that in all cases above the stream is made ava=
ilable to the core formatting function so no intermediate string objects ar=
e created. Also there is no dynamic memory used for the type-specific forma=
tting objects or, typically, their parameters.</div><div><br></div><div>You=
 can easily add formatters for any type, above uses a formatter for MyClass=
 (shown in the zipfile).<br><br></div><div>Basic architecture:</div><div><b=
r></div><div>Formatter is a variadic class template which creates a suitabl=
e DataFormatter object for each of its template parameters, and in its ctor=
 parses the format string and defers parsing of each insert's parameters to=
 the respective DataFormatter instance.</div><div><br></div><div>DataFormat=
ter is a class template which is specialized to handle formatting of each d=
ata type. It has a Format method which takes a outputs stream and a T, and =
a parameter parsing function.</div><div><br></div><div>Format is a free fun=
ction which takes a format string and a variadic set of parameters. It retu=
rns a FormatterWithValues which contains the Formatter and a tuple of refer=
ences to the parameters. This is a helper object.</div><div><br></div><div>=
operator&lt;&lt; on a ostream (or bytestream in the future) and a Formatter=
WithValues sends the kept references to the Formatter's format function alo=
ng with the ostream. This causes the Formatter to output the literal parts =
of the format string intersperced with the result of the formatting of the =
parameter values by the individual DataFormatters it contains.</div><div><b=
r></div><div>For the reused Formatter use case another helper called ValueH=
older is used. It is very similar to FormatterWithValues but refers to the =
Formatter instead of containing it.</div><div><br></div><div><br></div><div=
>I noticed when writing this that there should be an operator string() on F=
ormatterWithValues to cater for the "string =3D Format("fmt", pars);" use c=
ase. That's a simple addition.</div><div><br></div><div>Both the helper obj=
ects would benefit from a string operator auto() declaration. This syntax w=
as suggested in another thread to force conversion to a certain type (in th=
is string) when used as the initializer for an auto variable. In this case =
it would prevent</div><div>dangling references to the parameter values that=
 both of these objects run the risk of creating today, if kept after the su=
rrounding expression finishes.</div><div><br></div><div>I think this design=
 could act as a starting point for a very efficient and flexible formatting=
 facility which can hopefully be layered on top of both a new type of bytes=
treams and, via some adapter, on ostream.</div><div><br></div><div>What I t=
hink is the most important missing feature is to be able to collect sets of=
 formatting objects and use different such sets in different situation. I'm=
 considering using DataFormatter as a defaulted template template parameter=
.. Then you would be able to</div><div>create your own set like this:</div><=
div><br></div><div>template&lt;typename T&gt; class MyFormatter : public Da=
taFormatter&lt;T&gt; {</div><div>};</div><div><br></div><div>The inheritanc=
e defaults all formatting to DataFormatter but then you can specialize it f=
or the types you want special formatting for. Then you can write, possibly:=
</div><div><br></div><div>cout &lt;&lt; Format&lt;MyFormatter&gt;("formatst=
ring", pars) &lt;&lt; endl;</div><div><br></div><div><br></div><div>In some=
 cases you would want formatting object selection to be more dynamic than t=
his, in which case you typically want to adorn the output stream with an ob=
ject controlling the formatting. I don't see that this can be done within t=
he same framework as it would require using heap memory for all the individ=
ual DataFormatters. One path to explore would be to have a special Indirect=
Formatter type which can be used to defer formatting object selection to ru=
ntime. I think this is doable, but the problem is the Format&lt;IndirectFor=
matter&gt;("msg") is rather heavy typing at each point of use. A DFormat fu=
nction or similar could help with this.</div><div><br></div><br>Den l=C3=B6=
rdagen den 18:e januari 2014 kl. 21:01:59 UTC+1 skrev Farid Mehrabi:<blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><br><br>On Tuesday, =
January 14, 2014 10:09:55 PM UTC+3:30, fritzpoll wrote:<blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr">Aside from type-safety, are there any =
arguments against using a format string?&nbsp; The only other one I'm aware=
 of is the notion that it is another sub-language that one needs to get a r=
eference for.&nbsp; To my mind, though, that argument could just as easily =
apply to any library, including the present IOStreams.<br><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div><br></div></blockquote></div></blockquote><div>=
Extending this format string to user defined types is another issue; the ru=
n-time nature of strings will postpone detetction of any mistake in parsing=
 a UDT format specifier to run-time. In the absence of compile-time support=
 for parsing strings I try to avoid format strings. I agree that present IO=
Streams are not the best choice, but sticking to old style is IMHO due to m=
ental Inertia. A templated printf without formatting is good; if one needs =
formatting, string converter functions can be applied on the object before =
handing it to the printf. This also keeps the IO function simpler and faste=
r.</div><div><br></div><div>regards,</div><div>FM</div></div></blockquote><=
/div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_795_9285405.1390147249071--

.


Author: Miro Knejp <miro@knejp.de>
Date: Sun, 19 Jan 2014 19:47:01 +0100
Raw View
This is a multi-part message in MIME format.
--------------040904000700040301060306
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

In my oppinion it is not elegant to force the number of parameters in=20
the string to match the number values passed to format(). It creates a=20
tight coupling between the format string and the code that doesn't=20
contribute to the type safe nature and artificially limits its=20
capabilities. It prohibits uses like:

format("{0} =3D {1} ({1:x})", "x", 12345); // "x =3D 12345 (0x3039)"
format("<{0}>{1}</{0}>", type_name, type_content); // Other formats like=20
JSON don't require the key identifier twice
format("{2}, {1}, {3}", a, b, c, d); // Doesn't print the first argument

The way I see format() is "here are some values, print them somehow, I=20
don't care how". The only obvious restriction is the validity of the=20
argument indices.

Repetition of the same argument should not be necessary. If the author=20
of the format string decides not to print an argument, or has to print=20
it multiple times (depending on the language/text/file format/etc) then=20
no code change should be required. This makes life so much easier for=20
everyone. And even though I use literals in my examples one should=20
always keep in mind the format strings  (should) originate from external=20
sources most of the time in real production code.

This of course means the precompiled format string must use dynamic=20
memory as it cannot predict how many arguments get passed into the=20
string. There is a tradeoff to consider: either parse on every format,=20
or use some dynamic memory. Note that inline format() still gets around=20
without dynamic memory most of the time (it's required when right/center=20
alignment and padding is applied).

Am 19.01.2014 17:00, schrieb Bengt Gustafsson:
> Now I have made a prototype implementation of a formatting=20
> functionality that allows precompilation of formatting parameters. It=20
> compiles with VS2012 Nov CTP and plain VS2013, I haven't tested other=20
> compilers. Download: www.beamways.com/file/formatter.zip=20
> <http://www.beamways.com/file/formatter.zip>.
>
> To show the functionality here's the test function:
>
> |
> // Global formatter, checked at program start. This message
> // demonstrates out of order inserts and type-specific parameters.
> staticFormatter<int,float>my_error_message("Illegal value {1p2} at=20
> offset {0h}");
>
>
> voidtest_format(std::ostream&out)
> {
> boolerror =3Dfalse;
>
> // Excluded unrelated proposal here... see zipfile if interested.
>
> if(error)
> out<<my_error_message(1,3.15f);// Even though the error seldom occurs=20
> we know that if it occurs the message is ok.
>
>
> // Function static formatter which compiles its contents and checks
> // parameters at first call of test_format().
> staticFormatter<MyClass>local_fmt("Value: {0yxz}");
>
>
>   std::vector<MyClass>data;
>   data.emplace_back(1,2,3);
>   data.emplace_back(4,5,6);
>   data.emplace_back(17,42,4711);
>
> for(auto&d :data)
> out<<local_fmt(d)<<std::endl;
>
>
> // On the spot formatting (the cast is temporary due to lack of=20
> specialization for size_t).
> out<<Format("Total count {0}\n",int(data.size()))<<std::endl;
>
>
> // Ok, lets see the error message anyway.
> stringerr =3Dmy_error_message(1,3.15f);// Test the operator string of=20
> ValueHolder!
> out<<err <<std::endl;
> }
>
>
> |
>
> The main features of this package is that in all cases above the=20
> stream is made available to the core formatting function so no=20
> intermediate string objects are created. Also there is no dynamic=20
> memory used for the type-specific formatting objects or, typically,=20
> their parameters.
>
> You can easily add formatters for any type, above uses a formatter for=20
> MyClass (shown in the zipfile).
>
> Basic architecture:
>
> Formatter is a variadic class template which creates a suitable=20
> DataFormatter object for each of its template parameters, and in its=20
> ctor parses the format string and defers parsing of each insert's=20
> parameters to the respective DataFormatter instance.
>
> DataFormatter is a class template which is specialized to handle=20
> formatting of each data type. It has a Format method which takes a=20
> outputs stream and a T, and a parameter parsing function.
>
> Format is a free function which takes a format string and a variadic=20
> set of parameters. It returns a FormatterWithValues which contains the=20
> Formatter and a tuple of references to the parameters. This is a=20
> helper object.
>
> operator<< on a ostream (or bytestream in the future) and a=20
> FormatterWithValues sends the kept references to the Formatter's=20
> format function along with the ostream. This causes the Formatter to=20
> output the literal parts of the format string intersperced with the=20
> result of the formatting of the parameter values by the individual=20
> DataFormatters it contains.
>
> For the reused Formatter use case another helper called ValueHolder is=20
> used. It is very similar to FormatterWithValues but refers to the=20
> Formatter instead of containing it.
>
>
> I noticed when writing this that there should be an operator string()=20
> on FormatterWithValues to cater for the "string =3D Format("fmt",=20
> pars);" use case. That's a simple addition.
>
> Both the helper objects would benefit from a string operator auto()=20
> declaration. This syntax was suggested in another thread to force=20
> conversion to a certain type (in this string) when used as the=20
> initializer for an auto variable. In this case it would prevent
> dangling references to the parameter values that both of these objects=20
> run the risk of creating today, if kept after the surrounding=20
> expression finishes.
>
> I think this design could act as a starting point for a very efficient=20
> and flexible formatting facility which can hopefully be layered on top=20
> of both a new type of bytestreams and, via some adapter, on ostream.
>
> What I think is the most important missing feature is to be able to=20
> collect sets of formatting objects and use different such sets in=20
> different situation. I'm considering using DataFormatter as a=20
> defaulted template template parameter. Then you would be able to
> create your own set like this:
>
> template<typename T> class MyFormatter : public DataFormatter<T> {
> };
>
> The inheritance defaults all formatting to DataFormatter but then you=20
> can specialize it for the types you want special formatting for. Then=20
> you can write, possibly:
>
> cout << Format<MyFormatter>("formatstring", pars) << endl;
>
>
> In some cases you would want formatting object selection to be more=20
> dynamic than this, in which case you typically want to adorn the=20
> output stream with an object controlling the formatting. I don't see=20
> that this can be done within the same framework as it would require=20
> using heap memory for all the individual DataFormatters. One path to=20
> explore would be to have a special IndirectFormatter type which can be=20
> used to defer formatting object selection to runtime. I think this is=20
> doable, but the problem is the Format<IndirectFormatter>("msg") is=20
> rather heavy typing at each point of use. A DFormat function or=20
> similar could help with this.
>
>
> Den l=C3=B6rdagen den 18:e januari 2014 kl. 21:01:59 UTC+1 skrev Farid=20
> Mehrabi:
>
>
>
>     On Tuesday, January 14, 2014 10:09:55 PM UTC+3:30, fritzpoll wrote:
>
>         Aside from type-safety, are there any arguments against using
>         a format string?  The only other one I'm aware of is the
>         notion that it is another sub-language that one needs to get a
>         reference for.  To my mind, though, that argument could just
>         as easily apply to any library, including the present IOStreams.
>
>
>     Extending this format string to user defined types is another
>     issue; the run-time nature of strings will postpone detetction of
>     any mistake in parsing a UDT format specifier to run-time. In the
>     absence of compile-time support for parsing strings I try to avoid
>     format strings. I agree that present IOStreams are not the best
>     choice, but sticking to old style is IMHO due to mental Inertia. A
>     templated printf without formatting is good; if one needs
>     formatting, string converter functions can be applied on the
>     object before handing it to the printf. This also keeps the IO
>     function simpler and faster.
>
>     regards,
>     FM
>
> --=20
>
> ---
> You received this message because you are subscribed to the Google=20
> Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send=20
> an email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at=20
> http://groups.google.com/a/isocpp.org/group/std-proposals/.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--------------040904000700040301060306
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<html>
  <head>
    <meta content=3D"text/html; charset=3DUTF-8" http-equiv=3D"Content-Type=
">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    In my oppinion it is not elegant to force the number of parameters
    in the string to match the number values passed to format(). It
    creates a tight coupling between the format string and the code that
    doesn't contribute to the type safe nature and artificially limits
    its capabilities. It prohibits uses like:<br>
    <br>
    format("{0} =3D {1} ({1:x})", "x", 12345); // "x =3D 12345 (0x3039)"<br=
>
    format("&lt;{0}&gt;{1}&lt;/{0}&gt;", type_name, type_content); //
    Other formats like JSON don't require the key identifier twice<br>
    format("{2}, {1}, {3}", a, b, c, d); // Doesn't print the first
    argument<br>
    <br>
    The way I see format() is "here are some values, print them somehow,
    I don't care how". The only obvious restriction is the validity of
    the argument indices.<br>
    <br>
    Repetition of the same argument should not be necessary. If the
    author of the format string decides not to print an argument, or has
    to print it multiple times (depending on the language/text/file
    format/etc) then no code change should be required. This makes life
    so much easier for everyone. And even though I use literals in my
    examples one should always keep in mind the format strings=C2=A0 (shoul=
d)
    originate from external sources most of the time in real production
    code.<br>
    <br>
    This of course means the precompiled format string must use dynamic
    memory as it cannot predict how many arguments get passed into the
    string. There is a tradeoff to consider: either parse on every
    format, or use some dynamic memory. Note that inline format() still
    gets around without dynamic memory most of the time (it's required
    when right/center alignment and padding is applied).<br>
    <br>
    <div class=3D"moz-cite-prefix">Am 19.01.2014 17:00, schrieb Bengt
      Gustafsson:<br>
    </div>
    <blockquote
      cite=3D"mid:53426dcb-a68f-4679-a3c1-1da189410f42@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">Now I have made a prototype implementation of a
        formatting functionality that allows precompilation of
        formatting parameters. It compiles with VS2012 Nov CTP and plain
        VS2013, I haven't tested other compilers. Download:=C2=A0<a
          moz-do-not-send=3D"true"
          href=3D"http://www.beamways.com/file/formatter.zip">www.beamways.=
com/file/formatter.zip</a>.
        <div><br>
        </div>
        <div>To show the functionality here's the test function:</div>
        <div><br>
        </div>
        <div>
          <div class=3D"prettyprint" style=3D"background-color: rgb(250,
            250, 250); border: 1px solid rgb(187, 187, 187); word-wrap:
            break-word;"><code class=3D"prettyprint">
              <div class=3D"subprettyprint"><span style=3D"color: #800;"
                  class=3D"styled-by-prettify">// Global formatter,
                  checked at program start. This message</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                </span><span style=3D"color: #800;"
                  class=3D"styled-by-prettify">// demonstrates out of
                  order inserts and type-specific parameters.</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                </span><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">static</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #606;" class=3D"styled-by-prettify">Forma=
tter</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&lt;<=
/span><span
                  style=3D"color: #008;" class=3D"styled-by-prettify">int</=
span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #008;" class=3D"styled-by-prettify">float=
</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&gt;<=
/span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">
                  my_error_message</span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">(</span><span style=3D"color=
:
                  #080;" class=3D"styled-by-prettify">"Illegal value {1p2}
                  at offset {0h}"</span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">);</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                  <br>
                  <br>
                </span><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">void</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">
                  test_format</span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">(</span><span style=3D"color=
:
                  #000;" class=3D"styled-by-prettify">std</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">::</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">ostre=
am</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&amp;=
</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #008;" class=3D"styled-by-prettify">out</=
span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">)</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                </span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">{</span><span style=3D"color=
:
                  #000;" class=3D"styled-by-prettify"><br>
                  =C2=A0 </span><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">bool</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> erro=
r
                </span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or:
                  #000;" class=3D"styled-by-prettify"> </span><span
                  style=3D"color: #008;" class=3D"styled-by-prettify">false=
</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">;</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                  =C2=A0<br>
                </span><font color=3D"#880000"><span style=3D"color: #800;"
                    class=3D"styled-by-prettify">// Excluded unrelated
                    proposal here... see zipfile if interested.</span></fon=
t><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                  <br>
                </span><font color=3D"#000000"><span style=3D"color: #000;"
                    class=3D"styled-by-prettify">=C2=A0 </span></font><span
                  style=3D"color: #008;" class=3D"styled-by-prettify">if</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">error=
</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">)</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                  =C2=A0 =C2=A0 </span><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">out</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&=
lt;</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">
                  my_error_message</span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">(</span><span style=3D"color=
:
                  #066;" class=3D"styled-by-prettify">1</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #066;" class=3D"styled-by-prettify">3.15f=
</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #800;" class=3D"styled-by-prettify">//
                  Even though the error seldom occurs we know that if it
                  occurs the message is ok.</span><span style=3D"color:
                  #000;" class=3D"styled-by-prettify"><br>
                  <br>
                  <br>
                  =C2=A0 </span><span style=3D"color: #800;"
                  class=3D"styled-by-prettify">// Function static
                  formatter which compiles its contents and checks</span><s=
pan
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                  =C2=A0 </span><span style=3D"color: #800;"
                  class=3D"styled-by-prettify">// parameters at first call
                  of test_format().</span><span style=3D"color: #000;"
                  class=3D"styled-by-prettify"><br>
                  =C2=A0 </span><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">static</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #606;" class=3D"styled-by-prettify">Forma=
tter</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&lt;<=
/span><span
                  style=3D"color: #606;" class=3D"styled-by-prettify">MyCla=
ss</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&gt;<=
/span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">
                  local_fmt</span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">(</span><span style=3D"color=
:
                  #080;" class=3D"styled-by-prettify">"Value: {0yxz}"</span=
><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                  <br>
                  <br>
                  =C2=A0 std</span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">::</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">vecto=
r</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&lt;<=
/span><span
                  style=3D"color: #606;" class=3D"styled-by-prettify">MyCla=
ss</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&gt;<=
/span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> data=
</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">;</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                  =C2=A0 data</span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">.</span><span style=3D"color=
:
                  #000;" class=3D"styled-by-prettify">emplace_back</span><s=
pan
                  style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span
                  style=3D"color: #066;" class=3D"styled-by-prettify">1</sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #066;" class=3D"styled-by-prettify">2</sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #066;" class=3D"styled-by-prettify">3</sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                  =C2=A0 data</span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">.</span><span style=3D"color=
:
                  #000;" class=3D"styled-by-prettify">emplace_back</span><s=
pan
                  style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span
                  style=3D"color: #066;" class=3D"styled-by-prettify">4</sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #066;" class=3D"styled-by-prettify">5</sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #066;" class=3D"styled-by-prettify">6</sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                  =C2=A0 data</span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">.</span><span style=3D"color=
:
                  #000;" class=3D"styled-by-prettify">emplace_back</span><s=
pan
                  style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span
                  style=3D"color: #066;" class=3D"styled-by-prettify">17</s=
pan><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #066;" class=3D"styled-by-prettify">42</s=
pan><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #066;" class=3D"styled-by-prettify">4711<=
/span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                  <br>
                  =C2=A0 </span><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">for</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span
                  style=3D"color: #008;" class=3D"styled-by-prettify">auto<=
/span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&amp;=
</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> d </=
span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">:</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> data=
</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">)</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                  =C2=A0 =C2=A0 </span><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">out</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&=
lt;</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">
                  local_fmt</span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">(</span><span style=3D"color=
:
                  #000;" class=3D"styled-by-prettify">d</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">)</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&=
lt;</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> std<=
/span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">::</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">endl<=
/span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">;</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                  <br>
                  <br>
                  =C2=A0 =C2=A0</span><span style=3D"color: #800;"
                  class=3D"styled-by-prettify">// On the spot formatting
                  (the cast is temporary due to lack of specialization
                  for size_t).</span><span style=3D"color: #000;"
                  class=3D"styled-by-prettify"><br>
                  =C2=A0 =C2=A0</span><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">out</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&=
lt;</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #606;" class=3D"styled-by-prettify">Forma=
t</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span
                  style=3D"color: #080;" class=3D"styled-by-prettify">"Tota=
l
                  count {0}\n"</span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">,</span><span style=3D"color=
:
                  #000;" class=3D"styled-by-prettify"> </span><span
                  style=3D"color: #008;" class=3D"styled-by-prettify">int</=
span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">data<=
/span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">.</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">size<=
/span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">()))<=
/span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&=
lt;</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> std<=
/span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">::</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">endl<=
/span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">;</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                  <br>
                  <br>
                  =C2=A0 =C2=A0</span><span style=3D"color: #800;"
                  class=3D"styled-by-prettify">// Ok, lets see the error
                  message anyway.</span><span style=3D"color: #000;"
                  class=3D"styled-by-prettify"><br>
                  =C2=A0 =C2=A0</span><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">string</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> err =
</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">=3D</=
span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">
                  my_error_message</span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">(</span><span style=3D"color=
:
                  #066;" class=3D"styled-by-prettify">1</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #066;" class=3D"styled-by-prettify">3.15f=
</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #800;" class=3D"styled-by-prettify">//
                  Test the operator string of ValueHolder!</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                  =C2=A0 =C2=A0</span><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">out</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&=
lt;</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> err =
</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&=
lt;</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> std<=
/span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">::</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">endl<=
/span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">;</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                </span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">}</span><span style=3D"color=
:
                  #000;" class=3D"styled-by-prettify"><br>
                  <br>
                  <br>
                </span></div>
            </code></div>
          <div><br>
          </div>
          <div>The main features of this package is that in all cases
            above the stream is made available to the core formatting
            function so no intermediate string objects are created. Also
            there is no dynamic memory used for the type-specific
            formatting objects or, typically, their parameters.</div>
          <div><br>
          </div>
          <div>You can easily add formatters for any type, above uses a
            formatter for MyClass (shown in the zipfile).<br>
            <br>
          </div>
          <div>Basic architecture:</div>
          <div><br>
          </div>
          <div>Formatter is a variadic class template which creates a
            suitable DataFormatter object for each of its template
            parameters, and in its ctor parses the format string and
            defers parsing of each insert's parameters to the respective
            DataFormatter instance.</div>
          <div><br>
          </div>
          <div>DataFormatter is a class template which is specialized to
            handle formatting of each data type. It has a Format method
            which takes a outputs stream and a T, and a parameter
            parsing function.</div>
          <div><br>
          </div>
          <div>Format is a free function which takes a format string and
            a variadic set of parameters. It returns a
            FormatterWithValues which contains the Formatter and a tuple
            of references to the parameters. This is a helper object.</div>
          <div><br>
          </div>
          <div>operator&lt;&lt; on a ostream (or bytestream in the
            future) and a FormatterWithValues sends the kept references
            to the Formatter's format function along with the ostream.
            This causes the Formatter to output the literal parts of the
            format string intersperced with the result of the formatting
            of the parameter values by the individual DataFormatters it
            contains.</div>
          <div><br>
          </div>
          <div>For the reused Formatter use case another helper called
            ValueHolder is used. It is very similar to
            FormatterWithValues but refers to the Formatter instead of
            containing it.</div>
          <div><br>
          </div>
          <div><br>
          </div>
          <div>I noticed when writing this that there should be an
            operator string() on FormatterWithValues to cater for the
            "string =3D Format("fmt", pars);" use case. That's a simple
            addition.</div>
          <div><br>
          </div>
          <div>Both the helper objects would benefit from a string
            operator auto() declaration. This syntax was suggested in
            another thread to force conversion to a certain type (in
            this string) when used as the initializer for an auto
            variable. In this case it would prevent</div>
          <div>dangling references to the parameter values that both of
            these objects run the risk of creating today, if kept after
            the surrounding expression finishes.</div>
          <div><br>
          </div>
          <div>I think this design could act as a starting point for a
            very efficient and flexible formatting facility which can
            hopefully be layered on top of both a new type of
            bytestreams and, via some adapter, on ostream.</div>
          <div><br>
          </div>
          <div>What I think is the most important missing feature is to
            be able to collect sets of formatting objects and use
            different such sets in different situation. I'm considering
            using DataFormatter as a defaulted template template
            parameter. Then you would be able to</div>
          <div>create your own set like this:</div>
          <div><br>
          </div>
          <div>template&lt;typename T&gt; class MyFormatter : public
            DataFormatter&lt;T&gt; {</div>
          <div>};</div>
          <div><br>
          </div>
          <div>The inheritance defaults all formatting to DataFormatter
            but then you can specialize it for the types you want
            special formatting for. Then you can write, possibly:</div>
          <div><br>
          </div>
          <div>cout &lt;&lt; Format&lt;MyFormatter&gt;("formatstring",
            pars) &lt;&lt; endl;</div>
          <div><br>
          </div>
          <div><br>
          </div>
          <div>In some cases you would want formatting object selection
            to be more dynamic than this, in which case you typically
            want to adorn the output stream with an object controlling
            the formatting. I don't see that this can be done within the
            same framework as it would require using heap memory for all
            the individual DataFormatters. One path to explore would be
            to have a special IndirectFormatter type which can be used
            to defer formatting object selection to runtime. I think
            this is doable, but the problem is the
            Format&lt;IndirectFormatter&gt;("msg") is rather heavy
            typing at each point of use. A DFormat function or similar
            could help with this.</div>
          <div><br>
          </div>
          <br>
          Den l=C3=B6rdagen den 18:e januari 2014 kl. 21:01:59 UTC+1 skrev
          Farid Mehrabi:
          <blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
            0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
            <div dir=3D"ltr"><br>
              <br>
              On Tuesday, January 14, 2014 10:09:55 PM UTC+3:30,
              fritzpoll wrote:
              <blockquote class=3D"gmail_quote"
                style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc
                solid;padding-left:1ex">
                <div dir=3D"ltr">Aside from type-safety, are there any
                  arguments against using a format string?=C2=A0 The only
                  other one I'm aware of is the notion that it is
                  another sub-language that one needs to get a reference
                  for.=C2=A0 To my mind, though, that argument could just a=
s
                  easily apply to any library, including the present
                  IOStreams.<br>
                  <blockquote class=3D"gmail_quote"
                    style=3D"margin:0;margin-left:0.8ex;border-left:1px
                    #ccc solid;padding-left:1ex">
                    <div><br>
                    </div>
                  </blockquote>
                </div>
              </blockquote>
              <div>Extending this format string to user defined types is
                another issue; the run-time nature of strings will
                postpone detetction of any mistake in parsing a UDT
                format specifier to run-time. In the absence of
                compile-time support for parsing strings I try to avoid
                format strings. I agree that present IOStreams are not
                the best choice, but sticking to old style is IMHO due
                to mental Inertia. A templated printf without formatting
                is good; if one needs formatting, string converter
                functions can be applied on the object before handing it
                to the printf. This also keeps the IO function simpler
                and faster.</div>
              <div><br>
              </div>
              <div>regards,</div>
              <div>FM</div>
            </div>
          </blockquote>
        </div>
      </div>
      -- <br>
      =C2=A0<br>
      --- <br>
      You received this message because you are subscribed to the Google
      Groups "ISO C++ Standard - Future Proposals" group.<br>
      To unsubscribe from this group and stop receiving emails from it,
      send an email to <a class=3D"moz-txt-link-abbreviated" href=3D"mailto=
:std-proposals+unsubscribe@isocpp.org">std-proposals+unsubscribe@isocpp.org=
</a>.<br>
      To post to this group, send email to <a class=3D"moz-txt-link-abbrevi=
ated" href=3D"mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>=
..<br>
      Visit this group at <a moz-do-not-send=3D"true"
        href=3D"http://groups.google.com/a/isocpp.org/group/std-proposals/"=
>http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br>
    </blockquote>
    <br>
  </body>
</html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--------------040904000700040301060306--


.


Author: Brent Friedman <fourthgeek@gmail.com>
Date: Sun, 19 Jan 2014 14:11:13 -0600
Raw View
--089e01183fb8796b9604f0586098
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Thought I would just chime in a bit of bikeshedding.

The format string technique and the << technique both have value. If the
argument order is known statically then I shouldn't have to pay to parse
%0, %1. If the argument order is determined dynamically then the library
should have a mechanism to support that.

I would envision this something like:;
format(my_string, "Time: %0 Name: %1", Time, Username); //appends to
my_string
and
format(my_string) << "Location:" << Location; //appends to my_string
and
make_formatted<std::string>("Time: %0 Name:%1 Location: %2", Time,
Username, Location); //returns new my_string

also with support for formatting into a string_view, array, or pointer-like
object.

You then need to injecting all of the formatting support from iostreams and
printf. We definitely need formatter objects to handle this. Text
formatters can probably be a concept.

format(result) << param(Time).precision(5).show_positive();

But this syntax grows very large compared to printf. I believe that most
printf syntax can be embedded in overloaded operators when brevity is
valued.

// like %+.9f
format(result) << +param(Time)[9];

//like %X
format(result) << !hex(Address);

// like %0+5.5e
format(result) << 0+sci(Time)(5,5);

// like %+f OR %f.
format(result) << param(Time).show_positive( use_positive );

// like %n
int pos=3D0;
format(result, "And then she %0", position(pos));

This gives us lots of flexibility in specifying formatting options
statically or dynamically, with help from the IDE as to what our options
are, and the ability to extend/compose the interface of the formatters.

One problem: the % syntax won't scale well above 9; %10 could mean "print
param 10" or "print param 1 then a zero". There are a number of ways around
this but continuing with %A=3D10, %B=3D11 seems a fine approach that can sc=
ale
up beyond any practical use case.

I'd also encourage you to look at
http://www.codeproject.com/Articles/159910/Extremely-Efficient-Type-safe-pr=
intf-Library


On Sun, Jan 19, 2014 at 12:47 PM, Miro Knejp <miro@knejp.de> wrote:

>  In my oppinion it is not elegant to force the number of parameters in th=
e
> string to match the number values passed to format(). It creates a tight
> coupling between the format string and the code that doesn't contribute t=
o
> the type safe nature and artificially limits its capabilities. It prohibi=
ts
> uses like:
>
> format("{0} =3D {1} ({1:x})", "x", 12345); // "x =3D 12345 (0x3039)"
> format("<{0}>{1}</{0}>", type_name, type_content); // Other formats like
> JSON don't require the key identifier twice
> format("{2}, {1}, {3}", a, b, c, d); // Doesn't print the first argument
>
> The way I see format() is "here are some values, print them somehow, I
> don't care how". The only obvious restriction is the validity of the
> argument indices.
>
> Repetition of the same argument should not be necessary. If the author of
> the format string decides not to print an argument, or has to print it
> multiple times (depending on the language/text/file format/etc) then no
> code change should be required. This makes life so much easier for
> everyone. And even though I use literals in my examples one should always
> keep in mind the format strings  (should) originate from external sources
> most of the time in real production code.
>
> This of course means the precompiled format string must use dynamic memor=
y
> as it cannot predict how many arguments get passed into the string. There
> is a tradeoff to consider: either parse on every format, or use some
> dynamic memory. Note that inline format() still gets around without dynam=
ic
> memory most of the time (it's required when right/center alignment and
> padding is applied).
>
> Am 19.01.2014 17:00, schrieb Bengt Gustafsson:
>
> Now I have made a prototype implementation of a formatting functionality
> that allows precompilation of formatting parameters. It compiles with
> VS2012 Nov CTP and plain VS2013, I haven't tested other compilers.
> Download: www.beamways.com/file/formatter.zip.
>
>  To show the functionality here's the test function:
>
>   // Global formatter, checked at program start. This message
> // demonstrates out of order inserts and type-specific parameters.
> static Formatter<int, float> my_error_message("Illegal value {1p2} at
> offset {0h}");
>
>
> void test_format(std::ostream& out)
> {
>   bool error =3D false;
>
> // Excluded unrelated proposal here... see zipfile if interested.
>
>   if (error)
>     out << my_error_message(1, 3.15f); // Even though the error seldom
> occurs we know that if it occurs the message is ok.
>
>
>   // Function static formatter which compiles its contents and checks
>   // parameters at first call of test_format().
>   static Formatter<MyClass> local_fmt("Value: {0yxz}");
>
>
>   std::vector<MyClass> data;
>   data.emplace_back(1, 2, 3);
>   data.emplace_back(4, 5, 6);
>   data.emplace_back(17, 42, 4711);
>
>   for (auto& d : data)
>     out << local_fmt(d) << std::endl;
>
>
>    // On the spot formatting (the cast is temporary due to lack of
> specialization for size_t).
>    out << Format("Total count {0}\n", int(data.size())) << std::endl;
>
>
>    // Ok, lets see the error message anyway.
>    string err =3D my_error_message(1, 3.15f); // Test the operator string
> of ValueHolder!
>    out << err << std::endl;
> }
>
>
>
>  The main features of this package is that in all cases above the stream
> is made available to the core formatting function so no intermediate stri=
ng
> objects are created. Also there is no dynamic memory used for the
> type-specific formatting objects or, typically, their parameters.
>
>  You can easily add formatters for any type, above uses a formatter for
> MyClass (shown in the zipfile).
>
>  Basic architecture:
>
>  Formatter is a variadic class template which creates a suitable
> DataFormatter object for each of its template parameters, and in its ctor
> parses the format string and defers parsing of each insert's parameters t=
o
> the respective DataFormatter instance.
>
>  DataFormatter is a class template which is specialized to handle
> formatting of each data type. It has a Format method which takes a output=
s
> stream and a T, and a parameter parsing function.
>
>  Format is a free function which takes a format string and a variadic set
> of parameters. It returns a FormatterWithValues which contains the
> Formatter and a tuple of references to the parameters. This is a helper
> object.
>
>  operator<< on a ostream (or bytestream in the future) and a
> FormatterWithValues sends the kept references to the Formatter's format
> function along with the ostream. This causes the Formatter to output the
> literal parts of the format string intersperced with the result of the
> formatting of the parameter values by the individual DataFormatters it
> contains.
>
>  For the reused Formatter use case another helper called ValueHolder is
> used. It is very similar to FormatterWithValues but refers to the Formatt=
er
> instead of containing it.
>
>
>  I noticed when writing this that there should be an operator string() on
> FormatterWithValues to cater for the "string =3D Format("fmt", pars);" us=
e
> case. That's a simple addition.
>
>  Both the helper objects would benefit from a string operator auto()
> declaration. This syntax was suggested in another thread to force
> conversion to a certain type (in this string) when used as the initialize=
r
> for an auto variable. In this case it would prevent
> dangling references to the parameter values that both of these objects ru=
n
> the risk of creating today, if kept after the surrounding expression
> finishes.
>
>  I think this design could act as a starting point for a very efficient
> and flexible formatting facility which can hopefully be layered on top of
> both a new type of bytestreams and, via some adapter, on ostream.
>
>  What I think is the most important missing feature is to be able to
> collect sets of formatting objects and use different such sets in differe=
nt
> situation. I'm considering using DataFormatter as a defaulted template
> template parameter. Then you would be able to
> create your own set like this:
>
>  template<typename T> class MyFormatter : public DataFormatter<T> {
> };
>
>  The inheritance defaults all formatting to DataFormatter but then you
> can specialize it for the types you want special formatting for. Then you
> can write, possibly:
>
>  cout << Format<MyFormatter>("formatstring", pars) << endl;
>
>
>  In some cases you would want formatting object selection to be more
> dynamic than this, in which case you typically want to adorn the output
> stream with an object controlling the formatting. I don't see that this c=
an
> be done within the same framework as it would require using heap memory f=
or
> all the individual DataFormatters. One path to explore would be to have a
> special IndirectFormatter type which can be used to defer formatting obje=
ct
> selection to runtime. I think this is doable, but the problem is the
> Format<IndirectFormatter>("msg") is rather heavy typing at each point of
> use. A DFormat function or similar could help with this.
>
>
> Den l=F6rdagen den 18:e januari 2014 kl. 21:01:59 UTC+1 skrev Farid Mehra=
bi:
>>
>>
>>
>> On Tuesday, January 14, 2014 10:09:55 PM UTC+3:30, fritzpoll wrote:
>>>
>>> Aside from type-safety, are there any arguments against using a format
>>> string?  The only other one I'm aware of is the notion that it is anoth=
er
>>> sub-language that one needs to get a reference for.  To my mind, though=
,
>>> that argument could just as easily apply to any library, including the
>>> present IOStreams.
>>>
>>>>
>>>>   Extending this format string to user defined types is another issue;
>> the run-time nature of strings will postpone detetction of any mistake i=
n
>> parsing a UDT format specifier to run-time. In the absence of compile-ti=
me
>> support for parsing strings I try to avoid format strings. I agree that
>> present IOStreams are not the best choice, but sticking to old style is
>> IMHO due to mental Inertia. A templated printf without formatting is goo=
d;
>> if one needs formatting, string converter functions can be applied on th=
e
>> object before handing it to the printf. This also keeps the IO function
>> simpler and faster.
>>
>>  regards,
>> FM
>>
>  --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
>
>  --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--089e01183fb8796b9604f0586098
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Thought I would just chime in a bit of bikeshedding.<div><=
br></div><div>The format string technique and the &lt;&lt; technique both h=
ave value. If the argument order is known statically then I shouldn&#39;t h=
ave to pay to parse %0, %1. If the argument order is determined dynamically=
 then the library should have a mechanism to support that.</div>
<div><br></div><div>I would envision this something like:;</div><div>format=
(my_string, &quot;Time: %0 Name: %1&quot;, Time, Username); //appends to my=
_string</div><div>and</div><div>format(my_string) &lt;&lt; &quot;Location:&=
quot; &lt;&lt; Location; //appends to my_string</div>
<div>and</div><div>make_formatted&lt;std::string&gt;(&quot;Time: %0 Name:%1=
 Location: %2&quot;, Time, Username, Location); //returns new my_string</di=
v><div><br></div><div>also with support for formatting into a string_view, =
array, or pointer-like object.</div>
<div><br></div><div>You then need to injecting all of the formatting suppor=
t from iostreams and printf. We definitely need formatter objects to handle=
 this. Text formatters can probably be a concept.</div><div><br></div><div>
format(result) &lt;&lt; param(Time).precision(5).show_positive();</div><div=
><br></div><div>But this syntax grows very large compared to printf. I beli=
eve that most printf syntax can be embedded in overloaded operators when br=
evity is valued.</div>
<div><br></div><div>// like %+.9f=A0<br></div><div>format(result) &lt;&lt; =
+param(Time)[9];=A0</div><div><br></div><div>//like %X</div><div>format(res=
ult) &lt;&lt; !hex(Address);</div><div><br></div><div>// like %0+5.5e</div>
<div>format(result) &lt;&lt; 0+sci(Time)(5,5);</div><div><br></div><div>// =
like %+f OR %f.</div><div>format(result) &lt;&lt; param(Time).show_positive=
( use_positive );</div><div><br></div><div>// like %n</div><div>int pos=3D0=
;</div>
<div>format(result, &quot;And then she %0&quot;, position(pos));</div><div>=
<br></div><div>This gives us lots of flexibility in specifying formatting o=
ptions statically or dynamically, with help from the IDE as to what our opt=
ions are, and the ability to extend/compose the interface of the formatters=
..</div>
<div><br></div><div>One problem: the % syntax won&#39;t scale well above 9;=
 %10 could mean &quot;print param 10&quot; or &quot;print param 1 then a ze=
ro&quot;. There are a number of ways around this but continuing with %A=3D1=
0, %B=3D11 seems a fine approach that can scale up beyond any practical use=
 case.<br>
</div><div><br></div><div>I&#39;d also encourage you to look at=A0<a href=
=3D"http://www.codeproject.com/Articles/159910/Extremely-Efficient-Type-saf=
e-printf-Library">http://www.codeproject.com/Articles/159910/Extremely-Effi=
cient-Type-safe-printf-Library</a></div>
</div><div class=3D"gmail_extra"><br><br><div class=3D"gmail_quote">On Sun,=
 Jan 19, 2014 at 12:47 PM, Miro Knejp <span dir=3D"ltr">&lt;<a href=3D"mail=
to:miro@knejp.de" target=3D"_blank">miro@knejp.de</a>&gt;</span> wrote:<br>=
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">

 =20
   =20
 =20
  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
    In my oppinion it is not elegant to force the number of parameters
    in the string to match the number values passed to format(). It
    creates a tight coupling between the format string and the code that
    doesn&#39;t contribute to the type safe nature and artificially limits
    its capabilities. It prohibits uses like:<br>
    <br>
    format(&quot;{0} =3D {1} ({1:x})&quot;, &quot;x&quot;, 12345); // &quot=
;x =3D 12345 (0x3039)&quot;<br>
    format(&quot;&lt;{0}&gt;{1}&lt;/{0}&gt;&quot;, type_name, type_content)=
; //
    Other formats like JSON don&#39;t require the key identifier twice<br>
    format(&quot;{2}, {1}, {3}&quot;, a, b, c, d); // Doesn&#39;t print the=
 first
    argument<br>
    <br>
    The way I see format() is &quot;here are some values, print them someho=
w,
    I don&#39;t care how&quot;. The only obvious restriction is the validit=
y of
    the argument indices.<br>
    <br>
    Repetition of the same argument should not be necessary. If the
    author of the format string decides not to print an argument, or has
    to print it multiple times (depending on the language/text/file
    format/etc) then no code change should be required. This makes life
    so much easier for everyone. And even though I use literals in my
    examples one should always keep in mind the format strings=A0 (should)
    originate from external sources most of the time in real production
    code.<br>
    <br>
    This of course means the precompiled format string must use dynamic
    memory as it cannot predict how many arguments get passed into the
    string. There is a tradeoff to consider: either parse on every
    format, or use some dynamic memory. Note that inline format() still
    gets around without dynamic memory most of the time (it&#39;s required
    when right/center alignment and padding is applied).<br>
    <br>
    <div>Am 19.01.2014 17:00, schrieb Bengt
      Gustafsson:<br>
    </div><div><div class=3D"h5">
    <blockquote type=3D"cite">
      <div dir=3D"ltr">Now I have made a prototype implementation of a
        formatting functionality that allows precompilation of
        formatting parameters. It compiles with VS2012 Nov CTP and plain
        VS2013, I haven&#39;t tested other compilers. Download:=A0<a href=
=3D"http://www.beamways.com/file/formatter.zip" target=3D"_blank">www.beamw=
ays.com/file/formatter.zip</a>.
        <div><br>
        </div>
        <div>To show the functionality here&#39;s the test function:</div>
        <div><br>
        </div>
        <div>
          <div style=3D"background-color:rgb(250,250,250);border:1px solid =
rgb(187,187,187);word-wrap:break-word"><code>
              <div><span style=3D"color:#800">// Global formatter,
                  checked at program start. This message</span><span style>=
<br>
                </span><span style=3D"color:#800">// demonstrates out of
                  order inserts and type-specific parameters.</span><span s=
tyle><br>
                </span><span style=3D"color:#008">static</span><span style>=
 </span><span style=3D"color:#606">Formatter</span><span style=3D"color:#66=
0">&lt;</span><span style=3D"color:#008">int</span><span style=3D"color:#66=
0">,</span><span style> </span><span style=3D"color:#008">float</span><span=
 style=3D"color:#660">&gt;</span><span style>
                  my_error_message</span><span style=3D"color:#660">(</span=
><span style=3D"color:#080">&quot;Illegal value {1p2}
                  at offset {0h}&quot;</span><span style=3D"color:#660">);<=
/span><span style><br>
                  <br>
                  <br>
                </span><span style=3D"color:#008">void</span><span style>
                  test_format</span><span style=3D"color:#660">(</span><spa=
n style>std</span><span style=3D"color:#660">::</span><span style>ostream</=
span><span style=3D"color:#660">&amp;</span><span style> </span><span style=
=3D"color:#008">out</span><span style=3D"color:#660">)</span><span style><b=
r>

                </span><span style=3D"color:#660">{</span><span style><br>
                  =A0 </span><span style=3D"color:#008">bool</span><span st=
yle> error
                </span><span style=3D"color:#660">=3D</span><span style> </=
span><span style=3D"color:#008">false</span><span style=3D"color:#660">;</s=
pan><span style><br>
                  =A0<br>
                </span><font color=3D"#880000"><span style=3D"color:#800">/=
/ Excluded unrelated
                    proposal here... see zipfile if interested.</span></fon=
t><span style><br>
                  <br>
                </span><font color=3D"#000000"><span style>=A0 </span></fon=
t><span style=3D"color:#008">if</span><span style> </span><span style=3D"co=
lor:#660">(</span><span style>error</span><span style=3D"color:#660">)</spa=
n><span style><br>

                  =A0 =A0 </span><span style=3D"color:#008">out</span><span=
 style> </span><span style=3D"color:#660">&lt;&lt;</span><span style>
                  my_error_message</span><span style=3D"color:#660">(</span=
><span style=3D"color:#066">1</span><span style=3D"color:#660">,</span><spa=
n style> </span><span style=3D"color:#066">3.15f</span><span style=3D"color=
:#660">);</span><span style> </span><span style=3D"color:#800">//
                  Even though the error seldom occurs we know that if it
                  occurs the message is ok.</span><span style><br>
                  <br>
                  <br>
                  =A0 </span><span style=3D"color:#800">// Function static
                  formatter which compiles its contents and checks</span><s=
pan style><br>
                  =A0 </span><span style=3D"color:#800">// parameters at fi=
rst call
                  of test_format().</span><span style><br>
                  =A0 </span><span style=3D"color:#008">static</span><span =
style> </span><span style=3D"color:#606">Formatter</span><span style=3D"col=
or:#660">&lt;</span><span style=3D"color:#606">MyClass</span><span style=3D=
"color:#660">&gt;</span><span style>
                  local_fmt</span><span style=3D"color:#660">(</span><span =
style=3D"color:#080">&quot;Value: {0yxz}&quot;</span><span style=3D"color:#=
660">);</span><span style><br>
                  <br>
                  <br>
                  =A0 std</span><span style=3D"color:#660">::</span><span s=
tyle>vector</span><span style=3D"color:#660">&lt;</span><span style=3D"colo=
r:#606">MyClass</span><span style=3D"color:#660">&gt;</span><span style> da=
ta</span><span style=3D"color:#660">;</span><span style><br>

                  =A0 data</span><span style=3D"color:#660">.</span><span s=
tyle>emplace_back</span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#066">1</span><span style=3D"color:#660">,</span><span style> </span><=
span style=3D"color:#066">2</span><span style=3D"color:#660">,</span><span =
style> </span><span style=3D"color:#066">3</span><span style=3D"color:#660"=
>);</span><span style><br>

                  =A0 data</span><span style=3D"color:#660">.</span><span s=
tyle>emplace_back</span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#066">4</span><span style=3D"color:#660">,</span><span style> </span><=
span style=3D"color:#066">5</span><span style=3D"color:#660">,</span><span =
style> </span><span style=3D"color:#066">6</span><span style=3D"color:#660"=
>);</span><span style><br>

                  =A0 data</span><span style=3D"color:#660">.</span><span s=
tyle>emplace_back</span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#066">17</span><span style=3D"color:#660">,</span><span style> </span>=
<span style=3D"color:#066">42</span><span style=3D"color:#660">,</span><spa=
n style> </span><span style=3D"color:#066">4711</span><span style=3D"color:=
#660">);</span><span style><br>

                  <br>
                  =A0 </span><span style=3D"color:#008">for</span><span sty=
le> </span><span style=3D"color:#660">(</span><span style=3D"color:#008">au=
to</span><span style=3D"color:#660">&amp;</span><span style> d </span><span=
 style=3D"color:#660">:</span><span style> data</span><span style=3D"color:=
#660">)</span><span style><br>

                  =A0 =A0 </span><span style=3D"color:#008">out</span><span=
 style> </span><span style=3D"color:#660">&lt;&lt;</span><span style>
                  local_fmt</span><span style=3D"color:#660">(</span><span =
style>d</span><span style=3D"color:#660">)</span><span style> </span><span =
style=3D"color:#660">&lt;&lt;</span><span style> std</span><span style=3D"c=
olor:#660">::</span><span style>endl</span><span style=3D"color:#660">;</sp=
an><span style><br>

                  <br>
                  <br>
                  =A0 =A0</span><span style=3D"color:#800">// On the spot f=
ormatting
                  (the cast is temporary due to lack of specialization
                  for size_t).</span><span style><br>
                  =A0 =A0</span><span style=3D"color:#008">out</span><span =
style> </span><span style=3D"color:#660">&lt;&lt;</span><span style> </span=
><span style=3D"color:#606">Format</span><span style=3D"color:#660">(</span=
><span style=3D"color:#080">&quot;Total
                  count {0}\n&quot;</span><span style=3D"color:#660">,</spa=
n><span style> </span><span style=3D"color:#008">int</span><span style=3D"c=
olor:#660">(</span><span style>data</span><span style=3D"color:#660">.</spa=
n><span style>size</span><span style=3D"color:#660">()))</span><span style>=
 </span><span style=3D"color:#660">&lt;&lt;</span><span style> std</span><s=
pan style=3D"color:#660">::</span><span style>endl</span><span style=3D"col=
or:#660">;</span><span style><br>

                  <br>
                  <br>
                  =A0 =A0</span><span style=3D"color:#800">// Ok, lets see =
the error
                  message anyway.</span><span style><br>
                  =A0 =A0</span><span style=3D"color:#008">string</span><sp=
an style> err </span><span style=3D"color:#660">=3D</span><span style>
                  my_error_message</span><span style=3D"color:#660">(</span=
><span style=3D"color:#066">1</span><span style=3D"color:#660">,</span><spa=
n style> </span><span style=3D"color:#066">3.15f</span><span style=3D"color=
:#660">);</span><span style> </span><span style=3D"color:#800">//
                  Test the operator string of ValueHolder!</span><span styl=
e><br>
                  =A0 =A0</span><span style=3D"color:#008">out</span><span =
style> </span><span style=3D"color:#660">&lt;&lt;</span><span style> err </=
span><span style=3D"color:#660">&lt;&lt;</span><span style> std</span><span=
 style=3D"color:#660">::</span><span style>endl</span><span style=3D"color:=
#660">;</span><span style><br>

                </span><span style=3D"color:#660">}</span><span style><br>
                  <br>
                  <br>
                </span></div>
            </code></div>
          <div><br>
          </div>
          <div>The main features of this package is that in all cases
            above the stream is made available to the core formatting
            function so no intermediate string objects are created. Also
            there is no dynamic memory used for the type-specific
            formatting objects or, typically, their parameters.</div>
          <div><br>
          </div>
          <div>You can easily add formatters for any type, above uses a
            formatter for MyClass (shown in the zipfile).<br>
            <br>
          </div>
          <div>Basic architecture:</div>
          <div><br>
          </div>
          <div>Formatter is a variadic class template which creates a
            suitable DataFormatter object for each of its template
            parameters, and in its ctor parses the format string and
            defers parsing of each insert&#39;s parameters to the respectiv=
e
            DataFormatter instance.</div>
          <div><br>
          </div>
          <div>DataFormatter is a class template which is specialized to
            handle formatting of each data type. It has a Format method
            which takes a outputs stream and a T, and a parameter
            parsing function.</div>
          <div><br>
          </div>
          <div>Format is a free function which takes a format string and
            a variadic set of parameters. It returns a
            FormatterWithValues which contains the Formatter and a tuple
            of references to the parameters. This is a helper object.</div>
          <div><br>
          </div>
          <div>operator&lt;&lt; on a ostream (or bytestream in the
            future) and a FormatterWithValues sends the kept references
            to the Formatter&#39;s format function along with the ostream.
            This causes the Formatter to output the literal parts of the
            format string intersperced with the result of the formatting
            of the parameter values by the individual DataFormatters it
            contains.</div>
          <div><br>
          </div>
          <div>For the reused Formatter use case another helper called
            ValueHolder is used. It is very similar to
            FormatterWithValues but refers to the Formatter instead of
            containing it.</div>
          <div><br>
          </div>
          <div><br>
          </div>
          <div>I noticed when writing this that there should be an
            operator string() on FormatterWithValues to cater for the
            &quot;string =3D Format(&quot;fmt&quot;, pars);&quot; use case.=
 That&#39;s a simple
            addition.</div>
          <div><br>
          </div>
          <div>Both the helper objects would benefit from a string
            operator auto() declaration. This syntax was suggested in
            another thread to force conversion to a certain type (in
            this string) when used as the initializer for an auto
            variable. In this case it would prevent</div>
          <div>dangling references to the parameter values that both of
            these objects run the risk of creating today, if kept after
            the surrounding expression finishes.</div>
          <div><br>
          </div>
          <div>I think this design could act as a starting point for a
            very efficient and flexible formatting facility which can
            hopefully be layered on top of both a new type of
            bytestreams and, via some adapter, on ostream.</div>
          <div><br>
          </div>
          <div>What I think is the most important missing feature is to
            be able to collect sets of formatting objects and use
            different such sets in different situation. I&#39;m considering
            using DataFormatter as a defaulted template template
            parameter. Then you would be able to</div>
          <div>create your own set like this:</div>
          <div><br>
          </div>
          <div>template&lt;typename T&gt; class MyFormatter : public
            DataFormatter&lt;T&gt; {</div>
          <div>};</div>
          <div><br>
          </div>
          <div>The inheritance defaults all formatting to DataFormatter
            but then you can specialize it for the types you want
            special formatting for. Then you can write, possibly:</div>
          <div><br>
          </div>
          <div>cout &lt;&lt; Format&lt;MyFormatter&gt;(&quot;formatstring&q=
uot;,
            pars) &lt;&lt; endl;</div>
          <div><br>
          </div>
          <div><br>
          </div>
          <div>In some cases you would want formatting object selection
            to be more dynamic than this, in which case you typically
            want to adorn the output stream with an object controlling
            the formatting. I don&#39;t see that this can be done within th=
e
            same framework as it would require using heap memory for all
            the individual DataFormatters. One path to explore would be
            to have a special IndirectFormatter type which can be used
            to defer formatting object selection to runtime. I think
            this is doable, but the problem is the
            Format&lt;IndirectFormatter&gt;(&quot;msg&quot;) is rather heav=
y
            typing at each point of use. A DFormat function or similar
            could help with this.</div>
          <div><br>
          </div>
          <br>
          Den l=F6rdagen den 18:e januari 2014 kl. 21:01:59 UTC+1 skrev
          Farid Mehrabi:
          <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0=
..8ex;border-left:1px #ccc solid;padding-left:1ex">
            <div dir=3D"ltr"><br>
              <br>
              On Tuesday, January 14, 2014 10:09:55 PM UTC+3:30,
              fritzpoll wrote:
              <blockquote class=3D"gmail_quote" style=3D"margin:0;margin-le=
ft:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
                <div dir=3D"ltr">Aside from type-safety, are there any
                  arguments against using a format string?=A0 The only
                  other one I&#39;m aware of is the notion that it is
                  another sub-language that one needs to get a reference
                  for.=A0 To my mind, though, that argument could just as
                  easily apply to any library, including the present
                  IOStreams.<br>
                  <blockquote class=3D"gmail_quote" style=3D"margin:0;margi=
n-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
                    <div><br>
                    </div>
                  </blockquote>
                </div>
              </blockquote>
              <div>Extending this format string to user defined types is
                another issue; the run-time nature of strings will
                postpone detetction of any mistake in parsing a UDT
                format specifier to run-time. In the absence of
                compile-time support for parsing strings I try to avoid
                format strings. I agree that present IOStreams are not
                the best choice, but sticking to old style is IMHO due
                to mental Inertia. A templated printf without formatting
                is good; if one needs formatting, string converter
                functions can be applied on the object before handing it
                to the printf. This also keeps the IO function simpler
                and faster.</div>
              <div><br>
              </div>
              <div>regards,</div>
              <div>FM</div>
            </div>
          </blockquote>
        </div>
      </div>
      -- <br>
      =A0<br>
      --- <br>
      You received this message because you are subscribed to the Google
      Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
      To unsubscribe from this group and stop receiving emails from it,
      send an email to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.o=
rg" target=3D"_blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
      To post to this group, send email to <a href=3D"mailto:std-proposals@=
isocpp.org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
      Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/=
group/std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.o=
rg/group/std-proposals/</a>.<br>
    </blockquote>
    <br>
  </div></div></div><div class=3D"HOEnZb"><div class=3D"h5">


<p></p>

-- <br>
=A0<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e01183fb8796b9604f0586098--

.


Author: Miro Knejp <miro@knejp.de>
Date: Sun, 19 Jan 2014 22:27:36 +0100
Raw View
Am 19.01.2014 21:11, schrieb Brent Friedman:
> Thought I would just chime in a bit of bikeshedding.
>
> The format string technique and the << technique both have value. If
> the argument order is known statically then I shouldn't have to pay to
> parse %0, %1. If the argument order is determined dynamically then the
> library should have a mechanism to support that.
>
> I would envision this something like:;
> format(my_string, "Time: %0 Name: %1", Time, Username); //appends to
> my_string
My current implementation does this. Also does ostream and ostreambuf. A
generalized approach using iterators is in progress.
> and
> format(my_string) << "Location:" << Location; //appends to my_string
Why use format here in the first place? You would probably be better off
appending to my_string directly (or use ostringstream).
> and
> make_formatted<std::string>("Time: %0 Name:%1 Location: %2", Time,
> Username, Location); //returns new my_string
This is implemented, too, albeit the return type is currently fixed to a
basic_string<...>.
>
> also with support for formatting into a string_view, array, or
> pointer-like object.
string_view: as far as I remember string_view is read-only.
array: If wrapped in a proper iterator like object that knows when the
array ends, yeah.
pointer-like object: that's basically an iterator.

A lot of cases can be covered using iterators, although iterators don't
allow for block-writes. I'd be curious if a "*x++ = *y++" loop is
optimized into a memcpy.
>
> You then need to injecting all of the formatting support from
> iostreams and printf. We definitely need formatter objects to handle
> this. Text formatters can probably be a concept.
>
> format(result) << param(Time).precision(5).show_positive();
>
> But this syntax grows very large compared to printf. I believe that
> most printf syntax can be embedded in overloaded operators when
> brevity is valued.
>
> // like %+.9f
> format(result) << +param(Time)[9];
>
> //like %X
> format(result) << !hex(Address);
>
> // like %0+5.5e
> format(result) << 0+sci(Time)(5,5);
>
> // like %+f OR %f.
> format(result) << param(Time).show_positive( use_positive );
>
> // like %n
> int pos=0;
> format(result, "And then she %0", position(pos));
>
> This gives us lots of flexibility in specifying formatting options
> statically or dynamically, with help from the IDE as to what our
> options are, and the ability to extend/compose the interface of the
> formatters.
>
> One problem: the % syntax won't scale well above 9; %10 could mean
> "print param 10" or "print param 1 then a zero". There are a number of
> ways around this but continuing with %A=10, %B=11 seems a fine
> approach that can scale up beyond any practical use case.

The entire %xxx approach is inflexible and error-prone, that's why me
(and others) don't follow it. In addition only supporting the existing
printf() flags is needlessly limiting. I want to be able to write a type
that has it's own distinct and independent format options unrelated to
anything std::ios if I so desire by processing the options substring
myself. I'm not a fan of artificial limitations. Just consider the
date/time formatting example from earlier in this discussion as
motivation. But I do agree that some sort of interaction with
ios::fmtflags (and the other ios stuff) should exist, if for the sole
reason that using locale facets interface is currently based around
ios_base to control the output.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Brent Friedman <fourthgeek@gmail.com>
Date: Sun, 19 Jan 2014 16:08:21 -0600
Raw View
--001a11c322746442d804f05a0339
Content-Type: text/plain; charset=ISO-8859-1

But why do we need an options substring? If we wrap parameters in a (std or
user-defined) object (hex(), sci(), etc) then these options can be
specified programmatically and can be easily extended just by adding new
methods. If options are specified in a string it becomes more work to set
those flags programmatically.

In the example of say %.5g, if that 5 is in the format string then it is
hard to change. If the 5 is a parameter to a formatting object then it is
easier to specify and requires no parsing at runtime.


On Sun, Jan 19, 2014 at 3:27 PM, Miro Knejp <miro@knejp.de> wrote:

>
> Am 19.01.2014 21:11, schrieb Brent Friedman:
>
>  Thought I would just chime in a bit of bikeshedding.
>>
>> The format string technique and the << technique both have value. If the
>> argument order is known statically then I shouldn't have to pay to parse
>> %0, %1. If the argument order is determined dynamically then the library
>> should have a mechanism to support that.
>>
>> I would envision this something like:;
>> format(my_string, "Time: %0 Name: %1", Time, Username); //appends to
>> my_string
>>
> My current implementation does this. Also does ostream and ostreambuf. A
> generalized approach using iterators is in progress.
>
>  and
>> format(my_string) << "Location:" << Location; //appends to my_string
>>
> Why use format here in the first place? You would probably be better off
> appending to my_string directly (or use ostringstream).
>
>  and
>> make_formatted<std::string>("Time: %0 Name:%1 Location: %2", Time,
>> Username, Location); //returns new my_string
>>
> This is implemented, too, albeit the return type is currently fixed to a
> basic_string<...>.
>
>
>> also with support for formatting into a string_view, array, or
>> pointer-like object.
>>
> string_view: as far as I remember string_view is read-only.
> array: If wrapped in a proper iterator like object that knows when the
> array ends, yeah.
> pointer-like object: that's basically an iterator.
>
> A lot of cases can be covered using iterators, although iterators don't
> allow for block-writes. I'd be curious if a "*x++ = *y++" loop is optimized
> into a memcpy.
>
>
>> You then need to injecting all of the formatting support from iostreams
>> and printf. We definitely need formatter objects to handle this. Text
>> formatters can probably be a concept.
>>
>> format(result) << param(Time).precision(5).show_positive();
>>
>> But this syntax grows very large compared to printf. I believe that most
>> printf syntax can be embedded in overloaded operators when brevity is
>> valued.
>>
>> // like %+.9f
>> format(result) << +param(Time)[9];
>>
>> //like %X
>> format(result) << !hex(Address);
>>
>> // like %0+5.5e
>> format(result) << 0+sci(Time)(5,5);
>>
>> // like %+f OR %f.
>> format(result) << param(Time).show_positive( use_positive );
>>
>> // like %n
>> int pos=0;
>> format(result, "And then she %0", position(pos));
>>
>> This gives us lots of flexibility in specifying formatting options
>> statically or dynamically, with help from the IDE as to what our options
>> are, and the ability to extend/compose the interface of the formatters.
>>
>> One problem: the % syntax won't scale well above 9; %10 could mean "print
>> param 10" or "print param 1 then a zero". There are a number of ways around
>> this but continuing with %A=10, %B=11 seems a fine approach that can scale
>> up beyond any practical use case.
>>
>
> The entire %xxx approach is inflexible and error-prone, that's why me (and
> others) don't follow it. In addition only supporting the existing printf()
> flags is needlessly limiting. I want to be able to write a type that has
> it's own distinct and independent format options unrelated to anything
> std::ios if I so desire by processing the options substring myself. I'm not
> a fan of artificial limitations. Just consider the date/time formatting
> example from earlier in this discussion as motivation. But I do agree that
> some sort of interaction with ios::fmtflags (and the other ios stuff)
> should exist, if for the sole reason that using locale facets interface is
> currently based around ios_base to control the output.
>
>
> --
>
> --- You received this message because you are subscribed to the Google
> Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at http://groups.google.com/a/isocpp.org/group/std-
> proposals/.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a11c322746442d804f05a0339
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">But why do we need an options substring? If we wrap parame=
ters in a (std or user-defined) object (hex(), sci(), etc) then these optio=
ns can be specified programmatically and can be easily extended just by add=
ing new methods. If options are specified in a string it becomes more work =
to set those flags programmatically.<div>
<br></div><div>In the example of say %.5g, if that 5 is in the format strin=
g then it is hard to change. If the 5 is a parameter to a formatting object=
 then it is easier to specify and requires no parsing at runtime.</div>
</div><div class=3D"gmail_extra"><br><br><div class=3D"gmail_quote">On Sun,=
 Jan 19, 2014 at 3:27 PM, Miro Knejp <span dir=3D"ltr">&lt;<a href=3D"mailt=
o:miro@knejp.de" target=3D"_blank">miro@knejp.de</a>&gt;</span> wrote:<br><=
blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px=
 #ccc solid;padding-left:1ex">
<br>
Am 19.01.2014 21:11, schrieb Brent Friedman:<div class=3D"im"><br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
Thought I would just chime in a bit of bikeshedding.<br>
<br>
The format string technique and the &lt;&lt; technique both have value. If =
the argument order is known statically then I shouldn&#39;t have to pay to =
parse %0, %1. If the argument order is determined dynamically then the libr=
ary should have a mechanism to support that.<br>

<br>
I would envision this something like:;<br>
format(my_string, &quot;Time: %0 Name: %1&quot;, Time, Username); //appends=
 to my_string<br>
</blockquote></div>
My current implementation does this. Also does ostream and ostreambuf. A ge=
neralized approach using iterators is in progress.<div class=3D"im"><br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
and<br>
format(my_string) &lt;&lt; &quot;Location:&quot; &lt;&lt; Location; //appen=
ds to my_string<br>
</blockquote></div>
Why use format here in the first place? You would probably be better off ap=
pending to my_string directly (or use ostringstream).<div class=3D"im"><br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
and<br>
make_formatted&lt;std::string&gt;(&quot;<u></u>Time: %0 Name:%1 Location: %=
2&quot;, Time, Username, Location); //returns new my_string<br>
</blockquote></div>
This is implemented, too, albeit the return type is currently fixed to a ba=
sic_string&lt;...&gt;.<div class=3D"im"><br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
<br>
also with support for formatting into a string_view, array, or pointer-like=
 object.<br>
</blockquote></div>
string_view: as far as I remember string_view is read-only.<br>
array: If wrapped in a proper iterator like object that knows when the arra=
y ends, yeah.<br>
pointer-like object: that&#39;s basically an iterator.<br>
<br>
A lot of cases can be covered using iterators, although iterators don&#39;t=
 allow for block-writes. I&#39;d be curious if a &quot;*x++ =3D *y++&quot; =
loop is optimized into a memcpy.<div class=3D"im"><br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
<br>
You then need to injecting all of the formatting support from iostreams and=
 printf. We definitely need formatter objects to handle this. Text formatte=
rs can probably be a concept.<br>
<br>
format(result) &lt;&lt; param(Time).precision(5).show_<u></u>positive();<br=
>
<br>
But this syntax grows very large compared to printf. I believe that most pr=
intf syntax can be embedded in overloaded operators when brevity is valued.=
<br>
<br>
// like %+.9f<br>
format(result) &lt;&lt; +param(Time)[9];<br>
<br>
//like %X<br>
format(result) &lt;&lt; !hex(Address);<br>
<br>
// like %0+5.5e<br>
format(result) &lt;&lt; 0+sci(Time)(5,5);<br>
<br>
// like %+f OR %f.<br>
format(result) &lt;&lt; param(Time).show_positive( use_positive );<br>
<br>
// like %n<br>
int pos=3D0;<br>
format(result, &quot;And then she %0&quot;, position(pos));<br>
<br>
This gives us lots of flexibility in specifying formatting options statical=
ly or dynamically, with help from the IDE as to what our options are, and t=
he ability to extend/compose the interface of the formatters.<br>
<br>
One problem: the % syntax won&#39;t scale well above 9; %10 could mean &quo=
t;print param 10&quot; or &quot;print param 1 then a zero&quot;. There are =
a number of ways around this but continuing with %A=3D10, %B=3D11 seems a f=
ine approach that can scale up beyond any practical use case.<br>

</blockquote>
<br></div>
The entire %xxx approach is inflexible and error-prone, that&#39;s why me (=
and others) don&#39;t follow it. In addition only supporting the existing p=
rintf() flags is needlessly limiting. I want to be able to write a type tha=
t has it&#39;s own distinct and independent format options unrelated to any=
thing std::ios if I so desire by processing the options substring myself. I=
&#39;m not a fan of artificial limitations. Just consider the date/time for=
matting example from earlier in this discussion as motivation. But I do agr=
ee that some sort of interaction with ios::fmtflags (and the other ios stuf=
f) should exist, if for the sole reason that using locale facets interface =
is currently based around ios_base to control the output.<div class=3D"HOEn=
Zb">
<div class=3D"h5"><br>
<br>
-- <br>
<br>
--- You received this message because you are subscribed to the Google Grou=
ps &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@<u></u>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/<u></u>isocpp.=
org/group/std-<u></u>proposals/</a>.<br>
</div></div></blockquote></div><br></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a11c322746442d804f05a0339--

.


Author: Miro Knejp <miro@knejp.de>
Date: Sun, 19 Jan 2014 23:43:50 +0100
Raw View
Am 19.01.2014 23:08, schrieb Brent Friedman:
> But why do we need an options substring? If we wrap parameters in a
> (std or user-defined) object (hex(), sci(), etc) then these options
> can be specified programmatically and can be easily extended just by
> adding new methods. If options are specified in a string it becomes
> more work to set those flags programmatically.
>
> In the example of say %.5g, if that 5 is in the format string then it
> is hard to change. If the 5 is a parameter to a formatting object then
> it is easier to specify and requires no parsing at runtime.
>
If you know at compile time what your string is and how you want it
printed, then sure, use a readily available function. But I'd like to
cover other use cases, too. The number one scenario from my experience
where one needs a printf()-like method is localization or structured
text output. There you don't know how your string should be formatted.
All you know when writing the code is that you are going to provide the
values a, b, c and d to it. Those format string may come from an
entirely different company in case of translations. In short: I should
only specify *what* is formatted, not *how*. The *how* may be determined
by external sources out of my control.

Please consider this example from earlier:

format("%1.2d.%2.2d.%3.4d - %4.2d:%5.2d:%6.2d", tm1.tm_day, tm1.tm_mon,
tm1.tm_year, tm1.tm_hours, tm1.tm_min, tm1.tm_sec);
format("%2.2d/%1.2d/%3.4d - %4.2d:%5.2d:%6.2d", tm1.tm_day, tm1.tm_mon,
tm1.tm_year, tm1.tm_hours, tm1.tm_min, tm1.tm_sec);
versus
format("{0:dd.MM.yyyy - HH:mm:ss}", tm1); // "18.01.2014 - 20:36:09"
format("{0:MMM/dd/yyyy - h:mm t}", tm1); // "Jan/01/2014 - 8:36 pm"

Which is easier to read/write/teach/understand?

In both cases *how* the data is presented to the user or written to a
(structured) text file is not my concern. All I do is provide the
values. The strings could come from UI designers, translators, file
format architects, you name it. Where the second alternative really
shines is the flexibility in formatting custom types. The important
point is that in real world programs where changing language settings,
file formats, value representation, etc at runtime is possible the
strings are *not* present as string literals in the code but are fed
from external sources and usually not known to you as a programmer when
you write the code that calls format().

 From a library writer's viewpoint you provide (in the implementation
I'm currently working on) a method with the signature

string to_string(const T&, string_view options); // called with tm1 and
"dd.MM.yyyy - HH:mm:ss"

and you have full control over how you formatT (other signatures are
available, see https://github.com/mknejp/std-format for details). This
system is fully extensible to any custom user type and does not restrict
to only a handfull of hardcoded format options which may be totally
inappropriate and useless for your type.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Brent Friedman <fourthgeek@gmail.com>
Date: Sun, 19 Jan 2014 17:46:12 -0600
Raw View
--001a11339ae450dd4704f05b615d
Content-Type: text/plain; charset=ISO-8859-1

I understand the motivation now. But you don't have to know at compile time
what your string is and how you want to print it. The parameter formatter
can be as dynamic as you want it to be. Build the object dynamically. Throw
in some virtuals if you feel like it.

Here would be your example, then:

//create DateFormat from designer spec
string user_spec = get_user_format_spec();
format("{0}", DateFormat(spec, tm1));

 //create DateFormat from a localized config string (german might be
TT/mm/JJ instead of DD/mm/YY).
string user_spec = get_user_format_spec( current_language );
format( "{0}", DateFormat(current_language, user_spec, tm1));

And with little work we can also make it programmer friendly.

//default, developer DateFormat
format( "{0}", DateFormat(tm1));

//default for the given language
format( "{0}", DateFormat::lang(current_language).at(tm1);

//use ISO 8601
format( "{0}", DateFormat( iso_8601, tm1));

You don't have to write a parser to add new options, just add the method to
your format object and interface that with the outside world.

It seems, then, like non-positional format string parameters are an
unnecessary complication.



On Sun, Jan 19, 2014 at 4:43 PM, Miro Knejp <miro@knejp.de> wrote:

>
> Am 19.01.2014 23:08, schrieb Brent Friedman:
>
>  But why do we need an options substring? If we wrap parameters in a (std
>> or user-defined) object (hex(), sci(), etc) then these options can be
>> specified programmatically and can be easily extended just by adding new
>> methods. If options are specified in a string it becomes more work to set
>> those flags programmatically.
>>
>> In the example of say %.5g, if that 5 is in the format string then it is
>> hard to change. If the 5 is a parameter to a formatting object then it is
>> easier to specify and requires no parsing at runtime.
>>
>>  If you know at compile time what your string is and how you want it
> printed, then sure, use a readily available function. But I'd like to cover
> other use cases, too. The number one scenario from my experience where one
> needs a printf()-like method is localization or structured text output.
> There you don't know how your string should be formatted. All you know when
> writing the code is that you are going to provide the values a, b, c and d
> to it. Those format string may come from an entirely different company in
> case of translations. In short: I should only specify *what* is formatted,
> not *how*. The *how* may be determined by external sources out of my
> control.
>
> Please consider this example from earlier:
>
> format("%1.2d.%2.2d.%3.4d - %4.2d:%5.2d:%6.2d", tm1.tm_day, tm1.tm_mon,
> tm1.tm_year, tm1.tm_hours, tm1.tm_min, tm1.tm_sec);
> format("%2.2d/%1.2d/%3.4d - %4.2d:%5.2d:%6.2d", tm1.tm_day, tm1.tm_mon,
> tm1.tm_year, tm1.tm_hours, tm1.tm_min, tm1.tm_sec);
>
> versus
> format("{0:dd.MM.yyyy - HH:mm:ss}", tm1); // "18.01.2014 - 20:36:09"
> format("{0:MMM/dd/yyyy - h:mm t}", tm1); // "Jan/01/2014 - 8:36 pm"
>
> Which is easier to read/write/teach/understand?
>
> In both cases *how* the data is presented to the user or written to a
> (structured) text file is not my concern. All I do is provide the values.
> The strings could come from UI designers, translators, file format
> architects, you name it. Where the second alternative really shines is the
> flexibility in formatting custom types. The important point is that in real
> world programs where changing language settings, file formats, value
> representation, etc at runtime is possible the strings are *not* present as
> string literals in the code but are fed from external sources and usually
> not known to you as a programmer when you write the code that calls
> format().
>
> From a library writer's viewpoint you provide (in the implementation I'm
> currently working on) a method with the signature
>
> string to_string(const T&, string_view options); // called with tm1 and
> "dd.MM.yyyy - HH:mm:ss"
>
> and you have full control over how you formatT (other signatures are
> available, see https://github.com/mknejp/std-format for details). This
> system is fully extensible to any custom user type and does not restrict to
> only a handfull of hardcoded format options which may be totally
> inappropriate and useless for your type.
>
>
> --
>
> --- You received this message because you are subscribed to the Google
> Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at http://groups.google.com/a/isocpp.org/group/std-
> proposals/.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a11339ae450dd4704f05b615d
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I understand the motivation now. But you don&#39;t have to=
 know at compile time what your string is and how you want to print it. The=
 parameter formatter can be as dynamic as you want it to be. Build the obje=
ct dynamically. Throw in some virtuals if you feel like it.<div>
<br></div><div>Here would be your example, then:</div><div><br></div><div>/=
/create DateFormat from designer spec<br></div><div>string user_spec =3D ge=
t_user_format_spec();</div><div>format(&quot;{0}&quot;, DateFormat(spec, tm=
1));=A0</div>
<div><br></div><div>=A0//create DateFormat from a localized config string (=
german might be TT/mm/JJ instead of DD/mm/YY).<br></div><div>string user_sp=
ec =3D get_user_format_spec( current_language );</div><div>format( &quot;{0=
}&quot;, DateFormat(current_language, user_spec, tm1));</div>
<div><br></div><div>And with little work we can also make it programmer fri=
endly.</div><div><br></div><div>//default, developer DateFormat</div><div>f=
ormat( &quot;{0}&quot;, DateFormat(tm1));</div><div><br></div><div>//defaul=
t for the given language</div>
<div>format( &quot;{0}&quot;, DateFormat::lang(current_language).at(tm1);</=
div><div><br></div><div>//use ISO 8601</div><div>format( &quot;{0}&quot;, D=
ateFormat( iso_8601, tm1));</div><div><br></div><div>You don&#39;t have to =
write a parser to add new options, just add the method to your format objec=
t and interface that with the outside world.</div>
<div><br></div><div>It seems, then, like non-positional format string param=
eters are an unnecessary complication.=A0</div><div><br></div></div><div cl=
ass=3D"gmail_extra"><br><br><div class=3D"gmail_quote">On Sun, Jan 19, 2014=
 at 4:43 PM, Miro Knejp <span dir=3D"ltr">&lt;<a href=3D"mailto:miro@knejp.=
de" target=3D"_blank">miro@knejp.de</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><br>
Am 19.01.2014 23:08, schrieb Brent Friedman:<div class=3D"im"><br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
But why do we need an options substring? If we wrap parameters in a (std or=
 user-defined) object (hex(), sci(), etc) then these options can be specifi=
ed programmatically and can be easily extended just by adding new methods. =
If options are specified in a string it becomes more work to set those flag=
s programmatically.<br>

<br>
In the example of say %.5g, if that 5 is in the format string then it is ha=
rd to change. If the 5 is a parameter to a formatting object then it is eas=
ier to specify and requires no parsing at runtime.<br>
<br>
</blockquote></div>
If you know at compile time what your string is and how you want it printed=
, then sure, use a readily available function. But I&#39;d like to cover ot=
her use cases, too. The number one scenario from my experience where one ne=
eds a printf()-like method is localization or structured text output. There=
 you don&#39;t know how your string should be formatted. All you know when =
writing the code is that you are going to provide the values a, b, c and d =
to it. Those format string may come from an entirely different company in c=
ase of translations. In short: I should only specify *what* is formatted, n=
ot *how*. The *how* may be determined by external sources out of my control=
..<br>

<br>
Please consider this example from earlier:<br>
<br>
format(&quot;%1.2d.%2.2d.%3.4d - %4.2d:%5.2d:%6.2d&quot;, tm1.tm_day, tm1.t=
m_mon, tm1.tm_year, tm1.tm_hours, tm1.tm_min, tm1.tm_sec);<br>
format(&quot;%2.2d/%1.2d/%3.4d - %4.2d:%5.2d:%6.2d&quot;, tm1.tm_day, tm1.t=
m_mon, tm1.tm_year, tm1.tm_hours, tm1.tm_min, tm1.tm_sec);<div class=3D"im"=
><br>
versus<br>
format(&quot;{0:dd.MM.yyyy - HH:mm:ss}&quot;, tm1); // &quot;18.01.2014 - 2=
0:36:09&quot;<br></div>
format(&quot;{0:MMM/dd/yyyy - h:mm t}&quot;, tm1); // &quot;Jan/01/2014 - 8=
:36 pm&quot;<br>
<br>
Which is easier to read/write/teach/understand?<br>
<br>
In both cases *how* the data is presented to the user or written to a (stru=
ctured) text file is not my concern. All I do is provide the values. The st=
rings could come from UI designers, translators, file format architects, yo=
u name it. Where the second alternative really shines is the flexibility in=
 formatting custom types. The important point is that in real world program=
s where changing language settings, file formats, value representation, etc=
 at runtime is possible the strings are *not* present as string literals in=
 the code but are fed from external sources and usually not known to you as=
 a programmer when you write the code that calls format().<br>

<br>
From a library writer&#39;s viewpoint you provide (in the implementation I&=
#39;m currently working on) a method with the signature<br>
<br>
string to_string(const T&amp;, string_view options); // called with tm1 and=
 &quot;dd.MM.yyyy - HH:mm:ss&quot;<br>
<br>
and you have full control over how you formatT (other signatures are availa=
ble, see <a href=3D"https://github.com/mknejp/std-format" target=3D"_blank"=
>https://github.com/mknejp/std-<u></u>format</a> for details). This system =
is fully extensible to any custom user type and does not restrict to only a=
 handfull of hardcoded format options which may be totally inappropriate an=
d useless for your type.<div class=3D"HOEnZb">
<div class=3D"h5"><br>
<br>
-- <br>
<br>
--- You received this message because you are subscribed to the Google Grou=
ps &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@<u></u>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/<u></u>isocpp.=
org/group/std-<u></u>proposals/</a>.<br>
</div></div></blockquote></div><br></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a11339ae450dd4704f05b615d--

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Sun, 19 Jan 2014 15:48:18 -0800 (PST)
Raw View
------=_Part_919_28621053.1390175298825
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Lots of traffic here. I'll try to respond to the important stuff:

Mario: I also think that it is nice to be able to format the same parameter=
=20
twice. But it will be used extremely rarely and the work-around of writing=
=20
the parameter value twice. However, having to dynamically allocate memory=
=20
for the string_views for every formatting operation is a big deal,=20
performance wise. I would rather reserve twice the array size for the=20
parts, although that is of course a hack. I concur with your opinions of=20
Brent's suggestions, but want to add this:

Brent: I don't really see advantages with your versions. It would be=20
possible to make the parameter number optional, but that would prevent=20
changing the order in translation unless the format function gets to see=20
both the untranslated and translated string, which is a possibility.
The "Extremely Efficient Type-safe printf Library" description had a decent=
=20
set of formatting parameters. Actually very similar to one I made once, but=
=20
mine had the minwidth attached to the L, R or C padding options as when you=
=20
set a minwidth you need to tell it what to fill width. I also had a Z=20
option which performed zero filling (implying "right" fill direction).=20
However, this parameter set also shows the weakness: Several options are=20
only valid for floating point or time formats (for instance) but still=20
"consume" a letter for all other formats...

Mario, comparing our implementations: I think I focussed more than you on=
=20
performance. Using just a to_string() function prevents your implementation=
=20
from letting the individual insert parse their type-specific parameter=20
strings once and for all as mine does using the DataFormatter object. My=20
to_string is layered on top of the specialized DataFormatter objects and=20
act as convenience functions which are not used by the Formatter objects. I=
=20
like your idea of specifying the storage type, although it is less nice=20
that you have to specify for each created object. I wonder if you can have=
=20
a defaulted template parameter before a pack... I was not able to figure=20
out how to avoid the 'string' inside the Formatter, especially for the on=
=20
spot formatting case where it is totally unnecessary. I will revisit to see=
=20
if I can fix this using your idea.




Den s=C3=B6ndagen den 19:e januari 2014 kl. 14:43:50 UTC-8 skrev Miro Knejp=
:
>
>
> Am 19.01.2014 23:08, schrieb Brent Friedman:=20
> > But why do we need an options substring? If we wrap parameters in a=20
> > (std or user-defined) object (hex(), sci(), etc) then these options=20
> > can be specified programmatically and can be easily extended just by=20
> > adding new methods. If options are specified in a string it becomes=20
> > more work to set those flags programmatically.=20
> >=20
> > In the example of say %.5g, if that 5 is in the format string then it=
=20
> > is hard to change. If the 5 is a parameter to a formatting object then=
=20
> > it is easier to specify and requires no parsing at runtime.=20
> >=20
> If you know at compile time what your string is and how you want it=20
> printed, then sure, use a readily available function. But I'd like to=20
> cover other use cases, too. The number one scenario from my experience=20
> where one needs a printf()-like method is localization or structured=20
> text output. There you don't know how your string should be formatted.=20
> All you know when writing the code is that you are going to provide the=
=20
> values a, b, c and d to it. Those format string may come from an=20
> entirely different company in case of translations. In short: I should=20
> only specify *what* is formatted, not *how*. The *how* may be determined=
=20
> by external sources out of my control.=20
>
> Please consider this example from earlier:=20
>
> format("%1.2d.%2.2d.%3.4d - %4.2d:%5.2d:%6.2d", tm1.tm_day, tm1.tm_mon,=
=20
> tm1.tm_year, tm1.tm_hours, tm1.tm_min, tm1.tm_sec);=20
> format("%2.2d/%1.2d/%3.4d - %4.2d:%5.2d:%6.2d", tm1.tm_day, tm1.tm_mon,=
=20
> tm1.tm_year, tm1.tm_hours, tm1.tm_min, tm1.tm_sec);=20
> versus=20
> format("{0:dd.MM.yyyy - HH:mm:ss}", tm1); // "18.01.2014 - 20:36:09"=20
> format("{0:MMM/dd/yyyy - h:mm t}", tm1); // "Jan/01/2014 - 8:36 pm"=20
>
> Which is easier to read/write/teach/understand?=20
>
> In both cases *how* the data is presented to the user or written to a=20
> (structured) text file is not my concern. All I do is provide the=20
> values. The strings could come from UI designers, translators, file=20
> format architects, you name it. Where the second alternative really=20
> shines is the flexibility in formatting custom types. The important=20
> point is that in real world programs where changing language settings,=20
> file formats, value representation, etc at runtime is possible the=20
> strings are *not* present as string literals in the code but are fed=20
> from external sources and usually not known to you as a programmer when=
=20
> you write the code that calls format().=20
>
>  From a library writer's viewpoint you provide (in the implementation=20
> I'm currently working on) a method with the signature=20
>
> string to_string(const T&, string_view options); // called with tm1 and=
=20
> "dd.MM.yyyy - HH:mm:ss"=20
>
> and you have full control over how you formatT (other signatures are=20
> available, see https://github.com/mknejp/std-format for details). This=20
> system is fully extensible to any custom user type and does not restrict=
=20
> to only a handfull of hardcoded format options which may be totally=20
> inappropriate and useless for your type.=20
>
>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_919_28621053.1390175298825
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Lots of traffic here. I'll try to respond to the important=
 stuff:<div><br></div><div>Mario: I also think that it is nice to be able t=
o format the same parameter twice. But it will be used extremely rarely and=
 the work-around of writing the parameter value twice. However, having to d=
ynamically allocate memory for the string_views for every formatting operat=
ion is a big deal, performance wise. I would rather reserve twice the array=
 size for the parts, although that is of course a hack. I concur with your =
opinions of Brent's suggestions, but want to add this:<br><br>Brent: I don'=
t really see advantages with your versions. It would be possible to make th=
e parameter number optional, but that would prevent changing the order in t=
ranslation unless the format function gets to see both the untranslated and=
 translated string, which is a possibility.</div><div>The "<span style=3D"f=
ont-size: small; line-height: 24px; font-family: 'Segoe UI', Arial, sans-se=
rif;">Extremely Efficient Type-safe printf Library" description had a decen=
t set of formatting parameters. Actually very similar to one I made once, b=
ut mine had the minwidth attached to the L, R or C padding options as when =
you set a minwidth you need to tell it what to fill width. I also had a Z o=
ption which performed zero filling (implying "right" fill direction). Howev=
er, this parameter set also shows the weakness: Several options are only va=
lid for floating point or time formats (for instance) but still "consume" a=
 letter for all other formats...</span></div><div><span style=3D"font-size:=
 small; line-height: 24px; font-family: 'Segoe UI', Arial, sans-serif;"><br=
></span></div><div><span style=3D"font-size: small; line-height: 24px; font=
-family: 'Segoe UI', Arial, sans-serif;">Mario, comparing our implementatio=
ns: I think I focussed more than you on performance. Using just a to_string=
() function prevents your implementation from letting the individual insert=
 parse their type-specific parameter strings once and for all as mine does =
using the DataFormatter object. My to_string is layered on top of the speci=
alized DataFormatter objects and act as convenience functions which are not=
 used by the Formatter objects. I like your idea of specifying the storage =
type, although it is less nice that you have to specify for each created ob=
ject. I wonder if you can have a defaulted template parameter before a pack=
.... I was not able to figure out how to avoid the 'string' inside the Forma=
tter, especially for the on spot formatting case where it is totally unnece=
ssary. I will revisit to see if I can fix this using your idea.</span></div=
><div><br></div><div><br></div><div><br><br>Den s=C3=B6ndagen den 19:e janu=
ari 2014 kl. 14:43:50 UTC-8 skrev Miro Knejp:<blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;">
<br>Am 19.01.2014 23:08, schrieb Brent Friedman:
<br>&gt; But why do we need an options substring? If we wrap parameters in =
a=20
<br>&gt; (std or user-defined) object (hex(), sci(), etc) then these option=
s=20
<br>&gt; can be specified programmatically and can be easily extended just =
by=20
<br>&gt; adding new methods. If options are specified in a string it become=
s=20
<br>&gt; more work to set those flags programmatically.
<br>&gt;
<br>&gt; In the example of say %.5g, if that 5 is in the format string then=
 it=20
<br>&gt; is hard to change. If the 5 is a parameter to a formatting object =
then=20
<br>&gt; it is easier to specify and requires no parsing at runtime.
<br>&gt;
<br>If you know at compile time what your string is and how you want it=20
<br>printed, then sure, use a readily available function. But I'd like to=
=20
<br>cover other use cases, too. The number one scenario from my experience=
=20
<br>where one needs a printf()-like method is localization or structured=20
<br>text output. There you don't know how your string should be formatted.=
=20
<br>All you know when writing the code is that you are going to provide the=
=20
<br>values a, b, c and d to it. Those format string may come from an=20
<br>entirely different company in case of translations. In short: I should=
=20
<br>only specify *what* is formatted, not *how*. The *how* may be determine=
d=20
<br>by external sources out of my control.
<br>
<br>Please consider this example from earlier:
<br>
<br>format("%1.2d.%2.2d.%3.4d - %4.2d:%5.2d:%6.2d", tm1.tm_day, tm1.tm_mon,=
=20
<br>tm1.tm_year, tm1.tm_hours, tm1.tm_min, tm1.tm_sec);
<br>format("%2.2d/%1.2d/%3.4d - %4.2d:%5.2d:%6.2d", tm1.tm_day, tm1.tm_mon,=
=20
<br>tm1.tm_year, tm1.tm_hours, tm1.tm_min, tm1.tm_sec);
<br>versus
<br>format("{0:dd.MM.yyyy - HH:mm:ss}", tm1); // "18.01.2014 - 20:36:09"
<br>format("{0:MMM/dd/yyyy - h:mm t}", tm1); // "Jan/01/2014 - 8:36 pm"
<br>
<br>Which is easier to read/write/teach/understand?
<br>
<br>In both cases *how* the data is presented to the user or written to a=
=20
<br>(structured) text file is not my concern. All I do is provide the=20
<br>values. The strings could come from UI designers, translators, file=20
<br>format architects, you name it. Where the second alternative really=20
<br>shines is the flexibility in formatting custom types. The important=20
<br>point is that in real world programs where changing language settings,=
=20
<br>file formats, value representation, etc at runtime is possible the=20
<br>strings are *not* present as string literals in the code but are fed=20
<br>from external sources and usually not known to you as a programmer when=
=20
<br>you write the code that calls format().
<br>
<br>&nbsp;From a library writer's viewpoint you provide (in the implementat=
ion=20
<br>I'm currently working on) a method with the signature
<br>
<br>string to_string(const T&amp;, string_view options); // called with tm1=
 and=20
<br>"dd.MM.yyyy - HH:mm:ss"
<br>
<br>and you have full control over how you formatT (other signatures are=20
<br>available, see <a href=3D"https://github.com/mknejp/std-format" target=
=3D"_blank" onmousedown=3D"this.href=3D'https://www.google.com/url?q\75http=
s%3A%2F%2Fgithub.com%2Fmknejp%2Fstd-format\46sa\75D\46sntz\0751\46usg\75AFQ=
jCNFj4V0cgSD-Q54eNuKEmwPng8URWg';return true;" onclick=3D"this.href=3D'http=
s://www.google.com/url?q\75https%3A%2F%2Fgithub.com%2Fmknejp%2Fstd-format\4=
6sa\75D\46sntz\0751\46usg\75AFQjCNFj4V0cgSD-Q54eNuKEmwPng8URWg';return true=
;">https://github.com/mknejp/std-<wbr>format</a> for details). This=20
<br>system is fully extensible to any custom user type and does not restric=
t=20
<br>to only a handfull of hardcoded format options which may be totally=20
<br>inappropriate and useless for your type.
<br>
<br></blockquote></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_919_28621053.1390175298825--

.


Author: Miro Knejp <miro@knejp.de>
Date: Mon, 20 Jan 2014 01:51:49 +0100
Raw View
This is a multi-part message in MIME format.
--------------020303080405040704060902
Content-Type: text/plain; charset=UTF-8; format=flowed


Am 20.01.2014 00:48, schrieb Bengt Gustafsson:
> Lots of traffic here. I'll try to respond to the important stuff:
>
> Mario: I also think that it is nice to be able to format the same
> parameter twice. But it will be used extremely rarely and the
> work-around of writing the parameter value twice. However, having to
> dynamically allocate memory for the string_views for every formatting
> operation is a big deal, performance wise. I would rather reserve
> twice the array size for the parts, although that is of course a hack.
> I concur with your opinions of Brent's suggestions, but want to add this:
I just assume you meant Miro, not Mario :)

The allocation is only necessary for the preformatted object. And
actually, the string_views do not require the allocation, it is the
formatting objects. The formatter keeps *some* sort of reference to the
format string (1st template parameter) and for the constant parts and
format options all it saves are offsets into the original format strings
in the form of lambdas and all the type-independent values per format
argument. I just don't see a way of allowing arguments to be
duplicated/skipped without dynamic memory in a precompiler.

The inline format() method doesn't need any allocations most of the time.
> Mario, comparing our implementations: I think I focussed more than you
> on performance. Using just a to_string() function prevents your
> implementation from letting the individual insert parse their
> type-specific parameter strings once and for all as mine does using
> the DataFormatter object. My to_string is layered on top of the
> specialized DataFormatter objects and act as convenience functions
> which are not used by the Formatter objects. I like your idea of
> specifying the storage type, although it is less nice that you have to
> specify for each created object. I wonder if you can have a defaulted
> template parameter before a pack... I was not able to figure out how
> to avoid the 'string' inside the Formatter, especially for the on spot
> formatting case where it is totally unnecessary. I will revisit to see
> if I can fix this using your idea.
>
The precompile part isn't finished yet. I will work on it tomorrow. The
next step is to somehow open the doors to users to provide a means of
doing the preprocessing. Whether this is a class, function, lambda, etc
is still open. The current behavior is for cases where such a
preprocessing facility is not provided by a type. There is the approach
of doing it like std::hash where one has to specialize a template (does
it still require re-opening namespace std?) or a function that returns
an object with a suited operator(). The latter has the advantage it may
return an object (like a lambda) that is already specialized (i.e.
hardcoded) for the involved format options. If the formatter
instantiates the DataFormatter directly it has to parse the options in
the constructor and then remember what it is supposed to do, like
whether to output something in decimal or hex. That logic has to be
re-evaluated on every format, even though it doesn't change. A function
object could already have the decimal or hex code path baked in. I know
this is a silly and small example and I have not yet done any research
whether it would make a difference in the real world. I think there is
potential but that needs to be tested. Never say I don't care about
performance ;)

The biggest issue I currently face is the output. I could just template
it on an iterator and pass it on to user code, but not all iterators are
equal. Especially the difference on how OutputIterator and
ForwardIterator work. Using simple ForwardIterators I have observed that
std::copy() is indeed optimized into memcpy for simple iterators (how
about stuff like back_insert_iterator?). Looking at the implementation
of libc++ the streambuf.sputn() method calls sputc() in a loop, which is
a virtual function (both not overriden in stringbuf). And since an
OutputIterator doesn't have any "block copy" method it wouldn't even
pickup a specialized sputn(). That's all very weird. Will probably
require use of iterator_traits and other gimmicks and hide it behind
some kind of sink or appender type.

Or I wait for how the second part of this proposal comes along...

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--------------020303080405040704060902
Content-Type: text/html; charset=UTF-8

<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <br>
    <div class="moz-cite-prefix">Am 20.01.2014 00:48, schrieb Bengt
      Gustafsson:<br>
    </div>
    <blockquote
      cite="mid:43bc4f53-6958-4ad6-895e-5a5ccdf38d2b@isocpp.org"
      type="cite">
      <div dir="ltr">Lots of traffic here. I'll try to respond to the
        important stuff:
        <div><br>
        </div>
        <div>Mario: I also think that it is nice to be able to format
          the same parameter twice. But it will be used extremely rarely
          and the work-around of writing the parameter value twice.
          However, having to dynamically allocate memory for the
          string_views for every formatting operation is a big deal,
          performance wise. I would rather reserve twice the array size
          for the parts, although that is of course a hack. I concur
          with your opinions of Brent's suggestions, but want to add
          this:<br>
        </div>
      </div>
    </blockquote>
    I just assume you meant Miro, not Mario :)<br>
    <br>
    The allocation is only necessary for the preformatted object. And
    actually, the string_views do not require the allocation, it is the
    formatting objects. The formatter keeps *some* sort of reference to
    the format string (1st template parameter) and for the constant
    parts and format options all it saves are offsets into the original
    format strings in the form of lambdas and all the type-independent
    values per format argument. I just don't see a way of allowing
    arguments to be duplicated/skipped without dynamic memory in a
    precompiler.<br>
    <br>
    The inline format() method doesn't need any allocations most of the
    time.
    <blockquote
      cite="mid:43bc4f53-6958-4ad6-895e-5a5ccdf38d2b@isocpp.org"
      type="cite">
      <div dir="ltr">
        <div><span style="font-size: small; line-height: 24px;
            font-family: 'Segoe UI', Arial, sans-serif;">Mario,
            comparing our implementations: I think I focussed more than
            you on performance. Using just a to_string() function
            prevents your implementation from letting the individual
            insert parse their type-specific parameter strings once and
            for all as mine does using the DataFormatter object. My
            to_string is layered on top of the specialized DataFormatter
            objects and act as convenience functions which are not used
            by the Formatter objects. I like your idea of specifying the
            storage type, although it is less nice that you have to
            specify for each created object. I wonder if you can have a
            defaulted template parameter before a pack... I was not able
            to figure out how to avoid the 'string' inside the
            Formatter, especially for the on spot formatting case where
            it is totally unnecessary. I will revisit to see if I can
            fix this using your idea.</span></div>
        <div><br>
        </div>
      </div>
    </blockquote>
    The precompile part isn't finished yet. I will work on it tomorrow.
    The next step is to somehow open the doors to users to provide a
    means of doing the preprocessing. Whether this is a class, function,
    lambda, etc is still open. The current behavior is for cases where
    such a preprocessing facility is not provided by a type. There is
    the approach of doing it like std::hash where one has to specialize
    a template (does it still require re-opening namespace std?) or a
    function that returns an object with a suited operator(). The latter
    has the advantage it may return an object (like a lambda) that is
    already specialized (i.e. hardcoded) for the involved format
    options. If the formatter instantiates the DataFormatter directly it
    has to parse the options in the constructor and then remember what
    it is supposed to do, like whether to output something in decimal or
    hex. That logic has to be re-evaluated on every format, even though
    it doesn't change. A function object could already have the decimal
    or hex code path baked in. I know this is a silly and small example
    and I have not yet done any research whether it would make a
    difference in the real world. I think there is potential but that
    needs to be tested. Never say I don't care about performance ;)<br>
    <br>
    The biggest issue I currently face is the output. I could just
    template it on an iterator and pass it on to user code, but not all
    iterators are equal. Especially the difference on how OutputIterator
    and ForwardIterator work. Using simple ForwardIterators I have
    observed that std::copy() is indeed optimized into memcpy for simple
    iterators (how about stuff like back_insert_iterator?). Looking at
    the implementation of libc++ the streambuf.sputn() method calls
    sputc() in a loop, which is a virtual function (both not overriden
    in stringbuf). And since an OutputIterator doesn't have any "block
    copy" method it wouldn't even pickup a specialized sputn(). That's
    all very weird. Will probably require use of iterator_traits and
    other gimmicks and hide it behind some kind of sink or appender
    type. <br>
    <br>
    Or I wait for how the second part of this proposal comes along...<br>
    <br>
  </body>
</html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />

--------------020303080405040704060902--


.


Author: Miro Knejp <miro@knejp.de>
Date: Mon, 20 Jan 2014 02:02:08 +0100
Raw View
Am 20.01.2014 00:46, schrieb Brent Friedman:
> I understand the motivation now. But you don't have to know at compile
> time what your string is and how you want to print it. The parameter
> formatter can be as dynamic as you want it to be. Build the object
> dynamically. Throw in some virtuals if you feel like it.
>
> Here would be your example, then:
>
> //create DateFormat from designer spec
> string user_spec = get_user_format_spec();
> format("{0}", DateFormat(spec, tm1));
>
>  //create DateFormat from a localized config string (german might be
> TT/mm/JJ instead of DD/mm/YY).
> string user_spec = get_user_format_spec( current_language );
> format( "{0}", DateFormat(current_language, user_spec, tm1));
>
> And with little work we can also make it programmer friendly.
>
> //default, developer DateFormat
> format( "{0}", DateFormat(tm1));
>
> //default for the given language
> format( "{0}", DateFormat::lang(current_language).at(tm1);
>
> //use ISO 8601
> format( "{0}", DateFormat( iso_8601, tm1));
>
> You don't have to write a parser to add new options, just add the
> method to your format object and interface that with the outside world.
>
> It seems, then, like non-positional format string parameters are an
> unnecessary complication.
>
That is still hardcoding how the output should look like. Technically
you can do the same with my implementation already:

Just don't use "formatter<int>" but "formatter<MyPrettyPrintedInt>"
where "MyPrettyPrintedInt" is implicitly constructible from "int",
define to_string(const MyPrettyPrintedInt &) and you have your hardcoded
formatting that ignores any options passed into the format string. Yay!
(Same holds true for Bengt's implementaiton, although it works a bit
differently.)

So from:
formatter<int> fmt(ui_string_12345);
format(fmt, i);

formatter<MyPrettyPrintedInt> fmt(ui_string_12345);
format(fmt, i);

or if you need some options:
format(fmt, MyPrettyPrintedInt(i, width(5), ...));

But it doesn't change the fact the string doesn't control the formatting
anymore, which is bad in any scenario where the programmer is *not* in
control, which is basically always the case where there are translators,
writers, designers, involved who have no access to the code.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Sun, 19 Jan 2014 18:07:44 -0800 (PST)
Raw View
------=_Part_20_26019086.1390183664986
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Sorry for misspelling your name like that.

Your idea with the PrettyPrintedInt is a very simple way to customize=20
printing of an int. It works in many cases although it may be a bit=20
annoying in the on-spot case to write those type names out. In some cases=
=20
the formatting is more connected to the stream so we should also provide an=
=20
option for that case if possible.

The precompilation in the Init() method of DataFormatter can of course=20
perform whatever operations needed and store whatever results this=20
generates in its members. It could kick up clang to compile the appropriate=
=20
c function into assembly for instance...





Den s=C3=B6ndagen den 19:e januari 2014 kl. 17:02:08 UTC-8 skrev Miro Knejp=
:
>
>
> Am 20.01.2014 00:46, schrieb Brent Friedman:=20
> > I understand the motivation now. But you don't have to know at compile=
=20
> > time what your string is and how you want to print it. The parameter=20
> > formatter can be as dynamic as you want it to be. Build the object=20
> > dynamically. Throw in some virtuals if you feel like it.=20
> >=20
> > Here would be your example, then:=20
> >=20
> > //create DateFormat from designer spec=20
> > string user_spec =3D get_user_format_spec();=20
> > format("{0}", DateFormat(spec, tm1));=20
> >=20
> >  //create DateFormat from a localized config string (german might be=20
> > TT/mm/JJ instead of DD/mm/YY).=20
> > string user_spec =3D get_user_format_spec( current_language );=20
> > format( "{0}", DateFormat(current_language, user_spec, tm1));=20
> >=20
> > And with little work we can also make it programmer friendly.=20
> >=20
> > //default, developer DateFormat=20
> > format( "{0}", DateFormat(tm1));=20
> >=20
> > //default for the given language=20
> > format( "{0}", DateFormat::lang(current_language).at(tm1);=20
> >=20
> > //use ISO 8601=20
> > format( "{0}", DateFormat( iso_8601, tm1));=20
> >=20
> > You don't have to write a parser to add new options, just add the=20
> > method to your format object and interface that with the outside world.=
=20
> >=20
> > It seems, then, like non-positional format string parameters are an=20
> > unnecessary complication.=20
> >=20
> That is still hardcoding how the output should look like. Technically=20
> you can do the same with my implementation already:=20
>
> Just don't use "formatter<int>" but "formatter<MyPrettyPrintedInt>"=20
> where "MyPrettyPrintedInt" is implicitly constructible from "int",=20
> define to_string(const MyPrettyPrintedInt &) and you have your hardcoded=
=20
> formatting that ignores any options passed into the format string. Yay!=
=20
> (Same holds true for Bengt's implementaiton, although it works a bit=20
> differently.)=20
>
> So from:=20
> formatter<int> fmt(ui_string_12345);=20
> format(fmt, i);=20
>
> formatter<MyPrettyPrintedInt> fmt(ui_string_12345);=20
> format(fmt, i);=20
>
> or if you need some options:=20
> format(fmt, MyPrettyPrintedInt(i, width(5), ...));=20
>
> But it doesn't change the fact the string doesn't control the formatting=
=20
> anymore, which is bad in any scenario where the programmer is *not* in=20
> control, which is basically always the case where there are translators,=
=20
> writers, designers, involved who have no access to the code.=20
>
>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_20_26019086.1390183664986
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Sorry for misspelling your name like that.<div><br></div><=
div>Your idea with the PrettyPrintedInt is a very simple way to customize p=
rinting of an int. It works in many cases although it may be a bit annoying=
 in the on-spot case to write those type names out. In some cases the forma=
tting is more connected to the stream so we should also provide an option f=
or that case if possible.</div><div><br></div><div>The precompilation in th=
e Init() method of DataFormatter can of course perform whatever operations =
needed and store whatever results this generates in its members. It could k=
ick up clang to compile the appropriate c function into assembly for instan=
ce...</div><div><br></div><div><br><div><br></div><div><br><br>Den s=C3=B6n=
dagen den 19:e januari 2014 kl. 17:02:08 UTC-8 skrev Miro Knejp:<blockquote=
 class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1=
px #ccc solid;padding-left: 1ex;">
<br>Am 20.01.2014 00:46, schrieb Brent Friedman:
<br>&gt; I understand the motivation now. But you don't have to know at com=
pile=20
<br>&gt; time what your string is and how you want to print it. The paramet=
er=20
<br>&gt; formatter can be as dynamic as you want it to be. Build the object=
=20
<br>&gt; dynamically. Throw in some virtuals if you feel like it.
<br>&gt;
<br>&gt; Here would be your example, then:
<br>&gt;
<br>&gt; //create DateFormat from designer spec
<br>&gt; string user_spec =3D get_user_format_spec();
<br>&gt; format("{0}", DateFormat(spec, tm1));
<br>&gt;
<br>&gt; &nbsp;//create DateFormat from a localized config string (german m=
ight be=20
<br>&gt; TT/mm/JJ instead of DD/mm/YY).
<br>&gt; string user_spec =3D get_user_format_spec( current_language );
<br>&gt; format( "{0}", DateFormat(current_language, user_spec, tm1));
<br>&gt;
<br>&gt; And with little work we can also make it programmer friendly.
<br>&gt;
<br>&gt; //default, developer DateFormat
<br>&gt; format( "{0}", DateFormat(tm1));
<br>&gt;
<br>&gt; //default for the given language
<br>&gt; format( "{0}", DateFormat::lang(current_<wbr>language).at(tm1);
<br>&gt;
<br>&gt; //use ISO 8601
<br>&gt; format( "{0}", DateFormat( iso_8601, tm1));
<br>&gt;
<br>&gt; You don't have to write a parser to add new options, just add the=
=20
<br>&gt; method to your format object and interface that with the outside w=
orld.
<br>&gt;
<br>&gt; It seems, then, like non-positional format string parameters are a=
n=20
<br>&gt; unnecessary complication.
<br>&gt;
<br>That is still hardcoding how the output should look like. Technically=
=20
<br>you can do the same with my implementation already:
<br>
<br>Just don't use "formatter&lt;int&gt;" but "formatter&lt;MyPrettyPrinted=
Int&gt;<wbr>"=20
<br>where "MyPrettyPrintedInt" is implicitly constructible from "int",=20
<br>define to_string(const MyPrettyPrintedInt &amp;) and you have your hard=
coded=20
<br>formatting that ignores any options passed into the format string. Yay!=
=20
<br>(Same holds true for Bengt's implementaiton, although it works a bit=20
<br>differently.)
<br>
<br>So from:
<br>formatter&lt;int&gt; fmt(ui_string_12345);
<br>format(fmt, i);
<br>
<br>formatter&lt;MyPrettyPrintedInt&gt; fmt(ui_string_12345);
<br>format(fmt, i);
<br>
<br>or if you need some options:
<br>format(fmt, MyPrettyPrintedInt(i, width(5), ...));
<br>
<br>But it doesn't change the fact the string doesn't control the formattin=
g=20
<br>anymore, which is bad in any scenario where the programmer is *not* in=
=20
<br>control, which is basically always the case where there are translators=
,=20
<br>writers, designers, involved who have no access to the code.
<br>
<br></blockquote></div></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_20_26019086.1390183664986--

.


Author: "=?utf-8?B?YmlsbHkub25lYWxAZ21haWwuY29t?=" <billy.oneal@gmail.com>
Date: Wed, 22 Jan 2014 23:37:55 -0800
Raw View
------=_Part_0_1390462675388
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Your "dislike" is irrelevant.

Localization is more common a requirement than is a requirement for faster =
formatting than cstdio can provide. It is far simpler to implement faster I=
O on top of features provided by a platform than it is to implement a whole=
 formatter library. I would be highly Highly surprised if 99% of such uses =
are dominated by secondary storage rather than CPU time in any case.

Things that go into the standard are those which provide the most value to =
most general purpose software; not the fastest possible implementation of s=
omething just for fastness' sake. Performance matters, but so does utility.

Sent from a touchscreen. Please excuse the brevity and tpyos.

----- Reply message -----
From: "wsdwsd" <euloanty@live.com>
To: "Billy O'Neal" <billy.oneal@gmail.com>
Subject: [std-proposals] Re: The failures of iostreams
Date: Wed, Jan 22, 2014 10:55 PM

You misunderstand my meanings.

I mean:
mofstream fout(=E2=80=9Ca.txt=E2=80=9D);
fout.printf(=E2=80=9C%=E2=80=9D,fixed_precision(3.0,1));
=3D=3D
std::unique_ptr<std::FILE,decltype(fclose)*> fp(std::fopen(=E2=80=9Ca.txt=
=E2=80=9D,=E2=80=9Dw=E2=80=9D),fclose);
fprintf(fp.get(),=E2=80=9D%.1f=E2=80=9D,3.0);



Localization is the most useless things for many programmers.
I dislike localization, for I don=E2=80=99t need it at all. For example, fo=
r Chinese characters(for I don=E2=80=99t know what is its length, maybe 2 b=
ytes, maybe 3 bytes and maybe 4 bytes), localization is almost no use.
And the localization of my country is as same as ISO. We only use the ISO u=
nits, numbers.

Just like I dislike N, J such units, they are all no reason to use at all.(=
The =E2=80=9CINCH=E2=80=9D I never use it.)
I use kg.m.s^-2 to represent N.
I use kg.m^2.s^-2 to represent J.
The reason is that these units are more easy for me to understand what it c=
onnected to and easily to be computed.
I don=E2=80=99t think localization is a must for C++, for most programmers =
truly don=E2=80=99t need.

If a programmer truly needs it, he/she can easily write it.

IO operations need efficiency. If we can=E2=80=99t give programmers enough =
high efficiency, our new io libraries will still be failure. There are alwa=
ys programmers who use native API and make C++ more difficult to learn.

Many people think C++ is slow just because the efficiency of iostream and c=
stdio.
If we can provide a high-speed io library, C++ will have a better future.
When we provide a high-speed io library without localization, without mutex=
, it will be difficult for them to be unsatisfied to C++.

Sent from Windows Mail


From: Billy O'Neal
Sent: =E2=80=8EThursday=E2=80=8E, =E2=80=8EJanuary=E2=80=8E =E2=80=8E23=E2=
=80=8E, =E2=80=8E2014 =E2=80=8E11=E2=80=8E:=E2=80=8E02=E2=80=8E =E2=80=8EAM
To: wsd wsd

That is undesirable because you can't localize the digit format. And the di=
git format certainly does change from one culture to another.

At least in your example above you would probably want



printf(fout, ....);

there would be polymorphic calls inside fout to allow someone to change whe=
re the output is actually written. For instance, in the "real" case writing=
 to a file, but for testing purposes writing to a string or memory buffer.



This way the formatting code can be completely optimized, and the relativel=
y expensive virtual call overhead only happens after a complete (or at leas=
t large chunk) of output is formatted.


Billy O'Neal
https://github.com/BillyONeal/
http://stackoverflow.com/users/82320/billy-oneal






On Wed, Jan 22, 2014 at 5:06 PM, wsdwsd <euloanty@live.com> wrote:










I am wrong about the sizes. But I still think inheritance based polymorphic=
 is a mistake.

You have seen that my scanf  doesn=E2=80=99t maintain the c-style-format.=
=20
I use



fout.printf(=E2=80=9C%=E2=80=9D,fixed_precision(3.0,1));
=3D=3D
fprintf(fout,=E2=80=9D%.1f=E2=80=9D,3.0);

The wrapper could be optimized by compilers and in fact it can be done.



Sent from Windows Mail


From: Billy O'Neal


Sent: =E2=80=8ESaturday=E2=80=8E, =E2=80=8EJanuary=E2=80=8E =E2=80=8E18=E2=
=80=8E, =E2=80=8E2014 =E2=80=8E8=E2=80=8E:=E2=80=8E58=E2=80=8E =E2=80=8EAM
To: std-proposals@isocpp.org
Cc: wsd wsd, masse.nicolas@gmail.com




I don't think a template is the way to go here. While the potential perform=
ance increase is there, I don't think that's the way we want to go for the =
"general, default" library. Real programs often have localization requireme=
nts, and if those values are burned in as template parameters you can't go =
back later and fix this by changing the string.





If someone profiles and finds that they need faster formatting and don't ne=
ed localization, they can always fall back on a specialized library / imple=
mentation.

Also take a look at .NET's Stream vs. StreamReader distinction -- and note =
that today's stringstream is similar to .NETs StringReader. e.g. they have =
2 completely separate trees which both can be overridden; at the formatted =
and unformatted IO level. (Just don't repeat their mistake where the format=
ted IO level takes ownership of the stream :) )





Billy O'Neal
https://github.com/BillyONeal/
http://stackoverflow.com/users/82320/billy-oneal








On Fri, Jan 17, 2014 at 4:36 PM, Bengt Gustafsson <bengt.gustafsson@beamway=
s.com> wrote:




I'm still working on my compilable codebase for this.


I'm however basically on the same page as you, except that I specified a Da=
taFormatter template which both contains the parameters, the parsing of the=
 parameters from string form and the actual formatting of the value of type=
 T.





This template is then specialized for each T, including, as desired, user d=
efined types.

The advantage is that as there is only one template name you can do much mo=
re within the surrounding formatter template without having to resort to us=
ing heap memory and virtual methods (which I don't).





I'm getting really close to working code but I was hit by a nasty bug, poss=
ibly a compiler bug.

I think that the two subjects of a low level stream and a formatting facili=
ty will ultimately be two different proposals, but in this stage I think we=
 need to keep the discussion in one place to see the interdependencies and =
requirements more clearly. I'm also thinking that we need an intermediate l=
evel which basically holds the locale and maybe the line ending mode, as os=
tream already has this while it seems to be unnecessary baggage for a new b=
inary file class. I think that it would be nice if this intermediate object=
 held a "formatter set" that is, a container of formatters for diferent typ=
es. It is however beyond me how to get this without introducing things that=
 slow the process down consiredably such as searching a data structure for =
a formatter for typeid(T). Maybe a template template parameter which defaul=
ts to 'DataFormatter' but that only offers compile time specialization.=20





Den l=C3=B6rdagen den 18:e januari 2014 kl. 00:52:18 UTC+1 skrev masse....@=
gmail.com:



Hi all.
For the things of parsing the format string only once, I do believe the sim=
plest solution woul be to add some classes wich are able to contains the fo=
rmatting parameters.
For example, in .Net the NumberFormatInfo class contains all the necessary =
information in order to format a number.




Then you could add a method or a ctor in order to get an object from a stri=
ng reprsentation of the format.
For example :





string format_price(double price, locale loc =3D std::locale()) //I'll expl=
ain later why I put a std::locale here=20




{
static auto format =3D std::numeric_format(".2");//say that the prices shou=
ld be formatted using 2 digits for the decimal part. Note that the formatti=
ng syntax still need to be defined




return to_string(price, format, loc);//I assume here that such an overload =
of the to_string method exists.




}



The same could be achived by doing this :





std::numeric_format get_price_format()
{
std::numeric_format format;




format.decimal_digits =3D 2;




return format;
}

string format_price(double price, locale loc =3D std::locale())




{
static auto format =3D get_price_format();




return to_string(price, format, loc);




}



Note that I separate the notion of formatting and the notion of locales on =
purpose.
The idea beyond this is that they define different things.=20




Basically:=20
- the format will defined wich part of the data should be represented (and =
how).=20
For example :=20
* the decimal part should be represented using the first 2 digit
* a date should be represented with the day-of-the-month first (represented=
 as a numeric value), the the month (using a full string representation), t=
hen the year (using 4 digit)





- the locale will define wich char or string must be used for each part.
For example :=20
* the decimal separator to be used must be a dot. ('.')
* the name of the months are the strings "january", "february", ...if you'r=
e using an english locale for example.





Now, another tought:
It seems than this topic is speaking of 2 differents things:
- Adding another way to provide iostream facilities
- Adding another way to provide formatting facilities
While those 2 are complementary, I think they are differents subject. Then =
my question is :




What about creating a new topic about formatting facilities? (and keep this=
 one for  iostream facilities)











--=20



---=20

You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.

To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.

To post to this group, send email to std-proposals@isocpp.org.

Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_0_1390462675388
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline


<html>
<head>
<meta name=3D"generator" content=3D"Windows Mail 17.5.9600.20315">
<style data-externalstyle=3D"true"><!--
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph {
margin-top:0in;
margin-right:0in;
margin-bottom:0in;
margin-left:.5in;
margin-bottom:.0001pt;
}
p.MsoNormal, li.MsoNormal, div.MsoNormal {
margin:0in;
margin-bottom:.0001pt;
}
p.MsoListParagraphCxSpFirst, li.MsoListParagraphCxSpFirst, div.MsoListParag=
raphCxSpFirst,=20
p.MsoListParagraphCxSpMiddle, li.MsoListParagraphCxSpMiddle, div.MsoListPar=
agraphCxSpMiddle,=20
p.MsoListParagraphCxSpLast, li.MsoListParagraphCxSpLast, div.MsoListParagra=
phCxSpLast {
margin-top:0in;
margin-right:0in;
margin-bottom:0in;
margin-left:.5in;
margin-bottom:.0001pt;
line-height:115%;
}
--></style></head>
<body dir=3D"ltr"><div style=3D"font-size: 12pt; font-family: Calibri,sans-=
serif;"><div>Your "dislike" is irrelevant.</div><div><br></div><div>Localiz=
ation is more common a requirement than is a requirement for faster formatt=
ing than cstdio can provide. It is far simpler to implement faster IO on to=
p of features provided by a platform than it is to implement a whole format=
ter library. I would be highly Highly surprised if 99% of such uses are dom=
inated by secondary storage rather than CPU time in any case.</div><div><br=
></div><div>Things that go into the standard are those which provide the mo=
st value to most general purpose software; not the fastest possible impleme=
ntation of something just for fastness' sake. Performance matters, but so d=
oes utility.</div><div><br></div><div>Sent from a touchscreen. Please excus=
e the brevity and tpyos.</div><br><div id=3D"htc_header">----- Reply messag=
e -----<br>From: &quot;wsdwsd&quot; &lt;euloanty@live.com&gt;<br>To: &quot;=
Billy O&#39;Neal&quot; &lt;billy.oneal@gmail.com&gt;<br>Subject: [std-propo=
sals] Re: The failures of iostreams<br>Date: Wed, Jan 22, 2014 10:55 PM</di=
v></div><br>
<div data-externalstyle=3D"false" dir=3D"ltr" style=3D"font-family: 'Calibr=
i', 'Microsoft YaHei UI', 'Segoe UI', 'Meiryo', 'Microsoft JhengHei UI', 'M=
algun Gothic', 'sans-serif';font-size:12pt;"><div style=3D"color: rgb(0, 0,=
 0);">You misunderstand my meanings.</div><div style=3D"color: rgb(0, 0, 0)=
;"><br></div><div style=3D"color: rgb(0, 0, 0);">I mean:</div><div style=3D=
"color: rgb(0, 0, 0);">mofstream fout(=E2=80=9Ca.txt=E2=80=9D);<br></div><d=
iv style=3D"color: rgb(0, 0, 0);" data-signatureblock=3D"true"><div style=
=3D"color: rgb(0, 0, 0);">fout.printf(=E2=80=9C%=E2=80=9D,fixed_precision(3=
..0,1));</div><div style=3D"color: rgb(0, 0, 0);">=3D=3D</div><div style=3D"=
color: rgb(0, 0, 0);"><div>std::unique_ptr&lt;std::FILE,decltype(fclose)*&g=
t; fp(std::fopen(=E2=80=9Ca.txt=E2=80=9D,=E2=80=9Dw=E2=80=9D),fclose);</div=
><div>fprintf(fp.get(),=E2=80=9D%.1f=E2=80=9D,3.0);</div></div></div><div s=
tyle=3D"color: rgb(0, 0, 0);" data-signatureblock=3D"true"><br></div><div s=
tyle=3D"color: rgb(0, 0, 0);" data-signatureblock=3D"true"><div style=3D"co=
lor: rgb(0, 0, 0);"><br></div><div style=3D"color: rgb(0, 0, 0);">Localizat=
ion is the most useless things for many programmers.</div><div style=3D"col=
or: rgb(0, 0, 0);">I dislike localization, for I don=E2=80=99t need it at a=
ll. For example, for Chinese characters(for I don=E2=80=99t know what is it=
s length, maybe 2 bytes, maybe 3 bytes and maybe 4 bytes), localization is =
almost&nbsp;no use.</div><div style=3D"color: rgb(0, 0, 0);">And&nbsp;the l=
ocalization of my country&nbsp;is as same as ISO. We&nbsp;only use the&nbsp=
;ISO units, numbers.</div><div style=3D"color: rgb(0, 0, 0);"><br></div><di=
v style=3D"color: rgb(0, 0, 0);">Just like I dislike&nbsp;N, J&nbsp;such un=
its, they are all no reason to use at all.(The&nbsp;=E2=80=9CINCH=E2=80=9D =
I never use it.)</div><div style=3D"color: rgb(0, 0, 0);">I use kg.m.s^-2 t=
o represent N.</div><div style=3D"color: rgb(0, 0, 0);">I use kg.m^2.s^-2 t=
o represent J.</div><div style=3D"color: rgb(0, 0, 0);">The reason is&nbsp;=
that these units are more easy for me to understand what it connected to an=
d easily to be&nbsp;computed.</div><div style=3D"color: rgb(0, 0, 0);">I do=
n=E2=80=99t think localization is a must for C++, for most programmers trul=
y don=E2=80=99t need.</div><div style=3D"color: rgb(0, 0, 0);"><br></div><d=
iv style=3D"color: rgb(0, 0, 0);">If a programmer truly needs it, he/she ca=
n easily write it.</div><div style=3D"color: rgb(0, 0, 0);"><br></div><div =
style=3D"color: rgb(0, 0, 0);">IO operations need efficiency. If we can=E2=
=80=99t give programmers enough high efficiency, our new io libraries will =
still be failure. There are always programmers who use native API and make =
C++ more difficult to learn.</div><div style=3D"color: rgb(0, 0, 0);"><br><=
/div><div style=3D"color: rgb(0, 0, 0);">Many people think C++ is slow just=
 because the efficiency of iostream and cstdio.</div><div style=3D"color: r=
gb(0, 0, 0);">If we can&nbsp;provide a high-speed io library, C++ will have=
 a better future.</div><div style=3D"color: rgb(0, 0, 0);">When&nbsp;we pro=
vide a high-speed io library without localization, without mutex, it will b=
e difficult for them to be unsatisfied&nbsp;to C++.</div><div style=3D"colo=
r: rgb(0, 0, 0);"><br></div><div style=3D"color: rgb(0, 0, 0);">Sent from W=
indows Mail</div><div style=3D"color: rgb(0, 0, 0);"><br></div></div><div s=
tyle=3D"padding-top: 5px; border-top-color: rgb(229, 229, 229); border-top-=
width: 1px; border-top-style: solid;"><div><font face=3D" 'Calibri', 'Micro=
soft YaHei UI', 'Segoe UI', 'Meiryo', 'Microsoft JhengHei UI', 'Malgun Goth=
ic', 'sans-serif'" style=3D'line-height: 15pt; letter-spacing: 0.02em; font=
-family: "Calibri", "Microsoft YaHei UI", "Segoe UI", "Meiryo", "Microsoft =
JhengHei UI", "Malgun Gothic", "sans-serif"; font-size: 12pt;'><b>From:</b>=
&nbsp;<a href=3D"mailto:billy.oneal@gmail.com" target=3D"_parent">Billy O'N=
eal</a><br><b>Sent:</b>&nbsp;=E2=80=8EThursday=E2=80=8E, =E2=80=8EJanuary=
=E2=80=8E =E2=80=8E23=E2=80=8E, =E2=80=8E2014 =E2=80=8E11=E2=80=8E:=E2=80=
=8E02=E2=80=8E =E2=80=8EAM<br><b>To:</b>&nbsp;<a href=3D"mailto:euloanty@li=
ve.com" target=3D"_parent">wsd wsd</a></font></div></div><div><br></div><di=
v dir=3D""><div dir=3D"ltr"><div>That is undesirable because you can't loca=
lize the digit format. And the digit format certainly does change from one =
culture to another.</div><div><br></div><div>At least in your example above=
 you would probably want</div>

<div><br></div><div>printf(fout, ....);</div><div><br></div><div>there woul=
d be polymorphic calls inside fout to allow someone to change where the out=
put is actually written. For instance, in the "real" case writing to a file=
, but for testing purposes writing to a string or memory buffer.</div>

<div><br></div><div>This way the formatting code can be completely optimize=
d, and the relatively expensive virtual call overhead only happens after a =
complete (or at least large chunk) of output is formatted.</div></div>
<div class=3D"gmail_extra">
<br clear=3D"all"><div><div dir=3D"ltr"><div>Billy O'Neal</div><div><a href=
=3D"https://bitbucket.org/BillyONeal/" target=3D"_parent">https://github.co=
m/BillyONeal/</a></div><div><a href=3D"http://stackoverflow.com/users/82320=
/billy-oneal" target=3D"_parent">http://stackoverflow.com/users/82320/billy=
-oneal</a></div>

</div></div>
<br><br><div class=3D"gmail_quote">On Wed, Jan 22, 2014 at 5:06 PM, wsdwsd =
<span dir=3D"ltr">&lt;<a href=3D"mailto:euloanty@live.com" target=3D"_paren=
t">euloanty@live.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_qu=
ote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-col=
or: rgb(204, 204, 204); border-left-width: 1px; border-left-style: solid;">






<div dir=3D"ltr">
<div style=3D'font-family: "Calibri","Microsoft YaHei UI","Segoe UI","Meiry=
o","Microsoft JhengHei UI","Malgun Gothic","sans-serif"; font-size: 12pt;' =
dir=3D"ltr">

<div>I am wrong about the sizes. But I still think inheritance based polymo=
rphic is a mistake.</div><div><br></div><div>You have seen that my scanf&nb=
sp; doesn=E2=80=99t maintain the c-style-format. </div><div>I use</div><div=
><br></div>

<div>fout.printf(=E2=80=9C%=E2=80=9D,fixed_precision(3.0,1));<br></div><div=
><div>=3D=3D</div><div>fprintf(fout,=E2=80=9D%.1f=E2=80=9D,3.0);</div><div>=
<br></div><div>The wrapper could be optimized by compilers and in fact&nbsp=
;it can be done.</div><div><br></div>

<div>Sent from Windows Mail</div><div><br></div></div><div style=3D"padding=
-top: 5px; border-top-color: rgb(229, 229, 229); border-top-width: 1px; bor=
der-top-style: solid;"><div><font face=3D" 'Calibri', 'Microsoft YaHei UI',=
 'Segoe UI', 'Meiryo', 'Microsoft JhengHei UI', 'Malgun Gothic', 'sans-seri=
f'" style=3D'line-height: 15pt; letter-spacing: 0.02em; font-family: "Calib=
ri","Microsoft YaHei UI","Segoe UI","Meiryo","Microsoft JhengHei UI","Malgu=
n Gothic","sans-serif"; font-size: 12pt;'><b>From:</b>&nbsp;<a href=3D"mail=
to:billy.oneal@gmail.com" target=3D"_parent">Billy O'Neal</a><br>

<b>Sent:</b>&nbsp;=E2=80=8ESaturday=E2=80=8E, =E2=80=8EJanuary=E2=80=8E =E2=
=80=8E18=E2=80=8E, =E2=80=8E2014 =E2=80=8E8=E2=80=8E:=E2=80=8E58=E2=80=8E =
=E2=80=8EAM<br><b>To:</b>&nbsp;<a href=3D"mailto:std-proposals@isocpp.org" =
target=3D"_parent">std-proposals@isocpp.org</a><br><b>Cc:</b>&nbsp;<a href=
=3D"mailto:euloanty@live.com" target=3D"_parent">wsd wsd</a>, <a href=3D"ma=
ilto:masse.nicolas@gmail.com" target=3D"_parent">masse.nicolas@gmail.com</a=
></font></div>

</div><div><br></div><div dir=3D""><div dir=3D"ltr"><div>I don't think a te=
mplate is the way to go here. While the potential performance increase is t=
here, I don't think that's the way we want to go for the "general, default"=
 library. Real programs often have localization requirements, and if those =
values are burned in as template parameters you can't go back later and fix=
 this by changing the string.</div>



<div><br></div><div>If someone profiles and finds that they need faster for=
matting and don't need localization, they can always fall back on a special=
ized library / implementation.</div><div><br></div><div>Also take a look at=
 .NET's Stream vs. StreamReader distinction -- and note that today's string=
stream is similar to .NETs StringReader. e.g. they have 2 completely separa=
te trees which both can be overridden; at the formatted and unformatted IO =
level. (Just don't repeat their mistake where the formatted IO level takes =
ownership of the stream :) )</div>



</div><div class=3D"gmail_extra"><br clear=3D"all"><div><div dir=3D"ltr"><d=
iv>Billy O'Neal</div><div><a href=3D"https://bitbucket.org/BillyONeal/" tar=
get=3D"_parent">https://github.com/BillyONeal/</a></div><div><a href=3D"htt=
p://stackoverflow.com/users/82320/billy-oneal" target=3D"_parent">http://st=
ackoverflow.com/users/82320/billy-oneal</a></div>



</div></div>
<br><br><div class=3D"gmail_quote">On Fri, Jan 17, 2014 at 4:36 PM, Bengt G=
ustafsson <span dir=3D"ltr">&lt;<a href=3D"mailto:bengt.gustafsson@beamways=
..com" target=3D"_parent">bengt.gustafsson@beamways.com</a>&gt;</span> wrote=
:<br>



<blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; paddi=
ng-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px=
; border-left-style: solid;"><div dir=3D"ltr">I'm still working on my compi=
lable codebase for this.<div>

<br></div><div>I'm however basically on the same page as you, except that I=
 specified a DataFormatter template which both contains the parameters, the=
 parsing of the parameters from string form and the actual formatting of th=
e value of type T.</div>



<div><br></div><div>This template is then specialized for each T, including=
, as desired, user defined types.</div><div><br></div><div>The advantage is=
 that as there is only one template name you can do much more within the su=
rrounding formatter template without having to resort to using heap memory =
and virtual methods (which I don't).</div>



<div><br></div><div>I'm getting really close to working code but I was hit =
by a nasty bug, possibly a compiler bug.</div><div><br></div><div>I think t=
hat the two subjects of a low level stream and a formatting facility will u=
ltimately be two different proposals, but in this stage I think we need to =
keep the discussion in one place to see the interdependencies and requireme=
nts more clearly. I'm also thinking that we need an intermediate level whic=
h basically holds the locale and maybe the line ending mode, as ostream alr=
eady has this while it seems to be unnecessary baggage for a new binary fil=
e class. I think that it would be nice if this intermediate object held a "=
formatter set" that is, a container of formatters for diferent types. It is=
 however beyond me how to get this without introducing things that slow the=
 process down consiredably such as searching a data structure for a formatt=
er for typeid(T). Maybe a template template parameter which defaults to 'Da=
taFormatter' but that only offers compile time specialization.&nbsp;</div>



<div><div><br>Den l=C3=B6rdagen den 18:e januari 2014 kl. 00:52:18 UTC+1 sk=
rev <a href=3D"mailto:masse....@gmail.com" target=3D"_parent">masse....@gma=
il.com</a>:<div><div><blockquote class=3D"gmail_quote" style=3D"margin: 0px=
 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); b=
order-left-width: 1px; border-left-style: solid;">



<div dir=3D"ltr">Hi all.<br>For the things of parsing the format string onl=
y once, I do believe the simplest solution woul be to add some classes wich=
 are able to contains the formatting parameters.<br>For example, in .Net th=
e <a href=3D"http://msdn.microsoft.com/fr-fr/library/system.globalization.n=
umberformatinfo.numberformatinfo%28v=3Dvs.110%29.aspx" target=3D"_parent">N=
umberFormatInfo</a> class contains all the necessary information in order t=
o format a number.<br>



Then you could add a method or a ctor in order to get an object from a stri=
ng reprsentation of the format.<br>For example :<br><div style=3D"border: 1=
px solid rgb(187, 187, 187); border-image: none; background-color: rgb(250,=
 250, 250);"><code><div><span><br>



</span><span style=3D"color: rgb(0, 0, 136);">string</span><span> format_pr=
ice</span><span style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"c=
olor: rgb(0, 0, 136);">double</span><span> price</span><span style=3D"color=
: rgb(102, 102, 0);">,</span><span> locale loc </span><span style=3D"color:=
 rgb(102, 102, 0);">=3D</span><span> std</span><span style=3D"color: rgb(10=
2, 102, 0);">::</span><span>locale</span><span style=3D"color: rgb(102, 102=
, 0);">())</span><span> </span><span style=3D"color: rgb(136, 0, 0);">//I'l=
l explain later why I put a std::locale here </span><span><br>



</span><span style=3D"color: rgb(102, 102, 0);">{</span><span><br>&nbsp; &n=
bsp; </span><span style=3D"color: rgb(0, 0, 136);">static</span><span> </sp=
an><span style=3D"color: rgb(0, 0, 136);">auto</span><span> format </span><=
span style=3D"color: rgb(102, 102, 0);">=3D</span><span> std</span><span st=
yle=3D"color: rgb(102, 102, 0);">::</span><span>numeric_format</span><span =
style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 136=
, 0);">".2"</span><span style=3D"color: rgb(102, 102, 0);">);</span><span s=
tyle=3D"color: rgb(136, 0, 0);">//<u></u>say that the prices should be form=
atted using 2 digits for the decimal part. Note that the formatting syntax =
still need to be defined</span><span><br>



&nbsp; &nbsp; </span><span style=3D"color: rgb(0, 0, 136);">return</span><s=
pan> to_string</span><span style=3D"color: rgb(102, 102, 0);">(</span><span=
>price</span><span style=3D"color: rgb(102, 102, 0);">,</span><span> format=
</span><span style=3D"color: rgb(102, 102, 0);">,</span><span> loc</span><s=
pan style=3D"color: rgb(102, 102, 0);">);</span><span style=3D"color: rgb(1=
36, 0, 0);">//I assume here that such an overload of the to_string method e=
xists.</span><span><br>



</span><span style=3D"color: rgb(102, 102, 0);">}</span><span><br></span></=
div></code></div><br>The same could be achived by doing this :<br><br><div =
style=3D"border: 1px solid rgb(187, 187, 187); border-image: none; backgrou=
nd-color: rgb(250, 250, 250);">


<code><div>
<span>std</span><span style=3D"color: rgb(102, 102, 0);">::</span><span>num=
eric_format get_price_format</span><span style=3D"color: rgb(102, 102, 0);"=
>()</span><span><br></span><span style=3D"color: rgb(102, 102, 0);">{</span=
><span><br>&nbsp; &nbsp; std</span><span style=3D"color: rgb(102, 102, 0);"=
>::</span><span>numeric_format format</span><span style=3D"color: rgb(102, =
102, 0);">;</span><span><br>



&nbsp; &nbsp; format</span><span style=3D"color: rgb(102, 102, 0);">.</span=
><span>decimal_digits </span><span style=3D"color: rgb(102, 102, 0);">=3D</=
span><span> </span><span style=3D"color: rgb(0, 102, 102);">2</span><span s=
tyle=3D"color: rgb(102, 102, 0);">;</span><span><br>



&nbsp; &nbsp; </span><span style=3D"color: rgb(0, 0, 136);">return</span><s=
pan> format</span><span style=3D"color: rgb(102, 102, 0);">;</span><span><b=
r></span><span style=3D"color: rgb(102, 102, 0);">}</span><span><br><br></s=
pan><span style=3D"color: rgb(0, 0, 136);">string</span><span> format_price=
</span><span style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"colo=
r: rgb(0, 0, 136);">double</span><span> price</span><span style=3D"color: r=
gb(102, 102, 0);">,</span><span> locale loc </span><span style=3D"color: rg=
b(102, 102, 0);">=3D</span><span> std</span><span style=3D"color: rgb(102, =
102, 0);">::</span><span>locale</span><span style=3D"color: rgb(102, 102, 0=
);">())</span><span><br>



</span><span style=3D"color: rgb(102, 102, 0);">{</span><span><br>&nbsp; &n=
bsp; </span><span style=3D"color: rgb(0, 0, 136);">static</span><span> </sp=
an><span style=3D"color: rgb(0, 0, 136);">auto</span><span> format </span><=
span style=3D"color: rgb(102, 102, 0);">=3D</span><span> get_price_format</=
span><span style=3D"color: rgb(102, 102, 0);">();</span><span><br>



&nbsp; &nbsp; </span><span style=3D"color: rgb(0, 0, 136);">return</span><s=
pan> to_string</span><span style=3D"color: rgb(102, 102, 0);">(</span><span=
>price</span><span style=3D"color: rgb(102, 102, 0);">,</span><span> format=
</span><span style=3D"color: rgb(102, 102, 0);">,</span><span> loc</span><s=
pan style=3D"color: rgb(102, 102, 0);">);</span><span><br>



</span><span style=3D"color: rgb(102, 102, 0);">}</span><span><br></span></=
div></code></div><br>Note that I separate the notion of formatting and the =
notion of locales on purpose.<br>The idea beyond this is that they define d=
ifferent things. <br>



Basically: <br>- the format will defined wich part of the data should be re=
presented (and how). <br>&nbsp; For example : <br>&nbsp;&nbsp;&nbsp; * the =
decimal part should be represented using the first 2 digit<br>&nbsp;&nbsp;&=
nbsp; * a date should be represented with the day-of-the-month first (repre=
sented as a numeric value), the the month (using a full string representati=
on), then the year (using 4 digit)<br>



<br>- the locale will define wich char or string must be used for each part=
..<br>&nbsp; For example : <br>&nbsp;&nbsp;&nbsp; * the decimal separator to=
 be used must be a dot. ('.')<br>&nbsp;&nbsp;&nbsp; * the name of the month=
s are the strings "january", "february", ...if you're using an english loca=
le for example.<br>



<br>Now, another tought:<br>It seems than this topic is speaking of 2 diffe=
rents things:<br>- Adding another way to provide iostream facilities<br>- A=
dding another way to provide formatting facilities<br>While those 2 are com=
plementary, I think they are differents subject. Then my question is :<br>



What about creating a new topic about formatting facilities? (and keep this=
 one for  iostream facilities)<span class=3D"HOEnZb"><font color=3D"#888888=
"><br><br></font></span></div></blockquote></div></div></div></div></div><s=
pan class=3D"HOEnZb"><font color=3D"#888888"><div>

<div>

<p></p>

-- <br>
&nbsp;<br>
--- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org" target=3D=
"_parent">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_parent">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_parent">http://groups.google.com/a/isocpp.org/gr=
oup/std-proposals/</a>.<br>
</div></div></font></span></blockquote></div><br></div>
</div></div>
</div>

</blockquote></div><br></div>
</div></div>
</body>
</html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_0_1390462675388--


.


Author: Miro Knejp <miro@knejp.de>
Date: Thu, 23 Jan 2014 11:01:09 +0100
Raw View
This is a multi-part message in MIME format.
--------------000809080609010301000109
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable


Am 23.01.2014 08:37, schrieb billy.oneal@gmail.com:
> Your "dislike" is irrelevant.
>
> Localization is more common a requirement than is a requirement for=20
> faster formatting than cstdio can provide. It is far simpler to=20
> implement faster IO on top of features provided by a platform than it=20
> is to implement a whole formatter library. I would be highly Highly=20
> surprised if 99% of such uses are dominated by secondary storage=20
> rather than CPU time in any case.
>
> Things that go into the standard are those which provide the most=20
> value to most general purpose software; not the fastest possible=20
> implementation of something just for fastness' sake. Performance=20
> matters, but so does utility.
>
> Sent from a touchscreen. Please excuse the brevity and tpyos.
>
> ----- Reply message -----
> From: "wsdwsd" <euloanty@live.com>
> To: "Billy O'Neal" <billy.oneal@gmail.com>
> Subject: [std-proposals] Re: The failures of iostreams
> Date: Wed, Jan 22, 2014 10:55 PM
>
> You misunderstand my meanings.
>
> I mean:
> mofstream fout(=E2=80=9Ca.txt=E2=80=9D);
> fout.printf(=E2=80=9C%=E2=80=9D,fixed_precision(3.0,1));
> =3D=3D
> std::unique_ptr<std::FILE,decltype(fclose)*>=20
> fp(std::fopen(=E2=80=9Ca.txt=E2=80=9D,=E2=80=9Dw=E2=80=9D),fclose);
> fprintf(fp.get(),=E2=80=9D%.1f=E2=80=9D,3.0);
My design currently allows this use case, too. My idea (among many many=20
others) is to have a type that represents the whole set of formatting=20
options ostreams currently have and overload the iostream manipulators=20
to build such structs. It's originally meant for easier migration and=20
for people to re-use whatever whatever the syntaax is going to be for=20
the standard arithmetic types. This would allow use patterns like the=20
following in scenarios where the formatting is to be hardcoded and=20
format options aren't cared about:

format("{0}: {1}", scientific(precision(3, f)), hex(width(8, f)));

And there would be to_string overloads in the style of
to_string(ostream_format_options<T>& x, /* other stuff*/)

Compared to the flexible version that can be used by external people to=20
control output and is not hardcoded:
format("{0:e.3}: {1:x.8}"); // Syntax is for exposition only

I hope this makes sense, although this is still conceptual the current=20
state of my implementation already supports such a use case, so I hope=20
this is a good demonstration of it's flexibility. And it all happens=20
without virtual calls (not in the formatting, but the output probably=20
has virtuals).

> Localization is the most useless things for many programmers.
> I dislike localization, for I don=E2=80=99t need it at all. For example, =
for=20
> Chinese characters(for I don=E2=80=99t know what is its length, maybe 2 b=
ytes,=20
> maybe 3 bytes and maybe 4 bytes), localization is almost no use.
>
So is probably chi_squared_distribution or lgamma, but we still have it.=20
Don't project your own line of work on the entirety of all C++=20
programemrs out there.
>
> If a programmer truly needs it, he/she can easily write it.
Localization is among the most difficult and complicated things to do.=20
So many rules and so may violations to the same rules. Just look at how=20
big the average i18n framework is. This discussion isn't about providing=20
an i18n framework to the standard but about a printf()/ostream=20
substitution that makes it much, *much* easier to provide one on top of=20
later.
>
> IO operations need efficiency. If we can=E2=80=99t give programmers enoug=
h=20
> high efficiency, our new io libraries will still be failure. There are=20
> always programmers who use native API and make C++ more difficult to=20
> learn.
I would really like to see some numbers. Is the typical iostream use=20
case I/O or CPU bound?
>
> Many people think C++ is slow just because the efficiency of iostream=20
> and cstdio.
> If we can provide a high-speed io library, C++ will have a better future.
> When we provide a high-speed io library without localization, without=20
> mutex, it will be difficult for them to be unsatisfied to C++.
>
> Sent from Windows Mail
>
> *From:* Billy O'Neal <mailto:billy.oneal@gmail.com>
> *Sent:* =E2=80=8EThursday=E2=80=8E, =E2=80=8EJanuary=E2=80=8E =E2=80=8E23=
=E2=80=8E, =E2=80=8E2014 =E2=80=8E11=E2=80=8E:=E2=80=8E02=E2=80=8E =E2=80=
=8EAM
> *To:* wsd wsd <mailto:euloanty@live.com>
>
> That is undesirable because you can't localize the digit format. And=20
> the digit format certainly does change from one culture to another.
>
> At least in your example above you would probably want
>
> printf(fout, ....);
>
> there would be polymorphic calls inside fout to allow someone to=20
> change where the output is actually written. For instance, in the=20
> "real" case writing to a file, but for testing purposes writing to a=20
> string or memory buffer.
>
> This way the formatting code can be completely optimized, and the=20
> relatively expensive virtual call overhead only happens after a=20
> complete (or at least large chunk) of output is formatted.
Last time I checked libc++ stringbuf and filebuf do not override=20
streambuf's sputn() method meaning it is implemented as a loop over the=20
virtual sputc(). This is probably to be regarded as a QoI thing, though.=20
If the compiler cannot apply devirtualization this might be a=20
significant hit. But maybe this has changed in the meanwhile.

Regardless, because block writes are a thing and may potentially be more=20
efficient, I am currently using a "format_appender" type in my=20
implementation that has only appending methods and can do block-writes=20
if the underlying sink type supports it (i.e. it is not an=20
OuputIterator) - and also to act as tag type. There are specializations=20
for streambuf (using sputn()) and basic_string (using append()) and any=20
ForwardIterator or begin/end range (the latter with overflow=20
prevention). I want to emphasize that I have not done anything amongst=20
the "bytestream" aspect of this thread and am currently only focusing on=20
the formatting part.

I'm still actively working on this, but documentation is rather lacking=20
right now so I plan to write something up during the weekend on the=20
github wiki.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--------------000809080609010301000109
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<html>
  <head>
    <meta content=3D"text/html; charset=3DUTF-8" http-equiv=3D"Content-Type=
">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    <br>
    <div class=3D"moz-cite-prefix">Am 23.01.2014 08:37, schrieb
      <a class=3D"moz-txt-link-abbreviated" href=3D"mailto:billy.oneal@gmai=
l.com">billy.oneal@gmail.com</a>:<br>
    </div>
    <blockquote cite=3D"mid:52e0c6d4.ca3dec0a.3716.3bdb@mx.google.com"
      type=3D"cite">
      <meta name=3D"generator" content=3D"Windows Mail 17.5.9600.20315">
      <style data-externalstyle=3D"true"><!--
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph {
margin-top:0in;
margin-right:0in;
margin-bottom:0in;
margin-left:.5in;
margin-bottom:.0001pt;
}
p.MsoNormal, li.MsoNormal, div.MsoNormal {
margin:0in;
margin-bottom:.0001pt;
}
p.MsoListParagraphCxSpFirst, li.MsoListParagraphCxSpFirst, div.MsoListParag=
raphCxSpFirst,=20
p.MsoListParagraphCxSpMiddle, li.MsoListParagraphCxSpMiddle, div.MsoListPar=
agraphCxSpMiddle,=20
p.MsoListParagraphCxSpLast, li.MsoListParagraphCxSpLast, div.MsoListParagra=
phCxSpLast {
margin-top:0in;
margin-right:0in;
margin-bottom:0in;
margin-left:.5in;
margin-bottom:.0001pt;
line-height:115%;
}
--></style>
      <div style=3D"font-size: 12pt; font-family: Calibri,sans-serif;">
        <div>Your "dislike" is irrelevant.</div>
        <div><br>
        </div>
        <div>Localization is more common a requirement than is a
          requirement for faster formatting than cstdio can provide. It
          is far simpler to implement faster IO on top of features
          provided by a platform than it is to implement a whole
          formatter library. I would be highly Highly surprised if 99%
          of such uses are dominated by secondary storage rather than
          CPU time in any case.</div>
        <div><br>
        </div>
        <div>Things that go into the standard are those which provide
          the most value to most general purpose software; not the
          fastest possible implementation of something just for
          fastness' sake. Performance matters, but so does utility.</div>
        <div><br>
        </div>
        <div>Sent from a touchscreen. Please excuse the brevity and
          tpyos.</div>
        <br>
        <div id=3D"htc_header">----- Reply message -----<br>
          From: "wsdwsd" <a class=3D"moz-txt-link-rfc2396E" href=3D"mailto:=
euloanty@live.com">&lt;euloanty@live.com&gt;</a><br>
          To: "Billy O'Neal" <a class=3D"moz-txt-link-rfc2396E" href=3D"mai=
lto:billy.oneal@gmail.com">&lt;billy.oneal@gmail.com&gt;</a><br>
          Subject: [std-proposals] Re: The failures of iostreams<br>
          Date: Wed, Jan 22, 2014 10:55 PM</div>
      </div>
      <br>
      <div data-externalstyle=3D"false" dir=3D"ltr" style=3D"font-family:
        'Calibri', 'Microsoft YaHei UI', 'Segoe UI', 'Meiryo',
        'Microsoft JhengHei UI', 'Malgun Gothic',
        'sans-serif';font-size:12pt;">
        <div style=3D"color: rgb(0, 0, 0);">You misunderstand my meanings.<=
/div>
        <div style=3D"color: rgb(0, 0, 0);"><br>
        </div>
        <div style=3D"color: rgb(0, 0, 0);">I mean:</div>
        <div style=3D"color: rgb(0, 0, 0);">mofstream fout(=E2=80=9Ca.txt=
=E2=80=9D);<br>
        </div>
        <div style=3D"color: rgb(0, 0, 0);" data-signatureblock=3D"true">
          <div style=3D"color: rgb(0, 0, 0);">fout.printf(=E2=80=9C%=E2=80=
=9D,fixed_precision(3.0,1));</div>
          <div style=3D"color: rgb(0, 0, 0);">=3D=3D</div>
          <div style=3D"color: rgb(0, 0, 0);">
            <div>std::unique_ptr&lt;std::FILE,decltype(fclose)*&gt;
              fp(std::fopen(=E2=80=9Ca.txt=E2=80=9D,=E2=80=9Dw=E2=80=9D),fc=
lose);</div>
            <div>fprintf(fp.get(),=E2=80=9D%.1f=E2=80=9D,3.0);</div>
          </div>
        </div>
      </div>
    </blockquote>
    My design currently allows this use case, too. My idea (among many
    many others) is to have a type that represents the whole set of
    formatting options ostreams currently have and overload the iostream
    manipulators to build such structs. It's originally meant for easier
    migration and for people to re-use whatever whatever the syntaax is
    going to be for the standard arithmetic types. This would allow use
    patterns like the following in scenarios where the formatting is to
    be hardcoded and format options aren't cared about:<br>
    <br>
    format("{0}: {1}", scientific(precision(3, f)), hex(width(8, f)));<br>
    <br>
    And there would be to_string overloads in the style of<br>
    to_string(ostream_format_options&lt;T&gt;&amp; x, /* other stuff*/)<br>
    <br>
    Compared to the flexible version that can be used by external people
    to control output and is not hardcoded:<br>
    format("{0:e.3}: {1:x.8}"); // Syntax is for exposition only<br>
    <br>
    I hope this makes sense, although this is still conceptual the
    current state of my implementation already supports such a use case,
    so I hope this is a good demonstration of it's flexibility. And it
    all happens without virtual calls (not in the formatting, but the
    output probably has virtuals).<br>
    <br>
    <blockquote cite=3D"mid:52e0c6d4.ca3dec0a.3716.3bdb@mx.google.com"
      type=3D"cite">
      <div data-externalstyle=3D"false" dir=3D"ltr" style=3D"font-family:
        'Calibri', 'Microsoft YaHei UI', 'Segoe UI', 'Meiryo',
        'Microsoft JhengHei UI', 'Malgun Gothic',
        'sans-serif';font-size:12pt;">
        <div style=3D"color: rgb(0, 0, 0);" data-signatureblock=3D"true">
          <div style=3D"color: rgb(0, 0, 0);">Localization is the most
            useless things for many programmers.</div>
          <div style=3D"color: rgb(0, 0, 0);">I dislike localization, for
            I don=E2=80=99t need it at all. For example, for Chinese
            characters(for I don=E2=80=99t know what is its length, maybe 2
            bytes, maybe 3 bytes and maybe 4 bytes), localization is
            almost=C2=A0no use.</div>
        </div>
        <div style=3D"color: rgb(0, 0, 0);" data-signatureblock=3D"true">
          <div style=3D"color: rgb(0, 0, 0);"><br>
          </div>
        </div>
      </div>
    </blockquote>
    So is probably chi_squared_distribution or lgamma, but we still have
    it. Don't project your own line of work on the entirety of all C++
    programemrs out there.<br>
    <blockquote cite=3D"mid:52e0c6d4.ca3dec0a.3716.3bdb@mx.google.com"
      type=3D"cite">
      <div data-externalstyle=3D"false" dir=3D"ltr" style=3D"font-family:
        'Calibri', 'Microsoft YaHei UI', 'Segoe UI', 'Meiryo',
        'Microsoft JhengHei UI', 'Malgun Gothic',
        'sans-serif';font-size:12pt;">
        <div style=3D"color: rgb(0, 0, 0);" data-signatureblock=3D"true"><b=
r>
          <div style=3D"color: rgb(0, 0, 0);">If a programmer truly needs
            it, he/she can easily write it.</div>
        </div>
      </div>
    </blockquote>
    Localization is among the most difficult and complicated things to
    do. So many rules and so may violations to the same rules. Just look
    at how big the average i18n framework is. This discussion isn't
    about providing an i18n framework to the standard but about a
    printf()/ostream substitution that makes it much, *much* easier to
    provide one on top of later.<br>
    <blockquote cite=3D"mid:52e0c6d4.ca3dec0a.3716.3bdb@mx.google.com"
      type=3D"cite">
      <div data-externalstyle=3D"false" dir=3D"ltr" style=3D"font-family:
        'Calibri', 'Microsoft YaHei UI', 'Segoe UI', 'Meiryo',
        'Microsoft JhengHei UI', 'Malgun Gothic',
        'sans-serif';font-size:12pt;">
        <div style=3D"color: rgb(0, 0, 0);" data-signatureblock=3D"true">
          <div style=3D"color: rgb(0, 0, 0);"><br>
          </div>
          <div style=3D"color: rgb(0, 0, 0);">IO operations need
            efficiency. If we can=E2=80=99t give programmers enough high
            efficiency, our new io libraries will still be failure.
            There are always programmers who use native API and make C++
            more difficult to learn.</div>
        </div>
      </div>
    </blockquote>
    I would really like to see some numbers. Is the typical iostream use
    case I/O or CPU bound?<br>
    <blockquote cite=3D"mid:52e0c6d4.ca3dec0a.3716.3bdb@mx.google.com"
      type=3D"cite">
      <div data-externalstyle=3D"false" dir=3D"ltr" style=3D"font-family:
        'Calibri', 'Microsoft YaHei UI', 'Segoe UI', 'Meiryo',
        'Microsoft JhengHei UI', 'Malgun Gothic',
        'sans-serif';font-size:12pt;">
        <div style=3D"color: rgb(0, 0, 0);" data-signatureblock=3D"true">
          <div style=3D"color: rgb(0, 0, 0);"><br>
          </div>
          <div style=3D"color: rgb(0, 0, 0);">Many people think C++ is
            slow just because the efficiency of iostream and cstdio.</div>
          <div style=3D"color: rgb(0, 0, 0);">If we can=C2=A0provide a
            high-speed io library, C++ will have a better future.</div>
          <div style=3D"color: rgb(0, 0, 0);">When=C2=A0we provide a high-s=
peed
            io library without localization, without mutex, it will be
            difficult for them to be unsatisfied=C2=A0to C++.</div>
          <div style=3D"color: rgb(0, 0, 0);"><br>
          </div>
          <div style=3D"color: rgb(0, 0, 0);">Sent from Windows Mail</div>
          <div style=3D"color: rgb(0, 0, 0);"><br>
          </div>
        </div>
        <div style=3D"padding-top: 5px; border-top-color: rgb(229, 229,
          229); border-top-width: 1px; border-top-style: solid;">
          <div><font style=3D"line-height: 15pt; letter-spacing: 0.02em;
              font-family: &quot;Calibri&quot;, &quot;Microsoft YaHei
              UI&quot;, &quot;Segoe UI&quot;, &quot;Meiryo&quot;,
              &quot;Microsoft JhengHei UI&quot;, &quot;Malgun
              Gothic&quot;, &quot;sans-serif&quot;; font-size: 12pt;"
              face=3D" 'Calibri', 'Microsoft YaHei UI', 'Segoe UI',
              'Meiryo', 'Microsoft JhengHei UI', 'Malgun Gothic',
              'sans-serif'"><b>From:</b>=C2=A0<a moz-do-not-send=3D"true"
                href=3D"mailto:billy.oneal@gmail.com" target=3D"_parent">Bi=
lly
                O'Neal</a><br>
              <b>Sent:</b>=C2=A0=E2=80=8EThursday=E2=80=8E, =E2=80=8EJanuar=
y=E2=80=8E =E2=80=8E23=E2=80=8E, =E2=80=8E2014 =E2=80=8E11=E2=80=8E:=E2=80=
=8E02=E2=80=8E
              =E2=80=8EAM<br>
              <b>To:</b>=C2=A0<a moz-do-not-send=3D"true"
                href=3D"mailto:euloanty@live.com" target=3D"_parent">wsd ws=
d</a></font></div>
        </div>
        <div><br>
        </div>
        <div dir=3D"">
          <div dir=3D"ltr">That is undesirable because you can't localize
            the digit format. And the digit format certainly does change
            from one culture to another.
            <div><br>
            </div>
            <div>At least in your example above you would probably want</di=
v>
            <div><br>
            </div>
            <div>printf(fout, ....);</div>
            <div><br>
            </div>
            <div>there would be polymorphic calls inside fout to allow
              someone to change where the output is actually written.
              For instance, in the "real" case writing to a file, but
              for testing purposes writing to a string or memory buffer.</d=
iv>
            <div><br>
            </div>
            <div>This way the formatting code can be completely
              optimized, and the relatively expensive virtual call
              overhead only happens after a complete (or at least large
              chunk) of output is formatted.</div>
          </div>
        </div>
      </div>
    </blockquote>
    Last time I checked libc++ stringbuf and filebuf do not override
    streambuf's sputn() method meaning it is implemented as a loop over
    the virtual sputc(). This is probably to be regarded as a QoI thing,
    though. If the compiler cannot apply devirtualization this might be
    a significant hit. But maybe this has changed in the meanwhile.<br>
    <br>
    Regardless, because block writes are a thing and may potentially be
    more efficient, I am currently using a "format_appender" type in my
    implementation that has only appending methods and can do
    block-writes if the underlying sink type supports it (i.e. it is not
    an OuputIterator) - and also to act as tag type. There are
    specializations for streambuf (using sputn()) and basic_string
    (using append()) and any ForwardIterator or begin/end range (the
    latter with overflow prevention). I want to emphasize that I have
    not done anything amongst the "bytestream" aspect of this thread and
    am currently only focusing on the formatting part.<br>
    <br>
    I'm still actively working on this, but documentation is rather
    lacking right now so I plan to write something up during the weekend
    on the github wiki.<br>
    <br>
  </body>
</html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--------------000809080609010301000109--


.


Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Thu, 23 Jan 2014 09:26:23 -0800
Raw View
--047d7b472816c3746904f0a68c34
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

> cstdio is too slow and difficult to use.

Yes, it is difficult to use. It really isn't all that slow. Of course the
speed you get will depend entirely on your particular standard library
implementation.

> Efficiency is the root of C++. C++ is made for efficiency.
If we don=E2=80=99t need efficiency, then why we use computers?

Efficiency is a big part, yes. But it is not the only part. It matters not
how fast your program is if it produces wrong answers.

> Compared to the flexible version that can be used by external people to
control output and is not hardcoded:
format("{0:e.3}: {1:x.8}"); // Syntax is for exposition only

Sounds good to me. What happens if the format string and what the
programmer has set disagree? Fast Format gets around this by having
completely separate APIs; write and format.

> I would really like to see some numbers. Is the typical iostream use case
I/O or CPU bound?

This is what I said cstdio. IOStream is notoriously slow because it incurs
virtual call overhead for relatively small chunks of IO. Moreover, to my
understanding, the built in codecvt facet system converts characters one at
a time between encodings, which is 1. often wrong, and 2. often very
inefficient.

If we want to actually do IO quickly we would need to look into
asynchronous systems. Right now iostreams has no asynchronous IO facility
despite this often being a far more efficient way to do IO.

> I want to emphasize that I have not done anything amongst the
"bytestream" aspect of this thread and am currently only focusing on the
formatting part.

That's probably the right spot for now.

Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal


On Wed, Jan 22, 2014 at 11:46 PM, wsdwsd <euloanty@live.com> wrote:

>  cstdio is too slow and difficult to use.
> It=E2=80=99s 10 times slower than handwriting.
>
> how can I read size_t by using cstdio?
>
> %zu? not be supported..
> %u? wrong
> %llu? wrong.
> So cstdio is also a big failure.
>
> I think our actions are to make programmers not to use native API
> and so-called low-level.
>
> Efficiency is the root of C++. C++ is made for efficiency.
> If we don=E2=80=99t need efficiency, then why we use computers?
>
> Sent from Windows Mail
>
> *From:* Billy O'Neal <billy.oneal@gmail.com>
> *Sent:* =E2=80=8EThursday=E2=80=8E, =E2=80=8EJanuary=E2=80=8E =E2=80=8E23=
=E2=80=8E, =E2=80=8E2014 =E2=80=8E3=E2=80=8E:=E2=80=8E37=E2=80=8E =E2=80=8E=
PM
> *To:* wsd wsd <euloanty@live.com>, std-proposals@isocpp.org
>
> Your "dislike" is irrelevant.
>
> Localization is more common a requirement than is a requirement for faste=
r
> formatting than cstdio can provide. It is far simpler to implement faster
> IO on top of features provided by a platform than it is to implement a
> whole formatter library. I would be highly Highly surprised if 99% of suc=
h
> uses are dominated by secondary storage rather than CPU time in any case.
>
> Things that go into the standard are those which provide the most value t=
o
> most general purpose software; not the fastest possible implementation of
> something just for fastness' sake. Performance matters, but so does utili=
ty.
>
> Sent from a touchscreen. Please excuse the brevity and tpyos.
>
> ----- Reply message -----
> From: "wsdwsd" <euloanty@live.com>
> To: "Billy O'Neal" <billy.oneal@gmail.com>
> Subject: [std-proposals] Re: The failures of iostreams
> Date: Wed, Jan 22, 2014 10:55 PM
>
> You misunderstand my meanings.
>
> I mean:
> mofstream fout(=E2=80=9Ca.txt=E2=80=9D);
> fout.printf(=E2=80=9C%=E2=80=9D,fixed_precision(3.0,1));
> =3D=3D
> std::unique_ptr<std::FILE,decltype(fclose)*>
> fp(std::fopen(=E2=80=9Ca.txt=E2=80=9D,=E2=80=9Dw=E2=80=9D),fclose);
> fprintf(fp.get(),=E2=80=9D%.1f=E2=80=9D,3.0);
>
>
> Localization is the most useless things for many programmers.
> I dislike localization, for I don=E2=80=99t need it at all. For example, =
for
> Chinese characters(for I don=E2=80=99t know what is its length, maybe 2 b=
ytes,
> maybe 3 bytes and maybe 4 bytes), localization is almost no use.
> And the localization of my country is as same as ISO. We only use the ISO
> units, numbers.
>
> Just like I dislike N, J such units, they are all no reason to use at
> all.(The =E2=80=9CINCH=E2=80=9D I never use it.)
> I use kg.m.s^-2 to represent N.
> I use kg.m^2.s^-2 to represent J.
> The reason is that these units are more easy for me to understand what it
> connected to and easily to be computed.
> I don=E2=80=99t think localization is a must for C++, for most programmer=
s truly
> don=E2=80=99t need.
>
> If a programmer truly needs it, he/she can easily write it.
>
> IO operations need efficiency. If we can=E2=80=99t give programmers enoug=
h high
> efficiency, our new io libraries will still be failure. There are always
> programmers who use native API and make C++ more difficult to learn.
>
> Many people think C++ is slow just because the efficiency of iostream and
> cstdio.
> If we can provide a high-speed io library, C++ will have a better future.
> When we provide a high-speed io library without localization, without
> mutex, it will be difficult for them to be unsatisfied to C++.
>
> Sent from Windows Mail
>
> *From:* Billy O'Neal <billy.oneal@gmail.com>
> *Sent:* =E2=80=8EThursday=E2=80=8E, =E2=80=8EJanuary=E2=80=8E =E2=80=8E23=
=E2=80=8E, =E2=80=8E2014 =E2=80=8E11=E2=80=8E:=E2=80=8E02=E2=80=8E =E2=80=
=8EAM
> *To:* wsd wsd <euloanty@live.com>
>
> That is undesirable because you can't localize the digit format. And the
> digit format certainly does change from one culture to another.
>
> At least in your example above you would probably want
>
> printf(fout, ....);
>
> there would be polymorphic calls inside fout to allow someone to change
> where the output is actually written. For instance, in the "real" case
> writing to a file, but for testing purposes writing to a string or memory
> buffer.
>
> This way the formatting code can be completely optimized, and the
> relatively expensive virtual call overhead only happens after a complete
> (or at least large chunk) of output is formatted.
>
> Billy O'Neal
> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
> http://stackoverflow.com/users/82320/billy-oneal
>
>
> On Wed, Jan 22, 2014 at 5:06 PM, wsdwsd <euloanty@live.com> wrote:
>
>>  I am wrong about the sizes. But I still think inheritance based
>> polymorphic is a mistake.
>>
>> You have seen that my scanf  doesn=E2=80=99t maintain the c-style-format=
..
>> I use
>>
>> fout.printf(=E2=80=9C%=E2=80=9D,fixed_precision(3.0,1));
>> =3D=3D
>> fprintf(fout,=E2=80=9D%.1f=E2=80=9D,3.0);
>>
>> The wrapper could be optimized by compilers and in fact it can be done.
>>
>> Sent from Windows Mail
>>
>> *From:* Billy O'Neal <billy.oneal@gmail.com>
>> *Sent:* =E2=80=8ESaturday=E2=80=8E, =E2=80=8EJanuary=E2=80=8E =E2=80=8E1=
8=E2=80=8E, =E2=80=8E2014 =E2=80=8E8=E2=80=8E:=E2=80=8E58=E2=80=8E =E2=80=
=8EAM
>> *To:* std-proposals@isocpp.org
>> *Cc:* wsd wsd <euloanty@live.com>, masse.nicolas@gmail.com
>>
>> I don't think a template is the way to go here. While the potential
>> performance increase is there, I don't think that's the way we want to g=
o
>> for the "general, default" library. Real programs often have localizatio=
n
>> requirements, and if those values are burned in as template parameters y=
ou
>> can't go back later and fix this by changing the string.
>>
>> If someone profiles and finds that they need faster formatting and don't
>> need localization, they can always fall back on a specialized library /
>> implementation.
>>
>> Also take a look at .NET's Stream vs. StreamReader distinction -- and
>> note that today's stringstream is similar to .NETs StringReader. e.g. th=
ey
>> have 2 completely separate trees which both can be overridden; at the
>> formatted and unformatted IO level. (Just don't repeat their mistake whe=
re
>> the formatted IO level takes ownership of the stream :) )
>>
>> Billy O'Neal
>> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
>> http://stackoverflow.com/users/82320/billy-oneal
>>
>>
>> On Fri, Jan 17, 2014 at 4:36 PM, Bengt Gustafsson <
>> bengt.gustafsson@beamways.com> wrote:
>>
>>> I'm still working on my compilable codebase for this.
>>>
>>> I'm however basically on the same page as you, except that I specified =
a
>>> DataFormatter template which both contains the parameters, the parsing =
of
>>> the parameters from string form and the actual formatting of the value =
of
>>> type T.
>>>
>>> This template is then specialized for each T, including, as desired,
>>> user defined types.
>>>
>>> The advantage is that as there is only one template name you can do muc=
h
>>> more within the surrounding formatter template without having to resort=
 to
>>> using heap memory and virtual methods (which I don't).
>>>
>>> I'm getting really close to working code but I was hit by a nasty bug,
>>> possibly a compiler bug.
>>>
>>> I think that the two subjects of a low level stream and a formatting
>>> facility will ultimately be two different proposals, but in this stage =
I
>>> think we need to keep the discussion in one place to see the
>>> interdependencies and requirements more clearly. I'm also thinking that=
 we
>>> need an intermediate level which basically holds the locale and maybe t=
he
>>> line ending mode, as ostream already has this while it seems to be
>>> unnecessary baggage for a new binary file class. I think that it would =
be
>>> nice if this intermediate object held a "formatter set" that is, a
>>> container of formatters for diferent types. It is however beyond me how=
 to
>>> get this without introducing things that slow the process down consired=
ably
>>> such as searching a data structure for a formatter for typeid(T). Maybe=
 a
>>> template template parameter which defaults to 'DataFormatter' but that =
only
>>> offers compile time specialization.
>>>
>>> Den l=C3=B6rdagen den 18:e januari 2014 kl. 00:52:18 UTC+1 skrev
>>> masse....@gmail.com:
>>>
>>>> Hi all.
>>>> For the things of parsing the format string only once, I do believe th=
e
>>>> simplest solution woul be to add some classes wich are able to contain=
s the
>>>> formatting parameters.
>>>> For example, in .Net the NumberFormatInfo<http://msdn.microsoft.com/fr=
-fr/library/system.globalization.numberformatinfo.numberformatinfo%28v=3Dvs=
..110%29.aspx>class contains all the necessary information in order to forma=
t a number.
>>>> Then you could add a method or a ctor in order to get an object from a
>>>> string reprsentation of the format.
>>>> For example :
>>>>
>>>> string format_price(double price, locale loc =3D std::locale()) //I'll
>>>> explain later why I put a std::locale here
>>>> {
>>>>     static auto format =3D std::numeric_format(".2");//say that the
>>>> prices should be formatted using 2 digits for the decimal part. Note t=
hat
>>>> the formatting syntax still need to be defined
>>>>     return to_string(price, format, loc);//I assume here that such an
>>>> overload of the to_string method exists.
>>>> }
>>>>
>>>> The same could be achived by doing this :
>>>>
>>>>  std::numeric_format get_price_format()
>>>> {
>>>>     std::numeric_format format;
>>>>     format.decimal_digits =3D 2;
>>>>     return format;
>>>> }
>>>>
>>>> string format_price(double price, locale loc =3D std::locale())
>>>> {
>>>>     static auto format =3D get_price_format();
>>>>     return to_string(price, format, loc);
>>>> }
>>>>
>>>> Note that I separate the notion of formatting and the notion of locale=
s
>>>> on purpose.
>>>> The idea beyond this is that they define different things.
>>>> Basically:
>>>> - the format will defined wich part of the data should be represented
>>>> (and how).
>>>>   For example :
>>>>     * the decimal part should be represented using the first 2 digit
>>>>     * a date should be represented with the day-of-the-month first
>>>> (represented as a numeric value), the the month (using a full string
>>>> representation), then the year (using 4 digit)
>>>>
>>>> - the locale will define wich char or string must be used for each par=
t.
>>>>   For example :
>>>>     * the decimal separator to be used must be a dot. ('.')
>>>>     * the name of the months are the strings "january", "february",
>>>> ...if you're using an english locale for example.
>>>>
>>>> Now, another tought:
>>>> It seems than this topic is speaking of 2 differents things:
>>>> - Adding another way to provide iostream facilities
>>>> - Adding another way to provide formatting facilities
>>>> While those 2 are complementary, I think they are differents subject.
>>>> Then my question is :
>>>> What about creating a new topic about formatting facilities? (and keep
>>>> this one for iostream facilities)
>>>>
>>>>  --
>>>
>>> ---
>>> You received this message because you are subscribed to the Google
>>> Groups "ISO C++ Standard - Future Proposals" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to std-proposals+unsubscribe@isocpp.org.
>>> To post to this group, send email to std-proposals@isocpp.org.
>>> Visit this group at
>>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>>
>>
>>
>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--047d7b472816c3746904f0a68c34
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">&gt;=C2=A0<span style=3D"font-family:Calibri,&#39;Microsof=
t YaHei UI&#39;,&#39;Segoe UI&#39;,Meiryo,&#39;Microsoft JhengHei UI&#39;,&=
#39;Malgun Gothic&#39;,sans-serif;font-size:16px">cstdio is too slow and di=
fficult to use.</span><div>

<span style=3D"font-family:Calibri,&#39;Microsoft YaHei UI&#39;,&#39;Segoe =
UI&#39;,Meiryo,&#39;Microsoft JhengHei UI&#39;,&#39;Malgun Gothic&#39;,sans=
-serif;font-size:16px"><br></span></div><div><span style=3D"font-family:Cal=
ibri,&#39;Microsoft YaHei UI&#39;,&#39;Segoe UI&#39;,Meiryo,&#39;Microsoft =
JhengHei UI&#39;,&#39;Malgun Gothic&#39;,sans-serif;font-size:16px">Yes, it=
 is difficult to use. It really isn&#39;t all that slow. Of course the spee=
d you get will depend entirely on your particular standard library implemen=
tation.</span></div>

<div><span style=3D"font-family:Calibri,&#39;Microsoft YaHei UI&#39;,&#39;S=
egoe UI&#39;,Meiryo,&#39;Microsoft JhengHei UI&#39;,&#39;Malgun Gothic&#39;=
,sans-serif;font-size:16px"><br></span></div><div><span style=3D"font-famil=
y:Calibri,&#39;Microsoft YaHei UI&#39;,&#39;Segoe UI&#39;,Meiryo,&#39;Micro=
soft JhengHei UI&#39;,&#39;Malgun Gothic&#39;,sans-serif;font-size:16px">&g=
t;=C2=A0</span><span style=3D"font-family:Calibri,&#39;Microsoft YaHei UI&#=
39;,&#39;Segoe UI&#39;,Meiryo,&#39;Microsoft JhengHei UI&#39;,&#39;Malgun G=
othic&#39;,sans-serif;font-size:16px">Efficiency is the root of C++. C++ is=
 made for efficiency.</span></div>

<div style=3D"font-family:Calibri,&#39;Microsoft YaHei UI&#39;,&#39;Segoe U=
I&#39;,Meiryo,&#39;Microsoft JhengHei UI&#39;,&#39;Malgun Gothic&#39;,sans-=
serif;font-size:16px">If we don=E2=80=99t need efficiency, then why we use =
computers?</div>

<div style=3D"font-family:Calibri,&#39;Microsoft YaHei UI&#39;,&#39;Segoe U=
I&#39;,Meiryo,&#39;Microsoft JhengHei UI&#39;,&#39;Malgun Gothic&#39;,sans-=
serif;font-size:16px"><br></div><div style=3D"font-family:Calibri,&#39;Micr=
osoft YaHei UI&#39;,&#39;Segoe UI&#39;,Meiryo,&#39;Microsoft JhengHei UI&#3=
9;,&#39;Malgun Gothic&#39;,sans-serif;font-size:16px">

Efficiency is a big part, yes. But it is not the only part. It matters not =
how fast your program is if it produces wrong answers.</div><div style=3D"f=
ont-family:Calibri,&#39;Microsoft YaHei UI&#39;,&#39;Segoe UI&#39;,Meiryo,&=
#39;Microsoft JhengHei UI&#39;,&#39;Malgun Gothic&#39;,sans-serif;font-size=
:16px">

<br></div><div style=3D"font-family:Calibri,&#39;Microsoft YaHei UI&#39;,&#=
39;Segoe UI&#39;,Meiryo,&#39;Microsoft JhengHei UI&#39;,&#39;Malgun Gothic&=
#39;,sans-serif;font-size:16px">&gt;=C2=A0<span style=3D"font-family:arial,=
sans-serif;font-size:13px">Compared to the flexible version that can be use=
d by external people to control output and is not hardcoded:</span></div>

<span style=3D"font-family:arial,sans-serif;font-size:13px">format(&quot;{0=
:e.3}: {1:x.8}&quot;); // Syntax is for exposition only</span><div style=3D=
"font-family:Calibri,&#39;Microsoft YaHei UI&#39;,&#39;Segoe UI&#39;,Meiryo=
,&#39;Microsoft JhengHei UI&#39;,&#39;Malgun Gothic&#39;,sans-serif;font-si=
ze:16px">

<br></div><div style=3D"font-family:Calibri,&#39;Microsoft YaHei UI&#39;,&#=
39;Segoe UI&#39;,Meiryo,&#39;Microsoft JhengHei UI&#39;,&#39;Malgun Gothic&=
#39;,sans-serif;font-size:16px">Sounds good to me. What happens if the form=
at string and what the programmer has set disagree? Fast Format gets around=
 this by having completely separate APIs; write and format.</div>

<div style=3D"font-family:Calibri,&#39;Microsoft YaHei UI&#39;,&#39;Segoe U=
I&#39;,Meiryo,&#39;Microsoft JhengHei UI&#39;,&#39;Malgun Gothic&#39;,sans-=
serif;font-size:16px"><br></div><div style=3D"font-family:Calibri,&#39;Micr=
osoft YaHei UI&#39;,&#39;Segoe UI&#39;,Meiryo,&#39;Microsoft JhengHei UI&#3=
9;,&#39;Malgun Gothic&#39;,sans-serif;font-size:16px">

&gt;=C2=A0<span style=3D"font-family:arial,sans-serif;font-size:13px">I wou=
ld really like to see some numbers. Is the typical iostream use case I/O or=
 CPU bound?</span></div><div style=3D"font-family:Calibri,&#39;Microsoft Ya=
Hei UI&#39;,&#39;Segoe UI&#39;,Meiryo,&#39;Microsoft JhengHei UI&#39;,&#39;=
Malgun Gothic&#39;,sans-serif;font-size:16px">

<br></div><div style=3D"font-family:Calibri,&#39;Microsoft YaHei UI&#39;,&#=
39;Segoe UI&#39;,Meiryo,&#39;Microsoft JhengHei UI&#39;,&#39;Malgun Gothic&=
#39;,sans-serif;font-size:16px">This is what I said cstdio. IOStream is not=
oriously slow because it incurs virtual call overhead for relatively small =
chunks of IO. Moreover, to my understanding, the built in codecvt facet sys=
tem converts characters one at a time between encodings, which is 1. often =
wrong, and 2. often very inefficient.</div>

<div style=3D"font-family:Calibri,&#39;Microsoft YaHei UI&#39;,&#39;Segoe U=
I&#39;,Meiryo,&#39;Microsoft JhengHei UI&#39;,&#39;Malgun Gothic&#39;,sans-=
serif;font-size:16px"><br></div><div style=3D"font-family:Calibri,&#39;Micr=
osoft YaHei UI&#39;,&#39;Segoe UI&#39;,Meiryo,&#39;Microsoft JhengHei UI&#3=
9;,&#39;Malgun Gothic&#39;,sans-serif;font-size:16px">

If we want to actually do IO quickly we would need to look into asynchronou=
s systems. Right now iostreams has no asynchronous IO facility despite this=
 often being a far more efficient way to do IO.</div><div style=3D"font-fam=
ily:Calibri,&#39;Microsoft YaHei UI&#39;,&#39;Segoe UI&#39;,Meiryo,&#39;Mic=
rosoft JhengHei UI&#39;,&#39;Malgun Gothic&#39;,sans-serif;font-size:16px">

<br></div><div style=3D"font-family:Calibri,&#39;Microsoft YaHei UI&#39;,&#=
39;Segoe UI&#39;,Meiryo,&#39;Microsoft JhengHei UI&#39;,&#39;Malgun Gothic&=
#39;,sans-serif;font-size:16px">&gt;=C2=A0<span style=3D"font-family:arial,=
sans-serif;font-size:13px">I want to emphasize that I have not done anythin=
g amongst the &quot;bytestream&quot; aspect of this thread and am currently=
 only focusing on the formatting part.</span></div>

<div style=3D"font-family:Calibri,&#39;Microsoft YaHei UI&#39;,&#39;Segoe U=
I&#39;,Meiryo,&#39;Microsoft JhengHei UI&#39;,&#39;Malgun Gothic&#39;,sans-=
serif;font-size:16px"><br></div><div style=3D"font-family:Calibri,&#39;Micr=
osoft YaHei UI&#39;,&#39;Segoe UI&#39;,Meiryo,&#39;Microsoft JhengHei UI&#3=
9;,&#39;Malgun Gothic&#39;,sans-serif;font-size:16px">

That&#39;s probably the right spot for now.</div></div><div class=3D"gmail_=
extra"><br clear=3D"all"><div><div dir=3D"ltr"><div>Billy O&#39;Neal</div><=
div><a href=3D"https://bitbucket.org/BillyONeal/" target=3D"_blank">https:/=
/github.com/BillyONeal/</a></div>

<div><a href=3D"http://stackoverflow.com/users/82320/billy-oneal" target=3D=
"_blank">http://stackoverflow.com/users/82320/billy-oneal</a></div></div></=
div>
<br><br><div class=3D"gmail_quote">On Wed, Jan 22, 2014 at 11:46 PM, wsdwsd=
 <span dir=3D"ltr">&lt;<a href=3D"mailto:euloanty@live.com" target=3D"_blan=
k">euloanty@live.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex=
">






<div dir=3D"ltr">
<div dir=3D"ltr" style=3D"font-family:&#39;Calibri&#39;,&#39;Microsoft YaHe=
i UI&#39;,&#39;Segoe UI&#39;,&#39;Meiryo&#39;,&#39;Microsoft JhengHei UI&#3=
9;,&#39;Malgun Gothic&#39;,&#39;sans-serif&#39;;font-size:12pt"><div style>

cstdio is too slow and difficult to use.</div><div style>It=E2=80=99s 10 ti=
mes slower than handwriting.</div><div style><br></div><div style>how can I=
 read size_t by using cstdio?</div><div style><br></div><div style>%zu? not=
 be supported..</div>

<div style>%u? wrong</div><div style>%llu? wrong.</div><div style>So cstdio=
 is also a big failure.</div><div style><br></div><div style>I think our=C2=
=A0actions are to make programmers not to use native API and=C2=A0so-called=
 low-level.</div>

<div style><br></div><div style>Efficiency is the root of C++. C++ is made =
for efficiency.</div><div style>If we don=E2=80=99t need efficiency, then w=
hy we use computers?<br></div><div style><div style><br></div><div style>Se=
nt from Windows Mail</div>

<div style><br></div></div><div style=3D"padding-top:5px;border-top-color:r=
gb(229,229,229);border-top-width:1px;border-top-style:solid"><div><font fac=
e=3D" &#39;Calibri&#39;, &#39;Microsoft YaHei UI&#39;, &#39;Segoe UI&#39;, =
&#39;Meiryo&#39;, &#39;Microsoft JhengHei UI&#39;, &#39;Malgun Gothic&#39;,=
 &#39;sans-serif&#39;" style=3D"line-height:15pt;letter-spacing:0.02em;font=
-family:&quot;Calibri&quot;,&quot;Microsoft YaHei UI&quot;,&quot;Segoe UI&q=
uot;,&quot;Meiryo&quot;,&quot;Microsoft JhengHei UI&quot;,&quot;Malgun Goth=
ic&quot;,&quot;sans-serif&quot;;font-size:12pt"><b>From:</b>=C2=A0<a href=
=3D"mailto:billy.oneal@gmail.com" target=3D"_blank">Billy O&#39;Neal</a><br=
>

<b>Sent:</b>=C2=A0=E2=80=8EThursday=E2=80=8E, =E2=80=8EJanuary=E2=80=8E =E2=
=80=8E23=E2=80=8E, =E2=80=8E2014 =E2=80=8E3=E2=80=8E:=E2=80=8E37=E2=80=8E =
=E2=80=8EPM<br><b>To:</b>=C2=A0<a href=3D"mailto:euloanty@live.com" target=
=3D"_blank">wsd wsd</a>, <a href=3D"mailto:std-proposals@isocpp.org" target=
=3D"_blank">std-proposals@isocpp.org</a></font></div>

</div><div><div class=3D"h5"><div><br></div><div dir=3D"ltr"><div style=3D"=
font-family:Calibri,sans-serif;font-size:12pt"><div>Your &quot;dislike&quot=
; is irrelevant.</div><div><br></div><div>Localization is more common a req=
uirement than is a requirement for faster formatting than cstdio can provid=
e. It is far simpler to implement faster IO on top of features provided by =
a platform than it is to implement a whole formatter library. I would be hi=
ghly Highly surprised if 99% of such uses are dominated by secondary storag=
e rather than CPU time in any case.</div>

<div><br></div><div>Things that go into the standard are those which provid=
e the most value to most general purpose software; not the fastest possible=
 implementation of something just for fastness&#39; sake. Performance matte=
rs, but so does utility.</div>

<div><br></div><div>Sent from a touchscreen. Please excuse the brevity and =
tpyos.</div><br><div>----- Reply message -----<br>From: &quot;wsdwsd&quot; =
&lt;<a href=3D"mailto:euloanty@live.com" target=3D"_blank">euloanty@live.co=
m</a>&gt;<br>

To: &quot;Billy O&#39;Neal&quot; &lt;<a href=3D"mailto:billy.oneal@gmail.co=
m" target=3D"_blank">billy.oneal@gmail.com</a>&gt;<br>Subject: [std-proposa=
ls] Re: The failures of iostreams<br>Date: Wed, Jan 22, 2014 10:55 PM</div>

</div><br>
<div style>You misunderstand my meanings.</div><div style><br></div><div st=
yle>I mean:</div><div style>mofstream fout(=E2=80=9Ca.txt=E2=80=9D);<br></d=
iv><div style><div style>fout.printf(=E2=80=9C%=E2=80=9D,fixed_precision(3.=
0,1));</div><div style>=3D=3D</div>

<div style><div>std::unique_ptr&lt;std::FILE,decltype(fclose)*&gt; fp(std::=
fopen(=E2=80=9Ca.txt=E2=80=9D,=E2=80=9Dw=E2=80=9D),fclose);</div><div>fprin=
tf(fp.get(),=E2=80=9D%.1f=E2=80=9D,3.0);</div></div></div><div style><br></=
div><div style><div style><br></div><div style>

Localization is the most useless things for many programmers.</div><div sty=
le>I dislike localization, for I don=E2=80=99t need it at all. For example,=
 for Chinese characters(for I don=E2=80=99t know what is its length, maybe =
2 bytes, maybe 3 bytes and maybe 4 bytes), localization is almost=C2=A0no u=
se.</div>

<div style>And=C2=A0the localization of my country=C2=A0is as same as ISO. =
We=C2=A0only use the=C2=A0ISO units, numbers.</div><div style><br></div><di=
v style>Just like I dislike=C2=A0N, J=C2=A0such units, they are all no reas=
on to use at all.(The=C2=A0=E2=80=9CINCH=E2=80=9D I never use it.)</div>

<div style>I use kg.m.s^-2 to represent N.</div><div style>I use kg.m^2.s^-=
2 to represent J.</div><div style>The reason is=C2=A0that these units are m=
ore easy for me to understand what it connected to and easily to be=C2=A0co=
mputed.</div>

<div style>I don=E2=80=99t think localization is a must for C++, for most p=
rogrammers truly don=E2=80=99t need.</div><div style><br></div><div style>I=
f a programmer truly needs it, he/she can easily write it.</div><div style>=
<br></div><div style>

IO operations need efficiency. If we can=E2=80=99t give programmers enough =
high efficiency, our new io libraries will still be failure. There are alwa=
ys programmers who use native API and make C++ more difficult to learn.</di=
v><div style>

<br></div><div style>Many people think C++ is slow just because the efficie=
ncy of iostream and cstdio.</div><div style>If we can=C2=A0provide a high-s=
peed io library, C++ will have a better future.</div><div style>When=C2=A0w=
e provide a high-speed io library without localization, without mutex, it w=
ill be difficult for them to be unsatisfied=C2=A0to C++.</div>

<div style><br></div><div style>Sent from Windows Mail</div><div style><br>=
</div></div><div style=3D"padding-top:5px;border-top-color:rgb(229,229,229)=
;border-top-width:1px;border-top-style:solid"><div><font face=3D" &#39;Cali=
bri&#39;, &#39;Microsoft YaHei UI&#39;, &#39;Segoe UI&#39;, &#39;Meiryo&#39=
;, &#39;Microsoft JhengHei UI&#39;, &#39;Malgun Gothic&#39;, &#39;sans-seri=
f&#39;" style=3D"line-height:15pt;letter-spacing:0.02em;font-family:&quot;C=
alibri&quot;,&quot;Microsoft YaHei UI&quot;,&quot;Segoe UI&quot;,&quot;Meir=
yo&quot;,&quot;Microsoft JhengHei UI&quot;,&quot;Malgun Gothic&quot;,&quot;=
sans-serif&quot;;font-size:12pt"><b>From:</b>=C2=A0<a href=3D"mailto:billy.=
oneal@gmail.com" target=3D"_blank">Billy O&#39;Neal</a><br>

<b>Sent:</b>=C2=A0=E2=80=8EThursday=E2=80=8E, =E2=80=8EJanuary=E2=80=8E =E2=
=80=8E23=E2=80=8E, =E2=80=8E2014 =E2=80=8E11=E2=80=8E:=E2=80=8E02=E2=80=8E =
=E2=80=8EAM<br><b>To:</b>=C2=A0<a href=3D"mailto:euloanty@live.com" target=
=3D"_blank">wsd wsd</a></font></div></div><div><br></div><div dir=3D""><div=
 dir=3D"ltr"><div>That is undesirable because you can&#39;t localize the di=
git format. And the digit format certainly does change from one culture to =
another.</div>

<div><br></div><div>At least in your example above you would probably want<=
/div>

<div><br></div><div>printf(fout, ....);</div><div><br></div><div>there woul=
d be polymorphic calls inside fout to allow someone to change where the out=
put is actually written. For instance, in the &quot;real&quot; case writing=
 to a file, but for testing purposes writing to a string or memory buffer.<=
/div>



<div><br></div><div>This way the formatting code can be completely optimize=
d, and the relatively expensive virtual call overhead only happens after a =
complete (or at least large chunk) of output is formatted.</div></div>


<div class=3D"gmail_extra">
<br clear=3D"all"><div><div dir=3D"ltr"><div>Billy O&#39;Neal</div><div><a =
href=3D"https://bitbucket.org/BillyONeal/" target=3D"_blank">https://github=
..com/BillyONeal/</a></div><div><a href=3D"http://stackoverflow.com/users/82=
320/billy-oneal" target=3D"_blank">http://stackoverflow.com/users/82320/bil=
ly-oneal</a></div>



</div></div>
<br><br><div class=3D"gmail_quote">On Wed, Jan 22, 2014 at 5:06 PM, wsdwsd =
<span dir=3D"ltr">&lt;<a href=3D"mailto:euloanty@live.com" target=3D"_blank=
">euloanty@live.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quo=
te" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rg=
b(204,204,204);border-left-width:1px;border-left-style:solid">








<div dir=3D"ltr">
<div style=3D"font-family:&quot;Calibri&quot;,&quot;Microsoft YaHei UI&quot=
;,&quot;Segoe UI&quot;,&quot;Meiryo&quot;,&quot;Microsoft JhengHei UI&quot;=
,&quot;Malgun Gothic&quot;,&quot;sans-serif&quot;;font-size:12pt" dir=3D"lt=
r">



<div>I am wrong about the sizes. But I still think inheritance based polymo=
rphic is a mistake.</div><div><br></div><div>You have seen that my scanf=C2=
=A0 doesn=E2=80=99t maintain the c-style-format. </div><div>I use</div><div=
><br></div>



<div>fout.printf(=E2=80=9C%=E2=80=9D,fixed_precision(3.0,1));<br></div><div=
><div>=3D=3D</div><div>fprintf(fout,=E2=80=9D%.1f=E2=80=9D,3.0);</div><div>=
<br></div><div>The wrapper could be optimized by compilers and in fact=C2=
=A0it can be done.</div><div><br></div>



<div>Sent from Windows Mail</div><div><br></div></div><div style=3D"padding=
-top:5px;border-top-color:rgb(229,229,229);border-top-width:1px;border-top-=
style:solid"><div><font face=3D" &#39;Calibri&#39;, &#39;Microsoft YaHei UI=
&#39;, &#39;Segoe UI&#39;, &#39;Meiryo&#39;, &#39;Microsoft JhengHei UI&#39=
;, &#39;Malgun Gothic&#39;, &#39;sans-serif&#39;" style=3D"line-height:15pt=
;letter-spacing:0.02em;font-family:&quot;Calibri&quot;,&quot;Microsoft YaHe=
i UI&quot;,&quot;Segoe UI&quot;,&quot;Meiryo&quot;,&quot;Microsoft JhengHei=
 UI&quot;,&quot;Malgun Gothic&quot;,&quot;sans-serif&quot;;font-size:12pt">=
<b>From:</b>=C2=A0<a href=3D"mailto:billy.oneal@gmail.com" target=3D"_blank=
">Billy O&#39;Neal</a><br>



<b>Sent:</b>=C2=A0=E2=80=8ESaturday=E2=80=8E, =E2=80=8EJanuary=E2=80=8E =E2=
=80=8E18=E2=80=8E, =E2=80=8E2014 =E2=80=8E8=E2=80=8E:=E2=80=8E58=E2=80=8E =
=E2=80=8EAM<br><b>To:</b>=C2=A0<a href=3D"mailto:std-proposals@isocpp.org" =
target=3D"_blank">std-proposals@isocpp.org</a><br><b>Cc:</b>=C2=A0<a href=
=3D"mailto:euloanty@live.com" target=3D"_blank">wsd wsd</a>, <a href=3D"mai=
lto:masse.nicolas@gmail.com" target=3D"_blank">masse.nicolas@gmail.com</a><=
/font></div>



</div><div><br></div><div dir=3D""><div dir=3D"ltr"><div>I don&#39;t think =
a template is the way to go here. While the potential performance increase =
is there, I don&#39;t think that&#39;s the way we want to go for the &quot;=
general, default&quot; library. Real programs often have localization requi=
rements, and if those values are burned in as template parameters you can&#=
39;t go back later and fix this by changing the string.</div>





<div><br></div><div>If someone profiles and finds that they need faster for=
matting and don&#39;t need localization, they can always fall back on a spe=
cialized library / implementation.</div><div><br></div><div>Also take a loo=
k at .NET&#39;s Stream vs. StreamReader distinction -- and note that today&=
#39;s stringstream is similar to .NETs StringReader. e.g. they have 2 compl=
etely separate trees which both can be overridden; at the formatted and unf=
ormatted IO level. (Just don&#39;t repeat their mistake where the formatted=
 IO level takes ownership of the stream :) )</div>





</div><div class=3D"gmail_extra"><br clear=3D"all"><div><div dir=3D"ltr"><d=
iv>Billy O&#39;Neal</div><div><a href=3D"https://bitbucket.org/BillyONeal/"=
 target=3D"_blank">https://github.com/BillyONeal/</a></div><div><a href=3D"=
http://stackoverflow.com/users/82320/billy-oneal" target=3D"_blank">http://=
stackoverflow.com/users/82320/billy-oneal</a></div>





</div></div>
<br><br><div class=3D"gmail_quote">On Fri, Jan 17, 2014 at 4:36 PM, Bengt G=
ustafsson <span dir=3D"ltr">&lt;<a href=3D"mailto:bengt.gustafsson@beamways=
..com" target=3D"_blank">bengt.gustafsson@beamways.com</a>&gt;</span> wrote:=
<br>





<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding=
-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-l=
eft-style:solid"><div dir=3D"ltr">I&#39;m still working on my compilable co=
debase for this.<div>



<br></div><div>I&#39;m however basically on the same page as you, except th=
at I specified a DataFormatter template which both contains the parameters,=
 the parsing of the parameters from string form and the actual formatting o=
f the value of type T.</div>





<div><br></div><div>This template is then specialized for each T, including=
, as desired, user defined types.</div><div><br></div><div>The advantage is=
 that as there is only one template name you can do much more within the su=
rrounding formatter template without having to resort to using heap memory =
and virtual methods (which I don&#39;t).</div>





<div><br></div><div>I&#39;m getting really close to working code but I was =
hit by a nasty bug, possibly a compiler bug.</div><div><br></div><div>I thi=
nk that the two subjects of a low level stream and a formatting facility wi=
ll ultimately be two different proposals, but in this stage I think we need=
 to keep the discussion in one place to see the interdependencies and requi=
rements more clearly. I&#39;m also thinking that we need an intermediate le=
vel which basically holds the locale and maybe the line ending mode, as ost=
ream already has this while it seems to be unnecessary baggage for a new bi=
nary file class. I think that it would be nice if this intermediate object =
held a &quot;formatter set&quot; that is, a container of formatters for dif=
erent types. It is however beyond me how to get this without introducing th=
ings that slow the process down consiredably such as searching a data struc=
ture for a formatter for typeid(T). Maybe a template template parameter whi=
ch defaults to &#39;DataFormatter&#39; but that only offers compile time sp=
ecialization.=C2=A0</div>





<div><div><br>Den l=C3=B6rdagen den 18:e januari 2014 kl. 00:52:18 UTC+1 sk=
rev <a href=3D"mailto:masse....@gmail.com" target=3D"_blank">masse....@gmai=
l.com</a>:<div><div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0=
px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-lef=
t-width:1px;border-left-style:solid">





<div dir=3D"ltr">Hi all.<br>For the things of parsing the format string onl=
y once, I do believe the simplest solution woul be to add some classes wich=
 are able to contains the formatting parameters.<br>For example, in .Net th=
e <a href=3D"http://msdn.microsoft.com/fr-fr/library/system.globalization.n=
umberformatinfo.numberformatinfo%28v=3Dvs.110%29.aspx" target=3D"_blank">Nu=
mberFormatInfo</a> class contains all the necessary information in order to=
 format a number.<br>





Then you could add a method or a ctor in order to get an object from a stri=
ng reprsentation of the format.<br>For example :<br><div style=3D"border:1p=
x solid rgb(187,187,187);background-color:rgb(250,250,250)"><code><div><spa=
n><br>





</span><span style=3D"color:rgb(0,0,136)">string</span><span> format_price<=
/span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb=
(0,0,136)">double</span><span> price</span><span style=3D"color:rgb(102,102=
,0)">,</span><span> locale loc </span><span style=3D"color:rgb(102,102,0)">=
=3D</span><span> std</span><span style=3D"color:rgb(102,102,0)">::</span><s=
pan>locale</span><span style=3D"color:rgb(102,102,0)">())</span><span> </sp=
an><span style=3D"color:rgb(136,0,0)">//I&#39;ll explain later why I put a =
std::locale here </span><span><br>





</span><span style=3D"color:rgb(102,102,0)">{</span><span><br>=C2=A0 =C2=A0=
 </span><span style=3D"color:rgb(0,0,136)">static</span><span> </span><span=
 style=3D"color:rgb(0,0,136)">auto</span><span> format </span><span style=
=3D"color:rgb(102,102,0)">=3D</span><span> std</span><span style=3D"color:r=
gb(102,102,0)">::</span><span>numeric_format</span><span style=3D"color:rgb=
(102,102,0)">(</span><span style=3D"color:rgb(0,136,0)">&quot;.2&quot;</spa=
n><span style=3D"color:rgb(102,102,0)">);</span><span style=3D"color:rgb(13=
6,0,0)">//<u></u>say that the prices should be formatted using 2 digits for=
 the decimal part. Note that the formatting syntax still need to be defined=
</span><span><br>





=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">return</span><span>=
 to_string</span><span style=3D"color:rgb(102,102,0)">(</span><span>price</=
span><span style=3D"color:rgb(102,102,0)">,</span><span> format</span><span=
 style=3D"color:rgb(102,102,0)">,</span><span> loc</span><span style=3D"col=
or:rgb(102,102,0)">);</span><span style=3D"color:rgb(136,0,0)">//I assume h=
ere that such an overload of the to_string method exists.</span><span><br>





</span><span style=3D"color:rgb(102,102,0)">}</span><span><br></span></div>=
</code></div><br>The same could be achived by doing this :<br><br><div styl=
e=3D"border:1px solid rgb(187,187,187);background-color:rgb(250,250,250)">




<code><div>
<span>std</span><span style=3D"color:rgb(102,102,0)">::</span><span>numeric=
_format get_price_format</span><span style=3D"color:rgb(102,102,0)">()</spa=
n><span><br></span><span style=3D"color:rgb(102,102,0)">{</span><span><br>=
=C2=A0 =C2=A0 std</span><span style=3D"color:rgb(102,102,0)">::</span><span=
>numeric_format format</span><span style=3D"color:rgb(102,102,0)">;</span><=
span><br>





=C2=A0 =C2=A0 format</span><span style=3D"color:rgb(102,102,0)">.</span><sp=
an>decimal_digits </span><span style=3D"color:rgb(102,102,0)">=3D</span><sp=
an> </span><span style=3D"color:rgb(0,102,102)">2</span><span style=3D"colo=
r:rgb(102,102,0)">;</span><span><br>





=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">return</span><span>=
 format</span><span style=3D"color:rgb(102,102,0)">;</span><span><br></span=
><span style=3D"color:rgb(102,102,0)">}</span><span><br><br></span><span st=
yle=3D"color:rgb(0,0,136)">string</span><span> format_price</span><span sty=
le=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,136)">doub=
le</span><span> price</span><span style=3D"color:rgb(102,102,0)">,</span><s=
pan> locale loc </span><span style=3D"color:rgb(102,102,0)">=3D</span><span=
> std</span><span style=3D"color:rgb(102,102,0)">::</span><span>locale</spa=
n><span style=3D"color:rgb(102,102,0)">())</span><span><br>





</span><span style=3D"color:rgb(102,102,0)">{</span><span><br>=C2=A0 =C2=A0=
 </span><span style=3D"color:rgb(0,0,136)">static</span><span> </span><span=
 style=3D"color:rgb(0,0,136)">auto</span><span> format </span><span style=
=3D"color:rgb(102,102,0)">=3D</span><span> get_price_format</span><span sty=
le=3D"color:rgb(102,102,0)">();</span><span><br>





=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">return</span><span>=
 to_string</span><span style=3D"color:rgb(102,102,0)">(</span><span>price</=
span><span style=3D"color:rgb(102,102,0)">,</span><span> format</span><span=
 style=3D"color:rgb(102,102,0)">,</span><span> loc</span><span style=3D"col=
or:rgb(102,102,0)">);</span><span><br>





</span><span style=3D"color:rgb(102,102,0)">}</span><span><br></span></div>=
</code></div><br>Note that I separate the notion of formatting and the noti=
on of locales on purpose.<br>The idea beyond this is that they define diffe=
rent things. <br>





Basically: <br>- the format will defined wich part of the data should be re=
presented (and how). <br>=C2=A0 For example : <br>=C2=A0=C2=A0=C2=A0 * the =
decimal part should be represented using the first 2 digit<br>=C2=A0=C2=A0=
=C2=A0 * a date should be represented with the day-of-the-month first (repr=
esented as a numeric value), the the month (using a full string representat=
ion), then the year (using 4 digit)<br>





<br>- the locale will define wich char or string must be used for each part=
..<br>=C2=A0 For example : <br>=C2=A0=C2=A0=C2=A0 * the decimal separator to=
 be used must be a dot. (&#39;.&#39;)<br>=C2=A0=C2=A0=C2=A0 * the name of t=
he months are the strings &quot;january&quot;, &quot;february&quot;, ...if =
you&#39;re using an english locale for example.<br>





<br>Now, another tought:<br>It seems than this topic is speaking of 2 diffe=
rents things:<br>- Adding another way to provide iostream facilities<br>- A=
dding another way to provide formatting facilities<br>While those 2 are com=
plementary, I think they are differents subject. Then my question is :<br>





What about creating a new topic about formatting facilities? (and keep this=
 one for  iostream facilities)<span><font color=3D"#888888"><br><br></font>=
</span></div></blockquote></div></div></div></div></div><span><font color=
=3D"#888888"><div>



<div>

<p></p>

-- <br>
=C2=A0<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></font></span></blockquote></div><br></div>
</div></div>
</div>

</blockquote></div><br></div>
</div>


</div></div></div></div>
</div>

</blockquote></div><br></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7b472816c3746904f0a68c34--

.


Author: fritzpoll <fred.pollard@gmail.com>
Date: Sun, 26 Jan 2014 13:20:52 -0800 (PST)
Raw View
------=_Part_1300_23046689.1390771252113
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

I think it makes sense to not worry too much about the string formatters'=
=20
interaction with a new "bytestreams" replacement.  The whole emphasis of=20
this thread has been on the need for them to be separate anyway - I've been=
=20
fiddling with a sample bytestreams implementation for you all to rip apart=
=20
- once it compiles and I have some performance metrics of worth, I'll post=
=20
up the code.

The performance won't be comparable to IOStreams until there is a=20
formatter, of course, since we wouldn't be comparing like with like.  I've=
=20
had an e-mail from a contributor to this thread indicating a distaste for a=
=20
bytestreams implementation that involves inheritance from a common base=20
class.  For me, this was just a way of allowing a use case where a client=
=20
may wish to hold multiple streams in an array/vector and loop over it.  In=
=20
the simplest case, where one only uses a single stream class, the cost of=
=20
the inheritance should be negligible in most implementations.

If anyone has a better thought on this, I'm open for it to be discussed -=
=20
would just rather it were on this list!

On Thursday, January 23, 2014 5:26:23 PM UTC, Billy O'Neal wrote:
>
> > cstdio is too slow and difficult to use.
>
> Yes, it is difficult to use. It really isn't all that slow. Of course the=
=20
> speed you get will depend entirely on your particular standard library=20
> implementation.
>
> > Efficiency is the root of C++. C++ is made for efficiency.
> If we don=E2=80=99t need efficiency, then why we use computers?
>
> Efficiency is a big part, yes. But it is not the only part. It matters no=
t=20
> how fast your program is if it produces wrong answers.
>
> > Compared to the flexible version that can be used by external people to=
=20
> control output and is not hardcoded:
> format("{0:e.3}: {1:x.8}"); // Syntax is for exposition only
>
> Sounds good to me. What happens if the format string and what the=20
> programmer has set disagree? Fast Format gets around this by having=20
> completely separate APIs; write and format.
>
> > I would really like to see some numbers. Is the typical iostream use=20
> case I/O or CPU bound?
>
> This is what I said cstdio. IOStream is notoriously slow because it incur=
s=20
> virtual call overhead for relatively small chunks of IO. Moreover, to my=
=20
> understanding, the built in codecvt facet system converts characters one =
at=20
> a time between encodings, which is 1. often wrong, and 2. often very=20
> inefficient.
>
> If we want to actually do IO quickly we would need to look into=20
> asynchronous systems. Right now iostreams has no asynchronous IO facility=
=20
> despite this often being a far more efficient way to do IO.
>
> > I want to emphasize that I have not done anything amongst the=20
> "bytestream" aspect of this thread and am currently only focusing on the=
=20
> formatting part.
>
> That's probably the right spot for now.
>
> Billy O'Neal
> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
> http://stackoverflow.com/users/82320/billy-oneal
>
>
> On Wed, Jan 22, 2014 at 11:46 PM, wsdwsd <eulo...@live.com <javascript:>>=
wrote:
>
>>  cstdio is too slow and difficult to use.
>> It=E2=80=99s 10 times slower than handwriting.
>>
>> how can I read size_t by using cstdio?
>>
>> %zu? not be supported..
>> %u? wrong
>> %llu? wrong.
>> So cstdio is also a big failure.
>>
>> I think our actions are to make programmers not to use native API=20
>> and so-called low-level.
>>
>> Efficiency is the root of C++. C++ is made for efficiency.
>> If we don=E2=80=99t need efficiency, then why we use computers?
>>
>> Sent from Windows Mail
>>
>> *From:* Billy O'Neal <javascript:>
>> *Sent:* =E2=80=8EThursday=E2=80=8E, =E2=80=8EJanuary=E2=80=8E =E2=80=8E2=
3=E2=80=8E, =E2=80=8E2014 =E2=80=8E3=E2=80=8E:=E2=80=8E37=E2=80=8E =E2=80=
=8EPM
>> *To:* wsd wsd <javascript:>, std-pr...@isocpp.org <javascript:>
>>
>> Your "dislike" is irrelevant.
>>
>> Localization is more common a requirement than is a requirement for=20
>> faster formatting than cstdio can provide. It is far simpler to implemen=
t=20
>> faster IO on top of features provided by a platform than it is to implem=
ent=20
>> a whole formatter library. I would be highly Highly surprised if 99% of=
=20
>> such uses are dominated by secondary storage rather than CPU time in any=
=20
>> case.
>>
>> Things that go into the standard are those which provide the most value=
=20
>> to most general purpose software; not the fastest possible implementatio=
n=20
>> of something just for fastness' sake. Performance matters, but so does=
=20
>> utility.
>>
>> Sent from a touchscreen. Please excuse the brevity and tpyos.
>>
>> ----- Reply message -----
>> From: "wsdwsd" <eulo...@live.com <javascript:>>
>> To: "Billy O'Neal" <billy...@gmail.com <javascript:>>
>> Subject: [std-proposals] Re: The failures of iostreams
>> Date: Wed, Jan 22, 2014 10:55 PM
>>
>> You misunderstand my meanings.
>>
>> I mean:
>> mofstream fout(=E2=80=9Ca.txt=E2=80=9D);
>> fout.printf(=E2=80=9C%=E2=80=9D,fixed_precision(3.0,1));
>> =3D=3D
>> std::unique_ptr<std::FILE,decltype(fclose)*>=20
>> fp(std::fopen(=E2=80=9Ca.txt=E2=80=9D,=E2=80=9Dw=E2=80=9D),fclose);
>> fprintf(fp.get(),=E2=80=9D%.1f=E2=80=9D,3.0);
>>
>>
>> Localization is the most useless things for many programmers.
>> I dislike localization, for I don=E2=80=99t need it at all. For example,=
 for=20
>> Chinese characters(for I don=E2=80=99t know what is its length, maybe 2 =
bytes,=20
>> maybe 3 bytes and maybe 4 bytes), localization is almost no use.
>> And the localization of my country is as same as ISO. We only use the IS=
O=20
>> units, numbers.
>>
>> Just like I dislike N, J such units, they are all no reason to use at=20
>> all.(The =E2=80=9CINCH=E2=80=9D I never use it.)
>> I use kg.m.s^-2 to represent N.
>> I use kg.m^2.s^-2 to represent J.
>> The reason is that these units are more easy for me to understand what i=
t=20
>> connected to and easily to be computed.
>> I don=E2=80=99t think localization is a must for C++, for most programme=
rs truly=20
>> don=E2=80=99t need.
>>
>> If a programmer truly needs it, he/she can easily write it.
>>
>> IO operations need efficiency. If we can=E2=80=99t give programmers enou=
gh high=20
>> efficiency, our new io libraries will still be failure. There are always=
=20
>> programmers who use native API and make C++ more difficult to learn.
>>
>> Many people think C++ is slow just because the efficiency of iostream an=
d=20
>> cstdio.
>> If we can provide a high-speed io library, C++ will have a better future=
..
>> When we provide a high-speed io library without localization, without=20
>> mutex, it will be difficult for them to be unsatisfied to C++.
>>
>> Sent from Windows Mail
>>
>> *From:* Billy O'Neal <javascript:>
>> *Sent:* =E2=80=8EThursday=E2=80=8E, =E2=80=8EJanuary=E2=80=8E =E2=80=8E2=
3=E2=80=8E, =E2=80=8E2014 =E2=80=8E11=E2=80=8E:=E2=80=8E02=E2=80=8E =E2=80=
=8EAM
>> *To:* wsd wsd <javascript:>
>>
>> That is undesirable because you can't localize the digit format. And the=
=20
>> digit format certainly does change from one culture to another.
>>
>> At least in your example above you would probably want
>>
>> printf(fout, ....);
>>
>> there would be polymorphic calls inside fout to allow someone to change=
=20
>> where the output is actually written. For instance, in the "real" case=
=20
>> writing to a file, but for testing purposes writing to a string or memor=
y=20
>> buffer.
>>
>> This way the formatting code can be completely optimized, and the=20
>> relatively expensive virtual call overhead only happens after a complete=
=20
>> (or at least large chunk) of output is formatted.
>> =20
>> Billy O'Neal
>> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
>> http://stackoverflow.com/users/82320/billy-oneal
>> =20
>>
>> On Wed, Jan 22, 2014 at 5:06 PM, wsdwsd <eulo...@live.com <javascript:>>=
wrote:
>>
>>>  I am wrong about the sizes. But I still think inheritance based=20
>>> polymorphic is a mistake.
>>>
>>> You have seen that my scanf  doesn=E2=80=99t maintain the c-style-forma=
t.=20
>>> I use
>>>
>>> fout.printf(=E2=80=9C%=E2=80=9D,fixed_precision(3.0,1));
>>> =3D=3D
>>> fprintf(fout,=E2=80=9D%.1f=E2=80=9D,3.0);
>>>
>>> The wrapper could be optimized by compilers and in fact it can be done.
>>>
>>> Sent from Windows Mail
>>>
>>> *From:* Billy O'Neal <javascript:>
>>> *Sent:* =E2=80=8ESaturday=E2=80=8E, =E2=80=8EJanuary=E2=80=8E =E2=80=8E=
18=E2=80=8E, =E2=80=8E2014 =E2=80=8E8=E2=80=8E:=E2=80=8E58=E2=80=8E =E2=80=
=8EAM
>>> *To:* std-pr...@isocpp.org <javascript:>
>>> *Cc:* wsd wsd <javascript:>, masse....@gmail.com <javascript:>
>>>
>>> I don't think a template is the way to go here. While the potential=20
>>> performance increase is there, I don't think that's the way we want to =
go=20
>>> for the "general, default" library. Real programs often have localizati=
on=20
>>> requirements, and if those values are burned in as template parameters =
you=20
>>> can't go back later and fix this by changing the string.
>>>
>>> If someone profiles and finds that they need faster formatting and don'=
t=20
>>> need localization, they can always fall back on a specialized library /=
=20
>>> implementation.
>>>
>>> Also take a look at .NET's Stream vs. StreamReader distinction -- and=
=20
>>> note that today's stringstream is similar to .NETs StringReader. e.g. t=
hey=20
>>> have 2 completely separate trees which both can be overridden; at the=
=20
>>> formatted and unformatted IO level. (Just don't repeat their mistake wh=
ere=20
>>> the formatted IO level takes ownership of the stream :) )
>>>
>>> Billy O'Neal
>>> https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
>>> http://stackoverflow.com/users/82320/billy-oneal
>>> =20
>>>
>>> On Fri, Jan 17, 2014 at 4:36 PM, Bengt Gustafsson <
>>> bengt.gu...@beamways.com <javascript:>> wrote:
>>>
>>>> I'm still working on my compilable codebase for this.
>>>>
>>>> I'm however basically on the same page as you, except that I specified=
=20
>>>> a DataFormatter template which both contains the parameters, the parsi=
ng of=20
>>>> the parameters from string form and the actual formatting of the value=
 of=20
>>>> type T.
>>>>
>>>> This template is then specialized for each T, including, as desired,=
=20
>>>> user defined types.
>>>>
>>>> The advantage is that as there is only one template name you can do=20
>>>> much more within the surrounding formatter template without having to=
=20
>>>> resort to using heap memory and virtual methods (which I don't).
>>>>
>>>> I'm getting really close to working code but I was hit by a nasty bug,=
=20
>>>> possibly a compiler bug.
>>>>
>>>> I think that the two subjects of a low level stream and a formatting=
=20
>>>> facility will ultimately be two different proposals, but in this stage=
 I=20
>>>> think we need to keep the discussion in one place to see the=20
>>>> interdependencies and requirements more clearly. I'm also thinking tha=
t we=20
>>>> need an intermediate level which basically holds the locale and maybe =
the=20
>>>> line ending mode, as ostream already has this while it seems to be=20
>>>> unnecessary baggage for a new binary file class. I think that it would=
 be=20
>>>> nice if this intermediate object held a "formatter set" that is, a=20
>>>> container of formatters for diferent types. It is however beyond me ho=
w to=20
>>>> get this without introducing things that slow the process down consire=
dably=20
>>>> such as searching a data structure for a formatter for typeid(T). Mayb=
e a=20
>>>> template template parameter which defaults to 'DataFormatter' but that=
 only=20
>>>> offers compile time specialization.=20
>>>>
>>>> Den l=C3=B6rdagen den 18:e januari 2014 kl. 00:52:18 UTC+1 skrev=20
>>>> masse....@gmail.com:
>>>>
>>>>> Hi all.
>>>>> For the things of parsing the format string only once, I do believe=
=20
>>>>> the simplest solution woul be to add some classes wich are able to co=
ntains=20
>>>>> the formatting parameters.
>>>>> For example, in .Net the NumberFormatInfo<http://msdn.microsoft.com/f=
r-fr/library/system.globalization.numberformatinfo.numberformatinfo%28v=3Dv=
s.110%29.aspx>class contains all the necessary information in order to form=
at a number.
>>>>> Then you could add a method or a ctor in order to get an object from =
a=20
>>>>> string reprsentation of the format.
>>>>> For example :
>>>>>
>>>>> string format_price(double price, locale loc =3D std::locale()) //I'l=
l=20
>>>>> explain later why I put a std::locale here=20
>>>>> {
>>>>>     static auto format =3D std::numeric_format(".2");//say that the=
=20
>>>>> prices should be formatted using 2 digits for the decimal part. Note =
that=20
>>>>> the formatting syntax still need to be defined
>>>>>     return to_string(price, format, loc);//I assume here that such an=
=20
>>>>> overload of the to_string method exists.
>>>>> }
>>>>>
>>>>> The same could be achived by doing this :
>>>>>
>>>>>  std::numeric_format get_price_format()
>>>>> {
>>>>>     std::numeric_format format;
>>>>>     format.decimal_digits =3D 2;
>>>>>     return format;
>>>>> }
>>>>>
>>>>> string format_price(double price, locale loc =3D std::locale())
>>>>> {
>>>>>     static auto format =3D get_price_format();
>>>>>     return to_string(price, format, loc);
>>>>> }
>>>>>
>>>>> Note that I separate the notion of formatting and the notion of=20
>>>>> locales on purpose.
>>>>> The idea beyond this is that they define different things.=20
>>>>> Basically:=20
>>>>> - the format will defined wich part of the data should be represented=
=20
>>>>> (and how).=20
>>>>>   For example :=20
>>>>>     * the decimal part should be represented using the first 2 digit
>>>>>     * a date should be represented with the day-of-the-month first=20
>>>>> (represented as a numeric value), the the month (using a full string=
=20
>>>>> representation), then the year (using 4 digit)
>>>>>
>>>>> - the locale will define wich char or string must be used for each=20
>>>>> part.
>>>>>   For example :=20
>>>>>     * the decimal separator to be used must be a dot. ('.')
>>>>>     * the name of the months are the strings "january", "february",=
=20
>>>>> ...if you're using an english locale for example.
>>>>>
>>>>> Now, another tought:
>>>>> It seems than this topic is speaking of 2 differents things:
>>>>> - Adding another way to provide iostream facilities
>>>>> - Adding another way to provide formatting facilities
>>>>> While those 2 are complementary, I think they are differents subject.=
=20
>>>>> Then my question is :
>>>>> What about creating a new topic about formatting facilities? (and kee=
p=20
>>>>> this one for iostream facilities)
>>>>>
>>>>>  --=20
>>>> =20
>>>> ---=20
>>>> You received this message because you are subscribed to the Google=20
>>>> Groups "ISO C++ Standard - Future Proposals" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send=
=20
>>>> an email to std-proposal...@isocpp.org <javascript:>.
>>>> To post to this group, send email to std-pr...@isocpp.org <javascript:=
>
>>>> .
>>>> Visit this group at=20
>>>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>>>
>>>
>>> =20
>>  =20
>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_1300_23046689.1390771252113
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>I think it makes sense to not worry too much about th=
e string formatters' interaction with a new "bytestreams" replacement. &nbs=
p;The whole emphasis of this thread has been on the need for them to be sep=
arate anyway - I've been fiddling with a sample bytestreams implementation =
for you all to rip apart - once it compiles and I have some performance met=
rics of worth, I'll post up the code.<br></div><div><br></div><div>The perf=
ormance won't be comparable to IOStreams until there is a formatter, of cou=
rse, since we wouldn't be comparing like with like. &nbsp;I've had an e-mai=
l from a contributor to this thread indicating a distaste for a bytestreams=
 implementation that involves inheritance from a common base class. &nbsp;F=
or me, this was just a way of allowing a use case where a client may wish t=
o hold multiple streams in an array/vector and loop over it. &nbsp;In the s=
implest case, where one only uses a single stream class, the cost of the in=
heritance should be negligible in most implementations.</div><div><br></div=
><div>If anyone has a better thought on this, I'm open for it to be discuss=
ed - would just rather it were on this list!</div><div><br>On Thursday, Jan=
uary 23, 2014 5:26:23 PM UTC, Billy O'Neal wrote:<blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;"><div dir=3D"ltr">&gt;&nbsp;<span style=3D"font-family:Ca=
libri,'Microsoft YaHei UI','Segoe UI',Meiryo,'Microsoft JhengHei UI','Malgu=
n Gothic',sans-serif;font-size:16px">cstdio is too slow and difficult to us=
e.</span><div>

<span style=3D"font-family:Calibri,'Microsoft YaHei UI','Segoe UI',Meiryo,'=
Microsoft JhengHei UI','Malgun Gothic',sans-serif;font-size:16px"><br></spa=
n></div><div><span style=3D"font-family:Calibri,'Microsoft YaHei UI','Segoe=
 UI',Meiryo,'Microsoft JhengHei UI','Malgun Gothic',sans-serif;font-size:16=
px">Yes, it is difficult to use. It really isn't all that slow. Of course t=
he speed you get will depend entirely on your particular standard library i=
mplementation.</span></div>

<div><span style=3D"font-family:Calibri,'Microsoft YaHei UI','Segoe UI',Mei=
ryo,'Microsoft JhengHei UI','Malgun Gothic',sans-serif;font-size:16px"><br>=
</span></div><div><span style=3D"font-family:Calibri,'Microsoft YaHei UI','=
Segoe UI',Meiryo,'Microsoft JhengHei UI','Malgun Gothic',sans-serif;font-si=
ze:16px">&gt;&nbsp;</span><span style=3D"font-family:Calibri,'Microsoft YaH=
ei UI','Segoe UI',Meiryo,'Microsoft JhengHei UI','Malgun Gothic',sans-serif=
;font-size:16px">Efficiency is the root of C++. C++ is made for efficiency.=
</span></div>

<div style=3D"font-family:Calibri,'Microsoft YaHei UI','Segoe UI',Meiryo,'M=
icrosoft JhengHei UI','Malgun Gothic',sans-serif;font-size:16px">If we don=
=E2=80=99t need efficiency, then why we use computers?</div>

<div style=3D"font-family:Calibri,'Microsoft YaHei UI','Segoe UI',Meiryo,'M=
icrosoft JhengHei UI','Malgun Gothic',sans-serif;font-size:16px"><br></div>=
<div style=3D"font-family:Calibri,'Microsoft YaHei UI','Segoe UI',Meiryo,'M=
icrosoft JhengHei UI','Malgun Gothic',sans-serif;font-size:16px">

Efficiency is a big part, yes. But it is not the only part. It matters not =
how fast your program is if it produces wrong answers.</div><div style=3D"f=
ont-family:Calibri,'Microsoft YaHei UI','Segoe UI',Meiryo,'Microsoft JhengH=
ei UI','Malgun Gothic',sans-serif;font-size:16px">

<br></div><div style=3D"font-family:Calibri,'Microsoft YaHei UI','Segoe UI'=
,Meiryo,'Microsoft JhengHei UI','Malgun Gothic',sans-serif;font-size:16px">=
&gt;&nbsp;<span style=3D"font-family:arial,sans-serif;font-size:13px">Compa=
red to the flexible version that can be used by external people to control =
output and is not hardcoded:</span></div>

<span style=3D"font-family:arial,sans-serif;font-size:13px">format("{0:e.3}=
: {1:x.8}"); // Syntax is for exposition only</span><div style=3D"font-fami=
ly:Calibri,'Microsoft YaHei UI','Segoe UI',Meiryo,'Microsoft JhengHei UI','=
Malgun Gothic',sans-serif;font-size:16px">

<br></div><div style=3D"font-family:Calibri,'Microsoft YaHei UI','Segoe UI'=
,Meiryo,'Microsoft JhengHei UI','Malgun Gothic',sans-serif;font-size:16px">=
Sounds good to me. What happens if the format string and what the programme=
r has set disagree? Fast Format gets around this by having completely separ=
ate APIs; write and format.</div>

<div style=3D"font-family:Calibri,'Microsoft YaHei UI','Segoe UI',Meiryo,'M=
icrosoft JhengHei UI','Malgun Gothic',sans-serif;font-size:16px"><br></div>=
<div style=3D"font-family:Calibri,'Microsoft YaHei UI','Segoe UI',Meiryo,'M=
icrosoft JhengHei UI','Malgun Gothic',sans-serif;font-size:16px">

&gt;&nbsp;<span style=3D"font-family:arial,sans-serif;font-size:13px">I wou=
ld really like to see some numbers. Is the typical iostream use case I/O or=
 CPU bound?</span></div><div style=3D"font-family:Calibri,'Microsoft YaHei =
UI','Segoe UI',Meiryo,'Microsoft JhengHei UI','Malgun Gothic',sans-serif;fo=
nt-size:16px">

<br></div><div style=3D"font-family:Calibri,'Microsoft YaHei UI','Segoe UI'=
,Meiryo,'Microsoft JhengHei UI','Malgun Gothic',sans-serif;font-size:16px">=
This is what I said cstdio. IOStream is notoriously slow because it incurs =
virtual call overhead for relatively small chunks of IO. Moreover, to my un=
derstanding, the built in codecvt facet system converts characters one at a=
 time between encodings, which is 1. often wrong, and 2. often very ineffic=
ient.</div>

<div style=3D"font-family:Calibri,'Microsoft YaHei UI','Segoe UI',Meiryo,'M=
icrosoft JhengHei UI','Malgun Gothic',sans-serif;font-size:16px"><br></div>=
<div style=3D"font-family:Calibri,'Microsoft YaHei UI','Segoe UI',Meiryo,'M=
icrosoft JhengHei UI','Malgun Gothic',sans-serif;font-size:16px">

If we want to actually do IO quickly we would need to look into asynchronou=
s systems. Right now iostreams has no asynchronous IO facility despite this=
 often being a far more efficient way to do IO.</div><div style=3D"font-fam=
ily:Calibri,'Microsoft YaHei UI','Segoe UI',Meiryo,'Microsoft JhengHei UI',=
'Malgun Gothic',sans-serif;font-size:16px">

<br></div><div style=3D"font-family:Calibri,'Microsoft YaHei UI','Segoe UI'=
,Meiryo,'Microsoft JhengHei UI','Malgun Gothic',sans-serif;font-size:16px">=
&gt;&nbsp;<span style=3D"font-family:arial,sans-serif;font-size:13px">I wan=
t to emphasize that I have not done anything amongst the "bytestream" aspec=
t of this thread and am currently only focusing on the formatting part.</sp=
an></div>

<div style=3D"font-family:Calibri,'Microsoft YaHei UI','Segoe UI',Meiryo,'M=
icrosoft JhengHei UI','Malgun Gothic',sans-serif;font-size:16px"><br></div>=
<div style=3D"font-family:Calibri,'Microsoft YaHei UI','Segoe UI',Meiryo,'M=
icrosoft JhengHei UI','Malgun Gothic',sans-serif;font-size:16px">

That's probably the right spot for now.</div></div><div><br clear=3D"all"><=
div><div dir=3D"ltr"><div>Billy O'Neal</div><div><a href=3D"https://bitbuck=
et.org/BillyONeal/" target=3D"_blank" onmousedown=3D"this.href=3D'https://w=
ww.google.com/url?q\75https%3A%2F%2Fbitbucket.org%2FBillyONeal%2F\46sa\75D\=
46sntz\0751\46usg\75AFQjCNEUaaIry0cea0l0vX6ztWgwQ7_4Lg';return true;" oncli=
ck=3D"this.href=3D'https://www.google.com/url?q\75https%3A%2F%2Fbitbucket.o=
rg%2FBillyONeal%2F\46sa\75D\46sntz\0751\46usg\75AFQjCNEUaaIry0cea0l0vX6ztWg=
wQ7_4Lg';return true;">https://github.com/BillyONeal/</a></div>

<div><a href=3D"http://stackoverflow.com/users/82320/billy-oneal" target=3D=
"_blank" onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A%=
2F%2Fstackoverflow.com%2Fusers%2F82320%2Fbilly-oneal\46sa\75D\46sntz\0751\4=
6usg\75AFQjCNHY_gA133vyg0yY-U2PNMVA8cCSBg';return true;" onclick=3D"this.hr=
ef=3D'http://www.google.com/url?q\75http%3A%2F%2Fstackoverflow.com%2Fusers%=
2F82320%2Fbilly-oneal\46sa\75D\46sntz\0751\46usg\75AFQjCNHY_gA133vyg0yY-U2P=
NMVA8cCSBg';return true;">http://stackoverflow.com/<wbr>users/82320/billy-o=
neal</a></div></div></div>
<br><br><div class=3D"gmail_quote">On Wed, Jan 22, 2014 at 11:46 PM, wsdwsd=
 <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfusc=
ated-mailto=3D"L-r6fmQNswsJ" onmousedown=3D"this.href=3D'javascript:';retur=
n true;" onclick=3D"this.href=3D'javascript:';return true;">eulo...@live.co=
m</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">






<div dir=3D"ltr">
<div dir=3D"ltr" style=3D"font-family:'Calibri','Microsoft YaHei UI','Segoe=
 UI','Meiryo','Microsoft JhengHei UI','Malgun Gothic','sans-serif';font-siz=
e:12pt"><div>

cstdio is too slow and difficult to use.</div><div>It=E2=80=99s 10 times sl=
ower than handwriting.</div><div><br></div><div>how can I read size_t by us=
ing cstdio?</div><div><br></div><div>%zu? not be supported..</div>

<div>%u? wrong</div><div>%llu? wrong.</div><div>So cstdio is also a big fai=
lure.</div><div><br></div><div>I think our&nbsp;actions are to make program=
mers not to use native API and&nbsp;so-called low-level.</div>

<div><br></div><div>Efficiency is the root of C++. C++ is made for efficien=
cy.</div><div>If we don=E2=80=99t need efficiency, then why we use computer=
s?<br></div><div><div><br></div><div>Sent from Windows Mail</div>

<div><br></div></div><div style=3D"padding-top:5px;border-top-color:rgb(229=
,229,229);border-top-width:1px;border-top-style:solid"><div><font face=3D" =
'Calibri', 'Microsoft YaHei UI', 'Segoe UI', 'Meiryo', 'Microsoft JhengHei =
UI', 'Malgun Gothic', 'sans-serif'" style=3D"line-height:15pt;letter-spacin=
g:0.02em;font-family:&quot;Calibri&quot;,&quot;Microsoft YaHei UI&quot;,&qu=
ot;Segoe UI&quot;,&quot;Meiryo&quot;,&quot;Microsoft JhengHei UI&quot;,&quo=
t;Malgun Gothic&quot;,&quot;sans-serif&quot;;font-size:12pt"><b>From:</b>&n=
bsp;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"L-r6=
fmQNswsJ" onmousedown=3D"this.href=3D'javascript:';return true;" onclick=3D=
"this.href=3D'javascript:';return true;">Billy O'Neal</a><br>

<b>Sent:</b>&nbsp;=E2=80=8EThursday=E2=80=8E, =E2=80=8EJanuary=E2=80=8E =E2=
=80=8E23=E2=80=8E, =E2=80=8E2014 =E2=80=8E3=E2=80=8E:=E2=80=8E37=E2=80=8E =
=E2=80=8EPM<br><b>To:</b>&nbsp;<a href=3D"javascript:" target=3D"_blank" gd=
f-obfuscated-mailto=3D"L-r6fmQNswsJ" onmousedown=3D"this.href=3D'javascript=
:';return true;" onclick=3D"this.href=3D'javascript:';return true;">wsd wsd=
</a>, <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"L-=
r6fmQNswsJ" onmousedown=3D"this.href=3D'javascript:';return true;" onclick=
=3D"this.href=3D'javascript:';return true;">std-pr...@isocpp.org</a></font>=
</div>

</div><div><div><div><br></div><div dir=3D"ltr"><div style=3D"font-family:C=
alibri,sans-serif;font-size:12pt"><div>Your "dislike" is irrelevant.</div><=
div><br></div><div>Localization is more common a requirement than is a requ=
irement for faster formatting than cstdio can provide. It is far simpler to=
 implement faster IO on top of features provided by a platform than it is t=
o implement a whole formatter library. I would be highly Highly surprised i=
f 99% of such uses are dominated by secondary storage rather than CPU time =
in any case.</div>

<div><br></div><div>Things that go into the standard are those which provid=
e the most value to most general purpose software; not the fastest possible=
 implementation of something just for fastness' sake. Performance matters, =
but so does utility.</div>

<div><br></div><div>Sent from a touchscreen. Please excuse the brevity and =
tpyos.</div><br><div>----- Reply message -----<br>From: "wsdwsd" &lt;<a hre=
f=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"L-r6fmQNswsJ" =
onmousedown=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=
=3D'javascript:';return true;">eulo...@live.com</a>&gt;<br>

To: "Billy O'Neal" &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfusc=
ated-mailto=3D"L-r6fmQNswsJ" onmousedown=3D"this.href=3D'javascript:';retur=
n true;" onclick=3D"this.href=3D'javascript:';return true;">billy...@gmail.=
com</a>&gt;<br>Subject: [std-proposals] Re: The failures of iostreams<br>Da=
te: Wed, Jan 22, 2014 10:55 PM</div>

</div><br>
<div>You misunderstand my meanings.</div><div><br></div><div>I mean:</div><=
div>mofstream fout(=E2=80=9Ca.txt=E2=80=9D);<br></div><div><div>fout.printf=
(=E2=80=9C%=E2=80=9D,fixed_<wbr>precision(3.0,1));</div><div>=3D=3D</div>

<div><div>std::unique_ptr&lt;std::FILE,<wbr>decltype(fclose)*&gt; fp(std::f=
open(=E2=80=9Ca.txt=E2=80=9D,=E2=80=9Dw=E2=80=9D),<wbr>fclose);</div><div>f=
printf(fp.get(),=E2=80=9D%.1f=E2=80=9D,3.0);</div></div></div><div><br></di=
v><div><div><br></div><div>

Localization is the most useless things for many programmers.</div><div>I d=
islike localization, for I don=E2=80=99t need it at all. For example, for C=
hinese characters(for I don=E2=80=99t know what is its length, maybe 2 byte=
s, maybe 3 bytes and maybe 4 bytes), localization is almost&nbsp;no use.</d=
iv>

<div>And&nbsp;the localization of my country&nbsp;is as same as ISO. We&nbs=
p;only use the&nbsp;ISO units, numbers.</div><div><br></div><div>Just like =
I dislike&nbsp;N, J&nbsp;such units, they are all no reason to use at all.(=
The&nbsp;=E2=80=9CINCH=E2=80=9D I never use it.)</div>

<div>I use kg.m.s^-2 to represent N.</div><div>I use kg.m^2.s^-2 to represe=
nt J.</div><div>The reason is&nbsp;that these units are more easy for me to=
 understand what it connected to and easily to be&nbsp;computed.</div>

<div>I don=E2=80=99t think localization is a must for C++, for most program=
mers truly don=E2=80=99t need.</div><div><br></div><div>If a programmer tru=
ly needs it, he/she can easily write it.</div><div><br></div><div>

IO operations need efficiency. If we can=E2=80=99t give programmers enough =
high efficiency, our new io libraries will still be failure. There are alwa=
ys programmers who use native API and make C++ more difficult to learn.</di=
v><div>

<br></div><div>Many people think C++ is slow just because the efficiency of=
 iostream and cstdio.</div><div>If we can&nbsp;provide a high-speed io libr=
ary, C++ will have a better future.</div><div>When&nbsp;we provide a high-s=
peed io library without localization, without mutex, it will be difficult f=
or them to be unsatisfied&nbsp;to C++.</div>

<div><br></div><div>Sent from Windows Mail</div><div><br></div></div><div s=
tyle=3D"padding-top:5px;border-top-color:rgb(229,229,229);border-top-width:=
1px;border-top-style:solid"><div><font face=3D" 'Calibri', 'Microsoft YaHei=
 UI', 'Segoe UI', 'Meiryo', 'Microsoft JhengHei UI', 'Malgun Gothic', 'sans=
-serif'" style=3D"line-height:15pt;letter-spacing:0.02em;font-family:&quot;=
Calibri&quot;,&quot;Microsoft YaHei UI&quot;,&quot;Segoe UI&quot;,&quot;Mei=
ryo&quot;,&quot;Microsoft JhengHei UI&quot;,&quot;Malgun Gothic&quot;,&quot=
;sans-serif&quot;;font-size:12pt"><b>From:</b>&nbsp;<a href=3D"javascript:"=
 target=3D"_blank" gdf-obfuscated-mailto=3D"L-r6fmQNswsJ" onmousedown=3D"th=
is.href=3D'javascript:';return true;" onclick=3D"this.href=3D'javascript:';=
return true;">Billy O'Neal</a><br>

<b>Sent:</b>&nbsp;=E2=80=8EThursday=E2=80=8E, =E2=80=8EJanuary=E2=80=8E =E2=
=80=8E23=E2=80=8E, =E2=80=8E2014 =E2=80=8E11=E2=80=8E:=E2=80=8E02=E2=80=8E =
=E2=80=8EAM<br><b>To:</b>&nbsp;<a href=3D"javascript:" target=3D"_blank" gd=
f-obfuscated-mailto=3D"L-r6fmQNswsJ" onmousedown=3D"this.href=3D'javascript=
:';return true;" onclick=3D"this.href=3D'javascript:';return true;">wsd wsd=
</a></font></div></div><div><br></div><div dir=3D""><div dir=3D"ltr"><div>T=
hat is undesirable because you can't localize the digit format. And the dig=
it format certainly does change from one culture to another.</div>

<div><br></div><div>At least in your example above you would probably want<=
/div>

<div><br></div><div>printf(fout, ....);</div><div><br></div><div>there woul=
d be polymorphic calls inside fout to allow someone to change where the out=
put is actually written. For instance, in the "real" case writing to a file=
, but for testing purposes writing to a string or memory buffer.</div>



<div><br></div><div>This way the formatting code can be completely optimize=
d, and the relatively expensive virtual call overhead only happens after a =
complete (or at least large chunk) of output is formatted.</div></div>


<div>
<br clear=3D"all"><div><div dir=3D"ltr"><div>Billy O'Neal</div><div><a href=
=3D"https://bitbucket.org/BillyONeal/" target=3D"_blank" onmousedown=3D"thi=
s.href=3D'https://www.google.com/url?q\75https%3A%2F%2Fbitbucket.org%2FBill=
yONeal%2F\46sa\75D\46sntz\0751\46usg\75AFQjCNEUaaIry0cea0l0vX6ztWgwQ7_4Lg';=
return true;" onclick=3D"this.href=3D'https://www.google.com/url?q\75https%=
3A%2F%2Fbitbucket.org%2FBillyONeal%2F\46sa\75D\46sntz\0751\46usg\75AFQjCNEU=
aaIry0cea0l0vX6ztWgwQ7_4Lg';return true;">https://github.com/BillyONeal/</a=
></div><div><a href=3D"http://stackoverflow.com/users/82320/billy-oneal" ta=
rget=3D"_blank" onmousedown=3D"this.href=3D'http://www.google.com/url?q\75h=
ttp%3A%2F%2Fstackoverflow.com%2Fusers%2F82320%2Fbilly-oneal\46sa\75D\46sntz=
\0751\46usg\75AFQjCNHY_gA133vyg0yY-U2PNMVA8cCSBg';return true;" onclick=3D"=
this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fstackoverflow.com%2=
Fusers%2F82320%2Fbilly-oneal\46sa\75D\46sntz\0751\46usg\75AFQjCNHY_gA133vyg=
0yY-U2PNMVA8cCSBg';return true;">http://stackoverflow.com/<wbr>users/82320/=
billy-oneal</a></div>



</div></div>
<br><br><div class=3D"gmail_quote">On Wed, Jan 22, 2014 at 5:06 PM, wsdwsd =
<span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfusca=
ted-mailto=3D"L-r6fmQNswsJ" onmousedown=3D"this.href=3D'javascript:';return=
 true;" onclick=3D"this.href=3D'javascript:';return true;">eulo...@live.com=
</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin=
:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);bord=
er-left-width:1px;border-left-style:solid">








<div dir=3D"ltr">
<div style=3D"font-family:&quot;Calibri&quot;,&quot;Microsoft YaHei UI&quot=
;,&quot;Segoe UI&quot;,&quot;Meiryo&quot;,&quot;Microsoft JhengHei UI&quot;=
,&quot;Malgun Gothic&quot;,&quot;sans-serif&quot;;font-size:12pt" dir=3D"lt=
r">



<div>I am wrong about the sizes. But I still think inheritance based polymo=
rphic is a mistake.</div><div><br></div><div>You have seen that my scanf&nb=
sp; doesn=E2=80=99t maintain the c-style-format. </div><div>I use</div><div=
><br></div>



<div>fout.printf(=E2=80=9C%=E2=80=9D,fixed_<wbr>precision(3.0,1));<br></div=
><div><div>=3D=3D</div><div>fprintf(fout,=E2=80=9D%.1f=E2=80=9D,3.0);</div>=
<div><br></div><div>The wrapper could be optimized by compilers and in fact=
&nbsp;it can be done.</div><div><br></div>



<div>Sent from Windows Mail</div><div><br></div></div><div style=3D"padding=
-top:5px;border-top-color:rgb(229,229,229);border-top-width:1px;border-top-=
style:solid"><div><font face=3D" 'Calibri', 'Microsoft YaHei UI', 'Segoe UI=
', 'Meiryo', 'Microsoft JhengHei UI', 'Malgun Gothic', 'sans-serif'" style=
=3D"line-height:15pt;letter-spacing:0.02em;font-family:&quot;Calibri&quot;,=
&quot;Microsoft YaHei UI&quot;,&quot;Segoe UI&quot;,&quot;Meiryo&quot;,&quo=
t;Microsoft JhengHei UI&quot;,&quot;Malgun Gothic&quot;,&quot;sans-serif&qu=
ot;;font-size:12pt"><b>From:</b>&nbsp;<a href=3D"javascript:" target=3D"_bl=
ank" gdf-obfuscated-mailto=3D"L-r6fmQNswsJ" onmousedown=3D"this.href=3D'jav=
ascript:';return true;" onclick=3D"this.href=3D'javascript:';return true;">=
Billy O'Neal</a><br>



<b>Sent:</b>&nbsp;=E2=80=8ESaturday=E2=80=8E, =E2=80=8EJanuary=E2=80=8E =E2=
=80=8E18=E2=80=8E, =E2=80=8E2014 =E2=80=8E8=E2=80=8E:=E2=80=8E58=E2=80=8E =
=E2=80=8EAM<br><b>To:</b>&nbsp;<a href=3D"javascript:" target=3D"_blank" gd=
f-obfuscated-mailto=3D"L-r6fmQNswsJ" onmousedown=3D"this.href=3D'javascript=
:';return true;" onclick=3D"this.href=3D'javascript:';return true;">std-pr.=
...@isocpp.org</a><br><b>Cc:</b>&nbsp;<a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"L-r6fmQNswsJ" onmousedown=3D"this.href=3D'java=
script:';return true;" onclick=3D"this.href=3D'javascript:';return true;">w=
sd wsd</a>, <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=
=3D"L-r6fmQNswsJ" onmousedown=3D"this.href=3D'javascript:';return true;" on=
click=3D"this.href=3D'javascript:';return true;">masse....@gmail.com</a></f=
ont></div>



</div><div><br></div><div dir=3D""><div dir=3D"ltr"><div>I don't think a te=
mplate is the way to go here. While the potential performance increase is t=
here, I don't think that's the way we want to go for the "general, default"=
 library. Real programs often have localization requirements, and if those =
values are burned in as template parameters you can't go back later and fix=
 this by changing the string.</div>





<div><br></div><div>If someone profiles and finds that they need faster for=
matting and don't need localization, they can always fall back on a special=
ized library / implementation.</div><div><br></div><div>Also take a look at=
 .NET's Stream vs. StreamReader distinction -- and note that today's string=
stream is similar to .NETs StringReader. e.g. they have 2 completely separa=
te trees which both can be overridden; at the formatted and unformatted IO =
level. (Just don't repeat their mistake where the formatted IO level takes =
ownership of the stream :) )</div>





</div><div><br clear=3D"all"><div><div dir=3D"ltr"><div>Billy O'Neal</div><=
div><a href=3D"https://bitbucket.org/BillyONeal/" target=3D"_blank" onmouse=
down=3D"this.href=3D'https://www.google.com/url?q\75https%3A%2F%2Fbitbucket=
..org%2FBillyONeal%2F\46sa\75D\46sntz\0751\46usg\75AFQjCNEUaaIry0cea0l0vX6zt=
WgwQ7_4Lg';return true;" onclick=3D"this.href=3D'https://www.google.com/url=
?q\75https%3A%2F%2Fbitbucket.org%2FBillyONeal%2F\46sa\75D\46sntz\0751\46usg=
\75AFQjCNEUaaIry0cea0l0vX6ztWgwQ7_4Lg';return true;">https://github.com/Bil=
lyONeal/</a></div><div><a href=3D"http://stackoverflow.com/users/82320/bill=
y-oneal" target=3D"_blank" onmousedown=3D"this.href=3D'http://www.google.co=
m/url?q\75http%3A%2F%2Fstackoverflow.com%2Fusers%2F82320%2Fbilly-oneal\46sa=
\75D\46sntz\0751\46usg\75AFQjCNHY_gA133vyg0yY-U2PNMVA8cCSBg';return true;" =
onclick=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fstackove=
rflow.com%2Fusers%2F82320%2Fbilly-oneal\46sa\75D\46sntz\0751\46usg\75AFQjCN=
HY_gA133vyg0yY-U2PNMVA8cCSBg';return true;">http://stackoverflow.com/<wbr>u=
sers/82320/billy-oneal</a></div>





</div></div>
<br><br><div class=3D"gmail_quote">On Fri, Jan 17, 2014 at 4:36 PM, Bengt G=
ustafsson <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" g=
df-obfuscated-mailto=3D"L-r6fmQNswsJ" onmousedown=3D"this.href=3D'javascrip=
t:';return true;" onclick=3D"this.href=3D'javascript:';return true;">bengt.=
gu...@beamways.com</a><wbr>&gt;</span> wrote:<br>





<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding=
-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-l=
eft-style:solid"><div dir=3D"ltr">I'm still working on my compilable codeba=
se for this.<div>



<br></div><div>I'm however basically on the same page as you, except that I=
 specified a DataFormatter template which both contains the parameters, the=
 parsing of the parameters from string form and the actual formatting of th=
e value of type T.</div>





<div><br></div><div>This template is then specialized for each T, including=
, as desired, user defined types.</div><div><br></div><div>The advantage is=
 that as there is only one template name you can do much more within the su=
rrounding formatter template without having to resort to using heap memory =
and virtual methods (which I don't).</div>





<div><br></div><div>I'm getting really close to working code but I was hit =
by a nasty bug, possibly a compiler bug.</div><div><br></div><div>I think t=
hat the two subjects of a low level stream and a formatting facility will u=
ltimately be two different proposals, but in this stage I think we need to =
keep the discussion in one place to see the interdependencies and requireme=
nts more clearly. I'm also thinking that we need an intermediate level whic=
h basically holds the locale and maybe the line ending mode, as ostream alr=
eady has this while it seems to be unnecessary baggage for a new binary fil=
e class. I think that it would be nice if this intermediate object held a "=
formatter set" that is, a container of formatters for diferent types. It is=
 however beyond me how to get this without introducing things that slow the=
 process down consiredably such as searching a data structure for a formatt=
er for typeid(T). Maybe a template template parameter which defaults to 'Da=
taFormatter' but that only offers compile time specialization.&nbsp;</div>





<div><div><br>Den l=C3=B6rdagen den 18:e januari 2014 kl. 00:52:18 UTC+1 sk=
rev <a>masse....@gmail.com</a>:<div><div><blockquote class=3D"gmail_quote" =
style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(20=
4,204,204);border-left-width:1px;border-left-style:solid">





<div dir=3D"ltr">Hi all.<br>For the things of parsing the format string onl=
y once, I do believe the simplest solution woul be to add some classes wich=
 are able to contains the formatting parameters.<br>For example, in .Net th=
e <a href=3D"http://msdn.microsoft.com/fr-fr/library/system.globalization.n=
umberformatinfo.numberformatinfo%28v=3Dvs.110%29.aspx" target=3D"_blank" on=
mousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fmsdn.m=
icrosoft.com%2Ffr-fr%2Flibrary%2Fsystem.globalization.numberformatinfo.numb=
erformatinfo%2528v%3Dvs.110%2529.aspx\46sa\75D\46sntz\0751\46usg\75AFQjCNG7=
q0AGg2cpBKPq8H5K4QMXAmth4A';return true;" onclick=3D"this.href=3D'http://ww=
w.google.com/url?q\75http%3A%2F%2Fmsdn.microsoft.com%2Ffr-fr%2Flibrary%2Fsy=
stem.globalization.numberformatinfo.numberformatinfo%2528v%3Dvs.110%2529.as=
px\46sa\75D\46sntz\0751\46usg\75AFQjCNG7q0AGg2cpBKPq8H5K4QMXAmth4A';return =
true;">NumberFormatInfo</a> class contains all the necessary information in=
 order to format a number.<br>





Then you could add a method or a ctor in order to get an object from a stri=
ng reprsentation of the format.<br>For example :<br><div style=3D"border:1p=
x solid rgb(187,187,187);background-color:rgb(250,250,250)"><code><div><spa=
n><br>





</span><span style=3D"color:rgb(0,0,136)">string</span><span> format_price<=
/span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb=
(0,0,136)">double</span><span> price</span><span style=3D"color:rgb(102,102=
,0)">,</span><span> locale loc </span><span style=3D"color:rgb(102,102,0)">=
=3D</span><span> std</span><span style=3D"color:rgb(102,102,0)">::</span><s=
pan>locale</span><span style=3D"color:rgb(102,102,0)">())</span><span> </sp=
an><span style=3D"color:rgb(136,0,0)">//I'll explain later why I put a std:=
:locale here </span><span><br>





</span><span style=3D"color:rgb(102,102,0)">{</span><span><br>&nbsp; &nbsp;=
 </span><span style=3D"color:rgb(0,0,136)">static</span><span> </span><span=
 style=3D"color:rgb(0,0,136)">auto</span><span> format </span><span style=
=3D"color:rgb(102,102,0)">=3D</span><span> std</span><span style=3D"color:r=
gb(102,102,0)">::</span><span>numeric_format</span><span style=3D"color:rgb=
(102,102,0)">(</span><span style=3D"color:rgb(0,136,0)">".2"</span><span st=
yle=3D"color:rgb(102,102,0)">);</span><span style=3D"color:rgb(136,0,0)">//=
<u></u>sa<wbr>y that the prices should be formatted using 2 digits for the =
decimal part. Note that the formatting syntax still need to be defined</spa=
n><span><br>





&nbsp; &nbsp; </span><span style=3D"color:rgb(0,0,136)">return</span><span>=
 to_string</span><span style=3D"color:rgb(102,102,0)">(</span><span>price</=
span><span style=3D"color:rgb(102,102,0)">,</span><span> format</span><span=
 style=3D"color:rgb(102,102,0)">,</span><span> loc</span><span style=3D"col=
or:rgb(102,102,0)">);</span><span style=3D"color:rgb(136,0,0)">//I assume h=
ere that such an overload of the to_string method exists.</span><span><br>





</span><span style=3D"color:rgb(102,102,0)">}</span><span><br></span></div>=
</code></div><br>The same could be achived by doing this :<br><br><div styl=
e=3D"border:1px solid rgb(187,187,187);background-color:rgb(250,250,250)">




<code><div>
<span>std</span><span style=3D"color:rgb(102,102,0)">::</span><span>numeric=
_format get_price_format</span><span style=3D"color:rgb(102,102,0)">()</spa=
n><span><br></span><span style=3D"color:rgb(102,102,0)">{</span><span><br>&=
nbsp; &nbsp; std</span><span style=3D"color:rgb(102,102,0)">::</span><span>=
numeric_format format</span><span style=3D"color:rgb(102,102,0)">;</span><s=
pan><br>





&nbsp; &nbsp; format</span><span style=3D"color:rgb(102,102,0)">.</span><sp=
an>decimal_digits </span><span style=3D"color:rgb(102,102,0)">=3D</span><sp=
an> </span><span style=3D"color:rgb(0,102,102)">2</span><span style=3D"colo=
r:rgb(102,102,0)">;</span><span><br>





&nbsp; &nbsp; </span><span style=3D"color:rgb(0,0,136)">return</span><span>=
 format</span><span style=3D"color:rgb(102,102,0)">;</span><span><br></span=
><span style=3D"color:rgb(102,102,0)">}</span><span><br><br></span><span st=
yle=3D"color:rgb(0,0,136)">string</span><span> format_price</span><span sty=
le=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,136)">doub=
le</span><span> price</span><span style=3D"color:rgb(102,102,0)">,</span><s=
pan> locale loc </span><span style=3D"color:rgb(102,102,0)">=3D</span><span=
> std</span><span style=3D"color:rgb(102,102,0)">::</span><span>locale</spa=
n><span style=3D"color:rgb(102,102,0)">())</span><span><br>





</span><span style=3D"color:rgb(102,102,0)">{</span><span><br>&nbsp; &nbsp;=
 </span><span style=3D"color:rgb(0,0,136)">static</span><span> </span><span=
 style=3D"color:rgb(0,0,136)">auto</span><span> format </span><span style=
=3D"color:rgb(102,102,0)">=3D</span><span> get_price_format</span><span sty=
le=3D"color:rgb(102,102,0)">();</span><span><br>





&nbsp; &nbsp; </span><span style=3D"color:rgb(0,0,136)">return</span><span>=
 to_string</span><span style=3D"color:rgb(102,102,0)">(</span><span>price</=
span><span style=3D"color:rgb(102,102,0)">,</span><span> format</span><span=
 style=3D"color:rgb(102,102,0)">,</span><span> loc</span><span style=3D"col=
or:rgb(102,102,0)">);</span><span><br>





</span><span style=3D"color:rgb(102,102,0)">}</span><span><br></span></div>=
</code></div><br>Note that I separate the notion of formatting and the noti=
on of locales on purpose.<br>The idea beyond this is that they define diffe=
rent things. <br>





Basically: <br>- the format will defined wich part of the data should be re=
presented (and how). <br>&nbsp; For example : <br>&nbsp;&nbsp;&nbsp; * the =
decimal part should be represented using the first 2 digit<br>&nbsp;&nbsp;&=
nbsp; * a date should be represented with the day-of-the-month first (repre=
sented as a numeric value), the the month (using a full string representati=
on), then the year (using 4 digit)<br>





<br>- the locale will define wich char or string must be used for each part=
..<br>&nbsp; For example : <br>&nbsp;&nbsp;&nbsp; * the decimal separator to=
 be used must be a dot. ('.')<br>&nbsp;&nbsp;&nbsp; * the name of the month=
s are the strings "january", "february", ...if you're using an english loca=
le for example.<br>





<br>Now, another tought:<br>It seems than this topic is speaking of 2 diffe=
rents things:<br>- Adding another way to provide iostream facilities<br>- A=
dding another way to provide formatting facilities<br>While those 2 are com=
plementary, I think they are differents subject. Then my question is :<br>





What about creating a new topic about formatting facilities? (and keep this=
 one for  iostream facilities)<span><font color=3D"#888888"><br><br></font>=
</span></div></blockquote></div></div></div></div></div><span><font color=
=3D"#888888"><div>



<div>

<p></p>

-- <br>
&nbsp;<br>
--- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
L-r6fmQNswsJ" onmousedown=3D"this.href=3D'javascript:';return true;" onclic=
k=3D"this.href=3D'javascript:';return true;">std-proposal...@<wbr>isocpp.or=
g</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"L-r6fmQNswsJ" onmousedown=3D"this.href=3D'java=
script:';return true;" onclick=3D"this.href=3D'javascript:';return true;">s=
td-pr...@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank" onmousedown=3D"this.href=3D'http://groups=
..google.com/a/isocpp.org/group/std-proposals/';return true;" onclick=3D"thi=
s.href=3D'http://groups.google.com/a/isocpp.org/group/std-proposals/';retur=
n true;">http://groups.google.com/a/<wbr>isocpp.org/group/std-<wbr>proposal=
s/</a>.<br>
</div></div></font></span></blockquote></div><br></div>
</div></div>
</div>

</blockquote></div><br></div>
</div>


</div></div></div></div>
</div>

</blockquote></div><br></div>
</blockquote></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1300_23046689.1390771252113--

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Sun, 2 Feb 2014 20:51:01 -0800 (PST)
Raw View
------=_Part_705_10502548.1391403061608
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

After a while of thinking, Miro, I admit that you are right: The reuse and=
=20
on-spot formatting cases can be separated so that the cost of having to use=
=20
memory allocation in the reuse case does not imply such overhead in the=20
on-spot case. This of course needs to separate the code more than I did in=
=20
my implementation, but that's not a big deal.

Instead an implementation should try to avoid having to reimplement the=20
format string parsing for each template instantiation as it causes code=20
bloat, but I don't know if this is possible without virtual method calling=
=20
overhead. I admit to not having checked the implementation parts of your=20
code. I have not had time, sorry.


Den m=C3=A5ndagen den 20:e januari 2014 kl. 03:07:44 UTC+1 skrev Bengt=20
Gustafsson:
>
> Sorry for misspelling your name like that.
>
> Your idea with the PrettyPrintedInt is a very simple way to customize=20
> printing of an int. It works in many cases although it may be a bit=20
> annoying in the on-spot case to write those type names out. In some cases=
=20
> the formatting is more connected to the stream so we should also provide =
an=20
> option for that case if possible.
>
> The precompilation in the Init() method of DataFormatter can of course=20
> perform whatever operations needed and store whatever results this=20
> generates in its members. It could kick up clang to compile the appropria=
te=20
> c function into assembly for instance...
>
>
>
>
>
> Den s=C3=B6ndagen den 19:e januari 2014 kl. 17:02:08 UTC-8 skrev Miro Kne=
jp:
>>
>>
>> Am 20.01.2014 00:46, schrieb Brent Friedman:=20
>> > I understand the motivation now. But you don't have to know at compile=
=20
>> > time what your string is and how you want to print it. The parameter=
=20
>> > formatter can be as dynamic as you want it to be. Build the object=20
>> > dynamically. Throw in some virtuals if you feel like it.=20
>> >=20
>> > Here would be your example, then:=20
>> >=20
>> > //create DateFormat from designer spec=20
>> > string user_spec =3D get_user_format_spec();=20
>> > format("{0}", DateFormat(spec, tm1));=20
>> >=20
>> >  //create DateFormat from a localized config string (german might be=
=20
>> > TT/mm/JJ instead of DD/mm/YY).=20
>> > string user_spec =3D get_user_format_spec( current_language );=20
>> > format( "{0}", DateFormat(current_language, user_spec, tm1));=20
>> >=20
>> > And with little work we can also make it programmer friendly.=20
>> >=20
>> > //default, developer DateFormat=20
>> > format( "{0}", DateFormat(tm1));=20
>> >=20
>> > //default for the given language=20
>> > format( "{0}", DateFormat::lang(current_language).at(tm1);=20
>> >=20
>> > //use ISO 8601=20
>> > format( "{0}", DateFormat( iso_8601, tm1));=20
>> >=20
>> > You don't have to write a parser to add new options, just add the=20
>> > method to your format object and interface that with the outside world=
..=20
>> >=20
>> > It seems, then, like non-positional format string parameters are an=20
>> > unnecessary complication.=20
>> >=20
>> That is still hardcoding how the output should look like. Technically=20
>> you can do the same with my implementation already:=20
>>
>> Just don't use "formatter<int>" but "formatter<MyPrettyPrintedInt>"=20
>> where "MyPrettyPrintedInt" is implicitly constructible from "int",=20
>> define to_string(const MyPrettyPrintedInt &) and you have your hardcoded=
=20
>> formatting that ignores any options passed into the format string. Yay!=
=20
>> (Same holds true for Bengt's implementaiton, although it works a bit=20
>> differently.)=20
>>
>> So from:=20
>> formatter<int> fmt(ui_string_12345);=20
>> format(fmt, i);=20
>>
>> formatter<MyPrettyPrintedInt> fmt(ui_string_12345);=20
>> format(fmt, i);=20
>>
>> or if you need some options:=20
>> format(fmt, MyPrettyPrintedInt(i, width(5), ...));=20
>>
>> But it doesn't change the fact the string doesn't control the formatting=
=20
>> anymore, which is bad in any scenario where the programmer is *not* in=
=20
>> control, which is basically always the case where there are translators,=
=20
>> writers, designers, involved who have no access to the code.=20
>>
>>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_705_10502548.1391403061608
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">After a while of thinking, Miro, I admit that you are righ=
t: The reuse and on-spot formatting cases can be separated so that the cost=
 of having to use memory allocation in the reuse case does not imply such o=
verhead in the on-spot case. This of course needs to separate the code more=
 than I did in my implementation, but that's not a big deal.<div><br></div>=
<div>Instead an implementation should try to avoid having to reimplement th=
e format string parsing for each template instantiation as it causes code b=
loat, but I don't know if this is possible without virtual method calling o=
verhead. I admit to not having checked the implementation parts of your cod=
e. I have not had time, sorry.<br><div><br></div><div><br>Den m=C3=A5ndagen=
 den 20:e januari 2014 kl. 03:07:44 UTC+1 skrev Bengt Gustafsson:<blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">Sorry for misspelling y=
our name like that.<div><br></div><div>Your idea with the PrettyPrintedInt =
is a very simple way to customize printing of an int. It works in many case=
s although it may be a bit annoying in the on-spot case to write those type=
 names out. In some cases the formatting is more connected to the stream so=
 we should also provide an option for that case if possible.</div><div><br>=
</div><div>The precompilation in the Init() method of DataFormatter can of =
course perform whatever operations needed and store whatever results this g=
enerates in its members. It could kick up clang to compile the appropriate =
c function into assembly for instance...</div><div><br></div><div><br><div>=
<br></div><div><br><br>Den s=C3=B6ndagen den 19:e januari 2014 kl. 17:02:08=
 UTC-8 skrev Miro Knejp:<blockquote class=3D"gmail_quote" style=3D"margin:0=
;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>Am 20.01.2014 00:46, schrieb Brent Friedman:
<br>&gt; I understand the motivation now. But you don't have to know at com=
pile=20
<br>&gt; time what your string is and how you want to print it. The paramet=
er=20
<br>&gt; formatter can be as dynamic as you want it to be. Build the object=
=20
<br>&gt; dynamically. Throw in some virtuals if you feel like it.
<br>&gt;
<br>&gt; Here would be your example, then:
<br>&gt;
<br>&gt; //create DateFormat from designer spec
<br>&gt; string user_spec =3D get_user_format_spec();
<br>&gt; format("{0}", DateFormat(spec, tm1));
<br>&gt;
<br>&gt; &nbsp;//create DateFormat from a localized config string (german m=
ight be=20
<br>&gt; TT/mm/JJ instead of DD/mm/YY).
<br>&gt; string user_spec =3D get_user_format_spec( current_language );
<br>&gt; format( "{0}", DateFormat(current_language, user_spec, tm1));
<br>&gt;
<br>&gt; And with little work we can also make it programmer friendly.
<br>&gt;
<br>&gt; //default, developer DateFormat
<br>&gt; format( "{0}", DateFormat(tm1));
<br>&gt;
<br>&gt; //default for the given language
<br>&gt; format( "{0}", DateFormat::lang(current_<wbr>language).at(tm1);
<br>&gt;
<br>&gt; //use ISO 8601
<br>&gt; format( "{0}", DateFormat( iso_8601, tm1));
<br>&gt;
<br>&gt; You don't have to write a parser to add new options, just add the=
=20
<br>&gt; method to your format object and interface that with the outside w=
orld.
<br>&gt;
<br>&gt; It seems, then, like non-positional format string parameters are a=
n=20
<br>&gt; unnecessary complication.
<br>&gt;
<br>That is still hardcoding how the output should look like. Technically=
=20
<br>you can do the same with my implementation already:
<br>
<br>Just don't use "formatter&lt;int&gt;" but "formatter&lt;MyPrettyPrinted=
Int&gt;<wbr>"=20
<br>where "MyPrettyPrintedInt" is implicitly constructible from "int",=20
<br>define to_string(const MyPrettyPrintedInt &amp;) and you have your hard=
coded=20
<br>formatting that ignores any options passed into the format string. Yay!=
=20
<br>(Same holds true for Bengt's implementaiton, although it works a bit=20
<br>differently.)
<br>
<br>So from:
<br>formatter&lt;int&gt; fmt(ui_string_12345);
<br>format(fmt, i);
<br>
<br>formatter&lt;MyPrettyPrintedInt&gt; fmt(ui_string_12345);
<br>format(fmt, i);
<br>
<br>or if you need some options:
<br>format(fmt, MyPrettyPrintedInt(i, width(5), ...));
<br>
<br>But it doesn't change the fact the string doesn't control the formattin=
g=20
<br>anymore, which is bad in any scenario where the programmer is *not* in=
=20
<br>control, which is basically always the case where there are translators=
,=20
<br>writers, designers, involved who have no access to the code.
<br>
<br></blockquote></div></div></div></blockquote></div></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_705_10502548.1391403061608--

.


Author: Miro Knejp <miro@knejp.de>
Date: Mon, 03 Feb 2014 10:03:32 +0100
Raw View
Am 03.02.2014 05:51, schrieb Bengt Gustafsson:
> After a while of thinking, Miro, I admit that you are right: The reuse
> and on-spot formatting cases can be separated so that the cost of
> having to use memory allocation in the reuse case does not imply such
> overhead in the on-spot case. This of course needs to separate the
> code more than I did in my implementation, but that's not a big deal.
>
> Instead an implementation should try to avoid having to reimplement
> the format string parsing for each template instantiation as it causes
> code bloat, but I don't know if this is possible without virtual
> method calling overhead. I admit to not having checked the
> implementation parts of your code. I have not had time, sorry.
Well one does need some kind of type erasure as the argument index is a
runtime value, therefore the typical "recursive unpeeling" technique
doesn't apply here. What I do right now is to construct an
array<std::function<...>, N> from stateless lambdas (so they should not
cause any allocations if using small object optimization) in a variadic
unpack and the signature gets a tuple<...> as argument from which it
exctracts the i-th value and from there calls the appropriate to_string
overload. So there is one indirect call involved in every format
argument which I think can be neglected compared to the complexity of
the entire stringifying process. Talking code bloat the lambdas are
templated on a tuple and an index, meaning there are O(t1 + t2 + ... +
tn) lambdas (each consisting of a single call statement) where tx is the
size of tuple x and n is the number of unique combinations of format()
argument types.

What I'm currently stuck at is how locales fit into the picture.
Currently the facets are very stream oriented and cumbersome to use
without. Then there is codecvt, which some make responsible for
iostream's bad performance and the codecvt::out method is a bit clumsy
as there is no iterator-based interface to it so one has to guess how
much memory is needed in the destination in advance and loop over it
(unless I am completely mistaken on how it's supposed to be used).
Multicharacter aware alignment, i.e. the insight that a single printable
glyph can be represented with multiple codepoints but should only
consume 1 slot regarding alignment, is also something that's been
haunting me for a while, allthough that only really applies reliably to
monospace fonts so maybe it isn't that important after all.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Mon, 3 Feb 2014 04:23:01 -0800 (PST)
Raw View
------=_Part_321_16692455.1391430181624
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

I use a tuple<DataFormatter<Ts>...> in my code, plus a helper template=20
which accesses the i:th of these formatters. In my code the helper has two=
=20
methods, Init(string_view) and Format(T) or something like that. In your=20
on-spot case you will have to do both operations on the i:th data formatter=
=20
for each insert found, which I think is no problem with just tweaking my=20
code a little. I use no lambdas or std::function objects. (Download:=20
www.beamways.com/file/formatter.zip<http://www.google.com/url?q=3Dhttp%3A%2=
F%2Fwww.beamways.com%2Ffile%2Fformatter.zip&sa=3DD&sntz=3D1&usg=3DAFQjCNHKq=
GUpo4RSJMUM9J9Y1n_3Y4i4sA> still=20
available).

If I had time I would update my code to do the split between reuse and=20
onspot but right now I'm really up to my neck with other stuff ...

I looked at the C++ locale/facet system again a few weeks ago. It is a=20
really old and unintuitive design. It would be really nice if something=20
understandable was to supersede it.

The problem with codecvt is exactly that: You don't know how many bytes you=
=20
get until you actually do it. So if you have a buffer of a fixed length you=
=20
can get stuck in the middle of an input character. If I remember correctly=
=20
the function then stowes info about the half-consumed character in some=20
side state you have to supply. This allows the function to always fill the=
=20
output buffer for each call, but makes for a clumsy interface. I would have=
=20
prefered it to stop and back up the input one code point if the output=20
buffer could not contain the full representation of that code point. On the=
=20
other hand, if you are serious about file write performance the current api=
=20
guarantees that you can do an aligned write to the file after each codecvt=
=20
call. [I wrote this from memory 10 years or so after doing the codecvt=20
coding so grains of salt are appropriate].

I don't see how locale in data formatting connects to the on screen width,=
=20
isn't that a later step if you want to render the output string on screen?



Den m=C3=A5ndagen den 3:e februari 2014 kl. 10:03:32 UTC+1 skrev Miro Knejp=
:
>
>
> Am 03.02.2014 05:51, schrieb Bengt Gustafsson:=20
> > After a while of thinking, Miro, I admit that you are right: The reuse=
=20
> > and on-spot formatting cases can be separated so that the cost of=20
> > having to use memory allocation in the reuse case does not imply such=
=20
> > overhead in the on-spot case. This of course needs to separate the=20
> > code more than I did in my implementation, but that's not a big deal.=
=20
> >=20
> > Instead an implementation should try to avoid having to reimplement=20
> > the format string parsing for each template instantiation as it causes=
=20
> > code bloat, but I don't know if this is possible without virtual=20
> > method calling overhead. I admit to not having checked the=20
> > implementation parts of your code. I have not had time, sorry.=20
> Well one does need some kind of type erasure as the argument index is a=
=20
> runtime value, therefore the typical "recursive unpeeling" technique=20
> doesn't apply here. What I do right now is to construct an=20
> array<std::function<...>, N> from stateless lambdas (so they should not=
=20
> cause any allocations if using small object optimization) in a variadic=
=20
> unpack and the signature gets a tuple<...> as argument from which it=20
> exctracts the i-th value and from there calls the appropriate to_string=
=20
> overload. So there is one indirect call involved in every format=20
> argument which I think can be neglected compared to the complexity of=20
> the entire stringifying process. Talking code bloat the lambdas are=20
> templated on a tuple and an index, meaning there are O(t1 + t2 + ... +=20
> tn) lambdas (each consisting of a single call statement) where tx is the=
=20
> size of tuple x and n is the number of unique combinations of format()=20
> argument types.=20
>
> What I'm currently stuck at is how locales fit into the picture.=20
> Currently the facets are very stream oriented and cumbersome to use=20
> without. Then there is codecvt, which some make responsible for=20
> iostream's bad performance and the codecvt::out method is a bit clumsy=20
> as there is no iterator-based interface to it so one has to guess how=20
> much memory is needed in the destination in advance and loop over it=20
> (unless I am completely mistaken on how it's supposed to be used).=20
> Multicharacter aware alignment, i.e. the insight that a single printable=
=20
> glyph can be represented with multiple codepoints but should only=20
> consume 1 slot regarding alignment, is also something that's been=20
> haunting me for a while, allthough that only really applies reliably to=
=20
> monospace fonts so maybe it isn't that important after all.=20
>
>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_321_16692455.1391430181624
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I use a tuple&lt;DataFormatter&lt;Ts&gt;...&gt; in my code=
, plus a helper template which accesses the i:th of these formatters. In my=
 code the helper has two methods, Init(string_view) and Format(T) or someth=
ing like that. In your on-spot case you will have to do both operations on =
the i:th data formatter for each insert found, which I think is no problem =
with just tweaking my code a little. I use no lambdas or std::function obje=
cts. (Download:&nbsp;<a href=3D"http://www.google.com/url?q=3Dhttp%3A%2F%2F=
www.beamways.com%2Ffile%2Fformatter.zip&amp;sa=3DD&amp;sntz=3D1&amp;usg=3DA=
FQjCNHKqGUpo4RSJMUM9J9Y1n_3Y4i4sA" target=3D"_blank" style=3D"cursor: point=
er;">www.beamways.com/<wbr>file/formatter.zip</a>&nbsp;still available).<di=
v><br></div><div>If I had time I would update my code to do the split betwe=
en reuse and onspot but right now I'm really up to my neck with other stuff=
 ...</div><div><br></div><div>I looked at the C++ locale/facet system again=
 a few weeks ago. It is a really old and unintuitive design. It would be re=
ally nice if something understandable was to supersede it.</div><div><br></=
div><div>The problem with codecvt is exactly that: You don't know how many =
bytes you get until you actually do it. So if you have a buffer of a fixed =
length you can get stuck in the middle of an input character. If I remember=
 correctly the function then stowes info about the half-consumed character =
in some side state you have to supply. This allows the function to always f=
ill the output buffer for each call, but makes for a clumsy interface. I wo=
uld have prefered it to stop and back up the input one code point if the ou=
tput buffer could not contain the full representation of that code point. O=
n the other hand, if you are serious about file write performance the curre=
nt api guarantees that you can do an aligned write to the file after each c=
odecvt call. [I wrote this from memory 10 years or so after doing the codec=
vt coding so grains of salt are appropriate].</div><div><br></div><div>I do=
n't see how locale in data formatting connects to the on screen width, isn'=
t that a later step if you want to render the output string on screen?</div=
><div><br></div><div><br><br>Den m=C3=A5ndagen den 3:e februari 2014 kl. 10=
:03:32 UTC+1 skrev Miro Knejp:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>Am 03.02.2014 05:51, schrieb Bengt Gustafsson:
<br>&gt; After a while of thinking, Miro, I admit that you are right: The r=
euse=20
<br>&gt; and on-spot formatting cases can be separated so that the cost of=
=20
<br>&gt; having to use memory allocation in the reuse case does not imply s=
uch=20
<br>&gt; overhead in the on-spot case. This of course needs to separate the=
=20
<br>&gt; code more than I did in my implementation, but that's not a big de=
al.
<br>&gt;
<br>&gt; Instead an implementation should try to avoid having to reimplemen=
t=20
<br>&gt; the format string parsing for each template instantiation as it ca=
uses=20
<br>&gt; code bloat, but I don't know if this is possible without virtual=
=20
<br>&gt; method calling overhead. I admit to not having checked the=20
<br>&gt; implementation parts of your code. I have not had time, sorry.
<br>Well one does need some kind of type erasure as the argument index is a=
=20
<br>runtime value, therefore the typical "recursive unpeeling" technique=20
<br>doesn't apply here. What I do right now is to construct an=20
<br>array&lt;std::function&lt;...&gt;, N&gt; from stateless lambdas (so the=
y should not=20
<br>cause any allocations if using small object optimization) in a variadic=
=20
<br>unpack and the signature gets a tuple&lt;...&gt; as argument from which=
 it=20
<br>exctracts the i-th value and from there calls the appropriate to_string=
=20
<br>overload. So there is one indirect call involved in every format=20
<br>argument which I think can be neglected compared to the complexity of=
=20
<br>the entire stringifying process. Talking code bloat the lambdas are=20
<br>templated on a tuple and an index, meaning there are O(t1 + t2 + ... +=
=20
<br>tn) lambdas (each consisting of a single call statement) where tx is th=
e=20
<br>size of tuple x and n is the number of unique combinations of format()=
=20
<br>argument types.
<br>
<br>What I'm currently stuck at is how locales fit into the picture.=20
<br>Currently the facets are very stream oriented and cumbersome to use=20
<br>without. Then there is codecvt, which some make responsible for=20
<br>iostream's bad performance and the codecvt::out method is a bit clumsy=
=20
<br>as there is no iterator-based interface to it so one has to guess how=
=20
<br>much memory is needed in the destination in advance and loop over it=20
<br>(unless I am completely mistaken on how it's supposed to be used).=20
<br>Multicharacter aware alignment, i.e. the insight that a single printabl=
e=20
<br>glyph can be represented with multiple codepoints but should only=20
<br>consume 1 slot regarding alignment, is also something that's been=20
<br>haunting me for a while, allthough that only really applies reliably to=
=20
<br>monospace fonts so maybe it isn't that important after all.
<br>
<br></blockquote></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_321_16692455.1391430181624--

.


Author: Miro Knejp <miro@knejp.de>
Date: Tue, 04 Feb 2014 03:45:44 +0100
Raw View
This is a multi-part message in MIME format.
--------------080302070401040802060104
Content-Type: text/plain; charset=UTF-8; format=flowed


Am 03.02.2014 13:23, schrieb Bengt Gustafsson:
> I use a tuple<DataFormatter<Ts>...> in my code, plus a helper template
> which accesses the i:th of these formatters. In my code the helper has
> two methods, Init(string_view) and Format(T) or something like that.
> In your on-spot case you will have to do both operations on the i:th
> data formatter for each insert found, which I think is no problem with
> just tweaking my code a little. I use no lambdas or std::function
> objects. (Download: www.beamways.com/file/formatter.zip
> <http://www.google.com/url?q=http%3A%2F%2Fwww.beamways.com%2Ffile%2Fformatter.zip&sa=D&sntz=1&usg=AFQjCNHKqGUpo4RSJMUM9J9Y1n_3Y4i4sA> still
> available).
I looked at your code. Instead of using type erasure you use a if/else
cascade to find the actual conversion. If you inline all those
ParHelper::Init and ParHelper::Format calls you end up with

if(n == 5)
     ...
else
     if(n == 4)
         ...
     else
         if(n == 3)
             ...
         else
             if(n ==2)

and so on. If this cannot be optimized away (can it?) then you end up
with O(n) int comparisons for every argument in the string instead of an
array lookup using type erasure. But in the end that is a QoI issue. As
long as the stuff gets formatted properly it doesn't have implications
on the interface.
>
> If I had time I would update my code to do the split between reuse and
> onspot but right now I'm really up to my neck with other stuff ...
>
> I looked at the C++ locale/facet system again a few weeks ago. It is a
> really old and unintuitive design. It would be really nice if
> something understandable was to supersede it.
>
> The problem with codecvt is exactly that: You don't know how many
> bytes you get until you actually do it. So if you have a buffer of a
> fixed length you can get stuck in the middle of an input character. If
> I remember correctly the function then stowes info about the
> half-consumed character in some side state you have to supply. This
> allows the function to always fill the output buffer for each call,
> but makes for a clumsy interface. I would have prefered it to stop and
> back up the input one code point if the output buffer could not
> contain the full representation of that code point. On the other hand,
> if you are serious about file write performance the current api
> guarantees that you can do an aligned write to the file after each
> codecvt call. [I wrote this from memory 10 years or so after doing the
> codecvt coding so grains of salt are appropriate].
Yeah, I just wish there was a codecvt::out overload that accepted an
OutIterator and did it's conversion that way. As far as I can tell there
are always some kind of intermediate buffers involved in I/O operations
anyway.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--------------080302070401040802060104
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<html>
  <head>
    <meta content=3D"text/html; charset=3DUTF-8" http-equiv=3D"Content-Type=
">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    <br>
    <div class=3D"moz-cite-prefix">Am 03.02.2014 13:23, schrieb Bengt
      Gustafsson:<br>
    </div>
    <blockquote
      cite=3D"mid:52cfca2d-2820-4fea-bdc7-3aa9562baca5@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">I use a tuple&lt;DataFormatter&lt;Ts&gt;...&gt; in
        my code, plus a helper template which accesses the i:th of these
        formatters. In my code the helper has two methods,
        Init(string_view) and Format(T) or something like that. In your
        on-spot case you will have to do both operations on the i:th
        data formatter for each insert found, which I think is no
        problem with just tweaking my code a little. I use no lambdas or
        std::function objects. (Download:=C2=A0<a moz-do-not-send=3D"true"
href=3D"http://www.google.com/url?q=3Dhttp%3A%2F%2Fwww.beamways.com%2Ffile%=
2Fformatter.zip&amp;sa=3DD&amp;sntz=3D1&amp;usg=3DAFQjCNHKqGUpo4RSJMUM9J9Y1=
n_3Y4i4sA"
          target=3D"_blank" style=3D"cursor: pointer;">www.beamways.com/<wb=
r>file/formatter.zip</a>=C2=A0still
        available).</div>
    </blockquote>
    I looked at your code. Instead of using type erasure you use a
    if/else cascade to find the actual conversion. If you inline all
    those ParHelper::Init and ParHelper::Format calls you end up with<br>
    <br>
    if(n =3D=3D 5)<br>
    =C2=A0=C2=A0=C2=A0 ...<br>
    else<br>
    =C2=A0=C2=A0=C2=A0 if(n =3D=3D 4)<br>
    =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 ...<br>
    =C2=A0=C2=A0=C2=A0 else<br>
    =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 if(n =3D=3D 3)<br>
    =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 ...<br>
    =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 else<br>
    =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 if(n =3D=3D2)<=
br>
    <br>
    and so on. If this cannot be optimized away (can it?) then you end
    up with O(n) int comparisons for every argument in the string
    instead of an array lookup using type erasure. But in the end that
    is a QoI issue. As long as the stuff gets formatted properly it
    doesn't have implications on the interface.<br>
    <blockquote
      cite=3D"mid:52cfca2d-2820-4fea-bdc7-3aa9562baca5@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
        </div>
        <div>If I had time I would update my code to do the split
          between reuse and onspot but right now I'm really up to my
          neck with other stuff ...</div>
        <div><br>
        </div>
        <div>I looked at the C++ locale/facet system again a few weeks
          ago. It is a really old and unintuitive design. It would be
          really nice if something understandable was to supersede it.</div=
>
        <div><br>
        </div>
        <div>The problem with codecvt is exactly that: You don't know
          how many bytes you get until you actually do it. So if you
          have a buffer of a fixed length you can get stuck in the
          middle of an input character. If I remember correctly the
          function then stowes info about the half-consumed character in
          some side state you have to supply. This allows the function
          to always fill the output buffer for each call, but makes for
          a clumsy interface. I would have prefered it to stop and back
          up the input one code point if the output buffer could not
          contain the full representation of that code point. On the
          other hand, if you are serious about file write performance
          the current api guarantees that you can do an aligned write to
          the file after each codecvt call. [I wrote this from memory 10
          years or so after doing the codecvt coding so grains of salt
          are appropriate].</div>
      </div>
    </blockquote>
    Yeah, I just wish there was a codecvt::out overload that accepted an
    OutIterator and did it's conversion that way. As far as I can tell
    there are always some kind of intermediate buffers involved in I/O
    operations anyway.<br>
  </body>
</html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--------------080302070401040802060104--


.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Tue, 4 Feb 2014 14:44:20 -0800 (PST)
Raw View
------=_Part_5756_32306093.1391553860746
Content-Type: text/plain; charset=UTF-8

Yes, if I'm lucky the compiler will expand the tail recursion to an if tree
as you described. If I'm even more lucky it will then turn this into a jump
table. In another thread someone mentioned that clang (I think) has such an
optimization.

As std::function needs heap memory internally (again, I think!), this is
probably worse from a performance standpoint, but I can see that you can
centralize the format parsing loop (as a lazy range it seems) which is a
good thing.

I now see that you must have a predefined set of parsing flags, isn't that
right? I think it should be a type specific set, as in my design. I don't
really see a problem with fusing our designs (and specs!) to something
better.

Den tisdagen den 4:e februari 2014 kl. 03:45:44 UTC+1 skrev Miro Knejp:
>
>
> Am 03.02.2014 13:23, schrieb Bengt Gustafsson:
>
> I use a tuple<DataFormatter<Ts>...> in my code, plus a helper template
> which accesses the i:th of these formatters. In my code the helper has two
> methods, Init(string_view) and Format(T) or something like that. In your
> on-spot case you will have to do both operations on the i:th data formatter
> for each insert found, which I think is no problem with just tweaking my
> code a little. I use no lambdas or std::function objects. (Download:
> www.beamways.com/file/formatter.zip<http://www.google.com/url?q=http%3A%2F%2Fwww.beamways.com%2Ffile%2Fformatter.zip&sa=D&sntz=1&usg=AFQjCNHKqGUpo4RSJMUM9J9Y1n_3Y4i4sA> still
> available).
>
> I looked at your code. Instead of using type erasure you use a if/else
> cascade to find the actual conversion. If you inline all those
> ParHelper::Init and ParHelper::Format calls you end up with
>
> if(n == 5)
>     ...
> else
>     if(n == 4)
>         ...
>     else
>         if(n == 3)
>             ...
>         else
>             if(n ==2)
>
> and so on. If this cannot be optimized away (can it?) then you end up with
> O(n) int comparisons for every argument in the string instead of an array
> lookup using type erasure. But in the end that is a QoI issue. As long as
> the stuff gets formatted properly it doesn't have implications on the
> interface.
>
>
>  If I had time I would update my code to do the split between reuse and
> onspot but right now I'm really up to my neck with other stuff ...
>
>  I looked at the C++ locale/facet system again a few weeks ago. It is a
> really old and unintuitive design. It would be really nice if something
> understandable was to supersede it.
>
>  The problem with codecvt is exactly that: You don't know how many bytes
> you get until you actually do it. So if you have a buffer of a fixed length
> you can get stuck in the middle of an input character. If I remember
> correctly the function then stowes info about the half-consumed character
> in some side state you have to supply. This allows the function to always
> fill the output buffer for each call, but makes for a clumsy interface. I
> would have prefered it to stop and back up the input one code point if the
> output buffer could not contain the full representation of that code point.
> On the other hand, if you are serious about file write performance the
> current api guarantees that you can do an aligned write to the file after
> each codecvt call. [I wrote this from memory 10 years or so after doing the
> codecvt coding so grains of salt are appropriate].
>
> Yeah, I just wish there was a codecvt::out overload that accepted an
> OutIterator and did it's conversion that way. As far as I can tell there
> are always some kind of intermediate buffers involved in I/O operations
> anyway.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_5756_32306093.1391553860746
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Yes, if I'm lucky the compiler will expand the tail recurs=
ion to an if tree as you described. If I'm even more lucky it will then tur=
n this into a jump table. In another thread someone mentioned that clang (I=
 think) has such an optimization.<div><br></div><div>As std::function needs=
 heap memory internally (again, I think!), this is probably worse from a pe=
rformance standpoint, but I can see that you can centralize the format pars=
ing loop (as a lazy range it seems) which is a good thing.</div><div><br></=
div><div>I now see that you must have a predefined set of parsing flags, is=
n't that right? I think it should be a type specific set, as in my design. =
I don't really see a problem with fusing our designs (and specs!) to someth=
ing better.<br><br>Den tisdagen den 4:e februari 2014 kl. 03:45:44 UTC+1 sk=
rev Miro Knejp:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
 =20
   =20
 =20
  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
    <br>
    <div>Am 03.02.2014 13:23, schrieb Bengt
      Gustafsson:<br>
    </div>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">I use a tuple&lt;DataFormatter&lt;Ts&gt;...&gt; in
        my code, plus a helper template which accesses the i:th of these
        formatters. In my code the helper has two methods,
        Init(string_view) and Format(T) or something like that. In your
        on-spot case you will have to do both operations on the i:th
        data formatter for each insert found, which I think is no
        problem with just tweaking my code a little. I use no lambdas or
        std::function objects. (Download:&nbsp;<a href=3D"http://www.google=
..com/url?q=3Dhttp%3A%2F%2Fwww.beamways.com%2Ffile%2Fformatter.zip&amp;sa=3D=
D&amp;sntz=3D1&amp;usg=3DAFQjCNHKqGUpo4RSJMUM9J9Y1n_3Y4i4sA" target=3D"_bla=
nk" onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2F=
www.beamways.com%2Ffile%2Fformatter.zip\46sa\75D\46sntz\0751\46usg\75AFQjCN=
HKqGUpo4RSJMUM9J9Y1n_3Y4i4sA';return true;" onclick=3D"this.href=3D'http://=
www.google.com/url?q\75http%3A%2F%2Fwww.beamways.com%2Ffile%2Fformatter.zip=
\46sa\75D\46sntz\0751\46usg\75AFQjCNHKqGUpo4RSJMUM9J9Y1n_3Y4i4sA';return tr=
ue;">www.beamways.com/<wbr>file/formatter.zip</a>&nbsp;still
        available).</div>
    </blockquote>
    I looked at your code. Instead of using type erasure you use a
    if/else cascade to find the actual conversion. If you inline all
    those ParHelper::Init and ParHelper::Format calls you end up with<br>
    <br>
    if(n =3D=3D 5)<br>
    &nbsp;&nbsp;&nbsp; ...<br>
    else<br>
    &nbsp;&nbsp;&nbsp; if(n =3D=3D 4)<br>
    &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ...<br>
    &nbsp;&nbsp;&nbsp; else<br>
    &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(n =3D=3D 3)<br>
    &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ...<br>
    &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else<br>
    &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(n =3D=3D2)<=
br>
    <br>
    and so on. If this cannot be optimized away (can it?) then you end
    up with O(n) int comparisons for every argument in the string
    instead of an array lookup using type erasure. But in the end that
    is a QoI issue. As long as the stuff gets formatted properly it
    doesn't have implications on the interface.<br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div><br>
        </div>
        <div>If I had time I would update my code to do the split
          between reuse and onspot but right now I'm really up to my
          neck with other stuff ...</div>
        <div><br>
        </div>
        <div>I looked at the C++ locale/facet system again a few weeks
          ago. It is a really old and unintuitive design. It would be
          really nice if something understandable was to supersede it.</div=
>
        <div><br>
        </div>
        <div>The problem with codecvt is exactly that: You don't know
          how many bytes you get until you actually do it. So if you
          have a buffer of a fixed length you can get stuck in the
          middle of an input character. If I remember correctly the
          function then stowes info about the half-consumed character in
          some side state you have to supply. This allows the function
          to always fill the output buffer for each call, but makes for
          a clumsy interface. I would have prefered it to stop and back
          up the input one code point if the output buffer could not
          contain the full representation of that code point. On the
          other hand, if you are serious about file write performance
          the current api guarantees that you can do an aligned write to
          the file after each codecvt call. [I wrote this from memory 10
          years or so after doing the codecvt coding so grains of salt
          are appropriate].</div>
      </div>
    </blockquote>
    Yeah, I just wish there was a codecvt::out overload that accepted an
    OutIterator and did it's conversion that way. As far as I can tell
    there are always some kind of intermediate buffers involved in I/O
    operations anyway.<br>
  </div>

</blockquote></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_5756_32306093.1391553860746--

.


Author: Miro Knejp <miro@knejp.de>
Date: Wed, 05 Feb 2014 00:22:19 +0100
Raw View
Am 04.02.2014 23:44, schrieb Bengt Gustafsson:
> Yes, if I'm lucky the compiler will expand the tail recursion to an if
> tree as you described. If I'm even more lucky it will then turn this
> into a jump table. In another thread someone mentioned that clang (I
> think) has such an optimization.
Ah yes, the jump table...
>
> As std::function needs heap memory internally (again, I think!), this
> is probably worse from a performance standpoint, but I can see that
> you can centralize the format parsing loop (as a lazy range it seems)
> which is a good thing.
The lambdas have no state so std::function should not allocate anything
if it's implemented with small object optimization, basically making it
a home-brewn jump table. In any case, one ends up with an indirect jump
or call somewhere. Can't get rid of that. I wouldn't worry about it too
much.
>
> I now see that you must have a predefined set of parsing flags, isn't
> that right? I think it should be a type specific set, as in my design.
Only alignment is predefined as that can be applied universally to every
type output (regardless whether it's an int, complex or a SQL dump, you
can always pad it with spaces), drawing inspiration from .NET's
{0,-10:asdfg} where -10 is left alignment with minimum width of 10 and
not part of the type-specific format options "asdfg". Those are just
forwarded to the to_string method (unescaping nested braces first if
necessary). I haven't started with the builtin/std type conversions yet
so the format options there are entirely open. Allthough I do have some
ideas.
> I don't really see a problem with fusing our designs (and specs!) to
> something better.
Sure


--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.