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

2003-09-02 Thread Dave Gomboc
[Fernando Cacciola]
> I'm saying that the choice made by variant<> in this regards is to the
> code using get<> as hopeless as undefined behaviour.  I don't think that
> preconditions (and exceptions thereof) should be used to arbitrarily
> make the illusion of giving meaning to an operation that is undefined at
> the conceptual level.

For myself, and I think also for Joel, "nil" is a fully legitimate value,
not a hopeless, meaningless, conceptually undefined value.  It's quite
clear that you don't share this view.  The conceptual divide here is 
surprisingly large.

I'm surprised to find myself suggesting this, but perhaps instead of
debating this issue further I and like-interested people should create and
submit a high-quality implementation of nilable.hpp to Boost.  If
accepted, people could then choose whichever best meets their
needs/expectations.

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: generic uses of optional

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( nilable(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 nilable

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

Dave

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


[boost] Re: generic uses of optional

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 optional 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 nilable can take.  This means that
when we want to write generic code it is sufficient to support nilable:
with an implicit conversion from T to nilable, 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 nilable 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
nilable 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] generic uses of optional

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 optional is not a T, and most notably, a template
> function will never perform the coercion.  Replace the lines like
>B b = get<2>(args); 
> in your example with real calls to, e.g.
>do_something( get<2>(args) )
> and do_something() is likely to fail if it's a template function
> (expecting a T and not an optional).

Okay, you've demonstrated that it may not be possible to drop-in
optional 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 
#include 
#include 


template 
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 
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::vector v;
v.push_back(1);
v.push_back(2);
output(v);

try {

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

nilable< std::vector > nv2;
output(std::vector(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


[boost] Re: Optional, tie, and iterator_adaptor

2003-08-29 Thread Dave Gomboc
> template 
> class nilable {

Was that small enough to be considered not copyrightable, warrantable, etc.
?

If so, fine.  Otherwise I guess I have to disclaim any warranty, etc.  Boost
Public Licence?

Dave

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


[boost] Re: Optional, tie, and iterator_adaptor

2003-08-29 Thread Dave Gomboc
> Right now I am questioning whether the
> pointer-like semantics is worth it to me. I would probably prefer that
> clients type more to test whether a value is initialized so that they
> can type less to call a function that takes an optional as a parameter
> when they have a value to pass in. Sorry if this has already been
> covered, but here my question is: Have you experimented with a variant
> of optional that drops the pointer-like semantics, allowing implicit
> construction and disallowing implicit safe-bool conversion, and if so
> what did you learn that made you favor the current set of tradeoffs?

I've never been comfortable with the pointer-like semantics of optional.  If
you don't need an industrial-strength solution like Fernando's, perhaps
something simple like the below would be sufficient?  (Also, feel free to
suggest improvements.)

Dave

template 
class nilable {

public:

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

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

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

operator T(void) const {
if (nil_) boost::throw_exception(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 
bool
operator! (const nilable & a) {
return (a.nil() || !a.unsafe_reference());
};


template 
bool
operator< (const nilable & a, const nilable & b) {
if (b.nil()) return false;
if (a.nil()) return true;
return (a.unsafe_reference() < b.unsafe_reference());
};


template 
std::ostream &
operator<< (std::ostream & out, const nilable & value) {
if (value.nil()) {
out << "nil";
} else {
out << value.unsafe_reference();
};
};


// TODO: add input from std::istreams.

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


[boost] Fw: boost::filesystem file restrictions

2003-08-15 Thread Dave Gomboc
--> portable_path("/foo/bar") <- throws on Windows
-->
--> Not sure why this would throw, what is the purpose of
--> portable_path? "/foo/bar" is perfectly reasonable on Windows.
->
-> It's perfectly reasonable but it doesn't have a portable meaning.
-> It
-> is a relative path w.r.t. the drive of the current directory.
>
> Almost all paths are relative w.r.t. something, the current users
> filesystem mapping, the computer, the network.
--->
---> I find that somewhat compelling... but in the end it doesn't hold up.
--->
> I don't see how
> leaving out the drive makes it less portable then leaving out the
> computer name.
--->
---> It's less portable because how it is to be interpreted *with respect
---> to the filesystem* can change dynamically.  Remember the name of this
---> library, "filesystem"? ;->
--->
---> Filesystems belong to computers.  A computer's filesystem is accessed
---> via an infinite tree of names (**).  How those names which correspond
---> actual storage are mapped can be modified dynamically in any number of
---> ways: you can have symbolic and hard links, mount drives, remote
---> computers can come online or go away, non-storage devices can be
---> mounted at locations in the tree etc.  The one constant is the
---> structure of the tree of names which allows us to access a virtual
---> location in the filesystem (as opposed to physical).
--->
---> A path is a set of instructions for traversing the name tree.  By any
---> reasonable definition, an absolute path identifies a single virtual
---> location in a filesystem's name tree, not one that can change based on
---> the process state.  A path on windows that starts with '/' is a set
---> of instructions which begins: "go to the root of the current
---> directory path".
-->
-->Correction. It does not mean that. It means go to the root directory of
the
-->current drive. It is still not an absolute path since the current drive
-->changes. If one specified 'a:/', then that is an absolute path as defined
-->under Windows. Even if 'a:' were a removable disk, and thus could be
-->physically changed, it would be considered an absolute path.
->
-> I see you don't perceive changing a removable medium with changing the
-> "state" of the machine (interesting perception of state).
>
> That changes the physical file(s) associated with certain paths, just
> like deleting and creating files or creating symlinks.  It does not
> change where those paths refer to in the filesystem.

I think lack of agreement of a common vocabulary may be hampering the
discussion of boost::filesystem, and that this might stem from different
conceptual notions of what we are speaking of.

For example, while it is possible to think of all drives on an MS Windows
machine as being part of a single filesystem, an individual using NTFS on
C:, FAT32 on D:, FAT16 on E:, and FAT12 on A: reasonably would not.  It is
unquestionable that NTFS and FAT are different filesystems.  Now, one can
choose to use NTFS for both C: and D:, but that does not make C: and D:
together a single filesystem.  On UNIX and UNIX-like systems, it is quite
natural to have multiple drives with possibly different filesystems and to
think of their conglomeration to be a single filesystem, but this is just a
UNIXism.  It is neither natural for members of other communities (MS
Windows, VMS, etc.) to view file access in this manner, nor desirable to
force them to do so.

Other comments (e.g. re: "basename") also served to remind me that this
entire discussion would best have taken place during the Boost review for
the filesystem library.  (Indeed, it would surprise me if "basename" was not
both brought up and criticized during the review, notwithstanding POSIX's
endorsement, but the issue doesn't interest me enough to go and search for
it.  FWIW, I'm happy with root/branch/leaf.)  Mainly I think that if
boost::filesystem was deeply flawed, it would not have been accepted to
Boost.  It is not as if some startling new, unforeseen issues have arisen
that Beman and others had never considered before.  Current usage is clear
and not particularly problematic, so I feel it ought to be left well enough
alone.

As a tangential comment, I agree that boost::filesystem should be favoured
over boost::fs in sample code in the documentation.  I would also suggest
that said documentation should contain the #include lines to include the
library within the documentation's sample code, at least for the very first
example.  Fortunatley, it would appear that at the very least some important
improvements to the documentation have been made (or will be made) as a
result of the discussion.

Apologies in advance if the quote at the top is too long -- I thought it was
best left in here.  On first send, the email was apparently automatically
rejected for this reason, so I altered the quoting characters.

Dave

___
Unsubscribe & othe

[boost] boost::array

2003-08-14 Thread Dave Gomboc
> The problem is that boost::array is not a wrapper around an
> existing array, it IS an array.  This implys making a superfluous
> copy of the array in some cases.
> 
> Given an simple C array, I want a wrapper which will supply an
> iterator interface so that I can do something like.
> 
> const in array{] = {1, 2, 3, 4};
> boost::array ba(array);
> std::copy(ba.begin(), ba.end(), std_ostream_iterator(std::cout));
> 
> Is there already a way to do this?  Or is there some reason why
> one would never want to do this?

AFAICR boost::array allows initialization.  I would try

const boost::array ba = {1, 2, 3, 4};
std::copy(ba.begin(), ba.end(), std_ostream_iterator(std::cout));

Dave

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


[boost] Re: boost::array

2003-08-14 Thread Dave Gomboc
dave> > const in array{] = {1, 2, 3, 4};
dave> > boost::array ba(array);
dave> > std::copy(ba.begin(), ba.end(), std_ostream_iterator(std::cout));
dave> >
dave> > Is there already a way to do this?  Or is there some reason why
dave> > one would never want to do this?
dave>
dave> AFAICR boost::array allows initialization.  I would try
dave>
dave> const boost::array ba = {1, 2, 3, 4};
dave> std::copy(ba.begin(), ba.end(), std_ostream_iterator(std::cout));
> 
> But he doesn't want coping. There's the simple solution
> 
> const int array[] = {1, 2, 3, 4};
> std::copy(array, array + 4, ...);
> 
> and also there's the array_traits in the sandbox.
> 
> However, did he want the exact interface as boost::array? If so, I'd say
> we need a new class called ptr_array that adapts a pointer and a size 
> into an array.

Is this a copy, or an initialization?

> const in array{] = {1, 2, 3, 4};

Is this a copy, or an initialization?

> const boost::array ba = {1, 2, 3, 4};

Dave

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


[boost] RE: Re: Filesystem: create_directories

2003-08-03 Thread Dave Gomboc
> > > > create_directory
> > > > and
> > > > create_directories
> > >
> > > Another option might be: "create_directory_and_parents"
> > > That name is longer than "create_directories" although it better
> > > describes the function.
> >
> > I like "create_directory_path"
> 
> That one's good, and captures the essential distinction well.  Other
> possibles:  "create_full_directory," or "create_rooted_directory."  
> Dunno. On whole, I might prefer your choice.  Although it again 
> lengthens the name, "create_directory_and_path" captures another minor 
> piece of the distinction. You could also play with the distinction (none 
> save semantic in most file systems) between "pathname" and "filename;" a 
> filename is usually just the thing at the leaf-terminal end of the path 
> (and needn't be a "file," save as a directory is often actually 
> implemented as such), while the pathname is the full Monty.
> 
> In the original scheme, I would think the problem with 
> "create_directories" is that it would seem to imply (to me, at any rate) 
> the creation of multiple directories at the same depth in the file 
> system.  Anyway, them's my kibitz's.

Ah, naming again.  My favourite. :-)

I like create_path_and_directory.  I prefer this order of the two terms
because logically the path exists before the directory itself does.

Dave

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


[boost] Re: Re: Re: Formal Review Request: circular_buffer [long]

2003-07-21 Thread Dave Gomboc
> > > > 3. cb_iterator: is the m_end value needed?
> > > >
> > > >It can be computed using 'm_it == m_buff->m_last' in
> > > >those few (~2) places it is needed and if eliminated,
> > > >iterator will get smaller (by 30%) and simpler.
> > >
> > > Yes, the m_end member is needed. Suppose the circular_buffer is full.
> > > Then m_buff->m_first == m_buff->m_last. If there is no m_end variable
> > > how would you recognize that the iterator points to the beginning or
> > > end?
> >
> > 30% is a lot.  Would it make sense to always allocate one extra element,
> > so that this equality can never occur?
>
> 1) This is is not true. The members of the iterator are:
> const Buff* m_buff;
> pointer m_it;
> bool m_end;
>
> At Windows based systems sizeof(m_buff) == 4, sizeof(m_it) == 4 and
sizeof(m_end)
> == 1. It is not 30%.

30% was the number given by another poster.  I merely referenced their
number.

On most 32-bit platforms, including Windows on x86, sizeof(structure with
those 3 fields only) is 12, not 9.  30% is actually somewhat generous,
because it slightly underestimates the relative space allocated due to the
presence of the bool.

> 2) Suppose you are storing elements of size 1000 bytes. By allocating one
more
> extra element ...

To me, this seems significantly less likely than storing elements of size 1,
2, 4, or 8 (values of small concrete types, or pointers to larger types).
Even if you are storing value types of 1000 bytes directly, if you're
allowing space for 1000 of those then the extra kilobyte is still not a big
deal.  I would expect the combination of large-sized type and low permitted
count to be infrequent, and implement accordingly.

However, should that expectation be incorrect, there is likely a way to
represent an empty circular buffer differently by using the value 0 in a
judicious manner somewhere in your code, so that when the equailty is being
tested and holds it is always intpretable as that the buffer is full.  By
such a mechanism the bool would still be avoidable, for the cost of a slight
increase in code complexity.

Dave

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


[boost] boost::signal patch

2003-07-08 Thread Dave Gomboc
At the top of signal.hpp:

namespace boost {
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  namespace BOOST_SIGNALS_NAMESPACE {
namespace detail {
  template
  struct real_get_signal_impl;

MSVC 7.1 complains: warning  C4099:
'boost::signals::detail::real_get_signal_impl<0,T1,T2,T3,T4,T5>'  : type
name first seen using 'struct' now seen using 'class'

at several later points in the same file.  These can all be removed by
changing struct to class in the declaration quoted above.

Dave

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


[boost] minor nitpick: why signal.hpp instead of signals.hpp? (notext)

2003-07-07 Thread Dave Gomboc

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


[boost] regex possible bug

2003-06-28 Thread Dave Gomboc
Thanks for the quick fixes on the other bug reports, John.

Here is what might be a new one.  The code below indicates that no match
was found, but I was expecting it to indicate that a partial match was
found beginning at 'a'.  If I don't push the space on beforehand, I do
get a partial match.  Have I overlooked something?


#include 

#include 
#include 


int main(void) {

typedef char value_type;
typedef std::vector container_type;
typedef container_type::iterator iterator_type;

boost::regex find_this("ab");
container_type search_this;
search_this.push_back(' ');
search_this.push_back('a');

boost::match_results< iterator_type > what_matched;
bool match_found(boost::regex_search(search_this.begin(),
 search_this.end(), what_matched, find_this,
 boost::match_default | boost::match_partial));

if (match_found) {
if (what_matched[0].matched) {
std::cout << "Full match found." << std::endl;
} else {
std::cout << "Partial match found." << std::endl;
};
} else {
std::cout << "No match found." << std::endl;
};

};

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


[boost] regex documentation bug

2003-06-26 Thread Dave Gomboc
http://www.boost.org/libs/regex/template_class_ref.htm#partial_matches

There are two examples given.  Though the examples are different, in
both cases, the "example" links to a complete implementation of the
first example.  This likely was a cut-and-paste error.

Dave

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


[boost] boost::regex opeartor+= bug report

2003-06-24 Thread Dave Gomboc
The file "boost/regex/v4/perl_matcher_non_recursive.hpp" includes
statements such as

end += std::min((unsigned)re_detail::distance(position, last),
desired);

operator+= is appropriate for random-access iterators, but not for
merely bidirectional iterators such as std::list::iterator, which
is what I was using when I came across the problem.  [I don't have a
copy of the C++ standard, but I did check sections 2.3.4, 2.3.5, and
3.1.4 (which is of especial relevance) of Generic Programming and the
STL by Matt Austern.]

I received compilation errors using both g++ 3.3 and intel c++ for linux
7.1, but oddly enough, MSVC 7.1 compiles the code without complaint.
(Non-compliance issue, or superior QoI?)

I believe that consistent use of std::advance would solve the problem.
Or would this change be so costly that I ought to use vector or deque?
Unfortunately, doing so would cause me other problems such as iterator
invalidation. :-/

Dave

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


[boost] Re: Review Request: cyclic_buffer

2003-06-11 Thread Dave Gomboc
--

Date: Thu, 12 Jun 2003 02:36:10 +1000
From: Nigel Stewart <[EMAIL PROTECTED]>
To: [EMAIL PROTECTED]
Subject: [boost] Re: Review Request: cyclic_buffer
Message-ID: <[EMAIL PROTECTED]>
In-Reply-To: <[EMAIL PROTECTED]>
References: <[EMAIL PROTECTED]>
<[EMAIL PROTECTED]> <[EMAIL PROTECTED]>
<[EMAIL PROTECTED]>
<[EMAIL PROTECTED]>
<[EMAIL PROTECTED]> <[EMAIL PROTECTED]>
<[EMAIL PROTECTED]> <[EMAIL PROTECTED]>
Content-Type: text/plain; charset=us-ascii; format=flowed
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Precedence: list
Message: 15


> This strikes me as a good compromise.  For one thing, it leaves the 
> door open to inserting in a manner that resizes the capacity.  (Except 
> for the problem that if the buffer is full, every insert will require O(n) 
> time)

I later realised an important point: insert will be O(n)
anyway, given the need to make room for the inserted items.
So, it seems that allowing automatic resizing in this
case does not cost anything in terms of performence
implications.

Every insert will *not* require O(n) time, unless the implementation is, 
to quote another poster, "brain-damaged".

Is there a compelling use case for a circular buffer that resizes?  Why is
a deque inadequate?  IME circular buffers are constant-sized.

Dave

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


[boost] full cyclic_buffer

2003-06-09 Thread Dave Gomboc
> Instead of dropping elements when the buffer is full, we might also
> consider waiting or throwing a failure.

I consider "dropping elements" to be surprising behaviour.  If there's no
policy stuff, then either decide that it will throw, or leave what happens
to be implementation-defined.

Dave

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


[boost] Re: spirit 1.6 parsing question

2003-03-26 Thread Dave Gomboc
> Spirit-devel mailing list
> [EMAIL PROTECTED]

Thanks, Joel.  I've investigated further, learned something, and posted 
a modified message there.

Dave

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


[boost] spirit 1.6 parsing question

2003-03-26 Thread Dave Gomboc
When I define rules x, y, and z such that

x = ch_p('a');
y = ch_p('a');
z = !x >> y;

it appears to operate the same as if z were defined to be

z = (ch_p('a') | epsilon_p) >> 'a';

which accepts "aa", but rejects "a".


On the other hand, if I define z as

z = (epsilon_p | ch_p('a')) >> 'a'

then "a" is accepted, but "aa" is rejected.


(These are, of course, not the actual rules I am interested in, but a vast
simplification of them, focusing on the point of interest.)

My original expectation had been that first the choice on the left side of
the or operation would be attempted, but when ultimately failing to match
the entire string later on, to then backtrack and attempt matching via the
choice on the right side of the or.  How can I achieve this behaviour?  

In the real problem the semantic actions associated with x and y are
different, but the inputs they match individually have significant
overlap, and where they do overlap, I need y to be matched rather than x.


On a related note, when I defined BOOST_SPIRIT_DEBUG before #including the
core, and specified BOOST_SPIRIT_DEBUG_RULE(test); in my grammar I
received the following error message using g++-3.2.2 on linux-i686:

test_grammar.hpp:45: ISO C++ forbits declaration of `get_node_registry' 
with no type
test_grammar.hpp:45: invalid use of `::'
test_grammar.hpp:45: syntax error before `.' token

Any idea what I might be doing wrong?


Also, please let me know if I should be asking this on a spriit-specific
list rather than boost's.

Thanks,
Dave



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


[boost] Re: boost::optional feature request.

2003-03-25 Thread Dave Gomboc
> It would be nice if boost::optional had operator< defined whenever
> operator< was defined for T.   This would allow us to use optional
> as the key of an associative container.  I suggest the following 
> semantics:
> 
> bool operator<(optional const &x, optional const &y);
> 
> Returns: If y is uninitialized, false.  If  y is initialized and x is
> uninitialized, true.  If x and y are both initialized, (*x < *y).
> 
> This results in a strict weak ordering with uninitialized optional
> objects being sorted first.

Yes, I previously implemented this functionality -- exactly in the manner
you described -- in my nilable implementaton.  It's quite useful to
have.

(If anyone is curious, nilable was inspired by optional, though the
implementation is not derived from optional's.  The main differences are
that nilable doesn't use pointer deferencing for access to the internal
value.  Instead, it provides a direct, checked conversion to T (using
boost::throw_exception with a bad cast error when the object obj is nil),
obj.nil() returning bool, and obj.unsafe_reference() and
obj.unsafe_value() for when one has previously ensured obj.nil() is false
and want to make further accesses without that being tested repeatedly.)

Dave

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


[boost] Re: bad_lexical_cast

2003-03-24 Thread Dave Gomboc
> Even a simple overloading of two functions (if we don't want to
> disturb reference binding) seems to put it in serious trouble:
> 
> 
>   void f(int) { something... }
>   void f(short) { something else... }
> 
>   int main() {
>   int i = 0;
>   f(i);
>   }

int and short do not have an is_base_and_derived relationship.

This thread is getting off-topic, so I'll stop here.

Dave

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


[boost] Re: bad_lexical_cast

2003-03-23 Thread Dave Gomboc
> > Since you advocate elsewhere that exception classes be derived
> > from std::exception, the answer is because otherwise LSP would
> > be violated.
> 
> You can't access the derived class' assignment operator through a
> pointer/reference to a polymorphic base, so that point is moot.

Well, you're the expert on this.  (I thought you could catch a reference
to an exception, dynamic_cast it downwards, then use the assignment
operator.  Sure, this would be a stupid thing to do, but if possible I
certainly can imagine some few misguided souls who haven't yet grokked C++
exception handling doing so.)

> LSP is weird anyway.  What's the point of polymorphism if you're not
> going to change the behavior of the class in some observable way?  If
> the derived class were transparently substitutable for the base class
> it wouldn't be much good, would it?

I disagree here; "transparently substitutable" != "observable behaviour is
identical".

Dave

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


[boost] bad_lexical_cast

2003-03-23 Thread Dave Gomboc
>>>Yes. Since type_info objects can't be copied, one might instead store
>>>pointers or references to them. 
>>
>> Pointers would be better because, for better or for worse (mostly for
>> worse), standard exceptions support assignment as part of their
>> interface.
>
>Why should boost exception classes behave like std:: exception
>classes in this regard?

Since you advocate elsewhere that exception classes be derived from 
std::exception, the answer is because otherwise LSP would be violated.

Dave

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


[boost] spirit documentation bug

2003-03-20 Thread Dave Gomboc
Section "Portability"

> 8. Intel 7.0VisualAge C++ 5.02

should be split into two lines.

Dave

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


[boost] spirit documentation bug

2003-03-20 Thread Dave Gomboc
Page "Subrules":

> ... yields a complex type.  Thus, while it is easy to write:
> 
> int r = i | j >> k;  // where i, j, and k are ints
> 
> Forget rules for a second.  Expression templates...

The sentence seems to be cut off in the middle.  I'm not sure what the
repair should be.

Dave

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


[boost] spirit documentation mini-bug

2003-03-20 Thread Dave Gomboc
The navigation arrows at the bottom of each page do not have textual
aliases for non-graphical browsers (e.g. lynx, or browsers on some WAP
devices).  Other graphics sometimes also do not have textual aliases.

Dave

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


[boost] tracing / logging library

2003-03-18 Thread Dave Gomboc
Just curious if anyone's doing something along these lines.  A quick
google search on boost turned up only Boost.Test, which (I think?) is
something quite different.

Dave

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


[boost] lexical_cast and boost-1.30

2003-03-13 Thread Dave Gomboc
> Here is the current list:
> 
> It looks to me like we should hold the lexical_cast changes until the 
> next release. There are really two issues IIUC - some wide-character 
> support problems and VC++ 6.0 support. While the wide-character problems 
> might be possible to resolve quickly, VC++ 6.0 support is going to take 
> some time to work out. Thus I think we should revert the RC_1_30_0 
> branch and move on.

> I am biased anyway, but I would vote for reverting the lexical_cast 
> changes in RC_1_30_0.

I would vote to fix lexical_cast before release.  I've already been 
waiting months for 1.30 to have the space problem fixed, I really don't 
want to wait months more.  I know that I'm not the only one with this 
problem also.

Frankly, wchar_t support in lexical_cast isn't as important as fixing the
space problem, I'd rather the fix go in even if it regresses in this area
-- unless someone pipes up to say they are actually USING wchar_t and
lexical_cast on a compiler that won't grok the new code.  And if there is
such a person, then I'd appreciate the ugly hack of including both
versions with #ifdefs.

[In general, I do agree with the fellow who recommended bug-fixes-only
after the branch.  I consider the lexical_cast space problem a serious
bug, that's all. ;-]

Dave

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


[boost] lexical_cast(Was: FYI)

2003-03-05 Thread Dave Gomboc
> > Hi,
> > 
> > Yes, the whitespace problem is fixed in the forthcoming version.
> 
> What's "forthcoming version"? Is this forthcoming Boost release?
> Then I don't see any changes to lexical_cast.hpp at all. Or
> lexical_cast update will be committed later?

Yeah, I was aware that work had been done on it, but as of a couple of
days ago CVS had no change to lexical_cast.hpp, which is what prompted me
to write my original query.  Could whoever did the update please commit it
to CVS?

Thanks,
Dave

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


[boost] will lexical_cast improvements be in 1.30.0?

2003-03-03 Thread Dave Gomboc
http://lists.boost.org/MailArchives/boost/msg36221.php references an
improved lexical_cast.  Will it or a similar improvement will be included
in the 1.30 release?  Specifically, I'm looking for point 2: casting
between C-style strings and std::strings that accepts spaces within the
text instead of emitting the bad lexical cast error.

Dave

-- 
Dave Gomboc
M.Sc. Student1-41 Athabasca Hall
Department of Computing Science  Edmonton, Alberta,
University of AlbertaCanada  T6G 2E5


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


[boost] Re: resource manager naming

2003-03-01 Thread Dave Gomboc
> > *laugh*  I was thinking exactly the opposite.  To me, the resource
> > itself 
> > is clear from the template parameter -- it's the management that
> > needs to 
> > be indicated.
> > 
> > +1 for managed<>.
> 
> What template parameter? That's not a part of the name. 
> Template parameters, just like function arguments are never
> a part of the name. You do not need to read the header file
> to get the essence. The name itself should indicate the function
> of the class without looking elsewhere.

It does!  In this case, the function of the template class is to *manage*,
not to "resource".
 
> managed<>? What is managed? ... answer: take a look at
> the template parameter and you'll see what I mean. I'm
> sorry, that doesn't make sense.

I don't understand what doesn't make sense about it.  managed indicates
that T is managed, for whatever T might happen to be.  (If you prefer a
noun, manager suffices.)  This is analogous to optional or list.  
You always have to look at the template parameter to see the type that is
being managed, is considered optional, or that is being held in the list
for any particular instantiation.  By contrast, resource doesn't tell
me anything -- T is always a resource, or it wouldn't exist in my program.

Anyway, if (inexplicably to me) this turns out to be a large bone of
contention, it's probably best to drop back to managed_resource (or
resource_manager), which while wordier will be sufficiently obvious to
all concerned.

Dave

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


[boost] Re: resource manager naming

2003-02-27 Thread Dave Gomboc
> > So then reverse resource_manager and get managed_resource<>, or just
> > managed<>.
> 
> Why not just resource<>? Management is implied anyway; that's the
> reason for the existence of the class.

*laugh*  I was thinking exactly the opposite.  To me, the resource itself
is clear from the template parameter -- it's the management that needs to
be indicated.

+1 for managed<>.

Dave

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


[boost] resource manager naming

2003-02-25 Thread Dave Gomboc
> I would be searching namely for smart_ptr. I know that smart pointer is
> the name for the resource management idiom.
 
But those that don't would look for "resource_manager" or "resource_mgr"  
(and might even find "res_mgr").  The smart_ prefix is quite useless in
this context, there isn't an old resource manager that is being replaced.

Dave

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


[boost] Re: is_class

2003-02-17 Thread Dave Gomboc
> > No, I would prefer
> > 
> > #if BOOST_WORKAROUND(__HP_aCC, <=33900) || 
> > BOOST_WORKAROUND(__VisualAge, <=12345)
> > template  struct enable_if;
> > #else
> > template  struct enable_if;
> > #endif
> > 
> > I already explained the reason: C++ compiler vendors use Boost with
> > BOOST_NO_CONFIG for conformance testing.  I'd rather see broken
> > compilers get fixed than developers forever spending time finding
> > workarounds.
> 
> OK, agreed. Given that we use another approach for static constants,
> what do you think about:
> 
> template< BOOST_UNUSED_TEMPLATE_PARAMETER( bool, cond ),
>   BOOST_UNUSED_TEMPLATE_PARAMETER( typename, T ) >
> struct enable_if;
> 
> Or should we instead replace BOOST_STATIC_CONSTANT by a #ifdef, too? Or
> is BOOST_STATIC_CONSTANT different, probably because there is no "right"
> code and a workaround, but there are two equally good ways to declare
> static constants?

Yes, I think a distinction can be drawn between the declaration of integer
constants and the present issue.

As I was recently reminded in another thread, Boost uses BOOST_NO_... for
all defects, so the name you propose is perhaps not the most suitable.  

The construct itself seems satisfactory, I don't have a firm preference
between the two forms.  Anyway, let's not get stuck in the bicycle shed.  
;-)

Dave

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



[boost] Re: is_class

2003-02-16 Thread Dave Gomboc
> So you would prefer
> 
> #if BOOST_WORKAROUND(__HP_aCC, <= 33900)
> template struct enable_if;
> #elif BOOST_WORKAROUND(__VisualAge, <= 12345) // Dummy values
> template struct enable_if;
> #else
> template struct enable_if;
> #endif
> 
> over
> 
> template struct enable_if;
> 
> If that is the case, then we disagree. Do you have any reason to prefer
> the first version?

No, I would prefer

#if BOOST_WORKAROUND(__HP_aCC, <=33900) || BOOST_WORKAROUND(__VisualAge, 
<=12345)
template  struct enable_if;
#else
template  struct enable_if;
#endif

I already explained the reason: C++ compiler vendors use Boost with
BOOST_NO_CONFIG for conformance testing.  I'd rather see broken compilers
get fixed than developers forever spending time finding workarounds.

Dave

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



[boost] Re: is_class

2003-02-16 Thread Dave Gomboc
> See also the discussion about a "general coding guideline" to "always
> provide a name for template parameters". Here, the maintainer already 
> did the right thing when he received the patch.

If the maintainer hid the compiler brokenness completely, then they did
the wrong thing.  If they didn't, they used an #ifdef (via
BOOST_WORKAROUND).

Dave

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



Re: [boost] Re: Patch for function/function_base.hpp

2003-02-13 Thread Dave Gomboc
> Ah, that's the reason. But given my recent discomfort about
> unmaintainable code, look at it again:
> 
>   #  if BOOST_WORKAROUND(__HP_aCC, <= 33900)
>   template struct enable_if;
>   #  else
>   template struct enable_if;
>   #  endif
> 
> Does this really makes sense? Shouldn't we just keep one version with
> names for template parameters? AFAICS this should work for all compilers
> and it could be a general boost coding guideline to always provide names
> for template parameters. Comments?

Nah, the vendors will never fix problems that we hide.  In some regular
code I might just switch it, but since some vendors _are_ using Boost to
test their compiler conformance, we should leave the HP workaround in (and
use the same or a new workaround for VisualAge also).  That way, when they
compile with BOOST_NO_CONFIG they will see the problem.

Dave

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



[boost] Re: Fix for some Interval library tests

2003-02-08 Thread Dave Gomboc
> > > I suggest adding another boost defect: BOOST_BROKEN_ADL (or similar)
> >
> > How about BOOST_LIBRARY_IMPL_VULNERABLE_TO_ADL?  It's not that the
> > compiler's ADL implementation is broken, it's that the library
> > implementation isn't protected against ADL lookups where it needs
> > to be.
> >
> > Dave
>
> Sorry, but what is adl? (I tried google on this one, but since
> there is a c++ variant called adl, there was a lot of noise).
> I hope I don't misunderstand your sentence: it seems it's not
> the compiler which is broken but the library. So could you
> explain a bit more? We have tried to make the library compliant
> and I don't want to leave such a fault in it.

ADL is "argument dependent lookup", a.k.a. "Koenig lookup".  My original
explanation was ambiguous: it's not your library that is at fault, it is
the implementation of the standard library that the compiler is using that
is defective.

Dave

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



[boost] Fix for some Interval library tests

2003-02-07 Thread Dave Gomboc
> I suggest adding another boost defect: BOOST_BROKEN_ADL (or similar)

How about BOOST_LIBRARY_IMPL_VULNERABLE_TO_ADL?  It's not that the
compiler's ADL implementation is broken, it's that the library
implementation isn't protected against ADL lookups where it needs to be.

Dave

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



[boost] Re: (corrected) review of optional library

2002-12-15 Thread Dave Gomboc
I missed Alberto's post, so I'll reply to this one.

--
Date: Sat, 14 Dec 2002 22:46:27 -0300
From: "Fernando Cacciola" <[EMAIL PROTECTED]>
[snip]
> "Alberto Barbati" <[EMAIL PROTECTED]> escribió en el mensaje
> atf8kh$gvr$[EMAIL PROTECTED]">news:atf8kh$gvr$[EMAIL PROTECTED]...

[some examples snipped]
> > Those are interesting examples! Thanks.
[snip]
> If I can say it, I don't think that they are really good examples.

Sorry, those were from my originally private email to Fernando, I forgot
to review that message more carefully for defects before posting it here.

> > The proposed signature of set::insert is a downgrade and not an
> > improvement. Even if the element is not inserted, I still may want to
> > have the iterator. In order to perform its operation, insert() will
> > have to compute such iterator, so what's the point in discarding it?
> > 
> You're right here.
> The iterator is always valid so it is useful on itself.

Hmm, so it is.  For some reason I use find, then if the find fails, use 
insert with the find as a hint, so I never noticed!

The examples were unrelated to my main point, which I've discussed at 
length elsewhere already.

Dave

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



[boost] Re: (corrected) review of optional library

2002-12-15 Thread Dave Gomboc
> > Conversion from T' to T is straightforward except when the value of
> > type T' is nil.  In this case, the developer may want to throw,
> > default-construct the value of T, or assert.  Template policy choice?
> > (Perhaps that's overkill.)
> >
> As Peter said, default-construct T undermines the whole purpose of 
> optional.  The best is, IMO, to leave it undefined in that case.

Myself, I'd prefer

   int x(5);
   optional y;
   ...
   x = y;

to throw when the assignment happens.  However, sometimes people don't
want that (e.g. those compiling with BOOST_NO_EXCEPTIONS).  In a debug
compile, an assert is possible, but what to do in a release compile?  I
suppose aborting is possible, but highly unfriendly.  Instead, either your
suggestion of leaving the value alone (which means it would be
uninitialized if it hadn't been previously set) or setting it to the
default value make sense to me.  I thought that the latter would give more
consistent behaviour so that it would be easier to debug, but I'm not
wedded to the idea.  I do agree that these other options are undesirable
to the extent that they work against the purpose of optional<>.

That aside, the big issue remains whether people consider the "nil" value
to be truly exceptional, versus it being just another possible value.  I
think that your view is the former, and that this is reflected in your
interface design.  It really does highlight attention on the fact that
there's this "extra" possibility, and that one shouldn't forget to deal
with it.  It's screaming, "Hey!  Don't forget about the nil value!", and I
can understand why you view this as very positive.

It's just as visible from my comments that my view is the latter.  If you
treat nil as just another acceptable value, instead of the absence of one,
then the algebra works completely, and also quite usefully (e.g.  
consider relational algebra).  So why wouldn't I want to do just that?  
"nil" doesn't have to mean 'invalid', or 'uninitialized', or 'danger,
danger' ;-) in any particular circumstance -- of course it _can_ mean
those things, depending on what you're using it for.  But it might simply
mean there was nothing to return, nothing to pass, nothing to inspect,
nothing to whatever.  The asymmetry between the "nil" value and the other
values in the proposed interface really bothers me _because_ to me "nil"
is just "nil", and it's only of specific interest in the same manner that
zero might be of specific interest in some other circumstance.  Sometimes
you want to test for zero, so it's handy to have a shortcut for it, but
much of the time it's just an integer.

I would guess (handwaving alert ;-) that the traditional mechanism for
indicating an "optional" value uses a pointer because that was more
convenient than passing a separate flag alongside the value.  Let's not
forget that this practice predates data structures, never mind
object-orientation -- a pointer is a legacy interface for this job.  Now
that the extra bool can be wrapped and hidden away, there's no longer a
need for pointer-like treatment.  And I'd argue (granted, perhaps
unsuccessfully ) that the interface is counter-productive, because
people won't ever really become comfortable working with "nil-ness" as
long as the interface promotes it as being a special case.

Dave

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



[boost] (corrected) review of optional library

2002-12-12 Thread Dave Gomboc
Adjusted at five points; please ignore the previous one.

-- Forwarded message --
At this point in time, I vote to reject the library.  My vote is based
upon a review of the interface and implementation in optional.hpp of the
zip file I downloaded from the link posted by Fernando on Dec. 12, and
following the discussion via the mailing list digests.  I will qualify my
vote by indicating that this is my first review for boost.

The interface is undergoing a considerable amount of flux during the
review period, and I think that significantly more change is still
required before I would vote for its inclusion.

The operators that (unsuccessfully) attempt to provide pointer semantics
are misleading, and should be removed.  To me, appeals to optional being a
container (or giving it pointer semantics, as if it were an iterator!)  
are misguided.

In my opinion, optional [which perhaps ought to be may_be or
maybe, as an earlier poster suggested, also see below] works best as
denoting a type T', whose assignable values are the legal values for type
T unioned with the value "nil", or "nothing" (as in Haskell).  (It
shouldn't be called "uninitialized", because that would be misleading.  
"nil" is a perfectly valid value for a variable of type T' to take.)

Because "nil" is just another value, operator== can be defined
straightforwardly.  If both are "nil", return true; if exactly one is,
return false; otherwise the normal comparison value is returned.

operator< could be left undefined, but it is simple enough to arbitrarily
choose that "nil" is strictly less than every other value.  I don't see a
downside to this, and it would ensure that T' is a strict weak ordering
whenever T is, which is useful for STL usage.

The operators !=, >, <=, and >= directly follow from definitions of the
above two operators.

Conversion from T' to T is straightforward except when the value of type
T' is nil.  In this case, the developer may want to throw,
default-construct the value of T, or assert.  Template policy choice?  
(Perhaps that's overkill.)

One could possibly provide a test for the nil state by declaring an enum
(in some scope) that defined some (arbitrary) value to "nil", then
providing an operator== that allowed comparisons on that enum type, to
allow code such as:

using boost::may_be;
...

may_be blah(void) {

may_be x(5); // x is constructed to value 5
may_be y;// y is default-constructed to value nil
...
if (y != nil) { ... };
...
x = nil;
...
return std::max(x, y);  // defined since std::less uses operator<
};

It is possible, but not necessarily desirable, to include "is_nil()" or
"is_not_nil()" functions.  operator!() already exists in Fernando's code
as the equivalent to "is_nil()"; a double invocation (e.g. "!!x")  would
be equivalent to "is_not_nil(x)".  I suspect it is probably not worth
fattening the interface for them, but this may be a matter of taste.

(Also, below is a message I had sent to Fernando already, but I suppose it
might as well be sent to boost also.)

Dave


-- Forwarded message --

"Maybe" is a built-in type constructor in Haskell, which AFAIK is the most
widely used functional programming ("FP") language.  It is used to denote
exactly what your suggested optional is.  (Which is why I am
recommending use of "maybe" or "may_be" instead of optional.)


An example in Haskell syntax:

safe_division :: Float -> Float -> Maybe Float
safe_division x y =
if y == 0 then Nothing
  else Just (x/y)


Consider this Haskell declaration:
get_maximum_value :: BTree Int -> Maybe Int

The equivalent (free function) declaration in C++ would be:
may_be get_maximum_value(const BTree &);


Yet another function prototype:

get_cached_value :: a -> [(a, b)] -> Maybe b

which can return Nothing if the function does not have "a" as the first 
item of any of the pairs in the list.


Maybe is defined in Haskell as

data Maybe a = Nothing | Just a   deriving (Eq, Ord, Read, Show)

(here "a" is an arbitrary type; "Nothing" is like "nil", "NULL",
"uninitialized", or whatever you want to call it.)



As an example, currently the C++ standard includes
T & stack::top(), with precondition !(stack.empty()).

Instead, it could be
may_be & stack::top();  // no precondition required


 could be improved also, instead of:
pair set::insert(const value_type & x)

we would use
may_be set::insert(const value_type & x)

where the return value is initialized to the place of insertion if x 
was inserted, or is uninitialized if x was not inserted.


Of course, it is possible to use variables of type may_be:

int blah(int x) {

may_be y;  // default-constructed to uninitialized, right?
.
.
.
// expressions involving y here are okay instead of invalid.
.
.
.
};

(The use as an optional function parameter is no doubt what you had in
mind in the first

[boost] review of optional library

2002-12-12 Thread Dave Gomboc
At this point in time, I vote to reject the library.  My vote is based
upon a review of the interface and implementation in optional.hpp of the
zip file I downloaded from the link posted by Fernando on Dec. 12, and
following the discussion via the mailing list digests.  I will qualify my
vote by indicating that this is my first review for boost.

The interface is undergoing a considerable amount of flux during the
review period, and I think that significantly more change is still
required before I would vote for its inclusion.

The operators that (unsuccessfully) attempt to provide pointer semantics
are misleading, and should be removed.  To me, appeals to optional being a
container (or giving it pointer semantics, as if it were an iterator!)  
are misguided.

In my opinion, optional [which perhaps ought to be may_be or
maybe, as an earlier poster suggested, also see below] works best as
denoting a type T', whose assignable values are the legal values for type
T unioned with the value "nil", or "nothing" (as in Haskell).  (It
shouldn't be called "uninitialized", because that would be misleading.  
"nil" is a perfectly valid value for a variable of type T' to take.)

Because "nil" is just another value, operator== can be defined
straightforwardly.  If both are "nil", return true; if exactly one is,
return false; otherwise the normal comparison value is returned.

operator< could be left undefined, but it is simple enough to arbitrarily
choose that "nil" is strictly less than every other value.  I don't see a
downside to this, and it would ensure that T' is a strict weak ordering
whenever T is, which is useful for STL usage.

The operators !=, >, <=, and >= directly follow from definitions of the
above two operators.

Conversion from T' to T is straightforward except when the value of type
T' is uninitialized.  In this case, you may want to throw,
default-construct the value of T, or assert, depending on what behaviour a
developer wants.  Template policy choice?  (Perhaps that's overkill.)

One could possibly provide a test for the uninitialized state by declaring
an enum (in some scope) that defined some (arbitrary) value to "nil", then
providing an operator== that allowed comparisons on that enum type, to
allow code such as:

using boost::may_be;
...

may_be blah(void) {

may_be x(5); // x is constructed to value 5
may_be y;// y is default-constructed to value nil
...
if (y != nil) { ... };
...
x = nil;
...
return std::max(x, y);  // defined since std::less uses operator<
};

It may (or may not) be desirable to have "is_nil()", or "is_not_nil()".  
operator!() already exists in Fernando's code as the equivalent to
"is_nil()", so a double invocation (e.g. "!!x") would be eqivalent to
"is_not_nil(x)".  So these are not really necessary, and it is unclear to 
me whether it is worth fattening the interface for them.

(Also, below is a message I had sent to Fernando already, but I suppose it
might as well be sent to boost also.)

Dave


-- Forwarded message --

"Maybe" is a built-in type constructor in Haskell, which AFAIK is the most
widely used functional programming ("FP") language.  It is used to denote
exactly what your suggested optional is.  (Which is why I am
recommending use of "maybe" or "may_be" instead of optional.)


An example in Haskell syntax:

safe_division :: Float -> Float -> Maybe Float
safe_division x y =
if y == 0 then Nothing
  else Just (x/y)


Consider this Haskell declaration:
get_maximum_value :: BTree Int -> Maybe Int

The equivalent (free function) declaration in C++ would be:
may_be get_maximum_value(const BTree &);


Yet another function prototype:

get_cached_value :: a -> [(a, b)] -> Maybe b

which can return Nothing if the function does not have "a" as the first 
item of any of the pairs in the list.


Maybe is defined in Haskell as

data Maybe a = Nothing | Just a   deriving (Eq, Ord, Read, Show)

(here "a" is an arbitrary type; "Nothing" is like "nil", "NULL",
"uninitialized", or whatever you want to call it.)



As an example, currently the C++ standard includes
T & stack::top(), with precondition !(stack.empty()).

Instead, it could be
may_be & stack::top();  // no precondition required


 could be improved also, instead of:
pair set::insert(const value_type & x)

we would use
may_be set::insert(const value_type & x)

where the return value is initialized to the place of insertion if x 
was inserted, or is uninitialized if x was not inserted.


Of course, it is possible to use variables of type may_be:

int blah(int x) {

may_be y;  // default-constructed to uninitialized, right?
.
.
.
// expressions involving y here are okay instead of invalid.
.
.
.
};

(The use as an optional function parameter is no doubt what you had in
mind in the first place, and where you got the "optional" name from.)




[boost] Re: Possible Submissions

2002-11-10 Thread Dave Gomboc
> If people are interested I would like to present several possible 
> additions to the Boost library.  I will be willing to answer questions 
> about my code but won't be willing to modify my code to boost standards as 
> I simply don't have the time.

In that case, maybe the best thing to do is contribute them to the boost
sandbox.  Others could then pick up whichever balls they are interested in
and run with them.

I'm not sure exactly how to go about having something added to the 
sandbox, but I'm sure someone else can chip in with that. :-)

Dave

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