Re: [boost] Compile problem with Spirit CodeWarrior

2003-09-01 Thread James W. Walker
On Sunday, August 31, 2003, at 11:29 AM, Hartmut Kaiser wrote:

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

Thanks a lot, that's very helpful.
--
http://www.jwwalker.com/
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


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

2003-09-01 Thread Joel de Guzman
David Abrahams [EMAIL PROTECTED] wrote:
 Joel de Guzman [EMAIL PROTECTED] writes:

 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++.

Hmmm, nice! How does it handle iteration like x - a* and the optional
x - a? 

-- 
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] Re: Optional, tie, and iterator_adaptor

2003-09-01 Thread Joel de Guzman
Brian McNamara [EMAIL PROTECTED] wrote:

 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.)

Perhaps, but we were also taught that operator overloading  may create
arbitrary interface conflicts/conceptual ambiguities, and this is where
the real trouble begins ;-)

That may be true in some (many?) contexts, but it is not definitely universally 
true. As I mentioned in another post, I never had, nor seen, any complaints 
about reference_wrapperT, which incidentally, has an implicit conversion 
to T. ref(var) has been in extensive use by a lot of libraries for many years now.

-- 
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] Re: Optional, tie, and iterator_adaptor

2003-09-01 Thread Joel de Guzman
Brian McNamara [EMAIL PROTECTED] wrote:
 On Sun, Aug 31, 2003 at 10:41:15AM -0700, Mat Marcus wrote:

 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.

It does interfere with the implicit conversion to T. Consider this:

optionalbool o;
if (o) 
foo(o);

If you choose implicit conversion to T (which is debatable), the
implicit conversion to (safe)bool will have to go:

optionalbool o;
if (o != none) 
foo(o);

But I see now that you are against implicit conversions, in general.
Fair enough. FWIW, I never had, nor seen, any complaints about
reference_wrapperT, which incidentally, has an implicit conversion 
to T. In fact, I find the implicit conversion very useful. 

Anyway... at the very least, I wish this is possible:

optionalbool o;
if (o) 
foo(o.get());

But no, here too, we should write:

optionalbool o;
if (o) 
foo(*o.get());

Which goes against existing practice in boost. See reference_wrapper::get,
tuple::get, variant::get, etc.

-- 
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] Re: Optional, tie, and iterator_adaptor

2003-09-01 Thread Brian McNamara
On Mon, Sep 01, 2003 at 09:03:17AM +0800, Joel de Guzman wrote:
 Do it the ref, tuple and variant way:  get().  But get(), as an
 element-access interface, should return a reference, not a pointer, as
 it does currently. 

Clearly I had not been paying enough attention earlier in the thread; I
was oblivious to the fact that get() was returning a pointer and not a
reference.  I think get() (or operator*(), or however it ends up being 
spelled) should indeed return a reference. 

(Apologies for the confusion.)

As for the use-case with the function returning a pair of iterators
that we'd like to assign to optionals via a tie(), I think there
should also be a different method in the interface which returns the
hole in an empty optional where a new value can be constructed.  See,
e.g., my earlier message which defined an interface with operator+()
and operator~().

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


[boost] [Boost-bugs] [ boost-Bugs-798357 ] rational operator canoverflow

2003-09-01 Thread SourceForge.net
Bugs item #798357, was opened at 2003-09-01 02:57
Message generated for change (Tracker Item Submitted) made by Item Submitter
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detailatid=107586aid=798357group_id=7586

Category: None
Group: None
Status: Open
Resolution: None
Priority: 5
Submitted By: Derrick Bass (derrickbass)
Assigned to: Nobody/Anonymous (nobody)
Summary: rational operator can overflow

Initial Comment:
I recently discovered that the operator for the rational 

template is prone to overflow. It is noted in the design 

documentation that some care was taken to prevent 

overflows for most operators, but apparently not for this 

one.



The basic problem comes from the fact that it checks if

n1/d1 is less than n2/d2 by checking if n1 d1  n2 d1. Those 

products can easily overflow.



I suggest an algorithm that first checks the integer parts of 

the quotients. If they are equal, then the algorithm could be 

based on the observation: for n1d1 and n2d2 and 

everything positive and d1d2, then

n1/d1  n2/d2 iff n1/d1  n2-n1/d2-d1.

So if we write d2 = q d1 + r then

n1/d1  n2/d2 iff n1/d1  n2-q n1/r



One would then recursively check this inequality. Obviously, 

a similar observation would have to be made for d2d1.



--

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detailatid=107586aid=798357group_id=7586


---
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
___
Boost-bugs mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/boost-bugs
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


[boost] generic uses of optionalT

2003-09-01 Thread Dave Gomboc
 Here's a (contrived) example of how the implicit conversion breaks 
 generic code:

[example snipped]
 
 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).

Okay, you've demonstrated that it may not be possible to drop-in
optionalT for T with zero code changes when T is not a scalar type.  
(Usually, my Ts are! ;-)  Nonetheless, it is at least still possible to
write generic code that accepts either T or the wrapped T, which is
definitely an improvement over writing a whack of special-casing code.

Dave


// code below compiles, runs cleanly with g++ 3.3 and intel 7.1 on linux

#include exception
#include iostream
#include vector


template typename T
class nilable {

public:

nilable(void) : nil_(true) {};
nilable(const T  value) : value_(value), nil_(false) {};

// rely on default destructor
// rely on default copy constructor
// rely on default assignment operator

bool nil(void) const { return nil_; };

operator T(void) const {
if (nil_) throw std::bad_cast();
return value_;
};

const T  unsafe_reference(void) const { return value_; };
T  unsafe_reference(void) { return value_; };

const T unsafe_value(void) const { return value_; };
T unsafe_value(void) { return value_; };

private:

T value_;
bool nil_;

};


template typename container_type
void output(const container_type  c) {
for (typename container_type::const_iterator
 i(c.begin()); i != c.end(); ++i) {
std::cout  *i  '\n';
};
};


int main(void) {

std::vectorint v;
v.push_back(1);
v.push_back(2);
output(v);

try {

nilable std::vectorint  nv(v);
//output(nv);  // true, this fails
output(std::vectorint(nv));  // but this succeeds!

nilable std::vectorint  nv2;
output(std::vectorint(nv2)); // and this throws as expected.
} catch (std::bad_cast) {
std::cout  Cannot convert from nil to value.\n;
};

};


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


Re: [boost] generic uses of optionalT

2003-09-01 Thread Brian McNamara
On Sun, Aug 31, 2003 at 09:12:59PM -0600, Dave Gomboc wrote:
  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).
 
 Okay, you've demonstrated that it may not be possible to drop-in
 optionalT for T with zero code changes when T is not a scalar type.  
 (Usually, my Ts are! ;-)  Nonetheless, it is at least still possible to
 write generic code that accepts either T or the wrapped T, which is
 definitely an improvement over writing a whack of special-casing code.

Indeed.

[snipped most of code]

 template typename T
 class nilable {
 public:
...
 operator T(void) const {
 if (nil_) throw std::bad_cast();
 return value_;
 };
...

I'd add

  T get() { return T(*this); }   
  // in reality, return T -- using T here just to show the idea

...
 try {
 nilable std::vectorint  nv(v);
 //output(nv);  // true, this fails
 output(std::vectorint(nv));  // but this succeeds!
  
As does

  output( nv.get() );

 nilable std::vectorint  nv2;
 output(std::vectorint(nv2)); // and this throws as expected.

Again I'd prefer

  output( nv2.get() );

I was originally arguing with Joel because I thought he wanted to use
exactly nv and not anything like nv.get().  I think now that we've
cleared up the confusion about get() returning a reference instead of a
pointer, we're all back on the same page.

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


[boost] [BGL] Patch to add buffer parameter to dfs

2003-09-01 Thread Bruce Barr
Here's a patch to depth_first_search.hpp that allows a buffer parameter to be
used with depth_first_search().  I'm also including a patch to
depth_first_search.html to update the documentation.  The patches apply to CVS
revision 1.37 of depth_first_search.hpp, and 1.14 of depth_first_search.html.

The patch allows the named parameter version of depth_first_search() to have an
optional buffer(Buffer S) parameter included among the other named parameters.
 Also, the non-named parameter version allows an additional Buffer S
parameter.

Actually, I was all set to add an overload to depth_first_visit() too, but it
seems that to add another parameter after the func parameter, you'd have to
pass detail::nontruth2() as the value for func.  I'd rather add a Buffer
parameter before TerminatorFunc, but that would screw up other people's code.

The changes are generally patterned after the way the buffer parameter is
handled in breadth_first_search().

I've also create an additional traits class, dfs_buffer_traits, to allow the
user to declare the correct value_type for the buffer.

If no buffer parameter is used, reallocations of the search stack will be
greatly reduced, especially with large graphs.  However, if the user happens to
know in advance that the search depth will not go beyond a certain point,
reallocations can be eliminated by passing in a custom buffer as follows:

template typename T
struct ReserveStack : public std::stackT, std::vectorT  {
  void reserve(size_type size) { c.reserve(size); }
};

int main()
{
  // ...
  typedef dfs_buffer_traitsGraph::value_type BufferValueType;
  typedef ReserveStackBufferValueType StackType;
  const StackType::size_type maxSearchDepth = 100;
  StackType s;
  s.reserve(maxSearchDepth);
  depth_first_search(g, visitor(vis).buffer(s));
  // ...
}

Also, if allocating the entire stack in one block of memory is a bad idea, a
deque-based stack could be used instead:

int main()
{
  // ...
  typedef dfs_buffer_traitsGraph::value_type BufferValueType;
  std::stackBufferValueType s;
  depth_first_search(g, visitor(vis).buffer(s));
  // ...
}

If the user defines BOOST_RECURSIVE_DFS, the older recursive code is used, but
the behavior of the search will have nothing to do with whatever type of Buffer
parameter is passed in.  So, this could be a source of future unexpected
behavior.

The modifications to the HTML file includes the addition of the new parameter,
a reworking the of the starting vertex parameter to match the actual code, and
a few other minor fixes.

Bruce Barr,
schmoost at yahoo.com,
visit ubcomputer.com


__
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com

depth_first_search.hpp.patch
Description: depth_first_search.hpp.patch


depth_first_search.html.patch
Description: depth_first_search.html.patch
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


Re: [boost] generic uses of optionalT

2003-09-01 Thread Joel de Guzman
Brian McNamara [EMAIL PROTECTED] wrote:
 On Sun, Aug 31, 2003 at 09:12:59PM -0600, Dave Gomboc wrote:
 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).
 
 Okay, you've demonstrated that it may not be possible to drop-in
 optionalT for T with zero code changes when T is not a scalar type.
 (Usually, my Ts are! ;-)  Nonetheless, it is at least still possible to
 write generic code that accepts either T or the wrapped T, which is
 definitely an improvement over writing a whack of special-casing code.

Darn! Can't we just overload operator.() operator-dot ?
ahemahemcoughcoughcough ;-)

I want my proxies!

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

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


[boost] Re: [BGL] Missing open delimiter for HTML tag indijkstra_shortest_paths.html

2003-09-01 Thread Vladimir Prus
Janusz Piwowarski wrote:

 Hi,
 
 As in subject: first line, first character.
 

Fixed, thanks!

- Volodya

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


[boost] Re: generic uses of optionalT

2003-09-01 Thread Dave Gomboc
 [Dave Abrahans]
 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?

It darn well shouldn't be a container, it should be a concrete type! ;-)

 [Joel de Guzman]
 One can think of an optionalT as conceptually a specialized but 
 nevertheless, *IS-A* T,  with the added specialization that it can
 be in a dead-uninitialized state. Maybe we'll call it a zombie object,
 undead object, you name it ;-)

Indeed.  However, I suppose I actually have it backwards, because I'm so
used to thinking about T.  We know that the set of states T can take is a
proper subset of the set of states nilableT can take.  This means that
when we want to write generic code it is sufficient to support nilableT:
with an implicit conversion from T to nilableT, support for T directly
will come along for free.  (Or is it not possible to create such an
implicit conversion?)

I've been trying to set things up so that code is written for T that can
then also use nilableT seamlessly, but doing things the other way around
might be an improvement.

 [Brian McNamara]
 I was originally arguing with Joel because I thought he wanted to use
 exactly nv and not anything like nv.get().  I think now that we've
 cleared up the confusion about get() returning a reference instead of a
 pointer, we're all back on the same page.

Well, I guess you're still arguing with me ;-) because I _do_ want to use
exactly nv and not anything like nv.get().  I don't like get() because
I cannot write x.get() when x is a POD.  This would mean I have to support
nilableT and T with different code, which is exactly what I'm trying to
avoid.

I do agree that if there's a get(), it should return by reference.

Dave

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


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

2003-09-01 Thread Eric Friedman
Peter Dimov wrote:
 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. :-)

I'm not sure I agree. If the ordering scheme proposed by Dirk were 'natural'
in some way (as in the case of arithmetic types, std::string, etc.) then I
would offer no objection. But in fact it's quite arbitrary.

While it is true that there is one and only one strict weak ordering for
variant, it is not true IMO that there is one and only reasonable less-than
comparison operation for variant. For instance, in certain contexts, it may
make sense to allow comparison only between same types, returning false
otherwise. In other contexts, it may make sense to allow comparison between
any pair of bounded types of the variant (instead of simply between same
types). Still in other cases, it may be desirable to allow comparison
between a variant and non-variant type.

My point is that different users may reasonably desire differing semantics.
Worse still, I imagine many users will not realize their desired semantics
are not universally desired, and so they may never think to read the docs
for operator(variant,variant).

The absence of such an operator forces the user to read the docs. That's my
argument for boost::variant_before. It requires the user to demonstrate
his/her intent explicitly.

Other than the additional typing (the required boilerplate), are there
other more fundamental objections? (variant in generic contexts, for
instance...?)

Thanks,
Eric



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


[boost] Re: generic uses of optionalT

2003-09-01 Thread Eric Friedman
Dave Gomboc wrote:
[snip]
 I don't like get() because I cannot write x.get() when x is a POD.  This
 would mean I have to support nilableT and T with different code,
 which is exactly what I'm trying to avoid.

Why not overload boost::get again for optional? This would certainly improve
consistency with variant. For instance:

  optionalT opt;
  ...
  T r = boost::getT(opt); // throws bad_get if opt empty
  T* p = boost::getT(opt); // p is null if opt empty

In the same line, we could make optional visitable:

  class my_visitor : public boost::static_visitor {
void operator()(boost::empty) const
{
  ...
}

void operator()(const T operand) const
{
  ...
}
  };

  boost::apply_visitor( my_visitor(), opt );

Support for visitation would also allow seamless integration with the
typeswitch construct I'm working on:

  switch_(opt)
= case_boost::empty( ... )
= case_T( ... )
;

I don't have experience with boost::optional, so I don't know how any of the
above would require changes to its interface or concepts.

My two cents,
Eric



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


Re: [boost] Re: generic uses of optionalT

2003-09-01 Thread Brian McNamara
On Mon, Sep 01, 2003 at 12:13:11AM -0600, Dave Gomboc wrote:
 I've been trying to set things up so that code is written for T that can
 then also use nilableT seamlessly, but doing things the other way around
 might be an improvement.

Agreed.

  [Brian McNamara]
  I was originally arguing with Joel because I thought he wanted to use
  exactly nv and not anything like nv.get().  I think now that we've
  cleared up the confusion about get() returning a reference instead of a
  pointer, we're all back on the same page.
 
 Well, I guess you're still arguing with me ;-) because I _do_ want to use
 exactly nv and not anything like nv.get().  I don't like get() because
 I cannot write x.get() when x is a POD.  This would mean I have to support
 nilableT and T with different code, which is exactly what I'm trying to
 avoid.

This is trivial to fix:

   // Adapters to uniform-ify the interface
   template class T
   nilableT adapt( T x ) { return nilableT(x); }
   
   template class T
   nilableT adapt( nilableT x ) { return x; }

   // generic function
   template class T
   void do_something( nilableT x ) { ... }

   // examples demonstrating how code looks same regardless of type
   do_something( adapt( 3   ) );
   do_something( adapt( nilableint(3) ) );
   do_something( adapt( foo ) );  // foo has unknown type
   
-- 
-Brian McNamara ([EMAIL PROTECTED])
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


[boost] Re: variant questions

2003-09-01 Thread Alexander Nasonov
Eric Friedman wrote:
 But suppose I have a variant v3, with content of a different type (call it
 T3). Then the assignment v1 = v3 is far more complicated (we can't use
 T1::operator=) and, without double storage, far more dangerous. The single
 storage implementation behaves as follows:
 
 destroy v1 content
 copy v3 content into v1

Assuming that memcpy to new location followed by memcpy back to original 
allocation is safe, you would do it using two additional storages local to 
operator= function. Let's call them local1 and local2.

memcpy variant storage containing value1 into local1
initialize variant storage with copy of value3 content (may throw)
memcpy variant storage containing value3 into local2
memcpy local1 back to variant storage
destroy the content of variant storage (value1)
memcpy local2 back to variant storage


If second line of the algorithm above throws then:

memcpy variant storage containing value1 into local1
initialize variant storage with copy of value3 content (throws!)
memcpy local1 back to variant storage


Too complicated? may be ...

-- 
Alexander Nasonov
Remove minus and all between minus and at from my e-mail for timely response


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


[boost] Re: Help requested for Metrowerks workaround

2003-09-01 Thread Eric Friedman
Howard,

Howard Hinnant wrote:
[snip]
 If you will mail me a complete condensed demo, I'll take a look.  I
 downloaded boost 1.30.2 but was unable to find boost/variant.

 -Howard

Thanks for offering your assistance. Variant will make its debut in 1.31.
Thus, you'll need to work from Boost CVS for now.

I haven't been able to isolate the problem, as CodeWarrior generally seems
to handle the overloaded constructors without problems. However, the
attached test file exposes the error.

Thanks again,
Eric


begin 666 test.cpp
M(VEN8VQU94@(F)O;W-T+W9AFEA;G0N:'!P(@T*(VEN8VQU94@(F)O;W-T
M+W1EW0O;6EN:6UA;YH' B#0H-G-TG5C=!U9'0-GL-GT[#0H-FEN
M=!T97-T7VUA:6XH:6YT([EMAIL PROTECTED][EMAIL PROTECTED]@( @='EP961E9B!B
M;V]S=#HZ=F%R:6%N=#QI;G0^(5M8F5D95D7W9AE]T.PT*( @('1Y5D
[EMAIL PROTECTED]W0Z.G9AFEA;G0\=61T+!E;6)E91E9%]V87)[EMAIL PROTECTED]
M#0H-B @(!C;VYS=!I;[EMAIL PROTECTED]5S=%]V86QU92 ](#,[#0H@( @=F%R7W0@
M=F%R*'1EW1?=F%L=64I.R O+R!I;7!L:6-I=!C;VYV97)S:6]N('1O(5M
M8F5D95D7W9AE]T#0H-B @(!E;6)E91E9%]V87)?=[EMAIL PROTECTED]
M=F%R([EMAIL PROTECTED]W0Z.F=E=#QE;6)E91E9%]V87)?=#XH=F%R*3L-B @(!I
M;[EMAIL PROTECTED]:6YT([EMAIL PROTECTED]W0Z.F=E=#QI;G0^*5M8F5D95D7W9A
MBD[#0H-B @(!3T]35%]#2$5#2R@@96UB961D961?:6YT(#T]('1EW1?
[EMAIL PROTECTED]@T*( @(')E='5R;B!B;V]S=#HZ97AI=%]S=6-C97-S.PT*
#?0T*
`
end


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


[boost] Re: variant questions

2003-09-01 Thread Eric Friedman
Alexander Nasonov
 Eric Friedman wrote:
  But suppose I have a variant v3, with content of a different type (call
it
  T3). Then the assignment v1 = v3 is far more complicated (we can't use
  T1::operator=) and, without double storage, far more dangerous. The
single
  storage implementation behaves as follows:
 
  destroy v1 content
  copy v3 content into v1

 Assuming that memcpy to new location followed by memcpy back to original
 allocation is safe, you would do it using two additional storages local to
 operator= function. Let's call them local1 and local2.
[snip]

If I understand you correctly, earlier versions of variant did precisely
what you describe. Unfortunately, the assumption you make is false in
general. See http://aspn.activestate.com/ASPN/Mail/Message/boost/1311813.

Eric



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


[boost] Re: variant questions

2003-09-01 Thread Alexander Nasonov
Eric Friedman wrote:
 If I understand you correctly, earlier versions of variant did precisely
 what you describe. Unfortunately, the assumption you make is false in
 general. See http://aspn.activestate.com/ASPN/Mail/Message/boost/1311813.
 
 Eric

Well, is_polymorphicT based on compiler properties beyond the standrad. 
Why not optimize variant for compilers which safely memcpy forth and back?

-- 
Alexander Nasonov
Remove minus and all between minus and at from my e-mail for timely response

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


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

2003-09-01 Thread Mat Marcus


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

As for the use-case with the function returning a pair of iterators
that we'd like to assign to optionals via a tie(), I think there
should also be a different method in the interface which returns the
hole in an empty optional where a new value can be constructed.
See, e.g., my earlier message which defined an interface with
operator+() and operator~().
I agree that it seems reasonable to have something other then get() 
return the hole. operator+() might be confusing when used with 
optionalint's or other numeric types, so perhaps something like 
unchecked_reference(), or unwrap() or any other non-operator() would 
be best when getting at the hole.

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


Re: [boost] Re: generic uses of optionalT

2003-09-01 Thread Joel de Guzman
Eric! You DA Man!

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



Eric Friedman [EMAIL PROTECTED] wrote:
 Dave Gomboc wrote:
 [snip]
 I don't like get() because I cannot write x.get() when x is a POD.  This
 would mean I have to support nilableT and T with different code,
 which is exactly what I'm trying to avoid.
 
 Why not overload boost::get again for optional? This would certainly improve
 consistency with variant. For instance:
 
   optionalT opt;
   ...
   T r = boost::getT(opt); // throws bad_get if opt empty
   T* p = boost::getT(opt); // p is null if opt empty
 
 In the same line, we could make optional visitable:
 
   class my_visitor : public boost::static_visitor {
 void operator()(boost::empty) const
 {
   ...
 }
 
 void operator()(const T operand) const
 {
   ...
 }
   };
 
   boost::apply_visitor( my_visitor(), opt );
 
 Support for visitation would also allow seamless integration with the
 typeswitch construct I'm working on:
 
   switch_(opt)
 = case_boost::empty( ... )
 = case_T( ... )
 ;
 
 I don't have experience with boost::optional, so I don't know how any of the
 above would require changes to its interface or concepts.

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


[boost] [for Win] [was: Re: 1.30.0-1.30.2: no more thread supportfor Linux?]

2003-09-01 Thread vc
Hi,

I haven't followed this thread completely, but I have a question.
I'm working on Win 2k, and I'm using VC++ 7.1. Building
boost with this toolset, do I need to specify something to make it
thread-safe?

TIA,
Viv

- Original Message -
From: John Maddock [EMAIL PROTECTED]
To: Boost mailing list [EMAIL PROTECTED]
Sent: Sunday, August 31, 2003 12:33 PM
Subject: Re: [boost] Re: 1.30.0-1.30.2: no more thread support for Linux?


   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

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


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

2003-09-01 Thread Peter Dimov
Eric Friedman wrote:
 Peter Dimov wrote:
 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. :-)

 I'm not sure I agree. If the ordering scheme proposed by Dirk were
 'natural' in some way (as in the case of arithmetic types,
 std::string, etc.) then I would offer no objection. But in fact it's
 quite arbitrary.

It's not arbitrary at all. Ask several randomly selected programmers what
operator should do. It is not reasonable to declare the ordering
unnatural just because you don't like it. If there is one ordering, then
this is the natural ordering, whether we like it or not.

 While it is true that there is one and only one strict weak
 ordering for variant, it is not true IMO that there is one and only
 reasonable less-than comparison operation for variant. For instance,
 in certain contexts, it may make sense to allow comparison only
 between same types, returning false otherwise. In other contexts, it
 may make sense to allow comparison between any pair of bounded types
 of the variant (instead of simply between same types). Still in other
 cases, it may be desirable to allow comparison
 between a variant and non-variant type.

 My point is that different users may reasonably desire differing
 semantics. Worse still, I imagine many users will not realize their
 desired semantics are not universally desired, and so they may never
 think to read the docs for operator(variant,variant).

Note heavy speculation. May make sense in certain contexts. May make sense
in other contexts. May be desirable. Users may reasonably desire different
semantics. Have you considered the possibility that, in practice, it/they
perhaps might not?

 The absence of such an operator forces the user to read the docs.
 That's my argument for boost::variant_before. It requires the user to
 demonstrate his/her intent explicitly.

 Other than the additional typing (the required boilerplate), are
 there other more fundamental objections?

The fundamental objection is that you should not penalize the majority
because someone might need different operator semantics. Provide
operator. Wait six months. Collect feedback. If there is evidence that
operator is evil, remove it and document why it is not supplied.

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


Re: [boost] [for Win] [was: Re: 1.30.0-1.30.2: no more threadsupportfor Linux?]

2003-09-01 Thread John Maddock
 I haven't followed this thread completely, but I have a question.
 I'm working on Win 2k, and I'm using VC++ 7.1. Building
 boost with this toolset, do I need to specify something to make it
 thread-safe?

Actually you need to do more than that - you need to compile Boost against
the same runtime library options that you use to build your application -
otherwise you will get linker errors at the very least.  Relevant options
are:

threadingmulti : multithreaded builds
threadingsingle : single threaded builds
runtime-linkdynamic : dynamic runtime
runtime-linkstatic : static runtime.

The default behaviour is to build against the dynamic (and thread safe)
runtime, so if that's what you are using then you're OK, if you want the
static runtime library versions as well then:

bjam -sTOOLS=vc7.1 -sBUILD=debug release threadingmulti/single
runtime-linkstatic

will do the job.

Oh, and to answer your question: Boost is always as thread safe as the
runtime it's built against.

John.


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


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

2003-09-01 Thread John Torjo
Subject: [boost] Any interest in a string literal selector helper library?


 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
 ) );
  }
 
I've done this before as well.
But it's a very simple function.
And I assume TestAutoSelect is a macro.
Can I take a look at the code?

Best,
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-09-01 Thread Alexander Nasonov
David Abrahams wrote:

 Dirk Schreib [EMAIL PROTECTED] writes:
 
 I would like a variant to be LessThanComparable if all
 BoundedTypes are LessThanComparable.

 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 ).

 I assume that the resulting variant class will be StrictWeaklyComparable
 if all
 BoundedTypes are StrictWeaklyComparable.
 
 Sounds like maybe you want dynamic_any.  Have you looked at Alexander
 Nasonov's work?

I would like to emphasize one difference with variant library. User should 
_add_ less operation to the list of supported operations to enable 
operator. This operator isn't enabled by default. This protects from 
undesirable effects because if the user added less I can assume that she 
knows what she's doing. But the problem of different order is still 
persist.

I think we should coordinate our work on variant and dynamic_any library. 
The discussed problem is one point where coordination is needed.

Both libraries work with some set of types by (i) storing value of one 
selected type and (ii) calling some operation for stored value. This is 
done with some differences, though. In assumption that typedefs for variant 
and dynamic_any fixed I can say that:
1. variant operates with _fixed_ set of stored types but with _open_ set of 
supported operations (through static_visitor)
2. dynamic_any has _open_ set of stored type but _fixed_ set of supported 
operations

There is also some differences in operation support. Variant's operation 
looks like:

struct print : static_visitorvoid
{
  std::ostream out_;
  print(std::ostream out) : out_(out) {}

  templateclass T
  void operator()(const T value) const
  {
out_  value;
  }
};

while dynamic_any operation looks like:

struct print : functionprint, void (std::ostream, const anyT)
{
  templateclass T
  void call(std::ostream out, const T value) const
  {
out  value;
  }
};

On one hand, variant uses operator() which is good for anonymous 
operations (obviously, it's not possible for dynamic_any):

variantint, char v(0);

// anonymous function is ok
apply_visitor(v, std::cout  _1);

 // error, attempt to call std::cout  v
for_each(v, v + 1, std::cout  _1);

// ok
for_each(v, v + 1, print(std::cout));

On the other hand, dynamic_any has better support for std algorithms, 
lambda, bind, etc (well, in variant case it's also possible by binding 
apply_visitor):

dynamic_any::anympl::listprint  a(0);

// ok, direct call
print()(std::cout, a);

// ok if result of print doesn't contain anyT (void doesn't)
// otherwise, bindR is required
for_each(a, a + 1, bind(print(), std::cout, _1));

Other advantage of dynamic_any is a possibility to mix normal arguments 
and anyT-based. Due to nature of dynamic_any it's not possible to call the 
operation containing two or more anyT-based arguments for arbitrary 
arguments. Call can be made only if all any arguments hold same type or 
are derived publicly from one type T stored by one any argument.
However, less works fine with arbitrary types because I added 
call_ex/no_call mechanism to the library.
In variant the set of stored types is fixed and all combinations can be 
considered (be careful, it may cause combinatorial explosion):

struct plus : variant::functionplus, variantT (variantT, variantT)
{
  templateclass T1, class T2
  typeof(v1 + v2) call(T1 v1, T2 v2) const
  {
// Note that T1 and T2 are in general
// different (in opposite to dynamic_any)
return v1 + v2;
  }

  templateclass T2
  std::string call(std::string v1, T2 v2) const
  {
return v1 + lexical_caststd::string(v2);
  }

  templateclass T1
  std::string call(T1 v1, std::string v2) const
  {
return lexical_caststd::string(v1) + v2;
  }

  // ...
};


variantstd::string,int,char s(s);
variantstd::string,int,char i(0);

variantstd::string,int,char s0 = plus()(s, i);
// s2 == std::string(s0)

--
Alexander Nasonov
Remove minus and all between minus and at from my e-mail for timely response


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


[boost] adaptable_any vs any_with

2003-09-01 Thread Alexander Nasonov
I'm asking for voting for the new name of dynamic_any. Please, give you 
preference.
Here is my discussion about the name with Kevlin Henney ( and empty prefix 
- Kevlin,  - me)

--- cut ---
 Have you had any more thoughts on an alternative name? Something like
 adaptable_any or extensible_any?

I really don't like the current name and I don't like the fact that  
 namespace has different name.
If I understand meaning of the word, extensible_any is not a right name 
because when you extend operation list you narrow a set of supported types. 

Good point! reducible_any ;-)

Sometimes this set can be so narrow that I doubt about 'any' in name! 
adaptable_any is much better. I like it.

It seemed to be the best of the rest.

Another thought might be to take advantage of the way you might read
what is written. Instead of naming the operation list operation_list,
name it io_operations. Instead of dynamic_any, or even adaptable_any,
use the name any_with. This would give you any_withio_operations,
which reads as a perfectly accurate description in English.

Kevlin

--- end of cut ---

-- 
Alexander Nasonov
Remove minus and all between minus and at from my e-mail for timely response


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


Re: [boost] [for Win] [was: Re: 1.30.0-1.30.2: no morethreadsupportfor Linux?]

2003-09-01 Thread vc
Thanks for your reply.
I've created my own vcproj (VC++ 7.1 project) for building the libs that I
need,
and I've used the /MD flag which is the multithread- and DLL-specific
versions flag (used also for my application),
which means that everything is fine, right?

Thanks a lot,
Viv

- Original Message -
From: John Maddock [EMAIL PROTECTED]
To: Boost mailing list [EMAIL PROTECTED]
Sent: Monday, September 01, 2003 12:13 PM
Subject: Re: [boost] [for Win] [was: Re: 1.30.0-1.30.2: no more
threadsupportfor Linux?]


  I haven't followed this thread completely, but I have a question.
  I'm working on Win 2k, and I'm using VC++ 7.1. Building
  boost with this toolset, do I need to specify something to make it
  thread-safe?

 Actually you need to do more than that - you need to compile Boost against
 the same runtime library options that you use to build your application -
 otherwise you will get linker errors at the very least.  Relevant options
 are:

 threadingmulti : multithreaded builds
 threadingsingle : single threaded builds
 runtime-linkdynamic : dynamic runtime
 runtime-linkstatic : static runtime.

 The default behaviour is to build against the dynamic (and thread safe)
 runtime, so if that's what you are using then you're OK, if you want the
 static runtime library versions as well then:

 bjam -sTOOLS=vc7.1 -sBUILD=debug release threadingmulti/single
 runtime-linkstatic

 will do the job.

 Oh, and to answer your question: Boost is always as thread safe as the
 runtime it's built against.

 John.


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

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


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

2003-09-01 Thread Anthony Williams
Peter Dimov [EMAIL PROTECTED] writes:
 Eric Friedman wrote:
 Peter Dimov wrote:
 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. :-)

 I'm not sure I agree. If the ordering scheme proposed by Dirk were
 'natural' in some way (as in the case of arithmetic types,
 std::string, etc.) then I would offer no objection. But in fact it's
 quite arbitrary.

 It's not arbitrary at all. Ask several randomly selected programmers what
 operator should do. It is not reasonable to declare the ordering
 unnatural just because you don't like it. If there is one ordering, then
 this is the natural ordering, whether we like it or not.

I just started reading this thread, half way through, and so I didn't know
what Doug's proposed ordering was until I looked it up. It turns out that his
ordering is exactly what I assumed it would be --- if the types are different,
then the one which comes first in the list is less than the other; if the
types are the same, compare the values. It seems natural to me.

 My point is that different users may reasonably desire differing
 semantics. Worse still, I imagine many users will not realize their
 desired semantics are not universally desired, and so they may never
 think to read the docs for operator(variant,variant).

 Note heavy speculation. May make sense in certain contexts. May make sense
 in other contexts. May be desirable. Users may reasonably desire different
 semantics. Have you considered the possibility that, in practice, it/they
 perhaps might not?

Indeed, if people need different semantics, they are free to provide a
function; they can even supply it to standard algorithms and containers if
they wish.

 The absence of such an operator forces the user to read the docs.
 That's my argument for boost::variant_before. It requires the user to
 demonstrate his/her intent explicitly.

 Other than the additional typing (the required boilerplate), are
 there other more fundamental objections?

 The fundamental objection is that you should not penalize the majority
 because someone might need different operator semantics. Provide
 operator. Wait six months. Collect feedback. If there is evidence that
 operator is evil, remove it and document why it is not supplied.

I agree with Peter.

Anthony
-- 
Anthony Williams
Senior Software Engineer, Beran Instruments Ltd.
Remove NOSPAM when replying, for timely response.

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


[boost] SourceForge CVS performance upgrade

2003-09-01 Thread Beman Dawes
This hasn't happened yet. Here is what SourceForge says about the upgrade:

The performance increase I spoke of
(600%+ increase) is just days away from being deployed.The new
systems are now in place, additional electrical power has been added to
our colocation cage, and the Linux boxes are in their final stages of
configuration.   Hang in there.  Help is on the way.
--Beman

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


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

2003-09-01 Thread Fernando Cacciola
Joel de Guzman [EMAIL PROTECTED] wrote in message
news:[EMAIL PROTECTED]
 Fernando Cacciola [EMAIL PROTECTED] wrote:
  Hi Mat,
 
  Thanks for the input.
 
  optional is now out on the field and it is the only utility of its kind
  I've ever seen in C++, at least in real use. This has the drawback that there
  is very little experience with it. Therefore,  in a way it is a sort of

 There's a lot of experience with it in other languages. Why not leverage that?
 Haskell::Maybe for instance.

Do you know of anything else besides Haskell?
I don't, and I took the time to investigate Maybe looking at Haskell
programs using it.
As Brian pointed out, it is not so easy to port Maybe to C++ because
its usage is extensively supported by Haskell features that are
not present in C++.
The most fundamental point is that being Haskell a pure functional
language there is no possibly undefined behaviour to worry about,
so Maybe doesn't need to address this issue as optional does.


  experiment, even though it is now a fixed part of Boost.
  optional will evolve, that's for sure, as user's experience show which
  design desicions were right and which were wrong.
  I might even deprecate it and submit a replacement if it becomes clear that a
  drastic change is neccesary.
 
  Right now I still believe that the pointer-like interface is correct, because
  I add it specifically to solve a real problem and it did solve it.
  My first optional (named differently then) had the problem that it was really
  difficult to track which variables were 'optionals' and hence it was easy to
  forget to make the neccesary steps to mantain integrity (not to use an
  uninitialized optional). At some point I realized that I needed something at
  the syntax level that help me keep in mind that those variables are possibly
  uninitialized, and so I moved from value() member functions to operatos * and
  -

 If that's the only rationale for having the pointer-like interface, then pardon
 me but, I find that very flimsy. There should be other means to attack the
 problem (if it is a problem) without sacrificing the beauty of the interface.

I account the possibly undefined behavior of accesing an uninitialized
optional as a real and important problem.

From now on I'll refer to this as the
Possibly Uninitialized Problem: the PU problem in short.

The interface, in one way or another, should address this.

  The pointer-like interface is just about syntax really.
  Instead of opt.value() you type (*opt) or opt-
  This alone shouldn't be a problem.

 Right.

  What I think it is a problem are other design descicions that I made in order
  to make other parts of the interface with the pointer-like interface. Namely,
  the lack of implicit construction and direct assignment.

 Sacrificing this in order to track which variables were 'optionals' ?, IMO,
 is not a good idea.

I agree.


  These two points are raised here by Mat and have been raised by many others
  in the past.
 
  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.

 If optional had value semantics, it would be a lot cleaner:

 optionalint opt;
 opt = 1;
 i = opt;

First of all, let's not confuse syntax with semantics.
optional HAS strict value semantics.

If the choice of 'operators *', 'operator -' and 'get()'
as value accessors makes the appearance that is has pointer
semantics, then it is the documentation that has to be fixed,
not the interface.

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.

Also, let's not think of the pointer-like interface as a unity:
there are three items involved, namely *,- and get().
We'll be better off considering them separately.


Direct initialization: opt = 1
seems right since this operation is never undefined.
This would mirror variant's interface.

Direct value accesing via implicit conversion: int i = opt
seems wrong because this is the operation that can lead to undefined
behaviour.

 For those concerned about trackability, they can use an easy to
 grep alternative:

 optionalint opt;
 opt .reset(1);
 i = opt.get();

Addressing the PU problem via a 'get()' function returning a _reference_
seems right, but OTOH, using operator * seems even better because
the expressions of the form (*a) have a very familiar meaning
and is that meaning _exactly_ what we need here.
But don't let the rest of the optional interface get in the way
of this argument. If we agree that _some_ explicit function/operator
is needed as a value accesor, then in itself, operator* is IMO clearly
the best choice.


  Now I understand that generic uses of optional beg for conventional
  'syntax' for assignment and initialization.

 True!

  I could drop the pointer-like interface but only if replaced by some member
  function that aids to 

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

2003-09-01 Thread Fernando Cacciola
Brian McNamara [EMAIL PROTECTED] wrote in message
news:[EMAIL PROTECTED]
 On Sun, Aug 31, 2003 at 09:58:45AM +0800, Joel de Guzman wrote:
  Fernando Cacciola [EMAIL PROTECTED] wrote:
   Hi Mat,
  
   Thanks for the input.
  
   optional is now out on the field and it is the only utility of its
   kind I've ever seen in C++, at least in real use.  This has the
   drawback that there is very little experience with it.  Therefore, in
 
  There's a lot of experience with it in other languages.  Why not
  leverage that?  Haskell::Maybe for instance.

 I feel like Maybe works more smoothly in Haskell than in C++, but I
 haven't ever really tried to nail down the reasons why.  This thread has
 me thinking about it more, though, so I'll share some general thoughts
 (as well as some suggestions for optional at the end).

 Two issues spring to mind immediately: pattern matching and monads.

 Pattern matching:
 Haskell's Maybe is a type constructor, and thus the value constructors
 Just and Nothing can be used in pattern matches.  Pattern
 matching provides a common way to do the test and the unwrap
 steps.  Code like

optionalint o;
...
if( o )
   do_something( *o );
else
   maybe_do_other();

 in C++ sometimes takes a form like

o :: Maybe int
...
case o of Just x  - doSomething x
  Nothing - maybeDoOther

 in Haskell.  Since this form of using pattern matching to case-ify and
 deconstruct a datatype is a standard idiom in Haskell, nothing special
 needs to be done for Maybe.

 Monads:
 In addition, Maybe forms a monad, which means that you can use
 do-notation to string together computations involving Maybes.  Code like

optionalint x, y, z, result;
...
if( x ) {
   y = foo( *x );
   if( y ) {
  z = bar( *x, *y );
  if( z )
 result = baz( *x, *y, *z );
  else
 result.reset();  // being more explicit than I have to be
   }
   else
  result.reset();
}
else
   result.reset();

 can be written as

x, y, z, result :: Maybe int
...
do x - x
   y - foo x
   z - bar x y
   result - baz x y z
   return result

 in Haskell, which uses the Monad's bind operation to sugarize over all
 the if-then-else plumbing to push Nothings all the way through the
 computation.  In FC++, we have monad comprehensions, so it could be
 written as just

maybeint x;
...
fcomp_mmaybe_m()[ baz[X,Y,Z] | X = x,
 Y = foo[X],
 Z = bar[X,Y] ]

 Comprehensions are unlikely to be used much in normal C++ code, though.


 In any case, I suppose my point with both of those issues is that
 Haskell already has some kind of standard/idiomatic way to sugarize over
 the details of dealing with Maybes.  I don't think we have anything
 equivalent in C++, so it's not clear to me what we can learn from
 Haskell when trying to design the interface for optional in C++.

Hi Brian,
thanks fot the input.
I've reach a similar conclusion when I looked at Maybe for inspiration.



 Offhand, the pointer interface for reading the value of an optional
 seems good to me.  Being able to say

optionalint x;
...
if( x )  foo( *x );

 seems like a natural way to sugarize this in C++.

Great!
That's for I think too.

 As for the constructors, why not have a separate function for
 initializing optionals, a la Just/Nothing in Haskell?  I am imagining
 something like this:

template class T
class optional {
   optional(); // or maybe public, depending on preference
   optional( const T );   // private
public:
   optional( const optional );// still copyable,
   optional operator=( const optional ); // assignable
   ... operator bool ... operator*
};
template class T
optionalT just( const T );   // the constructor (a friend)

 Then you no longer have the issue of

optionalint x(3);
int r = *x;
optionalint y = 4;
r = *y;

 looking funny or unbalanced, because now it's

optionalint x( just(3) );
int r = *x;
optionalint y = just(4);
r = *y;

 and the just balances out the *, in a way.

 (This is similar to what we do with maybeT in FC++, though we don't
 have the op-bool/op-* sugar for reading maybes.  In FC++, the constant
 NOTHING can also be used to initialize an empty maybe.)


I'm not so sure anymore if the unbalance really needs to be addressed.
Solutions like the one you propose above do certainly add 'purity'
to the interface, but OTOH makes it harder to use.

I stress as fundamental the fact that initialization and assignment is
always defined, so I'm not sure if special syntax is really needed since
there is nothing to protect against.
Sure, the concept may be confusing _at first_, but once the user learns it,
she can leverage the power of a terser syntax.

So in this regard I prefer the variant way:
support implicit 

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

2003-09-01 Thread Fernando Cacciola

Joel de Guzman [EMAIL PROTECTED] wrote in message
news:[EMAIL PROTECTED]
 Brian McNamara [EMAIL PROTECTED] wrote:

  Offhand, the pointer interface for reading the value of an optional
  seems good to me.  Being able to say
 
 optionalint x;
 ...
 if( x )  foo( *x );
 
  seems like a natural way to sugarize this in C++.

 IMO, this is better:

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

 Although I don't see this as problematic:

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

 Or perhaps:

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


I see the implicit value access (in foo(x)) as problematic for the reasons I gave 
before.

 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;

Yes, I think this should be kept.
There is a special section on the documention dealing with the specific case of 
optionalbool
just in order to support these _very_ idiomatic operations.

 Perhaps it's just me, but I really dislike the * syntax. Why make optional
 pretend that it is a pointer when it's clearly not! Then, we go on and give
 it value semantics! C'mon!

The * syntax is not supposed to make optional pretend it is a pointer.
It is clearly not and the documentation says so quite clearly, I think.
And if it doesn't, then it is the documentation that needs to be fixed.

Fernando Cacciola





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


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

2003-09-01 Thread Joel de Guzman
Fernando Cacciola [EMAIL PROTECTED] wrote:

 First of all, let's not confuse syntax with semantics.
 optional HAS strict value semantics.

No it does not. The accessors have pointer behavior!

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

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


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

2003-09-01 Thread Fernando Cacciola
Joel de Guzman [EMAIL PROTECTED] wrote in message
news:[EMAIL PROTECTED]
 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);


safe_bool conversion wasn't part of the original submision.
I was against it for the reasons you give, but at some point I
was conviced that the expressive power of the highly idiomatic
implicit boolean evaluation was worth it.
So many objects provide boolean evaluation through implicit
conversion that it is nowaday the most common interface for
this operation.


 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's wrong operators * and -?
Iterators use them, and they're not pointers.

If the problem is that it makes optional appear as a pointer,
then it is the documentation job to avoid it.


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

How does the presence of operator* and - makes two interfaces?

optional has only one interface and one concept.

It just happen to use the ubiquitous * and - syntax to express
the same notion that is expressed through those operators when they're
used with pointers and iterators, but this doesn't mean that
optional pretends to be a pointer or an iterator.


 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);


Implicit safe_bool was supported becasue it is extremely idiomatic.

 A small price to pay, considering the advantages. 1) Unification of
 the optional and variant where optionalT -- variantT, none_t.

variant doesn't support implicit conversion to any of its bounded types.
It does support implicit construction and direct assignment, as I've
proposed for optional at my first post in this thread.

variant has get() as a value accessor.
optional has operator*() with the same semantic
(forget about optional's get() now)


 2) Only one underlying semantics (value-semantics) as opposed to
 (sometimes value, sometimes pointer semantics)

There is just one underlying semantic in optional: value semantics.

 and 3) Plays well
 with generic code (I'll give another use-case in addition to Mat's).

This can be addressed by fixing optional::get() to return a reference
instead of a pointer.
(more on this on another post)

Fernando Cacciola




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


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

2003-09-01 Thread Joel de Guzman
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. 

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

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


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

2003-09-01 Thread Fernando Cacciola
Brian McNamara [EMAIL PROTECTED] wrote in message
news:[EMAIL PROTECTED]
 On Mon, Sep 01, 2003 at 09:03:17AM +0800, Joel de Guzman wrote:
  Do it the ref, tuple and variant way:  get().  But get(), as an
  element-access interface, should return a reference, not a pointer, as
  it does currently.

 Clearly I had not been paying enough attention earlier in the thread; I
 was oblivious to the fact that get() was returning a pointer and not a
 reference.  I think get() (or operator*(), or however it ends up being
 spelled) should indeed return a reference.

operator*() does indeed return a reference, and I agree that operator get()
should too.

Anyway, there is a pragmetic advantage in having a function return a
pointer. It allow us to mix test+access with one call, as in:

if ( T* p = opt.get() )

but this functionality can be provided but a separate methods called
get_ptr() given the expected meaning of a method named get() for
something that is a value container.

Fernando Cacciola




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


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

2003-09-01 Thread Joel de Guzman
Fernando Cacciola [EMAIL PROTECTED] wrote:
 Joel de Guzman [EMAIL PROTECTED] wrote in message

 There's a lot of experience with it in other languages. Why not leverage
 that? Haskell::Maybe for instance.
 
 Do you know of anything else besides Haskell?

No.

 I don't, and I took the time to investigate Maybe looking at Haskell
 programs using it.
 As Brian pointed out, it is not so easy to port Maybe to C++ because
 its usage is extensively supported by Haskell features that are
 not present in C++.
 The most fundamental point is that being Haskell a pure functional
 language there is no possibly undefined behaviour to worry about,
 so Maybe doesn't need to address this issue as optional does.

Agreed.

-- 
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] Re: Re: Optional, tie, and iterator_adaptor

2003-09-01 Thread Joel de Guzman
Fernando Cacciola [EMAIL PROTECTED] wrote:
 Joel de Guzman [EMAIL PROTECTED] wrote in message

 Direct initialization: opt = 1
 seems right since this operation is never undefined.
 This would mirror variant's interface.

Ok.

 Direct value accesing via implicit conversion: int i = opt
 seems wrong because this is the operation that can lead to undefined
 behaviour.

Doesn't have to be undefined behaviour. Aren't you throwing an
exception or something? variant throws throws a bad_get exception
when you get a reference to a T which is not the held type. I don't see
a problem why you can't do something similar.

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

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


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

2003-09-01 Thread Fernando Cacciola
Mat Marcus [EMAIL PROTECTED] wrote in message
news:[EMAIL PROTECTED]
 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.

 [snip use case]

FWIW, your use case of pretty common to me.
I've used optional precisely as you did many times.
In fact, I often found mayself adding optional to a local
variable just because the flow changed and now the variable
may reach a point being uninitialized.

 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); file://sorry, ASSERT  looks too strange

 Wow, that looked strange to me. I don't think of begin and end as
 pointers at all here.

Right, they're not pointers and you shouldn't see them as such.

I think that your report is very important because it shows me
that while one may expect the need for special constructs in order
to 'access' an optional value, such need isn't there when one
wants to initialize or assign an optional.
It was very reasonable to expect optional to work with tie as
that is just assignment and assignment is always defined.

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).

I agree here.

 Such
 a concept might perhpaps embody notions of initialization via
 construction or assignment, testing whether the model has been
 initialized, etc.

Right.

 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.

I think that OptionalPointee's documentation failed its purpose.
That concept is intended to be exactly what you proposed,
except that I left initialization/assignment aside.

The concept just explains that the operator * and - syntax
is used to access the a value that is possibly uninitialized,
WITHOUT implying that a model of this concept IS a pointer.
The concept was invented precisely to allow the same
syntax to be used with entities that are NOT pointers.

The particular choice of operators is to allow pointers to be
models of the concept.

Perhaps it is the name which is misleading. It can be renamed as
PossiblyUninitialized if that helps.
And it should incorporate initialization and assignment.

Anyway, both concepts are 'conceptually' the same.

Fernando Cacciola




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


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

2003-09-01 Thread Fernando Cacciola
Brian McNamara [EMAIL PROTECTED] wrote in message
news:[EMAIL PROTECTED]
 On Sun, Aug 31, 2003 at 12:34:39AM -0700, Mat Marcus wrote:
 [snipped]

 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.)


My original submission used a proxy operator*() to allow assignment in
the same way you do here with operator+().
During the review I removed it because if expressions (*opt)
implied possibly undefined behaviour when used a rvalues so should
when used as lvalues. Yet assignment is always defined so
be changed it by reset().
It didn't ocurred to me though to use _another_ operator
instead, and so allow the definitely useful lvalue expressions.

Right now however, I'm inclined toward direct assignment,
ala variant, because the only problem with this is the
potential conceptual confusion (since this operation is always
defined), and I prefer to address this problem at the
documentation level.

Fernando Cacciola




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


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

2003-09-01 Thread Fernando Cacciola
Brian McNamara [EMAIL PROTECTED] wrote in message
news:[EMAIL PROTECTED]
 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.

In a way you're right.
My original optional submision followed this rule.
safe-bool was added because of the ubiquitousness of the
implicit boolean evaluation idiom.

Implicit construction and direct assignment was left out
precisely in order to keep both interfaces separated.


 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!

Right.
Just like any XYZB is not an B, so the middle line should have
the cannonical form:

XYZB b = get2(args).get();

Therefore, it is optional::get() that needs to be fixed, not optional::operator*(),
and not adding an implicit conversion to T.

Fernando Cacciola




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


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

2003-09-01 Thread Fernando Cacciola
Joel de Guzman [EMAIL PROTECTED] wrote in message
news:[EMAIL PROTECTED]
 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.

 One can think of an optionalT as conceptually a specialized but
 nevertheless, *IS-A* T,  with the added specialization that it can
 be in a dead-uninitialized state. Maybe we'll call it a zombie object,
 undead object, you name it ;-)

Theoretically, yes.
But there are practical barries here.

Unfortunately, in C++ subclassing is the only subtying mechanism,
but you can't subclass a non class type, so you can't subtype
an arbitrary T.
IOWs, there is no way to completely implement an optionalT which
*IS A* T.

The closer we could get is to have an implicit ctor and and implicit
conversion to T, but that would only take us half the way, so there
is little practical sense in approaching the problem this way.

  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!

 Even if I agree with you that an optionalT should not be a T,
 an optionalT is definitely not a pointer to T.

Definitely!
If HTML had blinking banners I think I'd use one to state this :-)

Yet iterators are not pointers either but they do use
operators * and -


  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').

 Right. In fact, looking at it more closely, I *could* almost agree with you
 that an optionalT is not a T. There is in fact a getter function (get).
 In fact all three (tuple, optional and variant) have a get function. That's
 fine, yet, here again, the optional does not jive well because it returns
 access *by pointer* whereas both tuple and variant return access by
 reference.

This get() issue we agree should be fixed.

Fernando Cacciola




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


[boost] Re: generic uses of optionalT

2003-09-01 Thread Fernando Cacciola
Eric Friedman [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED]
 Dave Gomboc wrote:
 [snip]
  I don't like get() because I cannot write x.get() when x is a POD.  This
  would mean I have to support nilableT and T with different code,
  which is exactly what I'm trying to avoid.

 Why not overload boost::get again for optional? This would certainly improve
 consistency with variant. For instance:

This was my intention from the very beginning.
I was just waiting for variant to be out there.


 In the same line, we could make optional visitable:

And so about this.

Fernando Cacciola




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


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

2003-09-01 Thread Mat Marcus


--On Monday, September 01, 2003 2:57 PM -0300 Fernando Cacciola 
[EMAIL PROTECTED] wrote:

Mat Marcus [EMAIL PROTECTED] wrote in message
[snip]

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); file://sorry, ASSERT  looks too strange

Wow, that looked strange to me. I don't think of begin and end as
pointers at all here.
Right, they're not pointers and you shouldn't see them as such.

I think that your report is very important because it shows me
that while one may expect the need for special constructs in order
to 'access' an optional value, such need isn't there when one
wants to initialize or assign an optional.
It was very reasonable to expect optional to work with tie as
that is just assignment and assignment is always defined.
Yes, it seems like optional is just the sum (disjoint union) of nil 
and T, so why not allow implicit construction and assignment from T. 
Of course, I realize that there may be technical obstacles to getting 
optional to work transparently with tie in this way(doesn't tie 
normally create a tuple of references?).

[snip]

I think that OptionalPointee's documentation failed its purpose.
That concept is intended to be exactly what you proposed,
except that I left initialization/assignment aside.
The concept just explains that the operator * and - syntax
is used to access the a value that is possibly uninitialized,
WITHOUT implying that a model of this concept IS a pointer.
The concept was invented precisely to allow the same
syntax to be used with entities that are NOT pointers.
The particular choice of operators is to allow pointers to be
models of the concept.
Perhaps it is the name which is misleading. It can be renamed as
PossiblyUninitialized if that helps.
OptionalPointee is a bit misleading for me. Also I work in a group 
that is ultimately responsible for transferring our technology to the 
product teams, so I need to be able be convince others that my code 
will be maintainable. I will probably choose to avoid the pointer-like 
operator interface since I think it makes optional harder to 
use/explain. I'm not sure that PossiblyUninitialized is the best name 
for the concept, but it works a bit better for me since it's more 
about Optional and less about (the arguably distracting) Pointee.

And it should incorporate initialization and assignment.
[snip]

Great. This should definitely help with my use cases. I'm still 
curious whether there will be a recipe to use optional with tie. And 
if there is such a recipe I wonder whether pointer will still be a 
model of the Concept.

- Mat

P.S. Doesn't ML have offer an option type? Haven't had a chance to 
look into this yet.

___
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


[boost] Reducing template compile-times

2003-09-01 Thread Brian McNamara
Template libraries, especially those employing expression templates,
take a long time to compile.  As an example, one of the example files
for FC++ (parser.cpp) takes about 10 minutes to compile on a blazingly
fast machine with tons of RAM.

I would like to reduce the compile-time.  I solicit any help/advice on
the topic; I am hoping some of the Boost contributors will have run into
this same problem with their own libraries, and have found some ways to
address it.


Here is what I have already figured out.

First off, in FC++, there are a number of templates whose sole purpose
is to provide better compiler diagnostics (along the same general lines
as concept_checks).  I rewrote the library code so that these checks
are only enabled when a certain preprocessor flag is defined.  Turning
off these checks reduced the compile-time of parser.cpp from 10 minutes
to 8 minutes--a significant speedup.

That was the most obvious piece of low-hanging fruit; since the code
to produce the compile-time diagnostics doesn't do anything at run-time,
it was straightforward to just have a switch to turn it on and off.

I imagine there are other things I can do to rewrite some of the
library templates that are doing real work so that they compile
faster.  Specifically, I imagine that some templates can be rewritten so
that they cause fewer auxiliary templates to be instantiated each time
the main template gets instantiated.

However there are two issues that make this hard to do:

  (1) Knowing which templates to focus on.  That is, which templates
  are effectively the inner loops in the compilation process, and
  thus deserve the most attention when it comes to optimizing
  them?

  (2) Knowing how to rewrite templates to make them faster.  I imagine
  that fewer templates instantiated will mean faster compile
  times, but I don't actually know this for sure.  I have no
  window into what the compiler is actually doing, to know what
  takes so long.  Maybe it's the template instantiation process;
  maybe it's all the inlining; maybe it's the code generation for
  lots of tiny functions.  I don't know.

I have made some headway with (1): the unix utility nm lists all the
symbols compiled into an executable program, and by parsing the output,
I am able to determine which templates have been instantiated with the
most number of different types.  My little script yields output like
...
313  boost::fcpp::lambda_impl::exp::Value
314  boost::fcpp::lambda_impl::BracketCallable
606  boost::fcpp::lambda_impl::exp::CONS
609  boost::fcpp::full1
610  boost::intrusive_ptr
670  boost::fcpp::lambda_impl::exp::Call
which tells me that the Call template class has been instantiated 670
different ways in parser.cpp.  This at least gives me some idea of
which classes to focus my optimizing attention on.  However a drawback
of using the nm approach is that it only shows templates with
run-time storage.  There are tons of template classes which contain
nothing but typedefs, and I imagine they're being instantiated lots of
ways too, and I don't know if this slows stuff down significantly too.

As to (2), I know nothing, other than the speculation that fewer
instantiations is better.

So, that's where I am.  Help!  :)

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


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

2003-09-01 Thread Joel de Guzman
Fernando Cacciola [EMAIL PROTECTED] wrote:

 Even if I agree with you that an optionalT should not be a T,
 an optionalT is definitely not a pointer to T.
 
 Definitely!
 If HTML had blinking banners I think I'd use one to state this :-)

Nor should it model a pointer. That was my point and the point
of others who dislike *opt.

 Yet iterators are not pointers either but they do use
 operators * and -

Iterators are not pointers, but they model the pointer.

 Right. In fact, looking at it more closely, I *could* almost agree with you
 that an optionalT is not a T. There is in fact a getter function (get).
 In fact all three (tuple, optional and variant) have a get function. That's
 fine, yet, here again, the optional does not jive well because it returns
 access *by pointer* whereas both tuple and variant return access by
 reference.
 
 This get() issue we agree should be fixed.

Agreed. If there's a way to get at the values through a generic get
function that unifies the access of optional with variant such that I
can think of optional as an optimized specialization of variantT, none,
I would be very happy. With such an interface, I can simply ignore
the pointer-like interface, if you wish to keep it ;-)

Thanks you very much! And BTW, kudos for such a well engineered
library! Spirit has been using it since v1.7 and I am very happy with
it. The comments I gave so far are merely my opinion. You are of
course free to have your own preferences :-)

Keep up the good work!

Regards,
-- 
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] Re: Re: Optional, tie, and iterator_adaptor

2003-09-01 Thread Joel de Guzman
Gregory Colvin [EMAIL PROTECTED] wrote:
 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);

No, because the model is half-baked, which is exactly the reason
for my dislike. 

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

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


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

2003-09-01 Thread Fernando Cacciola
Joel de Guzman [EMAIL PROTECTED] wrote in message
news:[EMAIL PROTECTED]
 Fernando Cacciola [EMAIL PROTECTED] wrote:
  Joel de Guzman [EMAIL PROTECTED] wrote in message


  Direct value accesing via implicit conversion: int i = opt
  seems wrong because this is the operation that can lead to undefined
  behaviour.

 Doesn't have to be undefined behaviour.

Yes it does.
Accesing a value that isn't there is by all means undefined behaviour.

  Aren't you throwing an
 exception or something?

This doesn't define the access value operation.
It just defines the function that is used to implement it.
But defining such a call doesn't help much from the POV of the
operation.
i.e., you cannot get the value if it isn't there and an exception
here is no better at it than a core dump.

Therefore, the operation is flaged as possibly undefined.
Whether to detect and throw, or assert, or do nothing is QoI issue.
If optional were to be someday standarized, implementators
would decide how to deal with the undefined behaviour here.

variant throws throws a bad_get exception
 when you get a reference to a T which is not the held type. I don't see
 a problem why you can't do something similar.

Doing something similar as an implementation detail is fine.
Currently, I use BOOST_ASSERT, which allows the end user
to control how to deal with it.

Doing it as part of the interface, that is, contracting that
accesing an uninitialized optional throws an exception
has performance and portability problems.

In most typical usages, you don't really need a runtime check to get
always in the way of getting the value.
In fact, the pointer like syntax is there precisely to help
you be confident that an explicit check is not needed
since the access syntax lends itself to well written code
were uninitialized access is properly guarded in the
client code, allowing you to leverage the speed of unguarded
access while giving you at the same time the idiomatic
power of a familiar syntax to access possibly uninitialized
values.

Fernando Cacciola




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


[boost] Re: Boost memory management guidelines

2003-09-01 Thread David Abrahams
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.

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

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


[boost] Re: xml library

2003-09-01 Thread Nicholas Mongeau
 I've just uploaded the preliminary version of my XML library to Yahoo
files
 section as xml_library.zip. Comments are welcome.


I think it's very nice, and I can already think of some code that could be
made much clearer using this...



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


[boost] Re: Reducing template compile-times

2003-09-01 Thread David Abrahams
Brian McNamara [EMAIL PROTECTED] writes:

 Template libraries, especially those employing expression templates,
 take a long time to compile.  As an example, one of the example files
 for FC++ (parser.cpp) takes about 10 minutes to compile on a blazingly
 fast machine with tons of RAM.

Which compiler?  Have you seen
http://users.rcn.com/abrahams/instantiation_speed/index.html?

 I would like to reduce the compile-time.  I solicit any help/advice on
 the topic

Switching compilers may be your best bet.

 I am hoping some of the Boost contributors will have run into this
 same problem with their own libraries, and have found some ways to
 address it.

Generally speaking, the key is to reduce the number of template
instantiations, but it's also a good idea to eliminate unused
computations... avoid traits blob templates since all the nested
definitions need to be evaluated if you want to use just one; use
mpl::apply_if and logical operators and_/or_ to avoid needless
evaluations.

 Here is what I have already figured out.

 First off, in FC++, there are a number of templates whose sole
 purpose is to provide better compiler diagnostics (along the same
 general lines as concept_checks).  I rewrote the library code so
 that these checks are only enabled when a certain preprocessor flag
 is defined.  Turning off these checks reduced the compile-time of
 parser.cpp from 10 minutes to 8 minutes--a significant speedup.

 That was the most obvious piece of low-hanging fruit; since the
 code to produce the compile-time diagnostics doesn't do anything at
 run-time, it was straightforward to just have a switch to turn it on
 and off.

 I imagine there are other things I can do to rewrite some of the
 library templates that are doing real work so that they compile
 faster.  Specifically, I imagine that some templates can be
 rewritten so that they cause fewer auxiliary templates to be
 instantiated each time the main template gets instantiated.

Good plan.  On all but the most-recent EDG compilers the nestedness
of symbol names generated may have a significant impact on compile
times.

 However there are two issues that make this hard to do:

   (1) Knowing which templates to focus on.  That is, which templates
   are effectively the inner loops in the compilation process, and
   thus deserve the most attention when it comes to optimizing
   them?

Heh.  Welcome to the black box of C++ metaprogramming.

   (2) Knowing how to rewrite templates to make them faster.  I imagine
   that fewer templates instantiated will mean faster compile
   times, but I don't actually know this for sure.  I have no
   window into what the compiler is actually doing, to know what
   takes so long.  Maybe it's the template instantiation process;
   maybe it's all the inlining; maybe it's the code generation for
   lots of tiny functions.  I don't know.

Yep, it's a nasty problem.  I suggest some experimentation.

 I have made some headway with (1): the unix utility nm lists all the
 symbols compiled into an executable program, and by parsing the output,
 I am able to determine which templates have been instantiated with the
 most number of different types.  My little script yields output like
 ...
 313  boost::fcpp::lambda_impl::exp::Value
 314  boost::fcpp::lambda_impl::BracketCallable
 606  boost::fcpp::lambda_impl::exp::CONS
 609  boost::fcpp::full1
 610  boost::intrusive_ptr
 670  boost::fcpp::lambda_impl::exp::Call
 which tells me that the Call template class has been instantiated 670
 different ways in parser.cpp.  This at least gives me some idea of
 which classes to focus my optimizing attention on.  However a drawback
 of using the nm approach is that it only shows templates with
 run-time storage.  There are tons of template classes which contain
 nothing but typedefs, and I imagine they're being instantiated lots of
 ways too, and I don't know if this slows stuff down significantly too.

It does; see the link at the top of my reply.

Also, if you're using something called CONS you're probably also using
hand-rolled metaprograms.  MPL contains some interesting techniques
designed to reduce the stress on compilers (e.g. compile-time
recursion unrolling, lazy evaluation); you might try using the
high-level interface of MPL to see if it improves things.

 As to (2), I know nothing, other than the speculation that fewer
 instantiations is better.

 So, that's where I am.  Help!  :)

You're on the right track.

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

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


[boost] Re: Re: Deprecation/removal of libraries

2003-09-01 Thread Daniel Frey
On Thu, 28 Aug 2003 16:19:24 +0200, Douglas Gregor wrote:

 On Thursday 28 August 2003 08:20 am, Daniel Frey wrote:
 utility/tie was moved to tuple, so should we remove the obsolete
 docs/references in utility now?
 
 Please do.

Done. I also updated the Revisited ..., but there is some checksum in
the HTML-source. I have no clue what it's good for, so if I broke it,
please fix it and tell me how to avoid it next time :o)

Regards, Daniel

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


[boost] Re: variant questions

2003-09-01 Thread Eric Friedman
Alexander Nasonov wrote:
 Eric Friedman wrote:
  If I understand you correctly, earlier versions of variant did precisely
  what you describe. Unfortunately, the assumption you make is false in
  general. See
http://aspn.activestate.com/ASPN/Mail/Message/boost/1311813.
 
  Eric

 Well, is_polymorphicT based on compiler properties beyond the standrad.
 Why not optimize variant for compilers which safely memcpy forth and back?

I'm not sure how we would know... It seems to be a very bad idea to simply
guess.

Plus, for compilers where it is in fact not allowed, we still need a
workable, defined solution.

Eric



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


[boost] Re: generic uses of optionalT

2003-09-01 Thread Dave Gomboc
[Eric Friedman]
 Why not overload boost::get again for optional?

It might be a good idea for other reasons, but it doesn't solve the problem
I'm trying to solve.

[Brian McNamara]
do_something( adapt( 3   ) );
do_something( adapt( nilableint(3) ) );
do_something( adapt( foo ) );  // foo has unknown type

But I'd like to write
do_something(3);
do_something(foo);  // of type T
do_something(bar);  // of type nilableT

Can I have my cake and eat it too? ;-)

Dave

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


[boost] Re: optional, tie, and iterator_adaptor

2003-09-01 Thread Dave Gomboc
[Fernando Cacciola]
 The most fundamental point is that being Haskell a pure functional
 language there is no possibly undefined behaviour to worry about,
 so Maybe doesn't need to address this issue as optional does.
... and later ...
 I account the possibly undefined behavior of accesing an uninitialized
 optional as a real and important problem.

You can get rid of the possibly undefined behaviour by defining it!  Throw
an exception when there's an attempted coercion from nil/undefined to a
normal value.

[Fernando Cacciola]
 First of all, let's not confuse syntax with semantics.
 optional HAS strict value semantics.

 If the choice of 'operators *', 'operator -' and 'get()'
 as value accessors makes the appearance that is has pointer
 semantics, then it is the documentation that has to be fixed,
 not the interface.
.. and later ...
 The * syntax is not supposed to make optional pretend it is a pointer.
 It is clearly not and the documentation says so quite clearly, I think.
 And if it doesn't, then it is the documentation that needs to be fixed.

No, the interface should be changed, because it _looks_ like it has pointer
semantics.  If the semantics of optional can be clear before reading the
documentation then they should be.  Face it, it's wishful thinking to assume
that documentation will solve the problem.

[Fernando Cacciola]
 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.

But they are iterators, and random-access iterators exhibit pointer
semantics.  That's the reason iterators use operator* and operator- in the
first place!

Dave

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


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

2003-09-01 Thread Fernando Cacciola
Joel de Guzman [EMAIL PROTECTED] wrote in message
news:[EMAIL PROTECTED]
 Fernando Cacciola [EMAIL PROTECTED] wrote:

  Even if I agree with you that an optionalT should not be a T,
  an optionalT is definitely not a pointer to T.
 
  Definitely!
  If HTML had blinking banners I think I'd use one to state this :-)

 Nor should it model a pointer.

It tries not to model a pointer at least.

The OptionalPointee concept was coined to stress this fact,
by formalizing the syntatic meaning of operators * and -
independently of pointers.

What I'm defending here is the idea of giving operators * and -
a meaning on their own: the possibly undefined value of its operands.

That this choice of operators still makes the appearance that optional
models a pointer I need to address on the documentation by a better
formalization of the concept.

 That was my point and the point of others who dislike *opt.


  Yet iterators are not pointers either but they do use
  operators * and -

 Iterators are not pointers, but they model the pointer.

  Right. In fact, looking at it more closely, I *could* almost agree with you
  that an optionalT is not a T. There is in fact a getter function (get).
  In fact all three (tuple, optional and variant) have a get function. That's
  fine, yet, here again, the optional does not jive well because it returns
  access *by pointer* whereas both tuple and variant return access by
  reference.
 
  This get() issue we agree should be fixed.

 Agreed. If there's a way to get at the values through a generic get
 function that unifies the access of optional with variant such that I
 can think of optional as an optimized specialization of variantT, none,
 I would be very happy. With such an interface, I can simply ignore
 the pointer-like interface, if you wish to keep it ;-)

All right, we're settled then!


 Thanks you very much! And BTW, kudos for such a well engineered
 library! Spirit has been using it since v1.7 and I am very happy with
 it. The comments I gave so far are merely my opinion. You are of
 course free to have your own preferences :-)

 Keep up the good work!

Thank you!

Fernando Cacciola




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