diff --git a/STL_Extension/doc_tex/STL_Extension_ref/compact_container.tex b/STL_Extension/doc_tex/STL_Extension_ref/compact_container.tex index 1c3cfd5268a..12157c7a71f 100644 --- a/STL_Extension/doc_tex/STL_Extension_ref/compact_container.tex +++ b/STL_Extension/doc_tex/STL_Extension_ref/compact_container.tex @@ -210,6 +210,12 @@ {swaps the contents of \ccVar\ and \ccStyle{cc} in constant time complexity. No exception is thrown.} + \ccMethod{void reserve(size_type value);} + {if \ccc{value} is less than or equal to \ccc{capacity()}, this call + has no effect. Otherwise, it is a request for allocation of + additional memory so that then \ccc{capacity()} is greater than or + equal to value. \ccc{size()} is unchanged.} + %% +-----------------------------------+ \ccHeading{Access Member Functions} @@ -254,7 +260,6 @@ {returns the total number of elements that~\ccVar\ can hold without requiring reallocation.} -% - reserve() % XXX FIXME % - block_size() % TODO \ccMethod{Allocator get_allocator() const;}{returns the allocator.} diff --git a/STL_Extension/include/CGAL/Compact_container.h b/STL_Extension/include/CGAL/Compact_container.h index bd58092fb50..2a299a64551 100644 --- a/STL_Extension/include/CGAL/Compact_container.h +++ b/STL_Extension/include/CGAL/Compact_container.h @@ -44,7 +44,7 @@ // a free/used/boundary element. // TODO : -// - Add .reserve() and .resize() (and proper copy of capacity_). +// - Add .resize() (and proper copy of capacity_). // - Add preconditions in input that real pointers need to have clean bits. // Also for the allocated memory alignment, and sizeof(). // - Do a benchmark before/after. @@ -82,6 +82,9 @@ namespace CGAL { +#define CGAL_INIT_BLOCK_SIZE 14 +#define CGAL_INCREMENT_BLOCK_SIZE 16 + // The following base class can be used to easily add a squattable pointer // to a class (maybe you loose a bit of compactness though). // TODO : Shouldn't adding these bits be done automatically and transparently, @@ -437,8 +440,6 @@ public: return capacity_; } - void reserve(size_type n); // TODO - // void resize(size_type sz, T c = T()); // TODO makes sense ??? bool empty() const @@ -488,6 +489,18 @@ public: return cit != end() && owns(cit); } + /** Reserve method to ensure that the capacity of the Compact_container be + * greater or equal than a given value n. + */ + void reserve(size_type n) + { + if ( capacity_>=n ) return; + size_type tmp = block_size; + block_size = std::max( n - capacity_, block_size ); + allocate_new_block(); + block_size = tmp+CGAL_INCREMENT_BLOCK_SIZE; + } + private: void allocate_new_block(); @@ -552,7 +565,7 @@ private: void init() { - block_size = 14; + block_size = CGAL_INIT_BLOCK_SIZE; capacity_ = 0; size_ = 0; free_list = NULL; @@ -649,7 +662,7 @@ void Compact_container::allocate_new_block() } set_type(last_item, NULL, START_END); // Increase the block_size for the next time. - block_size += 16; + block_size += CGAL_INCREMENT_BLOCK_SIZE; } template < class T, class Allocator > diff --git a/STL_Extension/test/STL_Extension/test_Compact_container.cpp b/STL_Extension/test/STL_Extension/test_Compact_container.cpp index 1cc07345087..509b4da7476 100644 --- a/STL_Extension/test/STL_Extension/test_Compact_container.cpp +++ b/STL_Extension/test/STL_Extension/test_Compact_container.cpp @@ -192,6 +192,15 @@ void test(const Cont &) assert(c9.size() == v1.size() - 2); + // test reserve + Cont c11; + c11.reserve(v1.size()); + for(typename Vect::const_iterator it = v1.begin(); it != v1.end(); ++it) + c11.insert(*it); + + assert(c11.size() == v1.size()); + assert(c10 == c11); + // owns() and owns_dereferencable(). for(typename Cont::const_iterator it = c9.begin(), end = c9.end(); it != end; ++it) { assert(c9.owns(it));