----- Original Message -----
From: "Anthony Williams" <[EMAIL PROTECTED]>
To: "Boost mailing list" <[EMAIL PROTECTED]>
Sent: Thursday, February 13, 2003 7:05 AM
Subject: Re: [boost] 'optional' - request for extension


> Aleksey Gurtovoy writes:
>  >
>  > The following is a sketch of a potential use case for the
newly-accepted and
>  > already very useful 'optional' class.
>  >
I'm glad to see optional<> being already exercised!

>  > Suppose you have a pure RAII guard/locker which unconditionally does
its
>  > job:
>  >
>  >     struct RAII_lock
>  >         : boost::noncopyable
>  >     {
>  >         RAII_lock(entity& e);
>  >         ~RAII_lock();
>  >     };
>  >
>  > and you want to write a semantic equivalent to the following
>  >
>  >     boost::scoped_ptr<RAII_lock> lock( cond ? new RAII_lock(entity) :
0 );
>  >     // ...
>  >
>  > expect for the dynamic allocation part. How would you do it?
>  >
>  > IMO the following seems only natural:
>  >
>  >     boost::optional<RAII_lock> lock( cond, entity );
>  >     // ...
>  >
>  > The only problem with the above is that currently you cannot write
something
>  > like this. It would be nice if we could, IMO.
>  >
>  > Thoughts?
>
OK, I can see the motivation: We can have a noncopyable class
and need an optional object of it.
Following optional semantics, it would be spelled:

boost::optional<RAII_lock> lock;
if ( cond )
  lock.reset( RAII_lock(entity) ) ;

But there is a probem: as William pointed out, reset() _needs_
to use T::T(T const&) in order acquire its own copy of the object;
but in this case is noncopyable, so the above won't compile.


> * Firstly, this would require optional to be able hold
non-copy-constructible
> types, whereas the current requirement say "T must be CopyConstructible".
>
Indeed.

> You could drop the "CopyConstructible" requirement if you said that
> boost::optional<T> is only itself CopyConstructible/Assignable/Swappable
if T
> is CopyConstructible.
Right.

>However, this leaves the question of how to get the
> value in there in the first place; the answer to which is ...
>
With the current implementation it is possible to construct the contained
object in-place.

> * Secondly, you would need a templated constructor to allow T to be
constructed
> using another type.
>
Exactly.
One possibility would be add additional templated ctor and reset that just
forward the arguments to T's contructor
(optional's interface could use a trailing tag to differentiate these).

A problem with this is that the Argument Forwarding problem is burried
into optional's itself.
Another approach would be to create a generic delay-factory object and just
let
optional use it:

Something like:

template<class T, class A0>
struct in_place_factory0
{
  in_place_factory0 ( A0& a0_ ) : a0(a0_) {}

  T* operator() ( void* address ) const { return new (address) T(a0) ; }

  A0& a0 ;
} ;

template<class T, class A0>
in_place_factory0<T,A0> in_place ( A0& a0 ) { return
in_place_factory0<T,A0>(a0) ; }

which requires the following changes in optional<>:

  template<class T>
  class optional
  {
    public :

      ....

      template<class Factory>
      explicit optional ( Factory f )
        :
        m_initialized(false)
      {
        construct_inplace(f);
      }

      ...

    private :

      template<class Factory>
      void construct_inplace ( Factory f )
       {
         f(m_storage.address());
         m_initialized = true ;
       }
  } ;

The above would allow something like this:

optional<RAII_lock> l( in_place<RAII_lock>(entity) );

If the same in-place idiom is used on reset(), the complete
solution will look, following optional<>'s way:

boost::optional<RAII_lock> lock;
if ( cond )
  lock.reset( in_place(entity) );

What do you think?

Fernando Cacciola


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

Reply via email to