Re: [boost] Cannot build static library with latest CVS on Linux

2003-08-31 Thread Rene Rivera
[2003-08-30] Jeff Garland wrote:

Just did a CVS update and I am now unable to build date_time.  This is on
Linux.  I'm looking at the CVS check-ins, but maybe someone workon on the
build stuff might know right away what's wrong

bjam from libs/date_time/test results in:

[snip]

/usr//bin/ar /usr/bin/ar  ru 
 -^^^
 
That duplication is strange -- I've now done a fix for that posibility. But
you may want to investigate why ar is showing up twice in your PATH.
Something funky with your file system?


-- grafik - Don't Assume Anything
-- rrivera (at) acm.org - grafik (at) redshift-software.com
-- 102708583 (at) icq
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Cannot build static library with latest CVS on Linux

2003-08-31 Thread Rene Rivera
[2003-08-30] Jeff Garland wrote:

Replies to self...
 Just did a CVS update and I am now unable to build date_time.  This 
 is on Linux.  I'm looking at the CVS check-ins, but maybe someone 
 workon on the build stuff might know right away what's wrong

Had to roll back the lastest change in gcc-tools.jam to fix this (back to
1.73)  

Latest change was:

3 days  grafik  Fix for when AR is distributed as part of the
compiler (ex.
mingw, cygwin) 

Yea, I definately broke it :-) I'm trying to figure out how though...


-- grafik - Don't Assume Anything
-- rrivera (at) acm.org - grafik (at) redshift-software.com
-- 102708583 (at) icq
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: [boost.variant] It is possible to make a variantLessThanComparable

2003-08-31 Thread Peter Dimov
David Abrahams wrote:
 Eric Friedman [EMAIL PROTECTED] writes:

 Ultimately, I do not believe any ordering scheme will provide
 meaningful, straightforward semantics. Assuming I am correct, I
 propose that the variant library offer your ordering scheme -- but
 only as an explicit comparison function, calling it variant_less.
 This would allow, for instance:

   std::set my_variant, boost::variant_lessmy_variant 

 I'd appreciate feedback.

 I had the same thought myself, though I'd be inclined to spend a
 little time searching for a better name than less, since it doesn't
 really mean that.  Maybe variant_before, using type_info::before as
 a precedent?

If you want a second opinion, I'm in the just provide operator== and
operator camp.

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


[boost] Re: Optional, tie, and iterator_adaptor

2003-08-31 Thread Daniel Frey
Joel de Guzman wrote:
Although I don't see this as problematic:

optionalint x;
 if (x)  
foo(x);

Or perhaps:

optionalint x;
 if (!!x)  
foo(x);

We already have an implicit conversion to safe_bool and an 
operator ! anyway. Keep it. There's nothing wrong with it:

operator unspecified-bool-type() const;
bool operator!() const;
IMHO, there is something terribly wrong here because now optionalT has 
two interfaces. The interface of optional itself and the interface of T. 
If you think that optionalT can be used like T (having the 
value-interface), you are immediately fooled by if(x) as it doesn't 
check T's value. A pointer-interface is much cleaner as it gives the 
user a hint that he is using a wrapper and in practice, I always prefer 
to be a little more explicit on these things (even at the cost of an 
occasional * here and there) than to have silent bugs.

Regards, Daniel

--
Daniel Frey
aixigo AG - financial training, research and technology
Schloß-Rahe-Straße 15, 52072 Aachen, Germany
fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
eMail: [EMAIL PROTECTED], web: http://www.aixigo.de
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: 1.30.0-1.30.2: no more thread support for Linux?

2003-08-31 Thread John Maddock
  Threading support is on when BOOST_HAS_THREADS is defined, and off when
it's
  not, or forced off by defining BOOST_DISABLE_THREADS, you'll find both
of
  these mentioned in the configure generated user.hpp (and in the config
  docs).

 So if I my program runs only on systems that I know support threads,
 and I want shared_ptr to use threading support, my program can guarantee
 this by defining BOOST_HAS_THREADS? No matter whether the user's Boost
 install is -

 1) Simply extracted from the tarball
 2) Configured without thread support
 3) Configured with thread support

 And I don't need to define anything about the platform thread library
being
 used, like BOOST_HAS_PTHREADS?

OK lets start with Linux and gcc as a specific and special case - in this
case I think that will work - BOOST_HAS_PTHREADS will be defined anyway, but
remember that your std lib will not be thread safe unless you define
_REENTRANT, and if you do that then BOOST_HAS_THREADS will get defined
anyway by the config system (either the out-the-box version or the
configure'd one).  Of course the user could always manually configure boost
in some obscure way, or deliberately disable thread support with
BOOST_DISABLE_THREADS, but if they've done that then you should probably be
emitting a #error not trying to work around it.

In the general case though, we're back to the situation that your code will
not be thread safe unless you invoke your chosen compiler with some magic
special flag (or in the case of IBM Visual Age use a different compiler
front end altogether), and if you do that then Boost.config will detect it's
presence by whatever macros it sets (usually but not always _REENTRANT) and
turn on BOOST_HAS_THREADS.  You should always regard BOOST_HAS_THREADS as
*information*, not as something you set yourself, in 99% of cases if you
find it's not set, then it's because the compiler in it's current mode isn't
capable of producing thread safe code.

Note for example that Boost.config explicitly defines BOOST_DISABLE_THREADS
for gcc on some platforms because we know that gcc isn't capable of
producing thread safe code on those platforms yet (even though they do have
a perfectly good pthread lib).

Finally if you're configuring your program via autoconf then there are some
nice looking autoconf macros on the net, for example:
http://ac-archive.sourceforge.net/Installed_Packages/acx_pthread.html.

Sorry to make this complicated, but threads _are_ complicated

John.


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


[boost] Re: [boost.variant] It is possible to make a variant LessThanComparable

2003-08-31 Thread Dirk Schreib
David Abrahams [EMAIL PROTECTED] wrote
 Eric Friedman [EMAIL PROTECTED] writes:
std::set my_variant, boost::variant_lessmy_variant 

 I had the same thought myself, though I'd be inclined to spend a
 little time searching for a better name than less, since it doesn't
 really mean that.  Maybe variant_before, using type_info::before as
 a precedent?

Maybe std::lessT is a precedent too?
Nearly everyone I know has written a small, little wrapper around
type_info to make it useable in the associative containers (and
the default std::lessT).

Dirk



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


[boost] Re: [boost.variant] It is possible to make a variant LessThanComparable

2003-08-31 Thread Dirk Schreib
Hello Eric,

Eric Friedman [EMAIL PROTECTED] wrote
 Dirk Schreib wrote:
  [...]
  In this example
 
typedef boost::variantT1, T2, ..., TN V;
V v1 = T1( x );
V v2 = T2( y );
V v3 = T1( z );
 
  v1  v2 should always be true. And v1  v3 should be the same as T1( x )

  T1( z ).

 For starters, I agree that v1  v3 should be the same as x  y.

Ok.

 I'm not so sure about v1  v2, though. I'm inferring that you believe that
 operator should be implemented as follows:

   template typename T1, ..., typename TN
   bool operator(
   const variantT1,...,TN lhs,
 , const variantT1,...,TN rhs
 )
   {
 if (lhs.which() == rhs.which())
   ... // compare using underlying operator
 else
   return lhs.which()  rhs.which()
   }

This is exactly what I want.

 While this certainly solves the problem of storing variants in associative
 containers by establishing an ordering, the ordering is rather arbitrary
and
 potentially confusing. Consider the following:

   typedef variantint, double var;
   bool result1 = int(3)  double(2.0); // false
   bool result2 = var(3)  var(2.0); // true

 On first glance, IMO most users would expect result1 == result2. With your
 ordering scheme, this would be untrue. Unfortunately, I do not believe the
 problem is specific to your ordering scheme.

Trying to establish an ordering between unrelated types where each type does
not
fall into it's own category is very difficult. My ordering scheme is very
easy and
simple because you never have to compare two different types.
Alternative solution would be to use

  typedef variantT1, T2 var;
  bool operator( T1 const lhs, T2 const rhs);

which usually does not exist. Even if it is possible to compare two
different types
with integral promotion or user defined conversion operators it will impose
problems on asymetry and transitivity.

  typedef variantdouble, std::string, int var;
  bool result1 = var(3.0)  var(2);  // false or true?
  bool result2 = var(3.0)  var(2.5); // false or true?
  bool result3 = var(2.5)  var(2); // false or true?

  // if (result2  result3) == result1 = true.

 Ultimately, I do not believe any ordering scheme will provide meaningful,
 straightforward semantics. Assuming I am correct, I propose that the
variant
 library offer your ordering scheme -- but only as an explicit comparison
 function, calling it variant_less. This would allow, for instance:

   std::set my_variant, boost::variant_lessmy_variant 

The default comparison operator for std::setT is std::lessT
(which just uses operator() ) and I would like this to work with
variant too. If there are no meaningful, straightforward semantics
the user will not put a variant into a set. If my ordering scheme
is the only one offered by variant, it can be the default too.

 P.S. The issue of equality comparison between variants is a bit more
 straightforward. However, we still have the following potentially
confusing
 situation:

   typedef variantint, double var;
   bool result3 = (int(3) == double(3.0)); // true
   bool result4 = (var(3) == var(3.0)); // false

I need exactly this behaviour...
 Thus, perhaps a boost::variant_equal comparison function is also in order.

...and don't have a need for this ;-)


Dirk



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


Re: [boost] Regression test page broken

2003-08-31 Thread Martin Wille
Jeff Garland wrote:
The regression test page seems to be on a diet

http://boost.sourceforge.net/regression-logs/
You can find some of the other results at
  http://boost.sourceforge.net/regression-logs/release
However, I'm not sure wether that is official already.

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


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

2003-08-31 Thread Mat Marcus
In this post I will put forward a use-case or two to help see whether
something a little different then the current version of optional
might be useful. I also begin making a case that a Concept like
PossiblyUninitializedVariable might be more generally useful than
OptionalPointee. As I mentioned in the post that started this thread,
I am writing a library that makes heavy use of using boost::graph and
boost::tie. In the implementation of my library there is plenty of
code that looks like this:
//...
typedef /*details ommitted*/ Iter;
typedef /*details ommitted*/ Vertex;
typedef /*details ommitted*/ Graph;
std::pairIter, Iter out_edges(Vertex, Graph);
//...
Iter begin, end;
Graph g(/*...*/);
//...
boost::tie(begin, end) = out_edges(v,g);
It bothers me somewhat that begin and end are sitting there in an
(implicitly) uninitialized state. Maybe during later maintenance of
this code a new control path could get added and begin or end might be
used without first being set. So I thought I'd try to see whether I
could make the code more robust using boost::optional. I imagined
following a convention along the lines of Initialize all local
variables where declared, or when that is impossible use optional to
protect against their inadvertent uninitialized use. But it turns out
the optional doesn't really work with tie. Here's what I thought would
be possible:
//... same as first version
typedef /*details ommitted*/ Iter;
typedef /*details ommitted*/ Vertex;
typedef /*details ommitted*/ Graph;
std::pairIter, Iter out_edges(Vertex, Graph);
//...
boost::optionalIter begin, end; //now use optional
Graph g(/*...*/);
//...
boost::tie(begin, end) = out_edges(v,g); //sorry, doesn't work
After reading the documentation more carefully I learned that optional
models pointer behavior. I spelled out how the code might look:
boost::tie(*begin, *end); //sorry, ASSERT  looks too strange

Wow, that looked strange to me. I don't think of begin and end as
pointers at all here. I just want to model values that haven't been
initialized, and I maintain that initialized/unintialized is the
concept worth modeling (I'm not sure what its name ought to be, so for
now I'll just refer to it as the PossiblyUninitialized Concept). Such
a concept might perhpaps embody notions of initialization via
construction or assignment, testing whether the model has been
initialized, etc. It may (or may not) also be true that there is some
use in thinking of pointer/NULL as model of PossiblyUnintialized
variables, but seems to me that the current version of optional has it
backwards: I don't want to model all cases of possibly unininitialized
behavior as OptionalPointees.
So here's my wishlist for an optional-like facility:

  * I want instances to model PossiblyUninitialized (not
OptionalPointee), e.g. optional sans pointer interface.
  * It want to be able to write functions that accept
PossiblyUninitialized variables as parameters. But I want it to be
easy for clients to call such routines with intialized values. That is
I want to write:
 void foo(optionalBar);
 //...
 Bar b(/*details ommitted*/);
 foo(b); // Ok: passing in a valid Bar
 foo(optionalBar()); //Also ok, passing in uninitialized Bar
This was one reason why I speculated that implicit construction might
be useful here.
 * I want to be able to use optional and tie together as in the
beginning of this post or pssibly using some additional syntax:
 tie(begin.uninitialized_ref(), end.uninitialized_ref()) = //...

if I really have to.

It may be that some of these wishes are ill-concevied or
impractical. But the fact that optional models OptionalPointee instead
of something like PossiblyUnitinitialized leaves me looking for
alternatives, especially if that's what is preventing me from having
other items on my wish list.
- Mat
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


[boost] Re: Optional, tie, and iterator_adaptor

2003-08-31 Thread Fernando Cacciola
Daniel Frey wrote:
 Fernando Cacciola wrote:
 My main argument is that if those were allowed, you could write:

 optionalint opt ;
 opt = 1 ;
 int i = *opt ;

 and the assymetry didn't look right to me.

 I agree that this looks wrong. What about this syntax:

 optionalint opt;
 *opt = 3;
 int i = *opt;
 opt-foo();

This was exactly the way the originally submmited optional worked.
I dropped it becasue reviweres thought that (*opt)=3 would lead to
undefined behaviour just as if *opt were an rvalue.
I realized that with true pointers, for instance, (*opt)=3 is in fact
undefined behaviour, so I replace it with .reset()

Fernando Cacciola



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


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

2003-08-31 Thread Brian McNamara
So I completely disagree that optionals should mix the interfaces of
optional and the wrapped object into one.  I think there should be an
explicit unwrapping operation.  But this is just my opinion, based on no
practical evidence/experience, and I'm sure there are trade-offs either
way.  I'll explain the crux of my own reasoning below.

On Sun, Aug 31, 2003 at 11:59:42PM +0800, Joel de Guzman wrote:
 It's really strange (and hard to explain) that you have to dereference
 optionalB. Example:
 
 F(tupleA, optionalB, C args)
 {
 A a = get1(args);
 B b = *get2(args); // strange!
 C c = get3(args);
 }

I don't think it's strange at all; an optionalB is not a B!

 Not only is it strange, it complexifies the code a lot when the code is
 automatically generated by some meta-program. Example:
 
 template class A, class B, class C
 F(tupleA, B, C args)
 {
 A a = get1(args);
 B b = get2(args); 
 C c = get3(args);
 }
 
 Whoops, have to do a special case IFF B is an optional!

Well, no.  B==optionalBprime via template unification, right?
If you want to do something with a Bprime, then yes, you have to
special-case it, as you should.


Here's a (contrived) example of how the implicit conversion breaks 
generic code:

   template class Container
   void contrived( Container c ) {
  c.begin();
   }
   ...
   vectorint v;
   contrived(v);   // fine
   optionalvectorint  ov( v );
   contrived(ov);  // fails

The point is that optionalT is not a T, and most notably, a template
function will never perform the coercion.  Replace the lines like
   B b = get2(args); 
in your example with real calls to, e.g.
   do_something( get2(args) )
and do_something() is likely to fail if it's a template function
(expecting a T and not an optionalT).


As another example, FC++ lists support conversion-to-bool as a test for
NIL:
   fcpp::listint l = NIL;
   if( l )  // if l not empty
  cout  head(l);  // print first element
Clearly if 'l' were an optional, the if test would have a different
meaning.  I know you've been supporting a separate way to do the test
(with ==none), but I think that's completely arbitrary.  The two
issues are both really the same issue, in my mind.  
   

 Of all the types involved in the passing of arguments to the semantic
 actions, the optional doesn't fit nicely because it is the only one
 that has mixed value/pointer semantics. I am tempted to not use
 optionalT because of this and instead use variantT, none,
 but I hate to miss the performance advantage of optional vs.
 variantT, none. 

I have not used variant and know little about it, but I imagine you have
to explicitly tell a variant which type you expect to get out of it.
I think the same is true of optional; the call to operator*() (or
whatever) says I want the T type (rather than the 'none').

My two cents.  Again let me stress I'm arguing based on no practical
experience working with any of these datatypes.

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


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

2003-08-31 Thread Mat Marcus


--On Sunday, August 31, 2003 10:29 AM -0400 Brian McNamara 
[EMAIL PROTECTED] wrote:

On Sun, Aug 31, 2003 at 12:34:39AM -0700, Mat Marcus wrote:
In this post I will put forward a use-case or two to help see
whether something a little different then the current version of
optional might be useful. I also begin making a case that a Concept
like PossiblyUninitializedVariable might be more generally useful
than OptionalPointee. As I mentioned in the post that started this
thread,
...
 std::pairIter, Iter out_edges(Vertex, Graph);
 boost::optionalIter begin, end; //now use optional
 Graph g(/*...*/);
 boost::tie(begin, end) = out_edges(v,g); //sorry, doesn't work
 boost::tie(*begin, *end); //sorry, ASSERT  looks too strange
...

First off, let me say I do think this is a compelling use-case.
(As an aside, this is exactly why people in functional languages love
pattern-matching; it's a general facility for deconstructing data
into its constituents, where each portion is a new, named variable.)
I missed the beginning of this thread, but I imagine the motivation
is to avoid having to say
   std::pairIter,Iter p = out_edges(v,g);
   Iter begin = p.first;
   Iter end   = p.second;
each and every single time you call out_edges().
IIUC, you are saying that you don't find the use of tie with pairs
very compelling. Fair enough. Of course tie is more generically useful
with arbitrary tuples and multi-value returns. I was just trying to
present a small familiar example of such usage.


As I think someone else in the thread mentioned, there has to be
some  explicit call to turn an optionalT into a T, or else the
two interfaces get muddled together.
In general I'm not a fan of implicit conversions or constructors.
However one of my goals is to be able to easily/readably move code
from using raw variables to use PossiblyUnitinitializedVariables
instead. So..
The same would be true of
PossiblyUninitializedVariable.  You've also mentioned that you think
operator*() is inapproprate/ugly for this use.
So, here's an idea for something completely new which maybe helps fit
your requirements.  I start with the motivating example:
   PossUninitVarIter begin, end;
   tie( +begin, +end ) = out_edges(v,g);
   for( Iter i = ~begin; i != ~end; ++i ) ...
(Effectively operator~() fetches the value (or asserts if there is
none),  whereas operator+() returns a reference to the
yet-nonexistent value so it can be filled in by someone else.)
... here I like the + or something like it
begin.reference_to_uninitialized(). That is I don't mind when users
have to be a little more explicit in the dangerous/uncommon case. ~ is
also interesting, although I think that readability suffers. I'd give
up bool conversion and operator! to avoid the need for ~ if that would
reasonably solve the muddling issues. But perhaps there would be too
many other problems -- I haven't explored this deeply yet.

Now here's a (sloppy, partial) summary of the interface, along with
some of the implementation:
   template class T
   struct PossUninitVar {
  PossUninitVar() : init(false) {}
  PossUninitVar( const T x ) : init(true) {
 new (raw_storage) T(x);
  }
  operator bool()  { return init; }
  Proxy operator +()   { return unsafe_get(); }
  T operator~()   { return get(); }
   private:
  bool init;
  Something raw_storage; // array of bytes with right
size/alignment   T get() { if(!init) assert; else /* returns T
from raw storage */ }   Proxy unsafe_get() { return Proxy(this);
}
  class Proxy {
 PossUninitVar* puv;
  public:
 T operator=( const T x ) {
new (puv-raw_storage) T(x);
puv-init = true;
return puv-get();
 }
  };
   };
Hopefully you get the idea.  I think this meets your wish list.
Making tie() interact properly with the Proxy might be hard.
Just some ideas; refine, reject, whatever, as you please...
--
-Brian McNamara ([EMAIL PROTECTED])


Thanks for the ideas, and for your functional programming explanations.

- Mat

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


Re: [boost] Regression test page broken

2003-08-31 Thread Rene Rivera
[2003-08-31] Jeff Garland wrote:

On Sun, 31 Aug 2003 09:59:26 +0200, Martin Wille wrote
 Jeff Garland wrote:
  The regression test page seems to be on a diet
  
  http://boost.sourceforge.net/regression-logs/
 
 You can find some of the other results at
http://boost.sourceforge.net/regression-logs/release
 
 However, I'm not sure wether that is official already.

Thanks, it looks like the main page is better now as well.  When I looked
at
it there were only results for SGI...

SF somehow deleted the contents of the regression-logs directory early
Saturday... I could only restore the empty index itself. But I see new tests
have run already :-)


-- grafik - Don't Assume Anything
-- rrivera (at) acm.org - grafik (at) redshift-software.com
-- 102708583 (at) icq
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


[boost] Any interest in a string literal selector helper library?

2003-08-31 Thread Ehsan Akhgari
Hi all,

I have written a relatively small library which I've found pretty useful
in my own projects.  I have to deal with std::basic_string objects a lot
in my applications, and I almost always write template code so that the
same code works with both std::string and std::wstring types.  The only
problem which cannot be directly solved with existing language construct
is handling string literals.

To make myself clear, the below code will only work for f char ():

 template  typename char_type 
 void f()
 {
  std::basic_string char_type  str( hello );
 }

What is needed here is some facility which selects either hello or
Lhello based upon char_type.  Now, using my library, the above code
can be fixed like this:

 template  typename char_type 
 void g()
 {
  std::basic_string char_type  str( TextAutoSelect( char_type, hello
) );
 }

Nearly all the job is done at compile-time, and the only runtime cost
would be that of a one-line inline function (which can be optimized away
using compiler optimizations, like the VC++ compiler does.)

I would like to know if there is any interest for this tiny library to
be submitted to Boost.

Thanks for your consideration,
-
Ehsan Akhgari

List Owner: [EMAIL PROTECTED]

[ Email: [EMAIL PROTECTED] ]
[ WWW: http://www.beginthread.com/Ehsan ]


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


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

2003-08-31 Thread Joel de Guzman
Daniel Frey [EMAIL PROTECTED] wrote:
 Joel de Guzman wrote:
 Although I don't see this as problematic:
 
 optionalint x;
  if (x)
 foo(x);
 
 Or perhaps:
 
 optionalint x;
  if (!!x)
 foo(x);
 
 We already have an implicit conversion to safe_bool and an
 operator ! anyway. Keep it. There's nothing wrong with it:
 
 operator unspecified-bool-type() const;
 bool operator!() const;
 
 IMHO, there is something terribly wrong here because now optionalT has
 two interfaces. The interface of optional itself and the interface of T.
 If you think that optionalT can be used like T (having the
 value-interface), you are immediately fooled by if(x) as it doesn't
 check T's value. A pointer-interface is much cleaner as it gives the
 user a hint that he is using a wrapper and in practice, I always prefer
 to be a little more explicit on these things (even at the cost of an
 occasional * here and there) than to have silent bugs.

If you really want it to be explicit, the first version, which I prefer
(and you snipped ;-) is so much better:

optionalint x;
 if (x != none)  
foo(x);

Who's fooling who? You said 2 interfaces, the current optionalT is
actually the one with the 2 interfaces. In some ways, it has a value
interface (construction, reset , ==, !=) and pointer interface on some
(*, -, get).

What I am trying very hard to say is to stick to only *ONE* interface
and one concept.

Syntactically, there's nothing inherently wrong with:

if (x)
foo(x);

We see it all the time with ints:

int x;
if (x)
foo(x);

Yet, I have to admit that after thinking about it some more, I realized
an ambiguity when T is bool. Example:

optionalbool x;
if (x)
foo(x);

That is why I really prefer the more explicit syntax:

optionalint x;
 if (x != none)  
foo(x);

A small price to pay, considering the advantages. 1) Unification of
the optional and variant where optionalT -- variantT, none_t.
2) Only one underlying semantics (value-semantics) as opposed to
(sometimes value, sometimes pointer semantics) and 3) Plays well
with generic code (I'll give another use-case in addition to Mat's).

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

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


Re: [boost] Compile problem with Spirit CodeWarrior

2003-08-31 Thread James W. Walker
On Aug 31, 2003, at 7:45 AM, Hartmut Kaiser wrote:

Please have a look at the FAQ here:

http://www.boost.org/libs/spirit/doc/faq.html#scanner_business

This should solve your problem.
Thanks, that helps, but I still have a question or two.  The FAQ says 
it is best to avoid rules as arguments to the parse functions, but 
then what are rules good for?  How else am I going to do any nontrivial 
parsing?

I've been looking at the Spirit article in the C/C++ Users Journal.  It 
contains a code example that defines rule expression, and later says 
if (parse( str, expression, space ).full)...  I supposed that space 
was a typo for space_p.  How do you reconcile that code sample with 
the FAQ?
--
http://www.jwwalker.com/

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


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

2003-08-31 Thread Mat Marcus


--On Sunday, August 31, 2003 1:35 PM -0400 Brian McNamara 
[EMAIL PROTECTED] wrote:

So I completely disagree that optionals should mix the interfaces of
optional and the wrapped object into one.  I think there should be an
explicit unwrapping operation.  But this is just my opinion, based
on no practical evidence/experience, and I'm sure there are
trade-offs either way.  I'll explain the crux of my own reasoning
below.
On Sun, Aug 31, 2003 at 11:59:42PM +0800, Joel de Guzman wrote:
It's really strange (and hard to explain) that you have to
dereference optionalB. Example:
F(tupleA, optionalB, C args)
{
A a = get1(args);
B b = *get2(args); // strange!
C c = get3(args);
}
I don't think it's strange at all; an optionalB is not a B!
That doesn't make it a pointer to B! I think the above code is strange
for two independent reasons. First, as I said before I think that
though pointers may model possibly uninitialized variables, the
converse does not always hold. Second, I think that it might be useful
to treat variables and possibly uninitialized variables uniformly as
much as possible (except where it overly compromises safety). I hold
strongly to the first argument, though I admit that the second one may
not stand up in the end.

Not only is it strange, it complexifies the code a lot when the
code is automatically generated by some meta-program. Example:
template class A, class B, class C
F(tupleA, B, C args)
{
A a = get1(args);
B b = get2(args);
C c = get3(args);
}
Whoops, have to do a special case IFF B is an optional!
Well, no.  B==optionalBprime via template unification, right?
If you want to do something with a Bprime, then yes, you have to
special-case it, as you should.
Here's a (contrived) example of how the implicit conversion breaks
generic code:
   template class Container
   void contrived( Container c ) {
  c.begin();
   }
   ...
   vectorint v;
   contrived(v);   // fine
   optionalvectorint  ov( v );
   contrived(ov);  // fails
The point is that optionalT is not a T, and most notably, a
template function will never perform the coercion.  Replace the
lines likeB b = get2(args);
in your example with real calls to, e.g.
   do_something( get2(args) )
and do_something() is likely to fail if it's a template function
(expecting a T and not an optionalT).
As another example, FC++ lists support conversion-to-bool
There's conversion-to-bool again. I still wonder whether dispensing 
with this would open the door to implicit conversions.

as a test
for NIL:
   fcpp::listint l = NIL;
   if( l )  // if l not empty
  cout  head(l);  // print first element
Clearly if 'l' were an optional, the if test would have a different
meaning.  I know you've been supporting a separate way to do the test
(with ==none), but I think that's completely arbitrary.  The two
issues are both really the same issue, in my mind.
I'm still not clear as to why.



Of all the types involved in the passing of arguments to the
semantic actions, the optional doesn't fit nicely because it is the
only one that has mixed value/pointer semantics. I am tempted to
not use optionalT because of this and instead use variantT,
none, but I hate to miss the performance advantage of optional vs.
variantT, none.
I have not used variant and know little about it, but I imagine you
have to explicitly tell a variant which type you expect to get out
of it. I think the same is true of optional; the call to operator*()
(or whatever) says I want the T type (rather than the 'none').
My two cents.  Again let me stress I'm arguing based on no practical
experience working with any of these datatypes.
--
-Brian McNamara ([EMAIL PROTECTED])
- Mat
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


RE: [boost] Compile problem with Spirit CodeWarrior

2003-08-31 Thread Hartmut Kaiser
James W. Walker wrote:

 Thanks, that helps, but I still have a question or two.  The FAQ says 
 it is best to avoid rules as arguments to the parse functions, but 
 then what are rules good for?  How else am I going to do any 
 nontrivial parsing?

Use grammars (see here:
http://www.boost.org/libs/spirit/doc/grammar.html). This is the best way
to implement non-trivial parsers with Spirit.

 I've been looking at the Spirit article in the C/C++ Users 
 Journal.  It 
 contains a code example that defines rule expression, and 
 later says 
 if (parse( str, expression, space ).full)...  I supposed that space 
 was a typo for space_p.  How do you reconcile that code sample with 
 the FAQ?

The article describes Spirit V1.2 (it was written nearly two years ago).

Spirit has undergone some minor interface changes since then (all
predefined parser objects have a '_p' appended).
Another change was a slight change of the scanner idiom, which lead to
the subtleties you've encountered. Generally the CUJ article is a good
starting point, but nevertheless you should have a look at the current
doc's and, may be, at the samples contained with Spirit.

HTH
Regrads Hartmut


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


[boost] Re: Optional, tie, and iterator_adaptor

2003-08-31 Thread David Abrahams
Joel de Guzman [EMAIL PROTECTED] writes:

 What I am trying very hard to say is to stick to only *ONE* interface
 and one concept.

Optional is a container.  I've never seen a container in C++ which didn't
have both a value interface and an element-access interface.  How do
you propose to achieve that with optional?

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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


[boost] Re: Optional, tie, and iterator_adaptor

2003-08-31 Thread David Abrahams
Joel de Guzman [EMAIL PROTECTED] writes:

 Hi,

 Here's another use-case...

 We are working on an alternative semantic action scheme with Spirit
 that will be a lot more easier to use than the current scheme. With this
 scheme, the signature of the semantic action will be dependent on the
 rule where it is attached to. This is similar in some sense to YACC.
 For instance (I'll write in plain EBNF):

 r ::= a b c

 The attached semantic-action to this rule will have a signature:

 F(tupleA, B, C)

 Another example:

 r ::= a | b | c

 The attached semantic-action to this rule will have a signature:

 F(variantA, B, C)

 Now, unlike YACC, Spirit has iteration (kleene, plus, optional)
 Here's a more or less the complete suite of patterns and the 
 corresponding semantic-action signatures:

 r ::= a b-F(tupleA, B)
 r ::= a | b  -F(variantA, B)
 r ::= a* -F(vectorA)
 r ::= a+ -F(vectorA)
 r ::= a? -F(optionalA)


This is somewhat OT, but I want to suggest you consider something
else.  I did this in a parser generator system I wrote, and it worked
out really well.

If the rule is

   x - a b | c d c 

Then the way you refer to the semantic value associated with the a
symbol is by writing, simply, 'a'.  The way you refer to the semantic
value of the first c symbol is by writing c[0], and you refer to the
2nd one as c[1].  I'm sure you get the idea.

Then the user almost never needs to worry about positional
associations between grammar symbols and their semantic values.  It's
actually fairly rare that the same symbol appears twice on the rhs of
a rule (especially when rules are reduced to eliminate |) and
keeping track of whether it's the first or nth instance of 'X' is much
easier than keeping track of precisely where the Xs fall in the
sequence of symbols.

My system was written in Python, but you might be able to adapt the
general idea to C++.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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


[boost] Re: Boost memory management guidelines

2003-08-31 Thread David Abrahams
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?

 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.

 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.

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.  Just a small example of why I'm
saying it's a harder interface.  Allocator has strange requirements,
like p shall not be null.  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.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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


[boost] Re: [boost.variant] It is possible to make a variantLessThanComparable

2003-08-31 Thread David Abrahams
Peter Dimov [EMAIL PROTECTED] writes:

 David Abrahams wrote:
 Eric Friedman [EMAIL PROTECTED] writes:

 Ultimately, I do not believe any ordering scheme will provide
 meaningful, straightforward semantics. Assuming I am correct, I
 propose that the variant library offer your ordering scheme -- but
 only as an explicit comparison function, calling it variant_less.
 This would allow, for instance:

   std::set my_variant, boost::variant_lessmy_variant 

 I'd appreciate feedback.

 I had the same thought myself, though I'd be inclined to spend a
 little time searching for a better name than less, since it doesn't
 really mean that.  Maybe variant_before, using type_info::before as
 a precedent?

 If you want a second opinion, I'm in the just provide operator== and
 operator camp.

But, IIUC, if operator is not provided, you'd oppose a std::less
specialization, right?

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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


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

2003-08-31 Thread Brian McNamara
On Sun, Aug 31, 2003 at 10:41:15AM -0700, Mat Marcus wrote:
 --On Sunday, August 31, 2003 10:29 AM -0400 Brian McNamara 
 First off, let me say I do think this is a compelling use-case.
...
 I missed the beginning of this thread, but I imagine the motivation
 is to avoid having to say
std::pairIter,Iter p = out_edges(v,g);
Iter begin = p.first;
Iter end   = p.second;
 each and every single time you call out_edges().
 
 IIUC, you are saying that you don't find the use of tie with pairs
 very compelling. Fair enough. Of course tie is more generically useful
 with arbitrary tuples and multi-value returns. I was just trying to
 present a small familiar example of such usage.

Apologies if I was unclear; I _do_ think it's compelling.  The syntactic
convenience of being able to bind multiple names in one expression is
very nice.  (Additionally, if you're doing lots of FP stuff (like me),
it's a real pain when you have to introduce those nasty _statements_
into your code, when you'd really like to do things all in one big
_expression_.  :)  )


 In general I'm not a fan of implicit conversions or constructors.
 However one of my goals is to be able to easily/readably move code
 from using raw variables to use PossiblyUnitinitializedVariables
 instead. So..

I agree that it would be nice for PossiblyUnitinitializedVariables to be
able to be included in existing code with a minimum of fuss.  I think,
perhaps, that that goal is incompatible with avoiding implicit
conversions, though.

 ... here I like the + or something like it
 begin.reference_to_uninitialized(). That is I don't mind when users
 have to be a little more explicit in the dangerous/uncommon case. ~ is

Indeed (make the easy/common things easy, and make the hard/uncommon 
things possible).

 also interesting, although I think that readability suffers. I'd give
 up bool conversion and operator! to avoid the need for ~ if that would
 reasonably solve the muddling issues. But perhaps there would be too
 many other problems -- I haven't explored this deeply yet.

Right; to clarify, I don't think the boolean conversion operator is
interfering with the implicit conversion to T.  Rather I think each is
an instance of implicit conversion, and implicit conversions just
don't work well with templates in general, in my experience.  

I chose '+' and '~' simply because they were the two unary operators
that sprang to mind (that aren't named '*').  Personally I have no
problem with '*'; C++ has a small finite set of operators, and so you
are bound to have to overload the conceptual meanings of some operators
if you want to use them for useful syntax sugar.  The way I see it, the
optional interface using '*' is fine, and I think perhaps what people
object to is the conceptual notion of optional being 'pointer-like'.
The way I choose to see it, optional is just a special kind of
container, which happens to use '*' to get at the value in the
container, and the fact that '*' is also used to dereference pointers
is a mere coincidence of names.

But perhaps other operators (like '+' and '~') or named operations
would be more generally acceptable.  That's fine.  My main point in
joining this discussion was to emphasize that I think there ought to be
an explicit operation to 'get' the value of an optional (as well as to
get the location of raw storage to construct a new value).  What those
operations are named matters much less than simply their existence.

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


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

2003-08-31 Thread Brian McNamara
On Sun, Aug 31, 2003 at 11:11:10AM -0700, Mat Marcus wrote:
 --On Sunday, August 31, 2003 1:35 PM -0400 Brian McNamara 
 On Sun, Aug 31, 2003 at 11:59:42PM +0800, Joel de Guzman wrote:
 It's really strange (and hard to explain) that you have to
 dereference optionalB. Example:
 
 F(tupleA, optionalB, C args)
 {
 A a = get1(args);
 B b = *get2(args); // strange!
 C c = get3(args);
 }
 
 I don't think it's strange at all; an optionalB is not a B!
 
 That doesn't make it a pointer to B!

True.  See my message of a moment ago, where I adopt the notion that
'*' is just an unfortunate coincidence of names, and that any
relationship between optional and pointers is mere happenstance.  (This
all despite the documentation on optional which explicitly describes
the relationship; I am merely trying to present another way of looking
at it which may be useful.)

 As another example, FC++ lists support conversion-to-bool
 
 There's conversion-to-bool again. I still wonder whether dispensing 
 with this would open the door to implicit conversions.

I think no.

I should mention in passing that, while in general I think implicit
conversions are bad news and should be avoided whenever reasonable, I
do think the conversion to bool is an exceptional case, simply because
it is already so deeply ingrained in C++ (and C) language/culture.

(Fortunately bool has a very narrow interface, so it doesn't get us into
too much trouble.  Implicit conversions to user-defined types may create
arbitrary interface conflicts/conceptual ambiguities, and this is where
the real trouble begins.)

-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: [boost.variant] It is possible to make a variantLessThanComparable

2003-08-31 Thread Peter Dimov
David Abrahams wrote:
 Peter Dimov [EMAIL PROTECTED] writes:

 If you want a second opinion, I'm in the just provide operator== and
 operator camp.

 But, IIUC, if operator is not provided, you'd oppose a std::less
 specialization, right?

Right. When there is one and only one strict weak ordering (equality) for a
type, not using operator and operator== because some users might have
different expectations is misguided. It is pretty clear what setvariant or
find(first, last, v) is supposed to do; variant_less or variant_equal is
required boilerplate as Howard says. :-)

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


[boost] Re: lexicographic: review request?

2003-08-31 Thread Jan Langer
Brian McNamara wrote:
The point is, that Jan proposed to add something which has a hidden 
overhead and I'm not sure it's a good idea. Instead of nested 
if-else-cascades, the user could also write:

bool operator( const person lhs, const person rhs )
{
  return
 lhs.lastname != rhs.lastname ? lhs.lastname  rhs.lastname :
 lhs.firstname != rhs.firstname ? lhs.firstname  rhs.firstname :
 lhs.age  rhs.age;
}


I am (re)appearing mid-thread, so I may have missed something along the
way, but...
What's with !=?  I think lexicographical orderings are built only on
the assumptions of operator, yes?  For two objects x and y, if neither
   x  y
nor
   y  x
is true, then they are in the same equivalence class, but this is not
the same thing as equality or inequality.
I just want to make sure the template parameter constraints (or macro
parameter constraints, as the case may be) are the right ones.
you are right. lexicographic only needs the operator  or the functor.

btw. i made some performance checks. for those who are interested the 
code is in lex_performance_test.cpp in the libs/utility/test in the 
sandbox. it just sorts a big vector of int for four criteria.

the outcome is as follows (linux/g++ 3.2.2, release build):
boost::lexicographic, division - 2.11
boost::lexicographic, no division - 1.21
boost::lexicographic emulation, no division - 0.68
if cascade, division - 0.92
if cascade, no division - 0.54
where emulation is the same algorithm as lexicographic, but everything 
is written inline (by hand). and the diference between division and no 
division is as follows.

division:

boost::lexicographic
  (a / 1000, b / 1000)
  (b / 100, a / 100)
  (a / 10, b / 10)
  (b, a)
no division:

boost::lexicographic
  (a, b)
  (b, a)
  (a, b)
  (b, a)
the result makes me think, that the comparison code is in fact not 
really inlined (1.21 with lexicographic to 0.68 with the emulation). and 
my unexperienced look into the assembly code acknowledges this.

maybe someone with a different compiler can run the test.

jan

--
jan langer ... [EMAIL PROTECTED]
pi ist genau drei
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] Re: Boost memory management guidelines

2003-08-31 Thread Peter Dimov
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.

[...]

 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.

___
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


[boost] Re: Re: [boost.variant] It is possible to make a variantLessThanComparable

2003-08-31 Thread Dirk Schreib
Peter Dimov [EMAIL PROTECTED] wrote
 David Abrahams wrote:
  But, IIUC, if operator is not provided, you'd oppose a std::less
  specialization, right?

 Right. When there is one and only one strict weak ordering (equality) for
a
 type, not using operator and operator== because some users might have
 different expectations is misguided. It is pretty clear what setvariant
or
 find(first, last, v) is supposed to do; variant_less or variant_equal is
 required boilerplate as Howard says. :-)

Thanks! Full ACK!

Dirk



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