Re: [boost] Re: Boost memory management guidelines

2003-09-02 Thread Gregory Colvin
On Tuesday, Sep 2, 2003, at 05:42 America/Denver, David Abrahams wrote:
Gregory Colvin [EMAIL PROTECTED] writes:

On Monday, Sep 1, 2003, at 14:48 America/Denver, David Abrahams wrote:
Gregory Colvin [EMAIL PROTECTED] writes:

Conforming containers had better use them.
I'm sorry, but I think that's flat wrong.  What do you suppose that
entry in column 2 of the allocator requirements table (20.1.5) 
means,
after all?
It means any value returned by construct, destroy, or deallocate 
goes
unused.

And once you are down in the coal mine customizing what a pointer
is, I'm not sure you won't need to customize how to construct and
destroy.
The class getting constructed/destroyed has full control over that 
or
the language is utterly bustificated.
Yes, but the allocator may want to do something else as well, and
construct and destroy serve as hooks for whatever that may be.
Regardless, there is absolutely _nothing_ in the standard AFAICT 
which
indicates the containers must use the allocator's construct and
destroy, and several implementations in fact do not.
Well then, I consider the standard broken in that regard.  But we are
off the topic that started this thread.
Apropos of which, I now think that the Boost UserAllocator 
requirements
should be the default for components that parameterize how they use
memory, with the Standard Allocator requirements being used only for
components that need what they offer: a potentially very efficient way
to allocate large numbers of small objects of known type, and/or a
way to access storage via proxied pointers.
I think part of my point was that *nobody* needs what they offer, if
you include construct/destroy.
Or rather that some implementations have failed to use what they
offer, and our standard unfortunately doesn't insist that they do.
Another reason construct is needed is that Allocator::pointer might
be a proxy, with operator* and operator- but not necessarily a
conversion to void* or even T*.
  In fact, construct requires undefined
behavior for non-POD T because you can't copy its T* argument which
points into raw storage.
I don't understand what you mean by this.  Are you claiming that
it is undefined to copy just a pointer to raw storage?  If so,
then how is placement new not undefined?  The standard says:
  a.construct(p,t)
  Effect: new((void*)p) T(t)
I think I would rather see a MPL lambda expression or metafunction
class interface for allocator type parameters.  It makes little sense
for the allocator's user to be choosing its value_type.
Something like:

  some_allocator_1

or

  struct select_allocator
  {
  template class T
  struct apply
  {
  typedef some_allocatorT type;
  };
  };
with some_allocator's interface being like what's required for
std::allocator but not including misplaced interface bits such as
address/construct/destroy, and possibly max_size -- these can be added
by a std::allocator facade wrapper if neccessary.
I'm not sure we need a simple version and a complicated version.
I'm not clear how you intend the above to be used, or what you
intend it to be a replacement for.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Boost memory management guidelines

2003-09-02 Thread Gregory Colvin
On Tuesday, Sep 2, 2003, at 09:22 America/Denver, David Abrahams wrote:

Gregory Colvin [EMAIL PROTECTED] writes:

I think part of my point was that *nobody* needs what they offer, if
you include construct/destroy.
Or rather that some implementations have failed to use what they
offer, and our standard unfortunately doesn't insist that they do.
It's not unfortunate if it adds nothing, which is what I believe.

Another reason construct is needed is that Allocator::pointer might
be a proxy, with operator* and operator- but not necessarily a
conversion to void* or even T*.
Doesn't matter; you can always get the address of an object.  See
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-closed.html#390
So you would rather use this than use construct?

  template typename T T* addressof(T v)
  {
return reinterpret_castT*(
 const_castchar(reinterpret_castconst volatile char 
(v)));
  }

In fact, construct requires undefined behavior for non-POD T
because you can't copy its T* argument which points into raw
storage.
I don't understand what you mean by this.  Are you claiming that
it is undefined to copy just a pointer to raw storage?
Unless the pointer has the right type, yes.
In which case the A::pointer return from A::allocate() is already
undefined behavior?
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Boost memory management guidelines

2003-09-02 Thread Gregory Colvin
On Tuesday, Sep 2, 2003, at 09:22 America/Denver, David Abrahams wrote:

Gregory Colvin [EMAIL PROTECTED] writes:
...
Dave:
I think I would rather see a MPL lambda expression or metafunction
class interface for allocator type parameters.  It makes little sense
for the allocator's user to be choosing its value_type.
Something like:

  some_allocator_1

or

  struct select_allocator
  {
  template class T
  struct apply
  {
  typedef some_allocatorT type;
  };
  };
with some_allocator's interface being like what's required for
std::allocator but not including misplaced interface bits such as
address/construct/destroy, and possibly max_size -- these can be 
added
by a std::allocator facade wrapper if neccessary.

I'm not sure we need a simple version and a complicated version.
I'm not clear how you intend the above to be used, or what you
intend it to be a replacement for.
I intend it to be the sort of type parameter that gets passed to our
objects which need custom allocation in place of a standard allocator.
It's ridiculous, IMO, to pass allocatorT to a node-based container
which is *never* going to allocate a T object.
But given rebind() it doesn't really matter.  We could just as
well have specified that all containers take allocatorvoid
arguments.
  The container itself
should decide which type the allocator template gets instantiated on,
via:
mpl::applympl::lambdaS, Node::type

 [
   this is approximately the same as:
 S::template applyU::type == some_allocatorU

   except that it works when S is the lambda expression
   some_allocator_1 as well as when it's the select_allocator
   metafunction class below it.
 ]
Sorry, but I'm still not following this, but that may be
because I don't know much MPL, so I can only guess at what
you are up to.  I probably need a detailed example of how to
write and use one of these thingys to make any sense of your
proposal.
Does your proposal support stateful allocators?

What the rebind requirement in the allocator means for pool
allocation, for example, is that a pool_allocatorT object must
either be stateless (in which case allocator inequality is
meaningless)
Yes, all stateless allocators compare equal, and stateless
allocators are the easiest kind to make compare equal, as
the standard currently requires allocators to do.
or effectively be able to allocate blocks of *any* size
and alignment, rather than just as appropriate for T.
Yes, because node-based containers need to allocate nodes,
perhaps of various kinds, but they don't expose their
node types in their interface.  So you have to pass in
something, and we went with T rather than void or whatever.
It might have been better to have different allocator
interfaces for array-based versus node-based containers,
since array-based containers have no need of rebind(), and
node-based containers have no need of allocatorT.
  It's a conceptual mess.
Alex didn't have MPL when he invented allocators.  So they are
messier than they need to be, but I still say they are not so
bad as you claim, and that it would be easier for the next
standard to repair them than to replace them.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Boost memory management guidelines

2003-09-02 Thread Gregory Colvin
On Tuesday, Sep 2, 2003, at 11:22 America/Denver, David Abrahams wrote:
Gregory Colvin [EMAIL PROTECTED] writes:

On Tuesday, Sep 2, 2003, at 09:22 America/Denver, David Abrahams 
wrote:

Gregory Colvin [EMAIL PROTECTED] writes:

I think part of my point was that *nobody* needs what they offer, 
if
you include construct/destroy.
Or rather that some implementations have failed to use what they
offer, and our standard unfortunately doesn't insist that they do.
It's not unfortunate if it adds nothing, which is what I believe.

Another reason construct is needed is that Allocator::pointer might
be a proxy, with operator* and operator- but not necessarily a
conversion to void* or even T*.
Doesn't matter; you can always get the address of an object.  See
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-closed.html#390
So you would rather use this than use construct?

   template typename T T* addressof(T v)
   {
 return reinterpret_castT*(
  const_castchar(reinterpret_castconst volatile char
  (v)));
   }
As long as it's packaged away and I don't have to look at the
implementation.  A customization point like an allocator should not be
required to supply boilerplate that's always going to be the same.
You are assuming that there was no good reason to allow an allocator
to hook construct and destroy, for instance to do some bookkeeping.
When I need to find out what I need to implement in order to customize
allocation, I don't want to have to read through something which is
50% irrelevant to the task, as the allocator requirements are.
Which is why I'm now suggesting that Boost UserAllocator is a better
default.
But in some cases, like the shared_ptr feature request that got me
thinking on this, what you want is just to have objects allocate
their internals using the same allocator as the container they
are being placed in, in which case you don't need to implement an
allocator, just call get_allocator().
n fact, construct requires undefined behavior for non-POD T
because you can't copy its T* argument which points into raw
storage.
I don't understand what you mean by this.  Are you claiming that
it is undefined to copy just a pointer to raw storage?
Unless the pointer has the right type, yes.
In which case the A::pointer return from A::allocate() is already
undefined behavior?
Wow.  Yes, IIUC.  DR, I guess.
I'm reeling from the implication that the following is undefined
behavior for non-POD T:
	T* p = (T*)malloc(sizeof T);

Are you sure?

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Boost memory management guidelines

2003-09-02 Thread Gregory Colvin
On Tuesday, Sep 2, 2003, at 11:39 America/Denver, David Abrahams wrote:
Gregory Colvin [EMAIL PROTECTED] writes:

On Tuesday, Sep 2, 2003, at 09:22 America/Denver, David Abrahams 
wrote:
...

I think you're missing my point.  There's no reason that a stateful
allocatorT should have access to the state data required to
allocate U objects, but that's the status quo.
I'm probably missing your point, but the idea is that a container
needs to allocate various kinds of things, and they all get
allocated with the same allocator, either directly or via rebind.
For instance, maybe you are are using memory-mapped files as a
persistent storage.  The Ts and the Us and whatever the container
needs all have to go into the same file, so the allocatorT and
all its rebinds must know which file to use and how.
...
  It's a conceptual mess.
Alex didn't have MPL when he invented allocators.  So they are
messier than they need to be, but I still say they are not so
bad as you claim
Are you saying my factual claims are wrong, or just that all those
issues don't amount to a very important problem?
Just that it doesn't look nearly as messy to me as it does to you.

and that it would be easier for the next standard to repair them
than to replace them.
That may be, but we're here at Boost, talking about the interface we
should be using in Boost components.
Yep.  I still think UserAllocator is a good default, and that where it
doesn't suffice there is some value to playing nicely with STL.
So even when we come up with some beautiful new thing to do the
allocation job better, we will still need adaptors both ways, so that
one can get an allocator from an STL container and turn it in to one
of our new things, or take one of our new things and turn it into an
allocator to use in an STL container.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Boost memory management guidelines

2003-09-02 Thread Gregory Colvin
On Tuesday, Sep 2, 2003, at 12:27 America/Denver, Peter Dimov wrote:

Gregory Colvin wrote:
You are assuming that there was no good reason to allow an allocator
to hook construct and destroy, for instance to do some bookkeeping.
I'm curious. Have you ever seen such an allocator? I've always assumed 
that
construct/destroy/pointer are a but someone might need to do that 
feature
that nobody has ever used.
I've heard allocators described that probably used construct()
to navigate efficiently from a proxy pointer to the raw memory
in which to construct.  But I never saw the code.
 Then again, the Dinkumware implementation
dutifully calls construct and destroy, paying (and forcing me to pay) 
the
abstraction penalty price... so maybe I'm wrong, and construct/destroy 
are
useful?
I don't see that there need be any performance price for what
Dinkumware does, or is that not what you mean by abstraction
penalty?
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Boost memory management guidelines

2003-09-02 Thread Gregory Colvin
On Tuesday, Sep 2, 2003, at 13:00 America/Denver, Peter Dimov wrote:

Gregory Colvin wrote:
On Tuesday, Sep 2, 2003, at 12:27 America/Denver, Peter Dimov wrote:

 Then again, the Dinkumware implementation
dutifully calls construct and destroy, paying (and forcing me to pay)
the abstraction penalty price... so maybe I'm wrong, and
construct/destroy are useful?
I don't see that there need be any performance price for what
Dinkumware does, or is that not what you mean by abstraction
penalty?
I'm not saying that there need be any price in a perfect world. I am 
saying
that in practice, on the compiler I use, there is a price, like 
calling a
non-inline destroy() O(N) times for a value_type that has an inline, 
empty,
nonvirtual destructor. Or even for a built-in value_type.
That is most unfortunate.

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Boost memory management guidelines

2003-09-02 Thread Gregory Colvin
On Tuesday, Sep 2, 2003, at 12:51 America/Denver, David Abrahams wrote:

Gregory Colvin [EMAIL PROTECTED] writes:

On Tuesday, Sep 2, 2003, at 11:22 America/Denver, David Abrahams 
wrote:
Gregory Colvin [EMAIL PROTECTED] writes:

So you would rather use this than use construct?

   template typename T T* addressof(T v)
   {
 return reinterpret_castT*(
  const_castchar(reinterpret_castconst volatile char
  (v)));
   }
As long as it's packaged away and I don't have to look at the
implementation.  A customization point like an allocator should not 
be
required to supply boilerplate that's always going to be the same.
You are assuming that there was no good reason to allow an allocator
to hook construct and destroy, for instance to do some bookkeeping.
The fact that nobody's required to use construct and/or destroy is
testament to that.
Thanks to the weasel-wording nobody's required to use much of
anything besides allocate, deallocate, and rebind.  That doesn't
mean there was no point to all the rest in the original design.
When I need to find out what I need to implement in order to
customize allocation, I don't want to have to read through
something which is 50% irrelevant to the task, as the allocator
requirements are.
Which is why I'm now suggesting that Boost UserAllocator is a better
default.
But in some cases, like the shared_ptr feature request that got me
thinking on this, what you want is just to have objects allocate
their internals using the same allocator as the container they
are being placed in, in which case you don't need to implement an
allocator, just call get_allocator().
Is it enough for all of Boost?
It's probably overkill for some things.

  If so, great!  If not, we still need
to think about what a more-sophisticated interface looks like.
Only if UserAllocator is inadequate?

Also, if shared_ptr only needs to allocate at construction time (I'm
not sure of this) we can avoid storing the allocator at all.
Then how to deallocate?

I'm reeling from the implication that the following is undefined
behavior for non-POD T:
	T* p = (T*)malloc(sizeof T);

Are you sure?
Nope.  3.8/5 shows that I'm wrong.
That's a relief.

 It still doesn't make any sense to
return a T* from allocate since normally with a non-singular T* p,
either p == 0 or *p refers to a constructed T.
The idea was that AllocatorT::pointer might be a proxy type
that cannot be converted to void* and back, so allocate() must
return and construct() must take an AllocatorT::pointer rather
than a void*.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Boost memory management guidelines

2003-09-02 Thread Gregory Colvin
On Tuesday, Sep 2, 2003, at 13:18 America/Denver, E. Gladyshev wrote:
--- Gregory Colvin [EMAIL PROTECTED] wrote:
Yep.  I still think UserAllocator is a good default, and that where it
doesn't suffice there is some value to playing nicely with STL.
So even when we come up with some beautiful new thing to do the
allocation job better, we will still need adaptors both ways, so that
one can get an allocator from an STL container and turn it in to one
of our new things, or take one of our new things and turn it into an
allocator to use in an STL container.
Am I right in trying to summarize your suggestion about UserAllocator?

If you want to parametrize how a boost class manages memory,
use UserAllocator parameter.
Unless you need the standard Allocator interface.

1. The allocator parameter should implement the UserAllocator 
interface.
2. All instances of UserAllocator must be equal and stateless.
The Boost pools use UserAllocator only as a type parameter.  It is not
required to be constructible or comparable.
3. If your class is using STL containers, use boost::memory::allocator
   adapter (see bellow).
Why not just use std::allocator?

4. To construct/destroy objects, use boost::memory::construct/destroy.
See below.

5. Avoid using explicit references to allocators.

... Usage example:
==
template typename T, typename UserAllocator = 
boost::default_user_allocator_new_delete 
class X
{
What if you want X to use the same allocator as some other STL container
constructed with a non-Boost allocator?  That would be difficult unless
you have
  templatetypename T, class StdAllocator = std::allocatorT 
  struct X {
X(const StdAllocator);
Also, it might sometimes be desirable, as it is for shared_ptr, to
defer the choice of allocator until construction time:
  templatetypename T
  struct X {
templateclass StdAllocator = std::allocatorT 
X(const StdAllocator);
Or, if UserAllocator suffices:

  templatetypename T
  struct X {
templateclass UserAllocator X();
T* _p;
Leading underscores are a no-no.

std::vectorT, boost::memory::allocatorT, UserAllocator  _v;

X()
{
_p = boost::memory::constructT, UserAllocator( 1 )
How to pass arguments to T's constructor?  Better just

  p = new(UserAllocator::malloc(sizeof T)) T(...)

}
~X()
{
if( _p )
boost::memory::destroyT, UserAllocator( _p, 1 );
In which case, why not just

  p-~T(), UserAllocator::free(p);

?

}
};
Eugene
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Boost memory management guidelines

2003-09-02 Thread Gregory Colvin
On Tuesday, Sep 2, 2003, at 15:00 America/Denver, David Abrahams wrote:
Gregory Colvin [EMAIL PROTECTED] writes:

Also, if shared_ptr only needs to allocate at construction time (I'm
not sure of this) we can avoid storing the allocator at all.
Then how to deallocate?
Using the custom deleter?
Which will need to store a copy of the allocator, unless one
takes advantage of the weasel wording that lets you instantiate
a new one for the purpose.
...
 It still doesn't make any sense to
return a T* from allocate since normally with a non-singular T* p,
either p == 0 or *p refers to a constructed T.
The idea was that AllocatorT::pointer might be a proxy type
that cannot be converted to void* and back, so allocate() must
return and construct() must take an AllocatorT::pointer rather
than a void*.
Wow, creepy.
Yes.  But unless you grant the desire to support such creepy
beasts then not much of Allocator makes any sense.  And such
beasts can do useful work, like persistent stores and shared
memory.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Re: Optional, tie, and iterator_adaptor

2003-09-01 Thread Gregory Colvin
On Monday, Sep 1, 2003, at 11:31 America/Denver, Joel de Guzman wrote:

Fernando Cacciola [EMAIL PROTECTED] wrote:

vector::begin returns an object with operators * and -,
yet these objects are not pointers, and once that is learned,
people do not think they are pointers.
Huh? pointer semantics (behavior) does not mean that they
have to be pointers.
But would the following hold if p and q are optionlint?

*q = 1;
p = q;
*p = 2;
assert(*q == 2);
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Boost memory management guidelines

2003-08-31 Thread Gregory Colvin
On Sunday, Aug 31, 2003, at 13:13 America/Denver, David Abrahams wrote:
Gregory Colvin [EMAIL PROTECTED] writes:

But indeed allocate/construct/deallocate/destroy is more work than
  ^^^^
Oyeah.  These two absolutely don't belong in allocator, period.  Do
any implementations even use them?  Allocators exist to provide a
point of customization for users, but you cannot/should not customize
these.
Conforming containers had better use them.
I'm sorry, but I think that's flat wrong.  What do you suppose that
entry in column 2 of the allocator requirements table (20.1.5) means,
after all?
It means any value returned by construct, destroy, or deallocate goes 
unused.

And once you are down in the coal mine customizing what a pointer
is, I'm not sure you won't need to customize how to construct and
destroy.
The class getting constructed/destroyed has full control over that or
the language is utterly bustificated.
Yes, but the allocator may want to do something else as well, and
construct and destroy serve as hooks for whatever that may be.
Using allocator is even more work than allocating raw memory with
malloc and doing placement new and explicit destruction, then freeing
the raw memory.  That's my biggest complaint.
It's new/delete

   T* p = new T();
   ...
   delete p;
versus malloc/free

   T* p = (T*)malloc(sizeof T);
When you need

 malloc(sizeof(T) + N)

Allocators get a lot harder to use.
Agreed.


   new(p) T();
   ...
   p-~T();
   free(p);
versus Boost UserAllocator

   T* p = (T*)user_allocator::malloc(sizeof T);
   new(p) T();
   ...
   p-~T();
   user_allocator::free(p);
versus standard Allocator

   Allocator::pointer p = allocator.allocate(sizeof T);
   allocator.construct(p,T());
   ...
   allocator.destroy(p);
   allocator.deallocate(sizeof T);
  

Oops! There's a pointer missing here.
Silly me for not compiling my email.

 Just a small example of why I'm saying it's a harder interface.
Very small.

 Allocator has strange requirements, like p shall not be null.
Another performance optimization.  In most cases there is no way
that p could be null in the first place, so why waste time checking?
  If I need to build a custom one I have to
navigate rebind and the implications of allocator inequality for which
the standard provides little guidance.
Agreed.  The Boost UserAllocator is easier to implement and to use.

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Boost memory management guidelines

2003-08-31 Thread Gregory Colvin
On Sunday, Aug 31, 2003, at 13:51 America/Denver, Peter Dimov wrote:

Gregory Colvin wrote:

[...]

Two small corrections:

shared_ptr currently uses std::allocator to allocate counts
regardless.
No, it uses plain new/delete by default. It is possible to get it to 
use
std::allocator via a #define.
OK.  Anyway, the std::allocator interface is adequate for shared_ptr.

[...]

versus standard Allocator

   Allocator::pointer p = allocator.allocate(sizeof T);
   allocator.construct(p,T());
   ...
   allocator.destroy(p);
   allocator.deallocate(sizeof T);
allocate(1) and deallocate(p, 1) if I'm not mistaken.
You are not.  I shouldn't post uncompiled code late at night.

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Boost memory management guidelines

2003-08-30 Thread Gregory Colvin
On Friday, Aug 29, 2003, at 18:05 America/Denver, David Abrahams wrote:
Gregory Colvin [EMAIL PROTECTED] writes:

* use the standard parameterization mechanisms (Allocator) when
   choosing to parameterize
I'm not sure about this one.  std::allocator are a mess, and almost
everyone knows it.  They were designed for containers, and they only
barely work there, IMO.
IMO they work just fine, and are not so messy as everyone thinks.
The only real ugliness is rebind, but without template typedefs there
isn't much choice.  And the only really missing functionality is
reallocation, but one can usually do without that.  They can be
difficult to implement well, but I think that is separate issue.
  Remember the weasel-wording about unequal
allocators and the assumptions implementations are allowed to make
about allocator's nested types?
Remember it?  I helped write it.  It's unfortunate, as I explained
earlier in this thread, but clear enough.  It mainly serves to give
implementors more latitude in how they implement their containers,
and thus to give users fewer guarantees that fancy allocators will
work.
 I really don't want to be in the
position of forcing library authors to match users' expectations about
the way their particular implementation's allocators work.
No force here.  If you choose to take any kind of template parameters
you should be clear what you require of them, and where the standard
provides a useable set of requirements it makes sense to point to them.
But if you need something different then by all means specify what you
need.
And I wasn't aware that there was that much variation in std::allocator
functionality, though I know there is some variation in whether the
standard containers support stateful allocators and proxy pointers.
From my point of view, by choosing the standard Allocator interface you
get:
* a standard set of requirements, with a few levels of strictness to
  choose from
* a usually high-quality standard implementation (std:allocator)
* a high quality Boost implementation (boost::pool_allocator)
* the ability to play nicely with the standard containers
In short, I think standard allocators are a squeaky wheel, but in most
cases it better to grease that wheel than reinvent it.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Boost memory management guidelines

2003-08-30 Thread Gregory Colvin
On Friday, Aug 29, 2003, at 18:16 America/Denver, E. Gladyshev wrote:
I'd like to start a new thread with Gregory's suggestion
and my comments.
Gregory Colvin wrote:
...
* use the standard mechanisms (::operator new or std::allocator)
   when it is necessary
Boost already has boost::allocator.  IMO other boost libaries
should consider using boost::allocator instead of
::new and std::allocator.
There is a tradeoff between possibly better performance and possibly
unwanted dependancies.
...
* parameterize only when there is a clear advantage to doing so
I'd modify it to

* Consider parametrization if your library is to be available
  for embedded or non-traditional platfroms.
Even on traditional platforms there may reason to parameterize, and
there may be alternatives to parameterization even on embedded plaforms.
* use the standard parameterization mechanisms (Allocator) when
   choosing to parameterize
I'd add to it
* Follow boost::allocator specification for allocator parameters
Which specification is that?  There are several here:

http://boost.org/libs/pool/doc/interfaces.html

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: what happened to allocators in boost?

2003-08-29 Thread Gregory Colvin
On Thursday, Aug 28, 2003, at 16:54 America/Denver, E. Gladyshev wrote:

--- Gregory Colvin [EMAIL PROTECTED] wrote:
And I have no objection myself to adding an allocator parameter
to the shared_ptr constructor, or to making some other change that
serves the purpose.  So if you need a change, why not just do it,
try it out, and submit a patch?
Just wondering what is the submission procedure exactly?
Dunno.  My last submission was too long ago.

For example I believe that shared_ptr must absolutely
have the counter type as a template parameter.
And I believe it absolutely must not:

http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1450.html

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: what happened to allocators in boost?

2003-08-29 Thread Gregory Colvin
On Thursday, Aug 28, 2003, at 16:26 America/Denver, E. Gladyshev wrote:
--- Gregory Colvin [EMAIL PROTECTED] wrote:
How will I even know it, the documentation is completely
ignorant on the memory issues.
Perhaps because you work with the authors of the documentation to
make it sure it says what needs saying?
Are the documentation authors monitoring this mailing list?

And I have no objection myself to adding an allocator parameter
to the shared_ptr constructor, or to making some other change that
serves the purpose.  So if you need a change, why not just do it,
try it out, and submit a patch?
How about

template typename T, typename Counter = int 
shared_ptr
{
   typedef Counter counter;  //counter type should be public
   template typename DataAlloc = std::allocatorT, typename  
CounterAlloc=std::allocatorcounter

   shared_ptr( const DataAlloc da = DataAlloc(), const IntAlloc ia =  
CountAlloc() );
};
shared_ptr doesn't allocate the data, it only deletes it, which is the  
job of the
current deleter parameter.  And the counter type is by design not part  
of the
shared_ptr type, so it doesn't belong as parameter to the shared_ptr  
template.
See:

http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/boost/boost/boost/ 
shared_ptr.hpp

So you what you might want is to add something more like this to  
shared_ptr:

   templatetypename Data, typename Deleter, templateclass Counter  
class Allocator
   shared_ptr(
  Data*,
  Deleter,
  const Allocatorboost::detail::sp_counted_base_implData*,  
Deleter  );

The idea being that you can use this constructor to get complete  
control over how
a particular shared_ptr manages memory.

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: what happened to allocators in boost?

2003-08-29 Thread Gregory Colvin
On Thursday, Aug 28, 2003, at 19:40 America/Denver, E. Gladyshev wrote:
--- Gregory Colvin [EMAIL PROTECTED] wrote:
shared_ptr doesn't allocate the data, it only deletes it, which is 
the job of the
current deleter parameter.  And the counter type is by design not 
part of the
shared_ptr type, so it doesn't belong as parameter to the shared_ptr 
template.
See:

http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/boost/boost/boost/
shared_ptr.hpp
So you what you might want is to add something more like this to
shared_ptr:
templatetypename Data, typename Deleter, templateclass Counter
class Allocator
shared_ptr(
   Data*,
   Deleter,
   const Allocatorboost::detail::sp_counted_base_implData*,
Deleter  );
The idea being that you can use this constructor to get complete 
control over how
a particular shared_ptr manages memory.
In this solution, there are some issues with who
controls the instances of the allocator that allocates
Data and instances that delete the Data.
Which issues concern you?

But I guess it is not big deal as soon as people understand it.
If are to use template template parameters,
Yes, the template template parameter is a pain.  Probably better to
take an arbitrary allocator object and rebind it:
   templateclass Y, class D, class A
   shared_ptr(T* p, D d, const A a)
   : px(p), pn(p, d, A::rebinddetail::sp_counted_base_implData*,D 
(a))
   {
detail::sp_enable_shared_from_this(p, p, pn);
   }

it would be nice to be able to define one allocator
type for both counter and data.
templatetypename Data, templateclass
class Allocator
shared_ptr(
   Data*,
   AllocatorData,
   const Allocatorboost::detail::sp_counted_base_implData*,
Deleter  );
This constructor would conflict with the constructors that take a
deleter, which must be a function pointer or function object, and
which might not use an allocator.
But for the purpose of creating shared objects using an allocator
you could instead use a factory function something like:
   templateclass Allocator,typename Data
   shared_ptrT
   allocate_shared_data(const Data data, Allocator allocator)
   {
  struct deleter {
 Allocator a;
 deleter(const Allocator a) : a(a) {}
 void operator()(Data* p) {
a.deallocate(p,1);
a.destroy(p);
 }
  };
  Data* p = allocator.allocate(1);
  allocator.construct(p,data);
  return shared_ptrData(p,deleterData(allocator),allocator);
   }
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: what happened to allocators in boost?

2003-08-29 Thread Gregory Colvin
On Thursday, Aug 28, 2003, at 23:48 America/Denver, E. Gladyshev wrote:
--- Gregory Colvin [EMAIL PROTECTED] wrote:
[...]
In this solution, there are some issues with who
controls the instances of the allocator that allocates
Data and instances that delete the Data.
Which issues concern you?
The potential problem is this. Let's assume that
I forgot (or didn't know) that shared_ptr creates
a copy of Deleter.
I can technically create a local allocator class
that will keep the heap control block
as a data memeber.
*pseudo-code*

template typename T 
sturct  my_allocator
{
   my_heap_control _heap;
   T* create()
   {
  return _heap.create();
   }
   void operator()( T* d )
   {
  _heap.destroy(d);
   }
};
Now if I do something like the following code (that looks perfecly 
fine).

f()
{
  my_allocatorint a;
  {
 shared_ptrint s( a.create(), a );
 ...
 int* n = a.create();
 a(n);
  }
}
I got a problem, because by the time when 's' deletes my data
the heap state is changed while 's' still has an old copy
of the heap state.
* If we state that boost allocators must be implemented
like statless policies not like real data types,
this problem is not a big deal.
I am not understanding the above at all, maybe because I don't
know what you mean by heap control block or stateless policies
or real data types.
But I guess it is not big deal as soon as people understand it.
If are to use template template parameters,
Yes, the template template parameter is a pain.  Probably better to
take an arbitrary allocator object and rebind it:
templateclass Y, class D, class A
shared_ptr(T* p, D d, const A a)
: px(p), pn(p, d, A::rebinddetail::sp_counted_base_implData*,D
(a))
{
 detail::sp_enable_shared_from_this(p, p, pn);
}
it would be nice to be able to define one allocator
type for both counter and data.
templatetypename Data, templateclass
class Allocator
shared_ptr(
   Data*,
   AllocatorData,
   const Allocatorboost::detail::sp_counted_base_implData*,
Deleter  );
This constructor would conflict with the constructors that take a
deleter, which must be a function pointer or function object, and
which might not use an allocator.
Right, a new constructor is not needed.

But for the purpose of creating shared objects using an allocator
you could instead use a factory function something like:
templateclass Allocator,typename Data
shared_ptrT
allocate_shared_data(const Data data, Allocator allocator)
{
   struct deleter {
  Allocator a;
  deleter(const Allocator a) : a(a) {}
  void operator()(Data* p) {
 a.deallocate(p,1);
 a.destroy(p);
  }
   };
   Data* p = allocator.allocate(1);
   allocator.construct(p,data);
   return shared_ptrData(p,deleterData(allocator),allocator);
}
I like it.

Or you can add operator()(Data*) to your allocator
and use it directly in shared_ptr and STL.
Right.

template typename T 
struct my_allocator : std::alocatorT
{
   void operator()(T* d)
   {
 try
 {
   d-~T();
 }
 catch(...)
 {
   deallocate(d, 1);
   throw std::runtime_error();
 }
 deallocate(d, 1);
 return;
   }
};
shared_ptrData s( p, my_allocatorData(), my_allocator() );

I am not sure how to specify the counter allocator in this case
What is legal syntax for template template parameters in functions?
We just got rid of the template template parameter.

Do you have to put the whole thing in.

shared_ptrData s( p, my_allocatorData(), 
my_allocatorp,my_allocatorData () );

or there is another way?
my_allocatorData a;

shared_ptrData s(p,a,a);

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: what happened to allocators in boost?

2003-08-29 Thread Gregory Colvin
On Friday, Aug 29, 2003, at 00:52 America/Denver, E. Gladyshev wrote:
--- Gregory Colvin [EMAIL PROTECTED] wrote:
On Thursday, Aug 28, 2003, at 23:48 America/Denver, E. Gladyshev 
wrote:

*pseudo-code*

template typename T 
sturct  my_allocator
{
   my_heap_control _heap;
   T* create()
   {
  return _heap.create();
   }
   void operator()( T* d )
   {
  _heap.destroy(d);
   }
};
Now if I do something like the following code (that looks perfecly
fine).
f()
{
  my_allocatorint a;
  {
 shared_ptrint s( a.create(), a );
 ...
 int* n = a.create();
 a(n);
  }
}
I got a problem, because by the time when 's' deletes my data
the heap state is changed while 's' still has an old copy
of the heap state.
* If we state that boost allocators must be implemented
like statless policies not like real data types,
this problem is not a big deal.
I am not understanding the above at all, maybe because I don't
know what you mean by heap control block or stateless policies
or real data types.
I called stateless policies data types that define some actions
(policies) that never change the state of any of this data
type instances.
The heap control block is a data type that manages
the state of a memory heap.  For instance it can keep
a list/directory of pointers to free block in the heap.
No imagine the the my_allocator has a list of pointers
to free memory blocks in some memory heap.
template typename T 
sturct  my_allocator
{
   char** _freeblocks[100];
};
When you write
shared_ptrint s( a.create(), a );
's' will create an internal copy of 'a'.

The internal copy will have a copy of _freeblocks[100];

Now we create a new object, that changes the state of _freeblocks[100]
int* n = a.create();
Next, 's' goes out scope and deallocates its object using
its own copy of _freeblocks[100] but this copy is already bad.
It doesn't represent the current configuration of free blocks
in the heap.
Does it make sense?
Not to me.  Sounds like a very broken allocator design.

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: what happened to allocators in boost?

2003-08-29 Thread Gregory Colvin
On Friday, Aug 29, 2003, at 12:33 America/Denver, E. Gladyshev wrote:
--- Gregory Colvin [EMAIL PROTECTED] wrote:

[...]
It's still not obvious to me. But I suspect I have yet to understand
your example.
Perhaps Peter can help me here. In his sample solution before, in this 
thread,
he addresses this problem nicely by using static functions
that take references to allocator instances. In his solution,
shared_ptr doesn't create an internal Allocator copy.
The C++ standard requires that a copy of an allocator is equivalent
to the original.
Instead he binds a static function pointer to an Allocator instance
and uses the pointer as Deleter.
My sample stateful allocator will work just fine in Peter's code.
Right.  If your allocators can't be copied safely then you have a
problem.  Peter's approach is one way to fix the problem.  But I
don't see that shared_ptr has a problem.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: what happened to allocators in boost?

2003-08-29 Thread Gregory Colvin
On Friday, Aug 29, 2003, at 13:34 America/Denver, E. Gladyshev wrote:
...
All I am trying to say is that shared_ptr doesn't specify
any requirements on its Deleter parameter.
Bullshit:

  templateclass Y, class D shared_ptr(Y * p, D d);

  Requirements: p must be convertible to T *.  D must be
  CopyConstructible. The copy constructor and destructor of D
  must not throw.  The expression d(p) must be well-formed, must
  not invoke undefined behavior, and must not throw exceptions.
  Effects: Constructs a shared_ptr that owns the pointer p and
  the deleter d.
  Postconditions: use_count() == 1  get() == p .

  Throws: std::bad_alloc or an implementation-defined exception
  when a resource other than memory could not be obtained.
  Exception safety: If an exception is thrown, d(p) is called.

  Notes: When the time comes to delete the object pointed to by p,
  the stored copy of d is invoked with the stored copy of p as an
  argument.
http://www.boost.org/libs/smart_ptr/shared_ptr.htm#constructors

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: what happened to allocators in boost?

2003-08-29 Thread Gregory Colvin
On Friday, Aug 29, 2003, at 13:57 America/Denver, Gregory Colvin wrote:
On Friday, Aug 29, 2003, at 13:34 America/Denver, E. Gladyshev wrote:
...
All I am trying to say is that shared_ptr doesn't specify
any requirements on its Deleter parameter.
Bullshit:
Please excuse my rude language.

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: what happened to allocators in boost?

2003-08-29 Thread Gregory Colvin
On Friday, Aug 29, 2003, at 15:14 America/Denver, E. Gladyshev wrote:
...
People are adopted to follow similar
requirements for STL allocators anyway.
I guess they can be recommended to all boost
authors who wants to make memory management
data types.
Perhaps they can be added to the Guidlines section
http://www.boost.org/more/lib_guide.htm#Guidelines
At the least, we could add the following bullet

  * Discussion of memory management strategy.

to http://www.boost.org/more/lib_guide.htm#Documentation

I'm reluctant to say very much more at this point, as my opinions
may not be suited to the needs of the many different libraries in
Boost.  But I think it's generally reasonable to:
* not allocate memory unless it's really necessary
* use the standard mechanisms (::operator new or std::allocator)
  when it is necessary
* use custom allocation mechanisms only when there is a clear
  advantage to doing so
* parameterize only when there is a clear advantage to doing so
* use the standard parameterization mechanisms (Allocator) when
  choosing to parameterize
* use custom parameterization mechanisms only when there is a
  clear advantage to doing so
* document whether and how a library allocates memory
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: what happened to allocators in boost?

2003-08-28 Thread Gregory Colvin
On Thursday, Aug 28, 2003, at 10:46 America/Denver, E. Gladyshev wrote:
--- Peter Dimov [EMAIL PROTECTED] wrote:
You can use all smart pointers except shared_ptr and shared_array as 
they do
not allocate any memory. In particular, intrusive_ptr is a good 
candidate if
memory is a concern as it has smaller memory footprint than 
shared_ptr.
Thanks, I'll consider it next time.
However if Boost doesn't have a clear memory management
concept, how can I guarantee that the next time around,
intrusive_ptr or something else in boost
won't start allocating memory under the covers.
It is perfectly legal in Boost.
Of course future releases of Boost are free to change in completely
arbitrary ways that break anything we want.  The same is true of
the C++ standard, operating system APIs, CPUs, and everything else.
So there are no guarantees that you can release a library today
and have it keep working with all future releases of Boost, C++,
etc.
Nonetheless, backwards compatibility matters, and Boost is no more
likely to change in ways that break your code than anything else.
And to the extent you remain active in Boost, you can help see to
it that such changes don't happen.
How will I even know it, the documentation is completely
ignorant on the memory issues.
Perhaps because you work with the authors of the documentation to
make it sure it says what needs saying?
You can also use Boost.Regex, it is completely allocator-enabled. ;-)
I never said that I am a huge allocators fan but at least
it seems that regex has one of the most consistent memory
management concepts in the library. :)
And I have no objection myself to adding an allocator parameter
to the shared_ptr constructor, or to making some other change that
serves the purpose.  So if you need a change, why not just do it,
try it out, and submit a patch?
I also have no objection, and much sympathy, for having a clear
memory management policy for Boost libraries.  But again, it is a
matter of people who care about and understand the issue doing the
necessary work, just like everything else here at Boost.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Re: Re: what happened to allocators in boost?

2003-08-26 Thread Gregory Colvin
On Tuesday, Aug 26, 2003, at 10:41 America/Denver, E. Gladyshev wrote:
--- Gregory Colvin [EMAIL PROTECTED] wrote:
For shared_ptr the count is allocated by the following line in the
shared_count
constructor:
new sp_counted_base_implP, D(p, d);

So it might be possible to make the allocation customizable by
specializing
sp_counted_base_impl.
I think it would be great.
Then I suggest giving it a try.

However there is another problem.
You have to new your object.
shared_ptrMyClass s( new MyClass );
You cannot use allocator like you would expect:
shared_ptr MyClass, std::allocatorMyClass  s;
Right.  The shared_ptr design carefully avoids any extra class
template parameters, in favor of parameterizing the constructor.
My idea, if it works, would be to specialize sp_counted_base_impl
on the pointer type P, e.g. MyClass*, so you just write
   shared_ptrMyClass s( new MyClass );

or on the deleter type D, so you would write, e.g.

   shared_ptrMyClass s( new MyClass, MyDeleterMyAllocatorMyClass 
);

The idea is that your sp_counted_base_impl specialization provides
a custom operator new and operator delete that uses your allocator.
Alternatively, we could consider adding shared_ptr constructor that
takes an allocator argument.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: converting Boost to other programming languages

2003-08-25 Thread Gregory Colvin
On Monday, Aug 25, 2003, at 11:46 America/Denver, David Abrahams wrote:

Daniel Frey [EMAIL PROTECTED] writes:

Mohamed Iqbal wrote:
For now I will cnvert three or four libraries for academia purposes 
but a
bigger number of libraries will be ported to my new language when the
commercial release is ready.
I think it would be best if you convert the three or four libraries
you have in mind, prepare it the way you like to redistribute/sell it
and show the result to us *before* redistribution. It's easier to say:
This is OK or This is not OK when we have something to look at
instead of giving you a Carte Blanche.
I'm afraid the license already gives him Carte Blanche.
Why be afraid?  The license is intended to give Carte Blanche.

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] GUI/GDI template library

2003-08-14 Thread Gregory Colvin
On Wednesday, Aug 6, 2003, at 17:36 America/Denver, Brock Peabody wrote:
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED]
On Behalf Of Gregory Colvin
Sent: Wednesday, August 06, 2003 4:48 PM
To: Boost mailing list
Subject: Re: [boost] GUI/GDI template library
Why the S?

On Wednesday, Aug 6, 2003, at 16:37 America/Denver, E. Gladyshev
wrote:

--- Brock Peabody [EMAIL PROTECTED]
wrote:
That sounds good.  What if we called the lower layer
boost::gui and the
upper layer boost::sgtl?
It stands for 'standard'.  Maybe that's a little pretentious for us at
this early stage :)
Yes, far too pretentious.  IMHO.

 gtl would probably be better.  I suspect that if we
get to a review some people may request something more verbose.
Brock

___
Unsubscribe  other changes: 
http://lists.boost.org/mailman/listinfo.cgi/boost
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] GUI/GDI template library

2003-08-09 Thread Gregory Colvin
Perhaps Perseus, who slew the Medusa, the snake-haired monster of
so frightful an aspect that no living thing could behold her without
being turned into stone.
Perseus avoid being turned to stone by clever use of indirection --
he avoided looking directly at Medusa, instead looking only at her
reflection in the mirror of his polished shield.
http://www.online-mythology.com/perseus_medusa/

On Thursday, Aug 7, 2003, at 11:52 America/Denver, Brock Peabody wrote:

On Behalf Of E. Gladyshev
[...]

Don't know where to start...
Greek and Roman mythology?
'Aquilo' the north wind, the ruler of the winds.
'Notus' the south wind
'Flora' goddess of flowers and spring.
'Arcadia' a district of the Peloponnesus, the home of
pastoral simplicity.
Hmm of those I like Notus.

Other ideas:

Atlas
Hydra
Muse
...

Eugene, you brought this whole thread up so I think you should pick the
name :)
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: GUI/GDI template library

2003-07-29 Thread Gregory Colvin
On Tuesday, Jul 29, 2003, at 12:25 America/Denver, Brock Peabody wrote:
...
I don't think custom resource files would be any easier to edit that
inline C++ code.  I think they would be much less easy to edit and 
read.
It's been a few years, but the last time I was writing a GUI application
for an international market the shops in Japan, Korea, and Ireland that
we paid to localize the application required platform-native resource
files as their starting point.  Neither custom resources nor C++ code
would have been acceptable.  And before that, when I was at XVT, we put
a lot of work into supporting native resource files in our portable GUI
toolkit.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Re: GUI/GDI template library

2003-07-29 Thread Gregory Colvin
On Tuesday, Jul 29, 2003, at 16:24 America/Denver, Bohdan wrote:
Brock Peabody [EMAIL PROTECTED] wrote in message
news:[EMAIL PROTECTED]
On Tuesday, Jul 29, 2003, at 12:25 America/Denver, Brock Peabody 
wrote:
...
I don't think custom resource files would be any easier to edit that
inline C++ code.  I think they would be much less easy to edit and
read.
It's been a few years, but the last time I was writing a GUI 
application
for an international market the shops in Japan, Korea, and Ireland 
that
we paid to localize the application required platform-native resource
files as their starting point.  Neither custom resources nor C++ code
would have been acceptable.  And before that, when I was at XVT, we 
put
a lot of work into supporting native resource files in our portable 
GUI
toolkit.

It might not be too hard to make the GUI objects 'serialize' 
themselves
into a native resource file but this would be useless without 
something
to convert a resource file back into C++ code.  Something like this
could be written on top of a pure C++ solution with the help of a
serialization library.
Sure, but this can be kind of simple c++ or even c code.
Alternatively very important is possibility to load resources in 
runtime,
possibly this can help to solve localization issues.
For this kind of localization loading the localized resources at runtime
is essential.  Regenerating C++ code and rebuilding the application is
not an option.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Re: GUI/GDI template library

2003-07-29 Thread Gregory Colvin
On Tuesday, Jul 29, 2003, at 16:02 America/Denver, Brock Peabody wrote:

On Behalf Of Gregory Colvin
[...]

For this kind of localization loading the localized resources at
runtime
is essential.  Regenerating C++ code and rebuilding the application is
not an option.
Why would it be necessary to reload anything besides the localized 
text?
That wouldn't be too hard:

gui_applicationemployee app = row(localized_text(name_text_id),
edit(employee::name));
Are you going to change the behavior of the application from one 
country
to another?
Yes, you might.  But I think text and graphics are most often changed, 
and
in the case I am describing this must be done with native resources.

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Proposed smart_handle library

2003-07-22 Thread Gregory Colvin
On Tuesday, Jul 22, 2003, at 05:56 America/Denver, David Abrahams wrote:

Gregory Colvin [EMAIL PROTECTED] writes:

I'm generally less afraid of automatic conversions than many others,
and dropped them from auto_ptr, and later from shared_ptr, only under
duress.  I like them for wrapper classes because they make it possible
to drop the wrappers directly into existing code that uses the wrapped
types.  I like the terseness too, but then I am perverse enough to
prefer *p to p.get().
Some conversions are worse than others.  For example, an implicit
conversion from a raw pointer to an owning handle/smart-pointer is
far more dangerous than the opposite conversion.
Agreed.  It is the latter conversions I like.

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Proposed smart_handle library

2003-07-21 Thread Gregory Colvin
I'm generally less afraid of automatic conversions than many others, and
dropped them from auto_ptr, and later from shared_ptr, only under 
duress.
I like them for wrapper classes because they make it possible to drop 
the
wrappers directly into existing code that uses the wrapped types.  I 
like
the terseness too, but then I am perverse enough to prefer *p to 
p.get().

On Monday, Jul 21, 2003, at 22:27 America/Denver, John Madsen wrote:

Eugene Lazutkin [EMAIL PROTECTED] wrote:
Inline.

John Madsen [EMAIL PROTECTED] wrote in message
news:[EMAIL PROTECTED]
If you can convince most of the people on this list to provide an
automatic
conversion, more power to you.  I still maintain that avoiding hard 
to
diagnose
errors is worth much more than saving 6 characters of typing.
I am not trying to convince anybody in overall goodness of automatic
conversion. :-) I am asking question, which is still ignored: what 
hard to
diagnose errors do you envision for smart handles??? Reference to 
some
dogma would suffice too. ;-)

For a discussion of why user defined conversions are a bad idea (not
always,
but most of the time), see More Effective C++, Item 5.
I've read it when it was printed. I know author's reasons. And I 
agree with
most of them. The question is: how do they apply in _this particular 
case_?



I am not ignoring the question.  The point is that it is hard to guess 
what
errors might occur.  I did reference some dogma as well.  I take 
Meyers' point
to be that automatic conversions can sometimes produce surprising 
effects.
Those effects may result in code that does something other than what 
it appears
to do.  Thus, *unless there is a very good reason*, avoid automatic
conversions.  That is what I did.  Your reason for including them, 
i.e.,
avoiding typing, does not strike me as a good one.

John

P.S.  Of course, if you want Scott Meyers on your side in this one, 
just look
at Item 9 in the same book, where he does exactly what you're 
suggesting :-).
Against his own better judgment IMHO.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Re: Proposed smart_handle library

2003-07-19 Thread Gregory Colvin
On Saturday, Jul 19, 2003, at 17:16 America/Denver, Ross Smith wrote:
...
(Of course all of these could easily be unified into a single
policy-based type; unfortunately the Powers That Be seem to have
decided that policies are too complicated for us mere mortals to be
trusted with.)
There are no Powers That Be.  Boost has no policy-based smart
pointers because nobody has done the difficult job of proposing
them.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Re: Proposed smart_handle library

2003-07-19 Thread Gregory Colvin
On Saturday, Jul 19, 2003, at 20:52 America/Denver, Ross Smith wrote:

On Sunday 20 July 2003 11:46, Gregory Colvin wrote:
On Saturday, Jul 19, 2003, at 17:16 America/Denver, Ross Smith wrote:
...
(Of course all of these could easily be unified into a single
policy-based type; unfortunately the Powers That Be seem to have
decided that policies are too complicated for us mere mortals to be
trusted with.)
There are no Powers That Be.  Boost has no policy-based smart
pointers because nobody has done the difficult job of proposing
them.
Now that is simply a barefaced lie. I proposed one myself, which got
roundly ignored, and there have been several others.
Excuse me.  By propose I meant a formal proposal, not just a posting.

There have been many postings and much discussion pro and con policy-
based smart pointers, but no formal proposal.  Only if such a proposal
were turned down would it be fair to say that Boost as such had made
any decision, let alone to speculate on the motivation for such a
decision.  My bet is that such a proposal would succeed, but would have
to be of very high quality to meet Boost's critical standards and do
justice to the inherent difficulty of the problem space.
I hope that someday soon someone will volunteer such a proposal, but
in the meantime, I think John's handles are a very good idea.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Proposed smart_handle library

2003-07-18 Thread Gregory Colvin
On Friday, Jul 18, 2003, at 15:21 America/Denver, John Madsen wrote:

Eugene Lazutkin [EMAIL PROTECTED] wrote:
I have a few comments in no particular order.

1) I cannot imaging someone programming in C++ and using FILE*s,and 
file
descriptors instead of iostream  Co. You've must be talking about
incomplete systems like embedded systems, which don't have complete 
standard
C++ library. Are there any real life examples for that? How frequent 
are
they?

That's quite right.  I don't see much use in having a wrapper for 
FILE*.
IMHO stdio is a useful standard, and for some purposes is better than 
iostreams.

Of course, boost::shared_ptr can already wrap FILE* pretty easily.

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] why no strict ownership smart pointer in boost

2003-07-01 Thread Gregory Colvin
On Tuesday, Jul 1, 2003, at 14:38 America/Denver, Boost wrote:

I did a search in the archives and found nothing on this:

Why is there no strict-ownership smart-pointer in boost?  Just curious 
to
know what the reasons are. Thanks,
What do want beyond what boost::scoped_ptr and std::auto_ptr provide?

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] why no strict ownership smart pointer in boost

2003-07-01 Thread Gregory Colvin
On Tuesday, Jul 1, 2003, at 17:36 America/Denver, Schoenborn, Oliver 
wrote:
On Tuesday, Jul 1, 2003, at 14:38 America/Denver, Boost wrote:

I did a search in the archives and found nothing on this:

Why is there no strict-ownership smart-pointer in boost?
Just curious
to
know what the reasons are. Thanks,
What do want beyond what boost::scoped_ptr and std::auto_ptr provide?
Ability to be used in STL containers, and explicit transfer of 
ownership
capabilities (e.g. *no* move-on-copy etc).
So what would the copy semantics be?

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Draft of new Boost Software License

2003-06-27 Thread Gregory Colvin
On Thursday, Jun 26, 2003, at 07:53 America/Denver, William E. Kempf 
wrote:
...
But it would be nice to just refer to the license instead of repeating 
it
in every single file.
Though this license is brief enough that inclusion is no big deal.

It seems that doing it by reference to a web page amounts to Boost 
reserving
the right to change terms in the future, possibly to the disadvantage 
of the
authors and users.  But I see lots of code that refers to the GPL that 
way,
so this is another question for the lawyers.

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Re: an XML API in boost

2003-06-04 Thread Gregory Colvin
It's worth noting that libxml2 is itself open source with what appears 
to be
Boost compatible license:

  http://www.opensource.org/licenses/mit-license.html

On Tuesday, Jun 3, 2003, at 20:21 America/Denver, Darryl Green wrote:

From: William E. Kempf [mailto:[EMAIL PROTECTED]
Vladimir Prus said:
William E. Kempf wrote:
If a submitted library required libxml2, I'd personally
vote no.  If
the interface was supposed to be portable to other backends, I'd
probably still vote no unless at least one other backend
was included
as proof of concept.  It would still be nice to have a
Boost supplied
backend, probably via Spirit, but so long as I was confident that I
was not tied to any specific non-Boost library, it wouldn't matter
that much.
I tend to disagree here. Writing XML library is not easy,
and libraries
like expat and libxml2 are already here, working and debugged.
...
Careful with what you disagree with.  I stated that it would
still be nice
to have a Boost supplied backend, but I didn't state this was a
requirement.  What I think *is* a requirement is that any
wrapper library
not be tied to a single backend, and I personally believe that what
follows from that is that the submission must have at least 2
referenced
backends for proof of concept.  Note that this is precisely what
Boost.Threads does, for instance.
I agree that the interface shouldn't be too tightly bound to the
underlying library. imho the interface Stefan has written isn't tightly
coupled to libxml2 in the sense that the interface would need to change
or be a poor fit on some other library. However, the implementation 
(and
efficiency) of the wrapper is certainly aided by the libxml2 library
interface needing only a very thin c++ veneer, and libxml2 being very
comprehensive in its facilities. As a user, I had already decided to 
use
libxml2 and wrap it when Stefan posted. The decision was based on code
size, performance and features of the xml lib. I had already looked at
using Spirit, and found the example xml parser too slow in comparison 
to
other parsers, in particular expat and libxml2. To provide the same
facilities as libxml2 requires considerably more than just a parser -
performance issues aside. I can't think of a good reason for wanting to
apply stephen's interface to another underlying xml lib, until or 
unless
there is a better performing xml lib than libxml2.

I would suggest that the portability (or otherwise) of Stefan's library
could be assessed/reviewed without necessarily requiring another
implementation for which there would likely be no users. This is a bit
different to threads,  (warning: Alexander bait) where there is clearly
a requirement to use the native platform library facilites, and these
facilities differ significantly. There isn't really that much variation
in how one presents xml using a dom, sax and xpath based interface - it
just needs a c++ language binding.
Regards
Darryl Green.
___
Unsubscribe  other changes: 
http://lists.boost.org/mailman/listinfo.cgi/boost
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] shared_cyclic_ptr question

2003-06-04 Thread Gregory Colvin
On Wednesday, Jun 4, 2003, at 08:22 America/Denver, Philippe A. 
Bouchard wrote:

Greetings Boost,

I am not that much familiar with garbage collection techniques so 
please
excuse me if the technique I am thinking of is already used somewhere.

Let's say:
- you can easily detect weither an object was allocated on the stack 
or on
the heap;
- a smart pointer contained within an object can somehow access it's 
object
header when the object was allocated on the heap with a placement 
operator
new();
Neither of which can be done portably.

Given:
Node = element of a possible cyclic graph allocated on the heap.
Entity = possible cyclic graph in its entirety allocated on the heap.
struct entity_header
{
int count;
};
struct node_header
{
int count;
entity_header * p_entity;
};
// Erroneous but simple allocation example:
inline void * operator new (size_t s, gc const )
{
return malloc(s + sizeof(node_header)) + sizeof(node_header);
}
template typename T
struct smart_pointer
{
template typename U
smart_pointer(U * p) : m_p(p)
{
if (is_on_the_stack(this))
{
// Allocate an entity_header and affect its 
address to
m_p's header-p_entity. *
// Initialize m_p's header-p_entity-count to 1.
}
// 'this' is part of a node with a header on the heap.
else
{
// Copy the this's header-p_entity to m_p's
header-p_entity. **
}
...
}

template typename U
smart_pointer(smart_pointerU const  p) : m_p(p.m_p)
{
// Possible merge / fragmentation of two entities. ***
...
// Possible incrementation / decrementation of this's
header-p_entity-count and m_p's header-p_entity-count. 
}
~smart_pointer()
{
if (m_p  m_p's header-p_entity-count == 1)
{
// Force an entity's destruction. *
}
}
...

private:
T * m_p;
};
Then:
An entity_header will be allocated each time a pointer on the stack 
refers
to a new node on the heap (*) and every other node derived from this 
root
node will refer to the same entity_header with node_header::p_entity.  
If a
new pointer on the stack refers to the entity, its 
entity_header::count will
be incremented.  If the last pointer on the stack refers to the entity 
then
the entire entity will be destructed (no more possible cyclic graph).

Ex.:
template typename T struct rope; // cyclic entity
smart_pointer ropeint  p = new (gc) ropeint(10);//
entity_header::count == 1
smart_pointer ropeint  q = p;// entity_header::count == 2
p.~smart_pointer ropeint ();// entity_header::count == 1
q.~smart_pointer ropeint ();// entity_header::count == 0,
destruction
Thus:
The purpose of the entity_header is to know the number of times the 
entity
is refered by a pointer on the stack.

Do this algorithm already has a name?  If so, why aren't you using it 
since
there is no need to scan the graph looking up for dangling entities.  
It may
take a little bit more memory (1 more pointer per node + 1 
entity_header per
heap graph) but I think the cost / benefits here are quite acceptable 
since
the speed will always be O(1).



Regards,

Philippe



___
Unsubscribe  other changes: 
http://lists.boost.org/mailman/listinfo.cgi/boost
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Cyclic smart pointers (holy grail: the uber-pointer)

2003-05-31 Thread Gregory Colvin
On Friday, May 30, 2003, at 09:56 America/Denver, Chuck Messenger wrote:
...
What I'm trying to develop (or even better, find) is a workable C++ 
library which supports cyclic structures, handling garbage collection 
for you, without resorting to a systemic (and non-portable) approach 
like the Boehm collector.  I want to build regular-old, C++ standard 
libraries upon this cyclic library -- I don't want to require users of 
my libraries to use my garbage collection system.  It needs to be 
perfectly invisible to the user (and ideally, as invisible as possible 
to the library writer).
There are a few attempts laying around various places in Boost, but
I've lost track of where they all are, how they all work, and what
their relative advantages and disadvantages are.  If someone could
pull this information together it might help to get this discussion
out of the cycle it seems caught in ;-
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Cyclic smart pointers (holy grail: the uber-pointer)

2003-05-31 Thread Gregory Colvin
On Friday, May 30, 2003, at 10:18 America/Denver, Larry Evans wrote:
Gregory Colvin wrote:
On Friday, May 30, 2003, at 09:56 America/Denver, Chuck Messenger 
wrote:
...
What I'm trying to develop (or even better, find) is a workable C++
[snip]
their relative advantages and disadvantages are.  If someone could
pull this information together it might help to get this discussion
out of the cycle it seems caught in ;-
http://groups.yahoo.com/group/boost/files/shared_cyclic_ptr/
draft-compare.zip might be a good starting point.  It
doesn't include the latest additions and still needs work :(.
Wow.

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Cyclic pointers - a comparison of known Boost efforts

2003-05-31 Thread Gregory Colvin
Thanks, but your description of cyclic_ptr is pretty far off the mark.
It does not maintain a global map, and copying cyclic_ptr cost the same
as copying shared_ptr.  The special assignment mode is used only during
the mark phase of a collection, and costs more or less the same as any
other discovery method.
On Friday, May 30, 2003, at 11:56 America/Denver, Chuck Messenger wrote:

Gregory Colvin wrote:
On Friday, May 30, 2003, at 09:56 America/Denver, Chuck Messenger 
wrote:
...
What I'm trying to develop (or even better, find) is a workable C++ 
library which supports cyclic structures, handling garbage 
collection for you, without resorting to a systemic (and 
non-portable) approach like the Boehm collector.  I want to build 
regular-old, C++ standard libraries upon this cyclic library -- I 
don't want to require users of my libraries to use my garbage 
collection system.  It needs to be perfectly invisible to the user 
(and ideally, as invisible as possible to the library writer).
There are a few attempts laying around various places in Boost, but
I've lost track of where they all are, how they all work, and what
their relative advantages and disadvantages are.  If someone could
pull this information together it might help to get this discussion
out of the cycle it seems caught in ;-
Let's do it!  I've been working (slowly!) toward just that.

Very briefly, here's what I've found so far -- please tear it apart at 
will:

1.  Systemic approaches like the Boehm collector (no Boost libs).  
These
aren't, and can't be, anything close to Standard C++, so they're 
out
of the realm of what I think we on Boost are interested in (for
inclusion in a Boost library, that is -- we're still interested in
them...)

2.  sp_collector - by Peter Dimov.  In Boost distro -- see
boost/libs/smart_ptr/src/sp_collector.cpp.  This is an experimental
extension to shared_ptr.  It makes the assumption that all
shared_ptr's are contained within objects owned by other
shared_ptr's.  It uses the Boehm-like trick of scanning raw 
memory
to find the shared_ptr's (I believe this is called conservative
collection), so it isn't 100.000% foolproof (but is close).  More
importantly, it doesn't work with the STL containers, which makes 
it
nothing more than an experimental toy (but an interesting one).

3.  cyclic_ptr - by Greg Colvin (i.e. yours).  See

http://groups.yahoo.com/group/boost/files/smart_pointers/cyclic_ptr.
I haven't studied it yet, but based on what I've read in recent
threads, I believe it works by tracking the locations of all
cyclic_ptr objects, in a global map. This means it *is* 100.000%
foolproof (unlike sp_collector).  However, it also means there is a
severe overhead to copying cyclic_ptr's.  In order to discover
the object dependency graph of an object, it makes a copy of it.
During the copy operation, cyclic_ptr's are put in a special mode,
so that during their operator=(), they tally the dependency graph.
One problem with this is that each object must then be copyable.
This can be messy if you're making extensive use of non-copyable
objects, such as in the Boost Threads library.  Also, it can lead
to unbounded inefficiency in the case of objects with lots of
non-cyclic-ptr material, which is intended to be copyable (for
example, imagine an image class).

4.  shared_cyclic_ptr - by Larry Evans.  See
http://groups.yahoo.com/group/boost/files/shared_cyclic_ptr.
This one seems to be under active development right (new
version uploaded a day or two ago).  Again, I haven't studied
this one yet.  About the discovery problem, Larry writes:
[it] works around this by using a smart ptr enumerator
function specialized for each type of container.  As I
understand this, it means that shared_cyclic_ptr objects
must either be within objects owned by another shared_cyclic_ptr
(as with sp_collector), or they can be in tagged STL
containers, e.g.:
template typename T struct SpecialList : public listT,
   public SpecialTag { };
That would be a best case.  Or, it might be necessary to do
something much messier, like this:
template typename T struct SpecialList {
// Implement wrapper for each std::list function...
private:
listT list_;
};
Perhaps Larry can comment.

5.  juju_ptr -- my own effort, under development.  Perhaps if I
finish it, I'll upload it for public examination.  If you're
even luckier, I may change the name.  I'm using a unique (I
think) discovery method -- some wicked juju (but, I believe,
adhering to Standard C++, and portable) -- which avoids
cyclic_ptr's need to copy instances.  For the STL containers,
it uses a public inheritance tagging method:
template typename T struct j_list : public listT,
   public

Re: [boost] Re: Cyclic smart pointers (holy grail: the uber-pointer)

2003-05-31 Thread Gregory Colvin
On Friday, May 30, 2003, at 11:58 America/Denver, Larry Evans wrote:

Gregory Colvin wrote:
 On Friday, May 30, 2003, at 10:18 America/Denver, Larry Evans wrote:

[snip]

 http://groups.yahoo.com/group/boost/files/shared_cyclic_ptr/
 draft-compare.zip might be a good starting point.  It
 doesn't include the latest additions and still needs work :(.


 Wow.
Thanks (I guess).

Since understanding some of the code was difficult,
I think you understood cyclic_ptr better than I do now, and maybe
better than I did then ;-
it would sure help
if the authors of each of the codes would analyze their own code to
check against what's already in draft-compare, or add to
draft-compare, as appropriate.  Also, it would most likely avoid the
jumping to conclusions which I was guilty of when evaluating
sp_collector earlier in a (this?) thread.
___
Unsubscribe  other changes: 
http://lists.boost.org/mailman/listinfo.cgi/boost
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Cyclic pointers - a comparison of known Boost efforts

2003-05-31 Thread Gregory Colvin
On Friday, May 30, 2003, at 12:38 America/Denver, Chuck Messenger wrote:

Gregory Colvin wrote:
Thanks, but your description of cyclic_ptr is pretty far off the mark.
Sorry -- hopefully you'll forgive my ignorance. I'm just throwing out 
what I understand to be the case, in the hopes that someone (such as 
yourself) would set me straight...

It does not maintain a global map, and copying cyclic_ptr cost the 
same
as copying shared_ptr.
OK, I'll have to review the old messages again.  I thought someone had 
said cyclic_ptr used a global map.  Sorry.  I suppose better yet would 
be for me to study your actual *code*...
Larry's analysis gives a better explanation than I could.

Do you do a raw scan of memory, like sp_collector, then?  (i.e. not 
perfect discovery)
No.  The self-assignment trick is precise, unless it is foiled by a
user-written operator=.
The special assignment mode is used only during
the mark phase of a collection, and costs more or less the same as any
other discovery method.
Suppose I have the structure:

struct Image {
char huge_image[ONE_ZILLION];
cyclic_ptrwhatever ptr;
};
As I understand it, in order to discover 'ptr', you'd invoke 
operator=() on each Image structure you came to.  Correct, or 
incorrect?
Correct.  So it would be smart to write an operator= for Image that
avoids copying huge_image to itself.  And it would best if the
uber-pointer used a less intrusive discovery method.  I think
sp_collector is on the right track, if it could be made precise.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] smart_ptr: sp_collector can't handle STL containers ofshared_ptr's

2003-05-30 Thread Gregory Colvin
On Thursday, May 29, 2003, at 08:45 America/Denver, Chuck Messenger 
wrote:
...
And so, sp_collector suffers the same problem as shared_cyclic_ptr, 
and requires the same remedy: that is, it is necessary to be able to 
tag a container as being one which might hold internal 
shared_ptr's.

Any interest in modifying shared_ptr to support something like this?
Yes, but I haven't had time since my cyclic_ptr work.

It seems that rather than take the route of modifying all the
standard containers one might as well just provide a special
operator new(gc) and gc_allocator that can track all the memory
blocks on the heap that might contain a shared_ptr.  Then one
can either replace global operator new with the special one,
or use new(gc) or gc_allocator wherever needed.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] smart_ptr: sp_collector can't handle STL containers ofshared_ptr's

2003-05-30 Thread Gregory Colvin
On Thursday, May 29, 2003, at 09:57 America/Denver, Larry Evans wrote:

Gregory Colvin wrote:
[snip]
It seems that rather than take the route of modifying all the
standard containers one might as well just provide a special
operator new(gc) and gc_allocator that can track all the memory
blocks on the heap that might contain a shared_ptr.  Then one
can either replace global operator new with the special one,
or use new(gc) or gc_allocator wherever needed.
I'm assuming that the advantage of the suggested method
over Boehm's collector would be the precision?  I.e. no
false pointers are possible?
Yes, that would be one (small) advantage.  It would also be
easier to provide a portable version.  The disadvantage is
the need to use smart pointers at all.
It is not that hard to write a new(gc) and gc_allocator
using Boehm's collector, for those who don't want to have
the collector take over all memory allocation.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] smart_ptr: sp_collector can't handle STL containers ofshared_ptr's

2003-05-30 Thread Gregory Colvin
Check out

   http://www.hpl.hp.com/personal/Hans_Boehm/gc/gcinterface.html

which provides a gc_alloc, and for new(gc) all you need is something 
like this:

   struct gc_t {};
   static const gc_t gc;
   void* operator new  (size_t n, const gc_t) { return GC_malloc(n); }
   void* operator new[](size_t n, const gc_t) { return GC_malloc(n); }
   void operator delete  (void* ptr, const gc_t) {}
   void operator delete[](void* ptr, const gc_t) {}
Much easier than hacking shared_ptr.

On Thursday, May 29, 2003, at 19:57 America/Denver, Larry Evans wrote:
Gregory Colvin wrote:

[snip]

 It is not that hard to write a new(gc) and gc_allocator
 using Boehm's collector, for those who don't want to have
 the collector take over all memory allocation.
I found John Max Skaller's posts on such a gc_allocator:

  http://aspn.activestate.com/ASPN/Mail/Message/boost/1150154

Since I still can't figure out how he did it, maybe he could provide
code or more details on howto.  However, I don't know his email.  I
may just download his Felix compiler and try deciphering the code.
___
Unsubscribe  other changes: 
http://lists.boost.org/mailman/listinfo.cgi/boost
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] smart_ptr: sp_collector can't handle STL containers ofshared_ptr's

2003-05-30 Thread Gregory Colvin
Also check out

   http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc_cpph.txt

for a gc base clase to inherit from.

On Thursday, May 29, 2003, at 20:20 America/Denver, Gregory Colvin 
wrote:

Check out

   http://www.hpl.hp.com/personal/Hans_Boehm/gc/gcinterface.html

which provides a gc_alloc, and for new(gc) all you need is something 
like this:

   struct gc_t {};
   static const gc_t gc;
   void* operator new  (size_t n, const gc_t) { return GC_malloc(n); }
   void* operator new[](size_t n, const gc_t) { return GC_malloc(n); }
   void operator delete  (void* ptr, const gc_t) {}
   void operator delete[](void* ptr, const gc_t) {}
Much easier than hacking shared_ptr.

On Thursday, May 29, 2003, at 19:57 America/Denver, Larry Evans wrote:
Gregory Colvin wrote:

[snip]

 It is not that hard to write a new(gc) and gc_allocator
 using Boehm's collector, for those who don't want to have
 the collector take over all memory allocation.
I found John Max Skaller's posts on such a gc_allocator:

  http://aspn.activestate.com/ASPN/Mail/Message/boost/1150154

Since I still can't figure out how he did it, maybe he could provide
code or more details on howto.  However, I don't know his email.  I
may just download his Felix compiler and try deciphering the code.
___
Unsubscribe  other changes: 
http://lists.boost.org/mailman/listinfo.cgi/boost
___
Unsubscribe  other changes: 
http://lists.boost.org/mailman/listinfo.cgi/boost
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] smart_ptr: sp_collector can't handle STL containers ofshared_ptr's

2003-05-30 Thread Gregory Colvin
On Thursday, May 29, 2003, at 20:52 America/Denver, Larry Evans wrote:

Gregory Colvin wrote:
Check out
   http://www.hpl.hp.com/personal/Hans_Boehm/gc/gcinterface.html
[snip]
On Thursday, May 29, 2003, at 19:57 America/Denver, Larry Evans wrote:
Gregory Colvin wrote:

[snip]

 It is not that hard to write a new(gc) and gc_allocator
 using Boehm's collector, for those who don't want to have
 the collector take over all memory allocation.
I found John Max Skaller's posts on such a gc_allocator:

  http://aspn.activestate.com/ASPN/Mail/Message/boost/1150154

Since I still can't figure out how he did it, maybe he could provide
code or more details on howto.  However, I don't know his email.  I
may just download his Felix compiler and try deciphering the code.
Now, how do we do something similar with a precise gc like that 
proposed
earlier?
Do you really need a precise collector?  Boehm's collector works just 
fine.

If so, I don't think you can do it without compiler support.

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] smart_ptr: sp_collector can't handle STL containers ofshared_ptr's

2003-05-30 Thread Gregory Colvin
On Thursday, May 29, 2003, at 21:25 America/Denver, Larry Evans wrote:
Gregory Colvin wrote:
[snip]
Do you really need a precise collector?  Boehm's collector works just 
fine.
Most people don't, but some do.  In Jones and Lins _Garbage Collection_
there's mention of misidentification or false pointers in 
applications with large compress bitmaps.  Also, for highly connected
structures, I remember reading that there could be a problem.
So don't allocate bitmaps and such with GC_malloc.  Other than that
the problem seems to be mostly theoretical.
If so, I don't think you can do it without compiler support.
I was hoping stl_container.cpp would be as close as possible w/o
compiler support.
Not close enough for me.

  I think Detlef also mentioned this somewhere
in his article.  The closer it is, then the less testing would
need to be done to change the compiler.
Well, if standard allocators supported proxied pointers you could do
it with a collected allocator.  I think Dinkum's allocators do, not
sure about other standard libraries.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Cyclic smart pointers (holy grail: the uber-pointer)

2003-05-29 Thread Gregory Colvin
On Wednesday, May 28, 2003, at 13:04 America/Denver, Chuck Messenger 
wrote:

Larry Evans wrote:
Chuck Messenger wrote:
[snip]
collections, put them in object heirarchies, etc).  This freedom 
should ideally apply both internally (within library L code) and 
most importantly, externally (in the code of users of library L).  
Crucially,
Would you require the users to use a smart pointer instead of a raw?
If not, then you're only option, that I can tell, is use a 
conservative
collector like Boehm's.
No -- users don't use pointers -- only objects.  The objects each have 
one pimpl_ (which will be whatever smart type we - the 
uber-pointer framework designers - want), pointing to the underlying 
object.

Note:  This is essentially a plain-vanilla Java-style object system 
which I am describing.

 The consequence of mis-identification is
that you may fail to destroy some unused objects.  If this leads to 
nothing worse than some leaked memory, then it's not a real problem 
-- it will be a vanishingly small amount of memory.
This is the justification for Boehm's conservative collector.
 http://www.hpl.hp.com/personal/Hans_Boehm/gc/
Does the Boehm collector likewise do a full scan of the heap?  I 
assume so...
It marks all objects on the heap pointed to by the machine registers, 
and
all objects pointed to by those objects, and so on.  It is conservative 
in
the sense that it cannot generally tell whether a register or memory 
cell
contains a pointer or an integer.

One big problem with this approach is that you end up having to scan 
all of your memory.  This could (and for me, would) be an outrageous 
proposition, as only a tiny portion of memory relates to my object 
set.  Most of it will be raw data (e.g. images, etc).
Boehm's collector includes functions for allocating pointer-free memory.

This is what Christopher's (alias= global rc mark-scan) algorithm 
does.
It's also what mark-sweep algorithms do, i.e. they have to mark all 
reachable
objects, and then scan thru the whole heap sweeping the unmarked into 
the
garbage collector. However, since this global scan is done, usually,
infrequently, the time isn't that big a factor, at least compared 
with the
updating of reference counts during each pointer copy.
That's why Boehm's gc should work faster than refcounting.
It does.

___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Is a 3% timing difference reliably repeatable in realcode?

2003-05-08 Thread Gregory Colvin
My experience tuning our java VM is similar, and it runs on a lot of
different CPUs.  Still, there is reason to be suspicious of very small
changes, which might be repeatable for our benchmark set, yet have no
real meaning for normal use.  And there is reason to be careful not to
waste time pursuing 3% tweaks instead of going for 100% breakthroughs.
On Thursday, May 8, 2003, at 09:11 America/Denver, Darin Adler wrote:
On Thursday, May 8, 2003, at 07:04 AM, Beman Dawes wrote:

A 2-3% timing difference probably isn't reliably repeatable in real 
code.

How code and data happens to land in hardware caches can easily swamp 
out such a small difference. The version-to-version or step-to-step 
differences in CPU's, memory, compilers, or operating systems can 
cause that much difference in a given program. Differences need to 
get up into the 20-30% range before they are likely to be reliably 
repeatable across different systems.

At least that's been my experience.
That has not been my recent experience. While working on my current 
project (the Safari web browser), we have routinely made 1% speedups 
that are measurable and have an effect across multiple machines and 
compilers (same basic CPU type and operating system), and we have also 
detected 1% slowdowns when we inadvertently introduced them.

They add up. Ten 1% speedups result in a 9.5% speedup.

It's true that differences in CPUs, memory, compilers, and operating 
systems can cause huge differences, but that does not mean that 
changes that make such small increases in performance are therefore 
not worthwhile.

In our project, a 3% speed increase is considered a cause for 
celebration.

I'm not sure, though, if this negates your point, Beman. Something 
that gives a 2-3% speedup for one Boost user might not be worth any 
level of obfuscation unless we can prove it provides a similar speedup 
for other Boost uses.

-- Darin

PS: On the occasions where you can fix an algorithm in a way that 
gives a 10x speed increase, or a 25% one, that's even more exciting. 
To give you an idea of what I'm talking about, here's a log from a 
week I spent increasing the speed of our JavaScript library:

Monday, November 18, 2002
- sped up JavaScript iBench by 70% by using a better sort algorithm 
and reducing the number of UString allocations
- sped up JavaScript iBench by 6% by turning ExecState into a simple 
object instead of a two level abstraction
- sped up JavaScript iBench by 7% by turning the property map into a 
hash table and improving String instance handling
- sped up JavaScript iBench by 6% by hoisting the property map into 
ObjectImp and doing less ref/unref
- sped up JavaScript iBench by 1.5% by converting integers into 
strings with custom code rather than sprintf

Tuesday, November 19, 2002
- sped up JavaScript iBench by 2% by using masking instead of modulus 
in the property map hash table code
- sped up JavaScript iBench by 3% by improving the implementation of 
the perfect hashing hash tables used for static properties
- sped up JavaScript iBench by 1.5% by storing computed hash values in 
the UString representation so we don't recompute them
- sped up JavaScript iBench by 6.5% by atomizing property identifiers
- sped up JavaScript iBench by 1.5% by not clearing and rebuilding the 
list each time during sorting

Wednesday, November 20, 2002
- sped up JavaScript iBench by 5% by decreasing the amount of 
ref/deref done by changing interfaces so they can deal directly with 
ValueImp
- sped up JavaScript iBench by 1% by making lists ref/unref less
- sped up JavaScript iBench by 7.5% by creating argument list objects 
only on demand rather than for each function call

Thursday, November 21, 2002
- sped up JavaScript iBench by 3% by allocating the ActivationImp 
objects on the stack rather than in the garbage-collected heap
- sped up JavaScript iBench by 11% by turning the scope chain into a 
singly-linked list that shares tails rather than a non-sharing 
doubly-linked list with subtly different semantics

Friday, November 22, 2002
- sped up JavaScript iBench by 10% by changing the List class from a 
linked list to a vector, and using a pool of instances

___
Unsubscribe  other changes: 
http://lists.boost.org/mailman/listinfo.cgi/boost
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Is a 3% timing difference reliably repeatable in realcode?

2003-05-08 Thread Gregory Colvin
On Thursday, May 8, 2003, at 11:07 America/Denver, Beman Dawes wrote:
At 11:11 AM 5/8/2003, Darin Adler wrote:

On Thursday, May 8, 2003, at 07:04 AM, Beman Dawes wrote:

 A 2-3% timing difference probably isn't reliably repeatable in real
 code.

 How code and data happens to land in hardware caches can easily 
swamp
 out such a small difference. The version-to-version or step-to-step
 differences in CPU's, memory, compilers, or operating systems can
 cause that much difference in a given program. Differences need to 
get
 up into the 20-30% range before they are likely to be reliably
 repeatable across different systems.

 At least that's been my experience.

That has not been my recent experience. While working on my current
project (the Safari web browser), we have routinely made 1% speedups
that are measurable and have an effect across multiple machines and
compilers (same basic CPU type and operating system), and we have also
detected 1% slowdowns when we inadvertently introduced them.

I notice the examples you give are JavaScript. Greg's example of a 
virtual machine is written mostly in C, IIRC. I wonder if C++ is more 
sensitive to compiler differences?

For example, some C++ compilers are a lot more aggressive about 
inlining than others. For some of the code I've timed, a change slowed 
results for a compiler that failed to inline it, but ran quicker for 
the compiler that was good at inlining.
Makes sense.  Boost code stresses compilers in ways that our code
doesn't -- the need to be as portable as we are means we don't
even use all the features of C89, let alone C++ or C99.  And of
course C89 doesn't have things like inlining and virtual function
dispatch that can vary so much across C++ compilers.   Plus we
spend a fair amount of time inspecting the output of our compilers
and tweaking our C code until we get what we want, and preserving
the tweaks in platform-specific macros.
The fact remains that it takes a lot of 3% tweaks to make a big
difference, so until you know you have the best possible data
structures and algorithms there isn't much point, and when there
is a point it is painstaking work at the limits of measurability.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Re: in/outparameters,codingstylesandmaintenance[was:classproposal]

2003-05-08 Thread Gregory Colvin
Somewhere in this thread I lost track of this -- but just how
do out and in differ from ref and cref?
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost