std::ios::binary?

D

Dietmar Kuehl

Alf said:
* Steven T. Hatton:

It won't. Stream buffer iterators operate on the character level and
don't use any form of formatting, neither when reading nor when
writing. They are quite different from stream iterators which operate
on object level and are for [text] formatted reading and writing. The
only mutations done when using stream buffer iterators are those done
by the underlying stream buffer and/or the system like possible
operations performed in text mode. Since the file is opened in binary,
these are also suppressed
Anyway, the things that can be done easily, like the above, are of the
variety "error handling omitted",

Is it, now? Well, I didn't check for whether 'in' could be opened, nor
did I check the result of closing it. However, I concentrated on the
problem at hand. Can I take your comment towards error handling that
you are always posting commercial strength code which can be used
unchanged in production code (from a code quality point of view; there
are, of course, copyright restrictions)? ... or are you seeing other
needs for error handling which are not covered? If so, which?
and it's not like what seems like an easy way when presented to you is
easy to come by when you don't already know it.

Yes, indeed, it is hard to find this solution if you got stuck with
the first class which sounds as if it could solve the problem (the
stream iterator classes). Given the specification which already asked
for an approach using iterators I consider it indeed obvious how the
problem is to be addressed - assuming you browse the complete list of
possible classes (which in this case consists of a set with a total of
two elements).
The popularity in certain circles seems to stem from the _complexity_, how
hard it is to use, and how it allows one to employ all sorts of "clever"
tricks to combat the inefficiency and unsafety, and how there is a whole
package of terminology mostly only understood by the converts, allowing
easy
recognition of fellow believers and -- of course -- of unbelievers.

Wow. The solution I posted above qualifies as "complex" if I understood
your correct. Can you please show me *any* alternative which achieves
the same objective simpler. Use Java or .Net classes, whatever library
you wish (as long as I can view documentation of the used components
online to verify that it is not made up to fit this problem).

You really think the above is "hard to use"? ... and, honestly, I don't
see an employment of clever tricks there. ... and concerning the
terminology: you always need to understand the basics of a library
component to use it effectively. This applies to the standard C++ library
as well as to any alternatives. Of course, you will struggle hard if
you refuse to accept these basics and consider it a clever idea to use
the basics of some other library.
So, when Dietmar characterizes alternatives to the standard library's i/o
facilities as "crap", that should IMO be considered as an emotional
utterance from a believer to an agnostic who just possibly may be
converted to the one true faith, and whose rash, random questioning should
be stopped before it lands on some less easily handled or diverted topic.

Ah, yes, I'm one of those highly religious fanatics who never ever would
possibly admit a flaw in his belief. This attitude is, of course,
clearly reflected in all articles I'm writing and absolute devotion and
faith is shown: the True Belief is not to be questioned. Every letter is
Holy Law. Hark infidel: do not dare to befoul thy STL!

As an alternative interpretation of my characterization I would offer
that I had experience with the Java I/O library which I didn't like at
all. Of course, to some something like

BufferedReader in = new BufferedReader(new FileReader(filename));

is far easier to read then

std::ifstream in(filename);

not to mention that the latter is more complex to everybody except to
those converted to the True Faith. Of course, non-intuitive code like

std::ifstream in("input.txt");
std::string name;
int age;
double weight;
while (in >> name >> age >> weight)
/* process the data */;
if (!in.eof())
std::cout << "format error during input\n";

should likewise abandoned in favor of the much clearer Java approach:

BufferedReader in = new BufferedReader(new FileReader("input.txt"));
String name;
int age;
double weight;
NumberFormat nf = NumberFormat.getInstance();

try {
while (true) // I haven't figured out how to easily detect end of
{ // file in a rush; sorry, I haven't embraced the Java I/O
StringTokenizer tok = new StringTokenizer(in.readLine(), "\t");
name = nextToken();
Number num = nf.parse(nextToken);
age = num.intValue();
num = nf.parse(nextToken);
weight = num.doubleValue();

// process the data
}
}
catch (ParseException e)
{
System.out.println("format error during input\n");
}

Now, *THAT* looks clear to me! It is *much* more obvious than the C++
stuff. ...or, just maybe, things like this are the reason for my
characterization of Java's I/O library. Have you possibly considered
this? Of course, there is a fair chance that I have missed the correct
Java approach to parsing text files. In this case I would appreciate
being pointed into the right direction and I guarantee that I'm willing
to reevaluate Java I/O if it is just me.
Like, say, exceptions, or like, say, undefined behavior of input
conversions, or like, say, the inability to copy standard input to
standard
output exactly, which is rather basic. Not to mention two-phase
initialization and other such ugliness in the internal design. Happily,
many practicing C++ programmers can choose whatever works or make it from
scratch, but students seldom can -- and that means we're putting them
off.

You mean, we should embrace Java I/O as an alternative in C++ and the
Java code above is *not* putting students off while the C++ code is?
Well, I might have to readjust my measure of complexity then...
 
P

P.J. Plauger

Technically speaking, it is not the perview of compiler writers, but
rather
the library implementors. Yes, they are often one in the same.

That was generally true in C. In the C++ world, however, compiler
writers and library writers form sets that are almost completely
disjoint.
After you
posted, I began thinking about why there hasn't been as much contribution
as one might expect to something as important as the C++ Standard Library.

I stand in awe of your persistent arrogance.
There /are/ several freely available I/O libraries for various kinds.
Some
of them look very nice, and from experience with software that uses them,
some of the are very reliable, and powerful. The problem, I suspect, is
the licensing conflicts with the conditions of the C++ Standard.

Oh, for heaven's sake. There are *no* licensing conflicts imposed
by any "conditions" in the C++ Standard. Please learn *something*
about what you're talking about before opening your mouth.
Actually, what probably should be done is a much more difficult task.
That
is to identify the abstract interfaces which effectively capture the
common
aspects of the vast majority of existing, and probable implementation of
any given design domain such as local harddrive I/O. Also worth
considering is the further abstraction of the different I/O interfaces
such
as harddrive, IPC, network, in order to create a baseclass for all I/O
instances. I'm really not talking about the existing std::ios_base, or
basic_ios. They may prove to provide some element of that interface, but
I
am considering starting from tabular rasa.

These should be interfaces, sans data, or implemented functions.

That pronouncement was so abstract and mealy mouthed that it could
be applied to damn near anything. It certainly described what went
into the design of every programming language I/O subsystem since
Fortran II. It could almost be applied to a project for making
universal mounting hardware for disk drives. Pure middle-management
speak.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
A

Alf P. Steinbach

* Dietmar Kuehl:
It won't.

Right, that's already covered.

Btw., the quoting is a bit off; this is the second time in this thread
something seems to be attributed to me that someone else wrote.


[lengthy diatribe snipped]
You mean, we should embrace Java I/O as an alternative in C++ and the
Java code above is *not* putting students off while the C++ code is?
Well, I might have to readjust my measure of complexity then...

Dietmar, you make me laugh. :)

Admit it, you _are_ a bit religious about these matters, aren't you?

Anyway, no, I'm not into Java.
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

P.J. Plauger said:
That was generally true in C. In the C++ world, however, compiler
writers and library writers form sets that are almost completely
disjoint.

But event in that case, compiler writers may have more work because of the
desire to optimize better the code generated by some uses of the library.
 
D

Dietmar Kuehl

Alf said:
* Dietmar Kuehl:

Right, that's already covered.

Btw., the quoting is a bit off; this is the second time in this thread
something seems to be attributed to me that someone else wrote.

Actually I don't think so: the question is attributed to Steven,
not to you. Stuff attributed to you used '>' as a prefix while
stuff attributed to Steven used '>>'. Maybe there is a space
missing for the interpretation for some newsreaders but then I'm
not aware of any strict quoting rules specifying prefixes...
Dietmar, you make me laugh. :)
OK.

Admit it, you _are_ a bit religious about these matters, aren't you?

I don't think I'm religious about these matters because, at least
to me, being religious would include that I cannot accept changing
my believe. I don't think this is the case: if there are convincing
arguments to change my perspective, I'm willing to do so. However,
I have worked with I/O libraries in other languages than C++ and
without other I/O libraries than IOStreams in C++ and I have no
reason to think that there are better alternatives except Perl's
I/O processing with its integration with regular expression. Of
course, this view is influenced by the fact that I'm mostly either
accessing databases or text files. For example, I don't normally
process binary formatted files or Java serialized data where the
latter is, of course, a pretty useless format anyway which
arrogantly assumes that everybody is using Java, not to mention
specific sets of classes.
Anyway, no, I'm not into Java.

I'm not too much into Java either but I have a certain view of
the language and did some work with it. This is very my evaluation
comes from. It neither comes from ignorance nor from religious
believes - and I stay with what I have said: its I/O library is
crap.
 
S

Steven T. Hatton

[...]

I am not the subject of this newsgroup.
Oh, for heaven's sake. There are *no* licensing conflicts imposed
by any "conditions" in the C++ Standard. Please learn *something*
about what you're talking about before opening your mouth.

Uh, if GPL code were used in the C++ Standard Library, it could seriously
incumber the use of the library for people who wanted to write proprietary
software. That is probably why the Boost licensing is worded quite
differently.
That pronouncement was so abstract and mealy mouthed that it could
be applied to damn near anything.

Rather than insulting me, why don't you either provide convincing evidence
to demonstrate my error, or ask for clarification? I actually did come up
with some ideas of what these things might mean. In the above statement,
it was very much my intent to be abstract, and as abstract as possible.
That is exactly where the realization of the design of something as
foundational as the C++ I/O library should begin.

Certainly, the first stage of design is identifying some sense of design
domain. When that is identified, then you try to identify the common
feature that all instances of the abstract type will share. That will lead
to identifying explicitly belongs in the interface. It may also lead to
identifying what else belongs in the abstraction class. It's likely that
will come to realize that some of the original candidates for inclusion are
not appropriately grouped in your abstraction class.

When such candidates are removed from the abstraction class, any unique
contribution they made to the interface should likewise be removed. This
is one place where the work gets difficult. It means reexamining all the
other members of the abstraction class to determine what aspects of the
excluded candidate they might have in common. It also means the
possibility of opening the door to candidates which did not meet the
inclusion requirements imposed by the excluded candidate.

As for "it could be applied to damn near anything."; in Unix, what is a
file?
It certainly described what went
into the design of every programming language I/O subsystem since
Fortran II. It could almost be applied to a project for making
universal mounting hardware for disk drives.

IOW, I described the tried and true approach.
 
P

P.J. Plauger

[...]

I am not the subject of this newsgroup.

No, but you became the subject of this posting when you opined
(rather arrogantly) in the first person.
Uh, if GPL code were used in the C++ Standard Library, it could seriously
incumber the use of the library for people who wanted to write proprietary
software. That is probably why the Boost licensing is worded quite
differently.

You were talking about an international *standard*, not a
specific implementation. There is a difference, you know.
Rather than insulting me, why don't you either provide convincing evidence
to demonstrate my error, or ask for clarification?

I didn't intend to be insulting, merely descriptive. I gave a
specific example -- that the words could apply to any programming
language since Fortran. I don't expect ever to convince you of
anything, however. My goal was merely to put your pronunciamento
in context for other readers.

In this particular case, the words are way too vague to demonstrate
any error, or offer any hope of clarification. As Enrico Fermi
once famously said of a weak theory, "it isn't even wrong."
I actually did come up
with some ideas of what these things might mean. In the above statement,
it was very much my intent to be abstract, and as abstract as possible.
That is exactly where the realization of the design of something as
foundational as the C++ I/O library should begin.

Certainly, the first stage of design is identifying some sense of design
domain. When that is identified, then you try to identify the common
feature that all instances of the abstract type will share. That will
lead
to identifying explicitly belongs in the interface. It may also lead to
identifying what else belongs in the abstraction class. It's likely that
will come to realize that some of the original candidates for inclusion
are
not appropriately grouped in your abstraction class.

When such candidates are removed from the abstraction class, any unique
contribution they made to the interface should likewise be removed. This
is one place where the work gets difficult. It means reexamining all the
other members of the abstraction class to determine what aspects of the
excluded candidate they might have in common. It also means the
possibility of opening the door to candidates which did not meet the
inclusion requirements imposed by the excluded candidate.

Do you even realize how vacuous this sort of drivel appears to
others? You could be giving a Powerpoint presentation to investment
bankers on software for dry cleaning establishments, and not have
to change a single blessed word in the last two paragraphs.
As for "it could be applied to damn near anything."; in Unix, what is a
file?

I use one to knock the burrs off metal castings, myself.
IOW, I described the tried and true approach.

Well, yes, in such broad terms that you offer absolutely no
guidance. For another apt quote, I'm reminded of a Brazilian
singer who put down another band's music by saying, "It don't
smell good; it don't smell bad; it just don't smell."

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
S

Steven T. Hatton

Dietmar said:
It won't. Stream buffer iterators operate on the character level and
don't use any form of formatting, neither when reading nor when
writing.

Sorry. I had missed the fact that you were using a istrembuf_iterator
instead of a istream_iterator.
 
S

Steven T. Hatton

P.J. Plauger said:
You were talking about an international *standard*, not a
specific implementation. There is a difference, you know.

Yes, but the Standard does contain code. If that code were taken directly
from a GPL product such as Socket++, there could be problems.

I didn't intend to be insulting, merely descriptive.
hua.

I gave a
specific example -- that the words could apply to any programming
language since Fortran. I don't expect ever to convince you of
anything, however. My goal was merely to put your pronunciamento
in context for other readers.

In this particular case, the words are way too vague to demonstrate
any error, or offer any hope of clarification. As Enrico Fermi
once famously said of a weak theory, "it isn't even wrong."

And then you turned around and said that my approach was the same as has
been taken for 3 decades.
Do you even realize how vacuous this sort of drivel appears to
others? You could be giving a Powerpoint presentation to investment
bankers on software for dry cleaning establishments, and not have
to change a single blessed word in the last two paragraphs.

If you don't understand, simply ask for clarification, or an example. I can
easily provide both. For an example, see the discussion in TC++PL(SE) in
chapter 12. (IIRC)

[...]

Ráðumk þér, Loddfáfnir,
en þú ráð nemir, -
njóta mundu, ef þú nemr,
þér munu góð, ef þú getr -:
orðum skipta
þú skalt aldregi
við ósvinna apa,
 
S

Steven T. Hatton

Dietmar said:
I'm not too much into Java either but I have a certain view of
the language and did some work with it. This is very my evaluation
comes from. It neither comes from ignorance nor from religious
believes - and I stay with what I have said: its I/O library is
crap.

The adjective used indicates to me that you are not thinking objectively.
And your assessment of Java's I/O is not helpful. It neither informs us as
to what you don't like about the Java I/O library, nor does it tell us what
feature of the C++ I/O library you find superior. I suspect a person with
your level of expertise could provide valuable insight. I'd be interested
to know the technical details of your assessment.
 
S

Steven T. Hatton

Julián Albo said:
So do you think that the codes of whitespace characters are not binary?
Binary, as ther people say in this thread several times, is related only
to new line conventions and end of file detection.

Yes, that is, more or less what it means, in C terminology which is implied
in the C++ Standard Library. It is by no means a common use of the meaning
of "binary I/O" in other contexts.
You have mixed the
concept of text/binary mode with the formatted/unformatted input, and you
blame the language for that?

Since whitespace is only meaningfull to me in terms of text, that was a
reasonable assumption, even though it does not reflect the design of the
I/O library. The documentation I was reading said this, which I believe is
misleading:

<quote>
If mode & ios_base::binary is nonzero, the function appends b to strmode to
open a binary stream instead of a text stream."
....
"A binary stream consists of one or more bytes of arbitrary information. You
can write the value stored in an arbitrary object to a (byte-oriented)
binary stream and read exactly what was stored in the object when you wrote
it. The library functions do not alter the bytes you transmit between the
program and a binary stream. They can, however, append an arbitrary number
of null bytes to the file that you write with a binary stream. The program
must deal with these additional null bytes at the end of any binary
stream."
</quote>

It then goes on to describe how to control streams using the C functions:

<quote>
Controlling Streams: fopen returns the address of an object of type FILE.
You use this address as the stream argument to several library functions to
perform various operations on an open file. For a byte stream, all input
takes place as if each character is read by calling fgetc, and all output
takes place as if each character is written by calling fputc. For a wide
stream (with Amendment 1), all input takes place as if each character is
read by calling fgetwc, and all output takes place as if each character is
written by calling fputwc.
....

Functions in the first three groups are declared in <stdio.h>:

* the byte read functions -- fgetc, fgets, fread, fscanf, getc, getchar,
gets, scanf, and ungetc
* the byte write functions -- fprintf, fputc, fputs, fwrite, printf,
putc, putchar, puts, vfprintf, and vprintf
* the position functions -- fflush, fseek, fsetpos, and rewind
....
</quote>

Learning the ways the language already has to do things instead of
expecting that ways more likely to you are written will save you a lot
more.

Well, it doesn't help that Stroustrup sidestepped the issue of binary I/O in
TC++PL(SE). As you can see above, there are problems with another commonly
recommended source of documentation for the C++ Standard Library.

I'm now beginning to realize much of my confusion comes from distinguishing
between the I/O streams and the the I/O stream buffers.
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

Steven said:
Yes, that is, more or less what it means, in C terminology which is
implied in the C++ Standard Library. It is by no means a common use
of the meaning of "binary I/O" in other contexts.

Maybe, but when reading C++ documentation you must suppose that the C++
sense is used by default.
As you can see above, there are problems with another commonly recommended
source of documentation for the C++ Standard Library.

Probably they are written under the assumption that people that reads it
already knows and have some experience with the fundamental concepts. If
you jump to it under knowledge and assumptions based in experience with
other languages, skipping the basic steps, you are in trouble.
 
D

Dietmar Kuehl

Steven said:
Dietmar Kuehl wrote: [talking about Java I/O]
- and I stay with what I have said: its I/O library is crap.

The adjective used indicates to me that you are not thinking objectively.

You mean, I would have used a stronger term if I were objective? Yes,
you are probably right...
And your assessment of Java's I/O is not helpful. It neither informs us
as to what you don't like about the Java I/O library, nor does it tell us
what feature of the C++ I/O library you find superior.

Well, I think I gave a fairly good basis to decide even for yourself
in the article where I posted C++ and Java code side by side: just
have a look at the code and decide for yourself. As I said in this
article, I think I did the best possible in Java but I would like to
be illuminated in case I missed Java functionality which does text
parsing more easily. Since I'm very fluent using C++ streams, the
comparison may not be fair because I may have missed something in
Java which I didn't do in C++. Of course, you will need to remove
a fair amount of sarcasm if you want to understand my thinking.
I suspect a person with your level of expertise could provide
valuable insight. I'd be interested to know the technical details
of your assessment.

Since I already posted the core issue I have with Java I/O your
interest cannot be that big: you apparently missed it altough you
wrote an answer to the corresponding artice, albeit to a different
part of it.
 
D

Dietmar Kuehl

Steven said:
Uh, if GPL code were used in the C++ Standard Library, it could seriously
incumber the use of the library for people who wanted to write proprietary
software. That is probably why the Boost licensing is worded quite
differently.

I second P.J.Plauger's advice! The standard C++ library is implemented
multiple times, including several commercial versions (at least three), at
least one GPL version, and at least one "free" version (although none is
public domain as far as I can tell). There is no licensing issue at all
with the standard C++ library because the standard is not an
implementation but a specification. The specification itself has
licensing restriction but there are no restrictions on implementing this
specification.
 
S

Steven T. Hatton

Dietmar said:
You can't and you shouldn't. Actually, you would be well advised
to read the documentation of classes before guessing about their
semantics: if at all, you want to use 'gptr()' as your starting
point because the sequence [eback(), gptr()) consists of already
processed characters (... and your wrong use clearly shows that
you had no inkling about what you are doing).

This is what I wrote:

copy(file_buf.eback(), file_buf.egptr(), back_inserter(data));

I'm not sure why you say that is fundamentally wrong. I'm assuming
eback()==gptr() when the iteration begins. I'm looking at page 676 of
TC++SL.
No, it doesn't.

How it /seems/, and how it actually /is/, may not be consistent. But you
are not in a position to determine how things seem to me.
You should operate on top of the stream buffer
abstraction, not within.

That is what I had wanted to do, but I didn't see a way of getting an
iterator representing egptr(). I understand that, in the general case of
I/O streams, egptr() and the end of the input stream are not necessarily
the same thing, and therefore the analog to container.end() is not as easy
to express.

The one mistake I made was not using the best resources I have available.
§13.13.2
Maybe you should at least try to
understand what the classes and functions are about and for.

This is a difficult thing to understand. Partly because it preserves some
very ancient, and less than elegant aspects, and partly because there are
multiple dimensions to the conceptual structure of the I/O system. There
is the inheritance hierarchy of the basic_ios class templates shown here:
http://baldur.globalsymmetry.com/~hattons/Standard/doc/html/inherit__graph__35.png

(I still have a lot of work to do on those files, and the ones on the server
are not the latest.)

There is a dimension of stream buffers which has its own inheritance
hierarchy.

There is a dimension of template arguments for the character type, and
character traits, which can impact both the streams and stream buffers.


One thing I find messy about the C++ I/O library is the use of format flags.
The following is on idea I have come up with which may have some
advantages:

class ios_base {
public:
static struct {
static const fmtflags boolalpha;
static const fmtflags dec;
static const fmtflags fixed;
static const fmtflags hex;
static const fmtflags internal;
static const fmtflags left;
static const fmtflags oct;
static const fmtflags right;
static const fmtflags scientific;
static const fmtflags showbase;
static const fmtflags showpoint;
static const fmtflags showpos;
static const fmtflags skipws;
static const fmtflags unitbuf;
static const fmtflags uppercase;
static const fmtflags adjustfield;
static const fmtflags basefield;
static const fmtflags floatfield;
} format_flags;

static struct {
static const openmode app;
static const openmode ate;
static const openmode binary;
static const openmode in;
static const openmode out;
static const openmode trunc;
} openmode_flags;

static namespace {
static const iostate badbit;
static const iostate eofbit;
static const iostate failbit;
static const iostate goodbit;
} state_flags;

static struct {
static const seekdir beg;
static const seekdir cur;
static const seekdir end;
} seekdir_flags;
};
 
S

Steven T. Hatton

Dietmar said:
I second P.J.Plauger's advice! The standard C++ library is implemented
multiple times, including several commercial versions (at least three), at
least one GPL version, and at least one "free" version (although none is
public domain as far as I can tell). There is no licensing issue at all
with the standard C++ library because the standard is not an
implementation but a specification. The specification itself has
licensing restriction but there are no restrictions on implementing this
specification.

What I'm talking about is the other way around. If you simply took
something such as http://www.alhem.net/Sockets/index.html and, say, for
example, copied its header files and used them as a basis for the
specification, there could be legal problems. What you are talking about
are products based on the Standard, not a standard based on the products.
 
D

Dietmar Kuehl

Steven said:
This is what I wrote:

I know what you wrote.
copy(file_buf.eback(), file_buf.egptr(), back_inserter(data));

I'm not sure why you say that is fundamentally wrong.

Have you considered the possibility that it is fundamtentally wrong?
First of all, you are dealing with stream buffer internals which you
are only supposed to access when implementing stream buffers, not
when using them. Second, as I said before, the sequence
[eback(), gptr()) consists of characters which have already been read.
Finally, the sequence [gptr(), egptr()) is actually an internal of the
stream buffer consisting essentially of a portion of the file. This is
a level of abstraction you don't want to operate on when using a stream.
It is the right level of abstraction, however, for reading from an
external source.
I'm assuming eback()==gptr() when the iteration begins.

Say what you mean, mean what you say! Even if the assumption may be true
at the beginning of the file, it is source obfuscation at the best to
use the wrong pointer which may happen by accident to be identical to
the correct pointer at some point.
I'm looking at page 676 of TC++SL.

I guess you are talking of Nico's book in which case I would have written
or translated the IOStream portion. I don't have the book at hand and
thus I can't check what is said on page 676. However, I doubt that it
states that eback() is any good for a stream buffer user or that it is
the right thing to get the start of a buffer.

In addition, it the wrong tag to the problem anyway: to get an iterator
for a stream buffer you use 'std::istreambuf_iterator said:
How it /seems/, and how it actually /is/, may not be consistent. But you
are not in a position to determine how things seem to me.

Right, I forgot that you keep phrasing your statements vague up to the
point of being meaningless. Have you considered becoming a politician?
These peoples job is to talk nonsense the whole day to entertain the
public with the search of any concrete statement the politicians cannot
worm their way out.
That is what I had wanted to do, but I didn't see a way of getting an
iterator representing egptr(). I understand that, in the general case of
I/O streams, egptr() and the end of the input stream are not necessarily
the same thing, and therefore the analog to container.end() is not as easy
to express.

The one mistake I made was not using the best resources I have available.
§13.13.2

I'd say that

Expression Effect
streambuf _iterator<char>() Creates an end-of-stream iterator

in the mentioned paragraph is a pretty clear statement of how to get
the end iterator for a stream buffer... (I have an electronic version
of the book and thus can check for paragraphs but not for page numbers).
This is a difficult thing to understand. Partly because it preserves some
very ancient, and less than elegant aspects, and partly because there are
multiple dimensions to the conceptual structure of the I/O system. There
is the inheritance hierarchy of the basic_ios class templates shown here:
http://baldur.globalsymmetry.com/~hattons/Standard/doc/html/inherit__graph__35.png

This is a broken link. Anyway, you don't want to educate me about the
IOStreams or stream buffer class hierarchies, do you? I know pretty
well how the C++ I/O mechanisms work, you know. ... and I think they
are pretty simple to use once you have accepted the basic ideas of
using extractors and inserters and/or the use of sequences. For most
of the normal work you don't have to understand these hierarchies at
all! You just operate on an 'std::istream' or an 'std::eek:stream' - you
can even get a 'std::istreambuf_iterator' with an 'std::istream'.
One thing I find messy about the C++ I/O library is the use of format
flags. The following is on idea I have come up with which may have some
advantages:

You pasted some code there, I didn't see any idea not to mention anything
having advantages (well, you didn't state what it would have advantages
over...).
 
D

Dietmar Kuehl

Steven said:
What I'm talking about is the other way around. If you simply took
something such as http://www.alhem.net/Sockets/index.html and, say, for
example, copied its header files and used them as a basis for the
specification, there could be legal problems. What you are talking about
are products based on the Standard, not a standard based on the products.

My understanding is that interfaces cannot be copyrighted. The actual file
can, the semantics cannot. That is, if someone specified a library having
the same interface and semantics as some other library, using his own
words for the description, this would not be a copyright infringement.

However, "taking" something is not how the C++ committee operates, anyway.
The details of how the C++ committee operates were discussed publically in
the past. That is, you could have had all necessary information but you
decided to make insulting statements instead.
 
S

Steven T. Hatton

Dietmar said:
Steven said:
This is what I wrote:

I know what you wrote.
copy(file_buf.eback(), file_buf.egptr(), back_inserter(data));

I'm not sure why you say that is fundamentally wrong.

Have you considered the possibility that it is fundamtentally wrong?
First of all, you are dealing with stream buffer internals which you
are only supposed to access when implementing stream buffers, not
when using them. Second, as I said before, the sequence
[eback(), gptr()) consists of characters which have already been read.
Finally, the sequence [gptr(), egptr()) is actually an internal of the
stream buffer consisting essentially of a portion of the file. This is
a level of abstraction you don't want to operate on when using a stream.
It is the right level of abstraction, however, for reading from an
external source.

Recall that when I described the objective that I said the fact that I
needed to inherit from the stream buffer seemed wrong. I was only asking
about the range of data I specified. Nothing more.
Say what you mean, mean what you say! Even if the assumption may be true
at the beginning of the file, it is source obfuscation at the best to
use the wrong pointer which may happen by accident to be identical to
the correct pointer at some point.

All I had intended by my example was to indicate the range of data I wanted
access to. One of the more difficult things about using the STL model is
that the association between iterators, and the objects they are designed
to work in conjunction with is not appearant from looking at the object.
This is one of the advantages to object oriented programming. The
functions that have access to member data are present in the class
interface. In the case of std::streambuf<> I cannot simply look at the
interface and see that std::istreambuf_iterator<> is available in the
library. The problem represents the downside of loose coupling. In Java,
iterators are typically provided by a factory method of the container.
This is somewhat similar to the STL containers that provide iterator
typedefs as well as begin() and end() as part of their definition.

In the US we have a traditional children's story called _Hansel and Gretel_,
about two children who went for walk in the woods. They were afraid they
would get lost so the left a trail of breadcrumbs. We often use that as a
metaphor for something done intentionally so that a person can follow an
otherwise obscure path. That's what having the iterator in the interface
of the collection provides, a trail of breadcrumbs that tells you there is
an iterator available for that class.

Now consider a typical STL algorithm. You cannot look at an STL container
and see which algorithms are associated with it. Of course, once you
become familiar with the library that isn't that much of a problem. The
problem is that it takes longer to learn the library because it's harder to
find the information and how the different parts fit together. That is
what was missing from std::streambuf said:
I guess you are talking of Nico's book in which case I would have written
or translated the IOStream portion. I don't have the book at hand and
thus I can't check what is said on page 676. However, I doubt that it
states that eback() is any good for a stream buffer user or that it is
the right thing to get the start of a buffer.

No, it merely shows where the beginning of the available data is. Figure
13.5 and associated text.
In addition, it the wrong tag to the problem anyway: to get an iterator
for a stream buffer you use 'std::istreambuf_iterator<...>'.

Yes. I now know that. Thank you for posting that example yesterday.
Right, I forgot that you keep phrasing your statements vague up to the
point of being meaningless. Have you considered becoming a politician?
These peoples job is to talk nonsense the whole day to entertain the
public with the search of any concrete statement the politicians cannot
worm their way out.

Perhaps you are not finding meaning in what I am saying because you believe
my objective are different than they are. I'm trying to explain to you
something that you cannot see. That is, what the current C++ looks like to
a person who is learning it. I believe that is a valuable perspective for
a person involved in design to understand.
I think uttering 'std::istreambuf_iterator<char>()' does not take that
much effort or intellectual capacity...

See above. Also consider that it is an easy pitfall to try and use
I'd say that

Expression Effect
streambuf _iterator<char>() Creates an end-of-stream iterator

in the mentioned paragraph is a pretty clear statement of how to get
the end iterator for a stream buffer... (I have an electronic version
of the book and thus can check for paragraphs but not for page numbers).

http://baldur.globalsymmetry.com/~hattons/Standard/doc/html/inherit__graph__35.png
I trust you were able to go to the parent directory and find the doxygen
output. Sorry about that, I decided to update the files and forgot about
the consequence it might have on the file names.
This is basically the same diagram:
http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/inherit__graph__98.png
This is a broken link. Anyway, you don't want to educate me about the
IOStreams or stream buffer class hierarchies, do you? I know pretty
well how the C++ I/O mechanisms work, you know. ... and I think they
are pretty simple to use once you have accepted the basic ideas of
using extractors and inserters and/or the use of sequences.

And knowing which iterators are available, as well as what flags to use to
modify the behavior of the stream. Also relevant is the distinction
between formatted and unformatted operations. It is well advised also to
understand that unformatted streams may still alter the underlying data,
and that formatted operations may alter the data in a so-called "binary"
stream. It is easy to put the stream into "stupid" format states where the
wrong combination of flags is set causing the numeric format to behave as
if the default were set. strm.clear(flag) unsets everything _but_ flag.
strm.setf(flags) doesn't mean `set flags' even though that's what it does.
Then there is 'basic_ios' verses 'ios_base'. std::string::clear() does
something completely different than std::stringstream::clear(). Reading a
stream completely and correctly puts it into a fail state.

Then there are the necessary complexities of the design to consider.
For most
of the normal work you don't have to understand these hierarchies at
all! You just operate on an 'std::istream' or an 'std::eek:stream' - you
can even get a 'std::istreambuf_iterator' with an 'std::istream'.

So what happens when I have a C-style file pointer returned from a library?
Can I use that with C++ I/O?
You pasted some code there, I didn't see any idea not to mention anything
having advantages (well, you didn't state what it would have advantages
over...).

The advantage to that code is simple. It provides support for code
completion. I now realize it can be improved by subgroupping flags
according to their related fields. It's a very similar concept to scoped
enumerators. The biggest drawback to adding anything like that is that
there are already too many ways to do the same thing. It would add clutter
to an already cluttered interface. There are several things that could be
done with the basic concept that would provide a more usable interface than
the existing one. Unfortunately, the existing interface will remain, no
matter what.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,276
Latest member
Sawatmakal

Latest Threads

Top