ASPN ActiveState Programmer Network
ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups


Recent Messages
List Archives
About the List
List Leaders
Subscription Options

View Subscriptions
Help

View by Topic
ActiveState
.NET Framework
Open Source
Perl
PHP
Python
Tcl
Web Services
XML & XSLT

View by Category
Database
General
SOAP
System Administration
Tools
User Interfaces
Web Programming
XML Programming


MyASPN >> Mail Archive >> boost
boost
[boost] Re: Mini-review request: aligned_storage.hpp
by Itay Maman other posts by this author
Aug 7 2002 7:58AM messages near this date
Re: [boost] Mini-review request: aligned_storage.hpp | Re: [boost] Re: Mini-review request: aligned_storage.hpp
"David Abrahams" <dave@[...].com>  wrote in message
news:06fd01c23dd8$63911d00$62f0fc0c@[...]..
>  From: "Eric Friedman" <ebf@[...].net>
> 
> 
>  >
>  > Additional features of my boost::aligned_storage include:
>  >
>  >  * aligned_storage::swap_as<T> and aligned_storage::assign_as<T> provide
>  > strong exception-safety guarantee
> 
>  If those things are supposed to have the "obvious" semantics, well, I'll
>  believe it when I see it.
> 
>  If you don't know something extra about T it isn't in general possible to
>  produce a strong guarantee swap or assignment.
> 
>  -Dave
> 



Although swap() cannot uphold the no-throw guarantee, it can be made
(strongly) exception safe. Here is a snip from one of the previous versions
of the variant library, without the alignment handling stuff. (Brad King
should be credited for a bug fix).



template<int MaxSize> 
class stack_storage
{

private:
     typedef char[MaxSize] t_buffer;
     t_buffer buf_;

     // Two function pointers
     void (*destroy_func_)(void *p);
     void (*clone_func_)(void *p);

     void clone(void* buf); // Creates a copy of the held value in specified
buffer (via clone_func_)
     void destroy();  // Invokes the destructor (via destroy_func_)

     void* get_ptr(); // Returns a pointer to the internal buffer

public:

      template<typename T> 
      stack_holder(const T& t);   // clone t to buf_ + assign destroy_func_,
clonse_func_

      void swap(stack_storage& other)
      {
         // Very awkward, but safe

         using std::memcpy;

         // Create two copies of the existing values
         t_buffer copy_me;
         memcpy(copy_me, get_ptr(), max_size);

         t_buffer copy_other;
         memcpy(copy_other, other.get_ptr(), max_size);

         t_buffer copy_me_new;
         t_buffer copy_other_new;

         try
         {
            // Clone other into *this
            other.clone(get_ptr());
         }
         catch(...)
         {
            // Undo it
            memcpy(get_ptr(), copy_me, max_size);
            throw;
         }

         // Create a copy of *this new value + restore old value
         memcpy(copy_me_new, get_ptr(), max_size);
         memcpy(get_ptr(), copy_me, max_size);

         try
         {
            // clone *this into other
            clone(other.get_ptr());
         }
         catch(...)
         {
            // Restore *this new value + Undo first clone + restore old
value
            memcpy(get_ptr(), copy_me_new, max_size);
            destroy();
            memcpy(get_ptr(), copy_me, max_size);

            // Undo the second clone (c'tor has failed so a memcpy will do)
            memcpy(other.get_ptr(), copy_other, max_size);
            throw;
         }

         // create a copy of other's new value
         memcpy(copy_other_new, other.get_ptr(), max_size);


         // From now on only non-throwing primitives are used
         // As always, destructors are assumed not to throw

         // Restore old value of *this + destroy it + switch in its new
value
         memcpy(get_ptr(), copy_me, max_size);
         destroy();
         memcpy(get_ptr(), copy_me_new, max_size);

         // Restore old value of other and destroy it
         memcpy(other.get_ptr(), copy_other, max_size);
         other.destroy();

         // Switch in other's new value
         memcpy(other.get_ptr(), copy_other_new, max_size);

        //Handle other data members
       ..
       ..

      }

};




_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Thread:
Fernando Cacciola
Eric Friedman
Fernando Cacciola
Douglas Gregor
Fernando Cacciola
Douglas Gregor
Itay Maman
David Abrahams
Eric Friedman
Itay Maman
Fernando Cacciola
David Abrahams
Eric Friedman
Douglas Gregor

Privacy Policy | Email Opt-out | Feedback | Syndication
© ActiveState Software Inc. All rights reserved