Topic: Containers and secondary storage (clarification req)


Author: xleobx@qmailcomq.com
Date: Sat, 26 Jan 2002 16:19:03 GMT
Raw View
The definition of a container as per 23.1 does not clarify whether
it is legal to have a container that keeps the stored objects in
secondary storage, and retrieves them from that storage, from a cache,
or recomputes them by request, that is at the time an iterator is
dereferenced (it will have to be an Input iterator, obviously).

There is nothing, AFAIKS, that would prevent such a container
from working properly, but the wording of 23.1 "a container is
an object that stores other objects" and of 1.8 "object is a
region of storage" (of which storage?), and the usage of the word
"storage" in 1.7, as well as the lack of "storage" in 1.3 (Definitions)
muddy the matter to a great extent.

In any case, it will be better if the standard clarifies the issue
one way or another (preferably with an example that allows such containers).

 Leo (no Q's or X's in my address)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "P.J. Plauger" <pjp@dinkumware.com>
Date: Sat, 26 Jan 2002 16:58:59 GMT
Raw View
<xleobx@qmailcomq.com> wrote in message news:brs48.96$Bf1.3079@sjc-read.news.verio.net...

> The definition of a container as per 23.1 does not clarify whether
> it is legal to have a container that keeps the stored objects in
> secondary storage, and retrieves them from that storage, from a cache,
> or recomputes them by request, that is at the time an iterator is
> dereferenced (it will have to be an Input iterator, obviously).
>
> There is nothing, AFAIKS, that would prevent such a container
> from working properly, but the wording of 23.1 "a container is
> an object that stores other objects" and of 1.8 "object is a
> region of storage" (of which storage?), and the usage of the word
> "storage" in 1.7, as well as the lack of "storage" in 1.3 (Definitions)
> muddy the matter to a great extent.
>
> In any case, it will be better if the standard clarifies the issue
> one way or another (preferably with an example that allows such containers).

It's a delicate business, and I don't think it was thought through completely
before the C++ Standard froze. The C++ Standard permits an implementation to
accept allocators that define operator* to return other than T*. Fine, so
you have the chance to intervene every time someone dereferences an iterator.
But you pretty much have to return a pointer into a cache, given other
constraints, and there are no words about the lifetime of iterators. So it's
hard to know when it's safe to bump an element out of the cache.

It's still not clear to me just what kind of addressing games you can safely
play with allocators and containers. Right now, I'd say the list of
possibilities is more than some implementors want to support and fewer than
some programmers want to have supported.

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



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: xleobx@qmailcomq.com
Date: Sat, 26 Jan 2002 22:40:43 GMT
Raw View
P.J. Plauger <pjp@dinkumware.com> wrote:

>> The definition of a container as per 23.1 does not clarify whether
>> it is legal to have a container that keeps the stored objects in
>> secondary storage, and retrieves them from that storage, from a cache,
>> or recomputes them by request, that is at the time an iterator is
>> dereferenced (it will have to be an Input iterator, obviously).

> It's a delicate business, and I don't think it was thought through
> completely
> before the C++ Standard froze. The C++ Standard permits an implementation to
> accept allocators that define operator* to return other than T*. Fine, so

Huh? Did you mean T& (const T& for const_iterators), like in forward
iterators (everybody seem to think of them when thinking of "an iterator",
forgetting that input iterators are more restrictive)?
But 24.1.1 (table 72) says that for an _input_ iterator the operator*
returns "convertible to T", and T is the best "convertible to T" type that
I know. The note after the table is also very promising.

> you have the chance to intervene every time someone dereferences an
> iterator.
> But you pretty much have to return a pointer into a cache, given other

My point is that by Table 72, no, I don't.

> constraints, and there are no words about the lifetime of iterators. So it's
> hard to know when it's safe to bump an element out of the cache.

One still can do quite a lot with algorithms that only accept input iterators,
and, if implemented corrctly, never do things like T& t = *it, where 'it'
is an input iterator.

> It's still not clear to me just what kind of addressing games you can safely
> play with allocators and containers. Right now, I'd say the list of

Oh, no, no addressing games here. operator* will return an rvalue.

> possibilities is more than some implementors want to support and fewer than
> some programmers want to have supported.

If a possibility is allowed by the standard, it must be supported (sooner
or later), must it not?

 Leo (no Q's or X's in my address)

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "P.J. Plauger" <pjp@dinkumware.com>
Date: Sun, 27 Jan 2002 19:14:33 GMT
Raw View
<xleobx@qmailcomq.com> wrote in message news:xVF48.271$A%3.4790@ord-read.news.verio.net...

> > It's a delicate business, and I don't think it was thought through
> > completely
> > before the C++ Standard froze. The C++ Standard permits an implementation to
> > accept allocators that define operator* to return other than T*. Fine, so
>
> Huh? Did you mean T& (const T& for const_iterators),

Yes, sorry.

>                                                    like in forward
> iterators (everybody seem to think of them when thinking of "an iterator",
> forgetting that input iterators are more restrictive)?
> But 24.1.1 (table 72) says that for an _input_ iterator the operator*
> returns "convertible to T", and T is the best "convertible to T" type that
> I know. The note after the table is also very promising.

We're talking about containers, however, the weakest of which (slist) supports
forward iterators. I agree that you can be arbitrarily creative with input
and output iterators, since both effectively provide a one-element window on
a sequence of unknown length. Containers need stronger iterators than that,
however.

> > you have the chance to intervene every time someone dereferences an
> > iterator.
> > But you pretty much have to return a pointer into a cache, given other
>
> My point is that by Table 72, no, I don't.

Table 72 describes input iterators. So I agree, modulo comments above.

> > constraints, and there are no words about the lifetime of iterators. So it's
> > hard to know when it's safe to bump an element out of the cache.
>
> One still can do quite a lot with algorithms that only accept input iterators,
> and, if implemented corrctly, never do things like T& t = *it, where 'it'
> is an input iterator.

Then you shouldn't be talking about containers in the same breath.

> > It's still not clear to me just what kind of addressing games you can safely
> > play with allocators and containers. Right now, I'd say the list of
>
> Oh, no, no addressing games here. operator* will return an rvalue.

Again, fine for input iterators, but not acceptable for a container.

> > possibilities is more than some implementors want to support and fewer than
> > some programmers want to have supported.
>
> If a possibility is allowed by the standard, it must be supported (sooner
> or later), must it not?

We all like to think so, but some things come later than others. (export
templates, anybody?)

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



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: xleobx@qmailcomq.com
Date: Mon, 28 Jan 2002 00:17:09 GMT
Raw View
P.J. Plauger <pjp@dinkumware.com> wrote:

>> But 24.1.1 (table 72) says that for an _input_ iterator the operator*
>> returns "convertible to T", and T is the best "convertible to T" type that
>> I know. The note after the table is also very promising.

> We're talking about containers, however, the weakest of which (slist) supports

Ah. The weakest of _standard_ containers is list, which supports forward
bidirectional iterator. Following your logic, it will mean that slist is
not a container, because its iterator is not bidirectional (I know, I know,
there is a clause that allows slist to be a sequence container).

But for a user-defined class (and slist is still one of
them) to be a container, it only has to conform to table 65, hasn't it?
And the fact that the standard does not give an example of a container that is
neither sequence nor associative does not mean such a container cannot
be declared.

> forward iterators. I agree that you can be arbitrarily creative with input
> and output iterators, since both effectively provide a one-element window on
> a sequence of unknown length. Containers need stronger iterators than that,
> however.

Where do I misread the standard, then? Most non-mutating algorithms
take Input iterators. If I wrap a file with a list of prime numbers
in a container, I will still be able to run for_each() or find() over it.

>> One still can do quite a lot with algorithms that only accept
>> input iterators,
>> and, if implemented corrctly, never do things like T& t = *it, where 'it'
>> is an input iterator.

> Then you shouldn't be talking about containers in the same breath.

Granted, all predefined containers have iterators that are stronger
than Input iterator, but the original question still stands: forgetting
all implementation details, if a class implements table 65
(with input iterator as its iterator category),
and its iterator implements table 72, using the axiom "T is convertible
to T", is it a container or not? If not what clause in the standard am I
missing?

>> Oh, no, no addressing games here. operator* will return an rvalue.

> Again, fine for input iterators, but not acceptable for a container.

By what clause? Containers are allowed to have input iterators as
iterator category.

>> If a possibility is allowed by the standard, it must be supported (sooner
>> or later), must it not?

> We all like to think so, but some things come later than others. (export
> templates, anybody?)

Member templates (mostly there, but still not in all compilers),
template templates (mostly not there) ...

 Leo

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]