[boost] Re: Variant Library: access interface

2003-04-03 Thread Gennadiy Rozental
  templatetypename T
  void foo( T const )
  {
   
  }
 
  int main()
  {
  boost::variantint,. v = 5;
 
 // Here I want to pass const reference to integer value of variant to
  function foo
// foo( getint( v ) ); - type T is incorrect
 foo( ??? );
  }

 I don't see why this wouldn't work. What is incorrect regarding type T?

Try to compile and run this:
#include iostream

templatetypename T
void
foo( T const )
{
   std::cout  typeid(T).name()  std::endl;
}

templatetypename T
struct get {
operator T() { return m_t; }

T m_t;
};


int main()
{
   foo( getint() );
}

 I see it as the difference between dynamic_cast with a reference type
versus
 a pointer type. That is, the reference-based dynamic_cast throws, which as
 you note, works fine. But the pointer-based dynamic_cast provides a
 non-throwing mechanism as well (returns a null pointer). Thus,
 extract::check is the non-throwing analogue for extract.


I don't argue that it may be used. I argue that it will be rarely used. In
most cases when you access your variant you either know what type it holds
by inspecting it's which() result or will use some kind of visitation. You
may provide this form of value access but only as an addition to free form
one.

Gennadiy.




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


[boost] Re: Variant Library: reflection

2003-04-03 Thread Gennadiy Rozental
 If the issue concerns you this much, you might propose something along the
 lines of BOOST_NO_EXCEPTIONS.

 That is, you might try: BOOST_NO_RTTI anyone?

  - Eric

I did. As a user defined parameter. Terrie made a point that it should be
config parameter cause some embedded compiler indeed does not provide this
functionally (maybe because it's taking too much space to implement?). No
consequences yet.

Gennadiy.




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


[boost] Re: Variant Library: top level const types

2003-04-03 Thread Gennadiy Rozental
 I think you misunderstand: What I'm arguing is that the usage case you
 propose here is itself erroneous. This is *not* an issue of whether I can
 implement the behavior. (In fact, I need to do additional work to prohibit
 it.)

 Let me know if you still disagree.

I disagree. Let say I want to define type that will hold constant parameter
that is represented either as constant int value or constant string that
could be used to lookup the value in some kind of global table.
So what I want is

typedef boost::variantint const,std::string const GlobalParameter;

GlobalParameter input_socket( 12345 ); // localhost::12345
GlobalParameter output_socket( MultiplexorSocket );

Is there anything wrong in such design?

Gennadiy.




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


Re: [boost] boost::any feature request

2003-04-03 Thread Peter Dimov
Vladimir Prus wrote:
 Hi Maxim,

 And here are the Intel VTune results (see the sources for details):

 Creation Assignment
 struct 13383 27358
 boost::any 3846 331870
 TailoredAny 9151 310717
 TailoredAnyLoki::SmallObject 3855 110022

 IOW, TailoredAny behaves much worse on creation in default
 configuration. It behaves much better on assignment, in tuned
 configuration. Hmm..

It might be interesting to try a modified boost::any that uses
boost/detail/quick_allocator.hpp.

void * operator new(std::size_t)
{
return detail::quick_allocatorthis_type::alloc();
}

void operator delete(void * p)
{
detail::quick_allocatorthis_type::dealloc(p);
}

needs to be added to any::holder.

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


Re: [boost] Re: Variant Library: top level const types

2003-04-03 Thread Peter Dimov
Gennadiy Rozental wrote:
 So what I want is
 
 typedef boost::variantint const,std::string const GlobalParameter;
 
 GlobalParameter input_socket( 12345 ); // localhost::12345
 GlobalParameter output_socket( MultiplexorSocket );

typedef boost::variantint, std::string GlobalParameter;

GlobalParameter const input_socket( 12345 ); // localhost::12345
GlobalParameter const output_socket( MultiplexorSocket );

Same as vectorint const vs vectorint const.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] [smart-ptr] Custom deallocator for scoped_ptr

2003-04-03 Thread Peter Dimov
Lars Gullik Bjønnes wrote:
 We find ourselves in want of a custom deallocator for scoped_ptr, but
 no such thing seems to exist now.

 Has this been thought of?

 If yes, what was the reason for not supporting this?

If you want a shared_ptr-style runtime custom deallocator support, this is
not supported because the overhead was (and is) considered unacceptable for
scoped_ptr. Use shared_ptr instead.

The alternative is

template class T, class D = boost::checked_deleterT  class scoped_ptr
{
public:

// ...

~scoped_ptr() { D()(ptr); }
};

The concern here is that the change may potentially break user code that
uses a template template parameter to pass
scoped_ptr/auto_ptr/shared_ptr/whatever_ptr as an argument.

I'm not yet sure whether the increased functionality justifies breaking such
code. OTOH I'm not sure whether such code even exists. ;-)

So if someone has an opinion about this potential change to scoped_ptr, now
is probably the right time to express it.

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


Re: [boost] [smart-ptr] Custom deallocator for scoped_ptr

2003-04-03 Thread Greg Colvin
I think scoped_ptr needs to remain as it is.  If we need this
functionality a new scoped_deallocator may be the way to go.
On Thursday, Apr 3, 2003, at 11:04 Europe/London, Peter Dimov wrote:

Lars Gullik Bjønnes wrote:
We find ourselves in want of a custom deallocator for scoped_ptr, but
no such thing seems to exist now.
Has this been thought of?

If yes, what was the reason for not supporting this?
If you want a shared_ptr-style runtime custom deallocator support, 
this is
not supported because the overhead was (and is) considered 
unacceptable for
scoped_ptr. Use shared_ptr instead.

The alternative is

template class T, class D = boost::checked_deleterT  class 
scoped_ptr
{
public:

// ...

~scoped_ptr() { D()(ptr); }
};
The concern here is that the change may potentially break user code 
that
uses a template template parameter to pass
scoped_ptr/auto_ptr/shared_ptr/whatever_ptr as an argument.

I'm not yet sure whether the increased functionality justifies 
breaking such
code. OTOH I'm not sure whether such code even exists. ;-)

So if someone has an opinion about this potential change to 
scoped_ptr, now
is probably the right time to express it.

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


[boost] [dynamic_bitset::reference] - questions to the users (and to the gurus)

2003-04-03 Thread Gennaro Prota
Among the several changes I've planned to dynamic_bitset there's one
which affects semantics and that, therefore, I would like to discuss
with you a bit. Note however that the old semantics were never
specified in the docs, so this would break nothing but adventurous
usages of undocumented features on the users part.

Here's the issue: dynamic_bitset::reference currently stores a
pointer to its bitset object and an index. For that reason:

 - after a swap of bitsets, references come to refer to
   different elements: they get track of the address of the
   bitset they are referencing, and the bitset has changed
   its contents.

 - value changing operations on the dynamic_bitset *don't*
   invalidate references unless they make the corresponding
   index out of range (by shrinking the bitset). In other
   words: semantics are intrinsecally those of a *pair*
   (bitset address, index); as long as the index remains
   valid for the pointed to bitset everything is fine.
   But then one wonders: why not using an index directly?
   And even if, how could one use a reference considering
   that all its constructors are private?

Both points above are the exact contrary of what one would expect by
analogy with references, pointers, or iterators (The standard
guarantees that no standard library swap() function invalidates any
references, pointers, or iterators referring to *the elements* of the
containers being swapped. To state it metaphorically: the elements
change containers but references follow them).

Now, the first question is: ok to change semantics and document the
new behavior? (BTW, the new semantics can be implemented much more
efficiently, e.g. by storing a pointer to a block and a *precomputed*
mask)


Second question: any interest in having this new referenceBlock as a
separate class? (In this case dynamic_bitset::reference would really
become a typedef as stated in the docs, rather than a nested class
:-))


Now, for the gurus: this is the current interface of reference:

class reference 
{ 
friend class dynamic_bitsetBlock, Allocator; 

// the one and only non-copy ctor 
reference(dynamic_bitset bs_, size_type bit_);


public: 
operator bool() const; // for x = b[i] 
bool operator~() const;// flips the bit 
reference flip(); // for b[i].flip();


reference operator=(bool value);  // for b[i] = x 
reference operator|=(bool value); // for b[i] |= x 
reference operator=(bool value); // for b[i] = x 
reference operator^=(bool value); // for b[i] ^= x 
reference operator-=(bool value); // for b[i] -= x


reference operator=(const reference j);  // for b[i] = b[j] 
reference operator|=(const reference j); // for b[i] |= b[j] 
reference operator=(const reference j); // for b[i] = b[j] 
reference operator^=(const reference j); // for b[i] ^= b[j] 
reference operator-=(const reference j); // for b[i] -= b[j]


}; 


Note the last two groups of 5 functions: they are identical except
that those of the first group take a bool and those of the second one
a const reference . But since we have an operator bool() const
wouldn't the first group be enough? 

In effect, declaring the copy-assignment operator has the pleasant
effect to force an explicit definition, showing that the shallow-copy
is intentional, but what about the other 4 functions? What's their
purpose? If we drop them, an expression like

   b[i] |= b[j]

changes from

   (b.operator[](i)).operator |= ( b.operator[](j) )

to

   (b.operator[](i)).operator |= ( b.operator[](j).operator bool() )



But I can't see any problem with that, even with self-assignment. Am I
missing something?


Genny.

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


Re: [boost] indentation algorithm for stream objects

2003-04-03 Thread Reece Dunn
Larry Evans wrote:
Wouldn't the following:

  *thisiomanip::setw(m_indent.length * 
m_indent.level)setfill(fill)fill;
  *thissetfill(fill);

do essentially what indentor OutputFileType ::indent() does?
Thanks. I didn't think of that. I'll implement it into the code (with the 
correction pointed out by Jason House).

This implementation also requires the user to know when the
beginning of line occurs. That does sound pretty reasonable,
and I'm kinda wondering why I didn't do it in marg_ostream; however,
marg_ostream doesn't require this, and I'm wondering whether other
people think this feature is worth the extra complexity in
marg_ostream.
There are two possible ways I see at simplifying your marg_ostream:
[1] Overload string operations only since you only really need to intercept 
'\n' characters - this appears to be the simpler of the two solutions (as 
there is no real need to overload for integer types, only strings and 
characters).
[2] Write a stream buffer that intercepts the '\n' characters - this seems 
overly complicated and a little overkill.

NOTE: I have not yet looked at the code for marg_ostream so I cannot give 
any more detailed comments on it at the moment.

One of the reasons I chose not to have the '\n' character trigger the code 
to perform the indentation is that you could have code like:

out.indent()  This is a test  '\n';
out.beginIndent();
  out.indent()  Indented  '\n';
out.endIndent();
out.indent()  End of test  '\n';
It makes sense to have the new lines at the end of the output. If, however, 
the '\n' character triggered the indentation, you would need something like:

out  This is a test;
out.beginIndent();
  out  \nIndented;
out.endIndent();
out  \nEnd of test;
which is less intuitive and can lead to mistakes if you are not careful. The 
reason for this is that the indentation will be done at the wrong time and 
lead to incorrect alignment of the string Indented.

Letting the user control *when* indentation occurs gives greater 
flexibility, for example if you were formatting an XML document, you could 
choose not to indent on CDATA sections, or pre elements in HTML.

Another indentor advantage is there's no need
to define operator for all the primitive types as was done in
marg_ostream.
That is due to the aim at keeping indentor's design as simple as possible, 
while giving it as much flexability as possible. Redefining the operator 
would have severly complicated the design.

-rhd-
mailto:[EMAIL PROTECTED]
_
Express yourself with cool emoticons http://www.msn.co.uk/messenger
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Statistics code example

2003-04-03 Thread Neal D. Becker
On Wednesday 02 April 2003 02:57 pm, Paul A. Bristow wrote:
 Sadly (but perhaps not too surpringly) this does not seem to work for MSVC
 7.0 with complex. (OK without)


Could you elaborate?  What didn't work?  Any ideas how to fix?  I don't use 
MSVC.

 A full working example with at least a few comments might sell this better?

 Paul

 Paul A Bristow, Prizet Farmhouse, Kendal, Cumbria, LA8 8AB  UK
 +44 1539 561830   Mobile +44 7714 33 02 04
 Mobile mailto:[EMAIL PROTECTED]
 mailto:[EMAIL PROTECTED]

  -Original Message-
  From: [EMAIL PROTECTED]
  [mailto:[EMAIL PROTECTED] Behalf Of Neal D. Becker
  Sent: Tuesday, April 01, 2003 2:26 PM
  To: [EMAIL PROTECTED]
  Subject: [boost] Statistics code example
 
 
  Here is an example of a class that can compute 2nd order stats that will
  work for either scalar or complex types.
 
  It could be made slightly more efficient.  It uses abs(), relying on the
  trick that abs() is defined for both scalar float and complex.  It
  could be improved by defining our own norm function for both scalar
  float and complex.  (Unfortunately for efficiency, complex norm is
  defined in terms of abs, which uses sqrt, on at least some systems
  (libstdc++)).

 ___
 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] Custom deallocator for scoped_ptr

2003-04-03 Thread Howard Hinnant
On Thursday, April 3, 2003, at 05:04  AM, Peter Dimov wrote:

So if someone has an opinion about this potential change to 
scoped_ptr, now
is probably the right time to express it.
I've been experimenting with:

templateclass T, class D = detail::apply_delete
class move_ptr;
So far I like it.  It is implemented so that the deallocator can also 
be a reference to a deallocator.  Can be used like:

templateclass T
templateclass Y, class D
shared_ptrT::shared_ptr(Y* p, D d)
: ptr_(p)
{
move_ptrY, D hold(p, d);
s_ = new detail::shared_ptr_deleterY, D(p, d);
hold.release();
...
}
-Howard

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


Re: [boost] document translation into Japanese

2003-04-03 Thread Beman Dawes
At 04:01 AM 4/2/2003, k.t. wrote:

And in translating, we found some incorrect expressions in boost
document. We want to report them for feedback, then is it no problem to
report them here? Is boost users mailing list better for it?
This list is probably the best place.

Thanks,

-- Beman

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


Re: [boost] Statistics code example

2003-04-03 Thread Reece Dunn
Neal D. Becker wrote:

Could you elaborate?  What didn't work?  Any ideas how to fix?  I don't use 
MSVC.
Looking at the code, I think the problem is this (although I have not yet 
tried it):

templatetypename T
struct Stat_t std::complexT  {
 typedef typename std::complexT::value_type value_t;
};
MSVC 7 does not handle partial template specialization, so it will not 
compile (you'll need to remove the above specialization). It should work for 
MSVC 7.1 final beta, but I do not have a copy of it to verify.

The solution would be to wrap the above in a guard statement similar to:

#if !defined(BOOST_NO_PARTIAL_SPECIALIZATION)
templatetypename T
struct Stat_t std::complexT  {
 typedef typename std::complexT::value_type value_t;
};
#endif
NOTE: I'm not sure if the BOOST_NO_PARTIAL_SPECIALIZATION name is correct, 
but you get the idea.

Then, if there is partial specialization support the program will work as 
indented. Compilers (like MSVC 7) that do not have partial specialization 
support will then be able to use the program and it will still work because 
the imaginary component is not used in sumXsqr so the complex number is in 
essence a real number. There are several concerns with this:
*  there is no automatic conversion of a complex number to a real number, so 
this is not a complete solution
*  output to a stream would probably result in a display of the form:
  (x, y)

I do not how how to get around these problems.

-rhd-
mailto:[EMAIL PROTECTED]
_
Hotmail messages direct to your mobile phone http://www.msn.co.uk/mobile
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


[boost] Re: [dynamic_bitset::reference] - questions to the users (and to the gurus)

2003-04-03 Thread Gennaro Prota
On Thu, 03 Apr 2003 14:15:27 +0200, Gennaro Prota
[EMAIL PROTECTED] wrote:

Now, for the gurus: this is the current interface of reference:

class reference 
{ 
friend class dynamic_bitsetBlock, Allocator; 

// the one and only non-copy ctor 
reference(dynamic_bitset bs_, size_type bit_);

Please don't scold me about the use of the term interface here. Just
sloppy language.


public: 
...
reference operator=(const reference j);  // for b[i] = b[j]
reference operator|=(const reference j); // for b[i] |= b[j]
...

In case this is confusing: the declarations and the corresponding
comments use the letter j with different meanings. I would have better
written:

   reference operator=(const reference rhs); // for b[i] = b[j]
   ...


Genny.

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


RE: [boost] Statistics code example

2003-04-03 Thread Paul A. Bristow
I believe this conjecture is correct, but I am still eagerly awaiting 7.1 :-)

This is quite interesting (though it needs Industrial Strengthening of course),
and could usefully generate the higher moments and other statistical thingys
too.

And it makes me wonder if one could use a container like a circular buffer.  I
can think of applications where one would like new data to pour in continuously
and to look back for mean (weighted Kalmanesque?), perhaps only a limited
distance.  Using a vector or valarray would imply it would grow for ever and run
out of space eventually. (I think someone else suggested something of this
sort?)
Is the STL queue suitable?

Paul

Paul A Bristow, Prizet Farmhouse, Kendal, Cumbria, LA8 8AB  UK
+44 1539 561830   Mobile +44 7714 33 02 04
Mobile mailto:[EMAIL PROTECTED]
mailto:[EMAIL PROTECTED]


 -Original Message-
 From: [EMAIL PROTECTED]
 [mailto:[EMAIL PROTECTED] Behalf Of Reece Dunn
 Sent: Thursday, April 03, 2003 3:33 PM
 To: [EMAIL PROTECTED]
 Subject: Re: [boost] Statistics code example


 MSVC 7 does not handle partial template specialization, so it will not
 compile (you'll need to remove the above specialization). It should work for
 MSVC 7.1 final beta, but I do not have a copy of it to verify.

 The solution would be to wrap the above in a guard statement similar to:

 #if !defined(BOOST_NO_PARTIAL_SPECIALIZATION)
 templatetypename T
 struct Stat_t std::complexT  {
   typedef typename std::complexT::value_type value_t;
 };
 #endif

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


Re: [boost] indentation algorithm for stream objects

2003-04-03 Thread Larry Evans
Reece Dunn wrote:
Larry Evans wrote:

[snip]
There are two possible ways I see at simplifying your marg_ostream:
[1] Overload string operations only since you only really need to 
intercept '\n' characters - this appears to be the simpler of the two 
solutions (as there is no real need to overload for integer types, only 
strings and characters).
[2] Write a stream buffer that intercepts the '\n' characters - this 
seems overly complicated and a little overkill.
Agreed.  I had to work at it IIRC.
NOTE: I have not yet looked at the code for marg_ostream so I cannot 
give any more detailed comments on it at the moment.
Thanks.  I'll think some more about it, when I get some time.
One of the reasons I chose not to have the '\n' character trigger the 
code to perform the indentation is that you could have code like:

out.indent()  This is a test  '\n';
out.beginIndent();
  out.indent()  Indented  '\n';
out.endIndent();
out.indent()  End of test  '\n';
It makes sense to have the new lines at the end of the output. If, 
however, the '\n' character triggered the indentation, you would need 
something like:
[snip]
which is less intuitive and can lead to mistakes if you are not careful. 
The reason for this is that the indentation will be done at the wrong 
time and lead to incorrect alignment of the string Indented.
I disagree. The following (almost) line by line translation of your example
to marg_ostream:
; marg_ostream mout(cout)
; unsigned i=0
; mout  This is a test i++ endl
; ++mout
; mout  Indented  endl
; --mout
; mout  End of test  endl
produces:

This is a test0
  Indented
End of test
[snip]
Another indentor advantage is there's no need
to define operator for all the primitive types as was done in
marg_ostream.


That is due to the aim at keeping indentor's design as simple as 
possible, while giving it as much flexability as possible. Redefining 
the operator would have severly complicated the design.
That's why I like your way; however, in the back of my mind,
there's a feeling I started out that way (this was done years ago)
and for some reason, after running some tests, found it better to
do it this other way.  I think the problem was I didn't always
know when the beginning-of-line occured; hence, I needed the
marg_ostream to keep track of this.  I can't remember specifics
yet.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


[boost] Re: [dynamic_bitset::reference] - questions to the users (and to the gurus)

2003-04-03 Thread Gennaro Prota
A couple of corrections to my previous post:

   And even if, how could one use a reference considering
   that all its constructors are private?

All non-copy constructors, actually. Client code can easily create a
reference object by copy:

  dynamic_bitset::reference ref = b[0];

This brings the question: should we disable copy construction? Note
that vectorbool has a member function to swap two references

  // see 23.2.5
  static void swap(reference x, reference y);

which, of course, requires a copy constructor. Should dynamic_bitset
have it too? In that case we could implement a private copy
constructor, which would be available to dynamic_bitset::swap (for
friendship) but not to the user; otherwise we could simply leave it
undefined:

  private:
reference(reference); // undefined

In effect, declaring the copy-assignment operator has the pleasant
effect to force an explicit definition, showing that the shallow-copy
is intentional

Sorry, I was thinking to the copy constructor (implicitly declared),
that makes a shallow copy. The copy assignment operator does something
completely different.


Genny.

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


[boost] Re: Variant Library: access interface

2003-04-03 Thread Eric Friedman
Gennadiy Rozental:
   templatetypename T
   void foo( T const )
   {

   }
  
   int main()
   {
   boost::variantint,. v = 5;
  
  // Here I want to pass const reference to integer value of variant
to
   function foo
 // foo( getint( v ) ); - type T is incorrect
  foo( ??? );
   }
 
  I don't see why this wouldn't work. What is incorrect regarding type
T?

 Try to compile and run this:
 #include iostream

 templatetypename T
 void
 foo( T const )
 {
std::cout  typeid(T).name()  std::endl;
 }

 templatetypename T
 struct get {
 operator T() { return m_t; }

 T m_t;
 };


 int main()
 {
foo( getint() );
 }

Sorry, I now understand. While I had planned to abandon this approach due to
MSVC conformance problems, I see now it must be abandoned for a more
significant reason.

Thanks,
Eric



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


[boost] Re: Variant Library: visitation algorithm

2003-04-03 Thread Eric Friedman
Gennadiy Rozental wrote:
  While I do agree O(1) is better than O(N), I would like to point out
that
  it is usable only when the pseudo-variadic template interface is used
(i.e.,
  variantT1, T2, ..., TN as opposed to variantTypes).

 Why? And to be absolutely clear: what do you mean by it?

By it I mean the use of a switch, as you propose.

If variant is given types as a MPL-sequence (e.g., variant mpl::listT1,
T2, ..., TN  instead of variantT1, T2, ..., TN), then technique you
propose will not work. Please prove me incorrect, but I don't think you can.
(Note, however, that loop-unrolling is still possible, though ultimately it
doesn't change the O(N) complexity of visitation.)


  Also, I am still not convinced that an unrolled if-else implementation
 would
  not be optimized in the same manner as a switch statement. That is,
 whether

 I do not know how smart are modern optimizers. But in general my
 understnding was that if-else form should use O(N) comparisons, while
switch
 form should be compiled into jump with some computed offset.

I'd be interested to know more about these assumptions before I spend a
great deal of time writing code based upon them.

Also possible, I'd like to note, is the use of a static array of function
pointers. I'll look into this, too, but the space-overhead involved may be
significant.


  Further, I would like to point out that we are debating integer O(1) vs.
  O(N) for integer-equality comparisons. While I am a proponent of
limiting
  complexity, I would like to observe that you yourself suggested a cap N
=
  128.
 
  In sum, I'm not sure how pertinent this issue is at this point.

 I agree that by itself the difference is not that significant. But note
that
 visitation is very basic operation in regards to variant type. Almost any
 activity that involve variant will include some kind of visitation (look
 into your implementation for example). Some people fight to eliminate
extra
 level of indirection by using references vs. pointers. Or eliminate
virtual
 function to prevent double resolution. In this case the difference could
be
 much more significant (up to 128 times).
 So unless it's really unreasonably difficult to implement different
 visitation scheme, I see enough point to try to do this.

I agree that visitation is the fundamental operation for variant. I'll look
into it.

Thanks,
Eric



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


[boost] BOOST_HAS_THREADS in Win32

2003-04-03 Thread Jiang Hong
I'm new to boost. But should '#define BOOST_HAS_THREADS' be added to

boost_1_30_0/config/platform/win32.hpp?

Or is there a better way?

Thanks.



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


[boost] Re: Variant Library: variant size and strong guaranty

2003-04-03 Thread Gennadiy Rozental
   overview.) This technique is necessary to provide a general guarantee
   of strong exception-safety, which in turn is necessary to maintain
   a never empty invariant for variant.
 
  What is this invariant? And why is it that important.

 The invariant is quite straightforward: any object of type variantT1, T2,
 ..., TN contains exactly one object of type T1, T2, ..., or TN.

From this it seems that in above passage (This technique is necessary ...)
you switched an order of importance:
In fact you need double storage to implement never empty invariant (in
other case you would need during copy/assignment to first destroy current
object), that is necessary to implement strong guaranty.
Isn't it?

 I am well aware, of course, of the trade-offs made by the use of this
 technique. Thus the decision is not set in stone, and I'd be willing to
 consider arguments against it.

 I will make two final notes, however.

 1) In addition to its role in enabling recursive variants,
 boost::incompleteT provides a convenient way to increase space
efficiency
 (though at the expense of speed efficiency due to heap allocation). Note
 though that this is only because incomplete wraps a T*, which is small. It
 does *not* disable the double-storage technique.

 2) For every type supporting non-throwing move operations, I have
 implemented variant to use single-storage. As a (trivial) proof of this,
 boost::has_nothrow_copy types *do* currently avoid the double-storage
 overhead.) Of course, until Boost.Move becomes a reality this is nearly
all
 but meaningless for the vast majority of types.

Several notes:

1. Intrinsic types have nothrow move constructor, so should follow second
case road. Isn't it?
2. Could type that implements swap() method somehow follow the second case
road also? For example, could you somehow deduce T* from buffer and swap it
with local copy of the argument?
3. Could you use placement copy into local to assign storage and then
memcopy it to variant storage? It wouldn't work with all types but may work
in many cases isn't it? Here we would have different tradeoff.
4. Whatever way these matters will be decided I think it should be carefully
documented so the user have a perfect understanding of possible choices.

 Another approach might be to take advantage of the introduction of 'void'
 content. Since 'void' content would introduce the notion of an empty
 variant, it *might* (see below for my strong reservations) make sense to
 disable the double-storage technique for variants with allowable empty
(i.e.
 void content) states.
 While this is certainly quite implementable, I feel a bit uneasy about
 hinging variant's exception-safety guarantees on such a small point as
 whether 'void' content is allowed. I imagine it would not only make
variant
 more confusing to use but also may not satisfactorily solve the problem of
 delegating the space-vs-safety decision to the user.

I agree on that. I would rather have a variant of variant (;-)) that doesn't
have strong guaranty at all.

Separate issue is the type of which field. Having it as int is an
  This is implementation issue that affect the library design (it affects
  an abstraction overhead). So it's as important as issues above.

 So long as variant::which() returns an int, I don't see how it is anything
 other than a design issue: in terms of space efficiency, the difference
 between sizeof(char) and sizeof(int) is constant.

I do not want to argue on terms. My point is that this implementation detail
make variantint,short size at least 6 instead of 3. 100% difference. So
let's just fix it before release.

Gennadiy.




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