Boost logo

Boost :

Subject: Re: [boost] [utility] auto_buffer v2
From: John Bytheway (jbytheway+boost_at_[hidden])
Date: 2009-03-07 13:52:22


Thorsten Ottosen wrote:
> Hereby an updated class. Thanks to all who contributed with comments to
> the first try.

Thanks for persisting :).

> I have made the following changes:
>
> 2. added swap() (boy, was this nasty to implement).

I see what you mean! I hadn't quite understood your implementation; I
had assumed that you continued to use the stack space when extending to
the heap. The fact that you don't makes swapping more complex.

Your current implementation assumes default-constructibility of T (when
T is not trivially assignable). For example, the following won't compile:

#include "auto_buffer.hpp"

class T {
  public:
    T(int) {}
    T& operator=(T) { return *this; }
  private:
    T();
};

int main()
{
  boost::auto_buffer<T> a, b;
  swap(a, b);
  return 0;
}

Changes such as the diff below should fix it (I also had to add a couple
of #includes to make it compile).

However, this change could make certain swaps slower. For example, if T
is a std::vector or suchlike which can be much more expensive to copy
than to default construct and swap.

I'm not sure if there's an implementation which gets the best of both
worlds (without resorting to move semantics).

--- auto_buffer-1.hpp 2009-03-07 18:09:33.000000000 +0000
+++ auto_buffer.hpp 2009-03-07 18:26:31.000000000 +0000
@@ -6,6 +6,8 @@
 #ifndef BOOST_UTILITY_AUTO_BUFFER_HPP_25_02_2009
 #define BOOST_UTILITY_AUTO_BUFFER_HPP_25_02_2009

+#include <boost/detail/workaround.hpp>
+
 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
 # pragma once
 #endif
@@ -16,6 +18,7 @@
 #endif

 #include <boost/assert.hpp>
+#include <boost/throw_exception.hpp>
 #include <boost/iterator/reverse_iterator.hpp>
 #include <boost/mpl/if.hpp>
 #include <boost/multi_index/detail/scope_guard.hpp>
@@ -288,11 +291,12 @@
             auto_buffer* smallest = l.size_ == min_size ? &l : &r;
             auto_buffer* largest = smallest == &l ? &r : &l;

- for( unsigned i = 0u; i < diff; ++i )
- smallest->unchecked_push_back();
-
- for( size_type i = 0u; i < max_size; ++i )
+ size_type i;
+ for( i = 0u; i < min_size; ++i )
                 boost::swap( (*smallest)[i], (*largest)[i] );
+
+ for( ; i < max_size; ++i )
+ smallest->unchecked_push_back( (*largest)[i] );
             largest->pop_back_n( diff );
             boost::swap( l.capacity_, r.capacity_ );
         }


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk