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

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

First off, let me say I do think this is a compelling use-case.
(As an aside, this is exactly why people in functional languages love
pattern-matching; it's a general facility for deconstructing data
into its constituents, where each portion is a new, named variable.)
I missed the beginning of this thread, but I imagine the motivation
is to avoid having to say
   std::pair<Iter,Iter> p = out_edges(v,g);
   Iter begin = p.first;
   Iter end   = p.second;
each and every single time you call out_edges().

IIUC, you are saying that you don't find the use of tie with pairs very compelling. Fair enough. Of course tie is more generically useful with arbitrary tuples and multi-value returns. I was just trying to present a small familiar example of such usage.



As I think someone else in the thread mentioned, there has to be
some  explicit call to turn an "optional<T>" into a "T", or else the
two interfaces get muddled together.

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

The same would be true of
PossiblyUninitializedVariable.  You've also mentioned that you think
operator*() is inapproprate/ugly for this use.

So, here's an idea for something completely new which maybe helps fit
your requirements.  I start with the motivating example:

   PossUninitVar<Iter> begin, end;
   tie( +begin, +end ) = out_edges(v,g);
   for( Iter i = ~begin; i != ~end; ++i ) ...

(Effectively operator~() fetches the value (or asserts if there is
none),  whereas operator+() returns a reference to the
yet-nonexistent value so it can be filled in by someone else.)

... here I like the + or something like it begin.reference_to_uninitialized(). That is I don't mind when users have to be a little more explicit in the dangerous/uncommon case. ~ is also interesting, although I think that readability suffers. I'd give up bool conversion and operator! to avoid the need for ~ if that would reasonably solve the muddling issues. But perhaps there would be too many other problems -- I haven't explored this deeply yet.


Now here's a (sloppy, partial) summary of the interface, along with
some of the implementation:

   template <class T>
   struct PossUninitVar {
      PossUninitVar() : init(false) {}
      PossUninitVar( const T& x ) : init(true) {
         new (raw_storage) T(x);
      }
      operator bool()      { return init; }
      Proxy operator +()   { return unsafe_get(); }
      T& operator~()       { return get(); }
   private:
      bool init;
      Something raw_storage; // array of bytes with right
size/alignment       T& get() { if(!init) assert; else /* returns T&
from raw storage */ }       Proxy unsafe_get() { return Proxy(this);
}
      class Proxy {
         PossUninitVar* puv;
      public:
         T& operator=( const T& x ) {
            new (puv->raw_storage) T(x);
            puv->init = true;
            return puv->get();
         }
      };
   };

Hopefully you get the idea.  I think this meets your wish list.
Making tie() interact properly with the Proxy might be hard.

Just some ideas; refine, reject, whatever, as you please...
--
-Brian McNamara ([EMAIL PROTECTED])


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

- Mat

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

Reply via email to