|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r53918 - in sandbox/monotonic: boost/monotonic boost/utility libs/monotonic/test
From: christian.schladetsch_at_[hidden]
Date: 2009-06-15 02:07:42
Author: cschladetsch
Date: 2009-06-15 02:07:40 EDT (Mon, 15 Jun 2009)
New Revision: 53918
URL: http://svn.boost.org/trac/boost/changeset/53918
Log:
added bubble-sort test
Text files modified:
sandbox/monotonic/boost/monotonic/allocator.h | 4
sandbox/monotonic/boost/monotonic/inline_storage.h | 26 ++++++++
sandbox/monotonic/boost/monotonic/rope.h | 87 ++++++++++++++++++++++---------
sandbox/monotonic/boost/utility/iter_range.h | 22 ++++++++
sandbox/monotonic/libs/monotonic/test/main.cpp | 109 +++++++++++++++++++++++++++++++++++++++
sandbox/monotonic/libs/monotonic/test/monotonic.vcproj | 30 ++++++++++
sandbox/monotonic/libs/monotonic/test/rope.cpp | 60 ++++++++++++++++-----
7 files changed, 291 insertions(+), 47 deletions(-)
Modified: sandbox/monotonic/boost/monotonic/allocator.h
==============================================================================
--- sandbox/monotonic/boost/monotonic/allocator.h (original)
+++ sandbox/monotonic/boost/monotonic/allocator.h 2009-06-15 02:07:40 EDT (Mon, 15 Jun 2009)
@@ -78,8 +78,8 @@
template <class U>
allocator(const allocator<U> &Q) throw()
{
- typedef typename allocator<T>::template rebind<U> Other;
- typedef typename Other::other OtherStorage;
+ typedef BOOST_DEDUCED_TYPENAME allocator<T>::template rebind<U> Other;
+ typedef BOOST_DEDUCED_TYPENAME Other::other OtherStorage;
storage = OtherStorage(*Q.storage).storage;
}
Modified: sandbox/monotonic/boost/monotonic/inline_storage.h
==============================================================================
--- sandbox/monotonic/boost/monotonic/inline_storage.h (original)
+++ sandbox/monotonic/boost/monotonic/inline_storage.h 2009-06-15 02:07:40 EDT (Mon, 15 Jun 2009)
@@ -36,9 +36,15 @@
private:
buffer_type buffer; ///< the storage
size_t cursor; ///< pointer to current index within storage for next allocation
-
+#ifndef NDEBUG
+ size_t num_allocations;
+#endif
public:
- inline_storage() : cursor(0)
+ inline_storage()
+ : cursor(0)
+#ifndef NDEBUG
+ , num_allocations(0)
+#endif
{
}
@@ -57,6 +63,9 @@
void reset()
{
cursor = 0;
+#ifndef NDEBUG
+ num_allocations = 0;
+#endif
}
size_t get_cursor() const
@@ -72,6 +81,9 @@
/// allocate storage, given alignment requirement
void *allocate(size_t num_bytes, size_t alignment)
{
+#ifndef NDEBUG
+ ++num_allocations;
+#endif
// ensure we return a point on an aligned boundary
size_t extra = cursor & (alignment - 1);
if (extra > 0)
@@ -101,6 +113,16 @@
{
return N - cursor;
}
+ size_t used() const
+ {
+ return cursor;
+ }
+#ifndef NDEBUG
+ size_t get_num_allocs() const
+ {
+ return num_allocations;
+ }
+#endif
};
}
}
Modified: sandbox/monotonic/boost/monotonic/rope.h
==============================================================================
--- sandbox/monotonic/boost/monotonic/rope.h (original)
+++ sandbox/monotonic/boost/monotonic/rope.h 2009-06-15 02:07:40 EDT (Mon, 15 Jun 2009)
@@ -8,22 +8,31 @@
#include <boost/monotonic/allocator.h>
#include <boost/monotonic/storage_base.h>
#include <boost/utility/iter_range.h>
-#include <boost/unordered_map.hpp>
+#include <boost/iterator.hpp>
+#include <boost/iterator/iterator_categories.hpp>
namespace boost
{
namespace monotonic
{
- /// a set of sequences that are tied together to present a contiguous sequence
+ /// a list of vectors that are tied together to present a contiguous sequence
///
/// this is to provide a sequence type that is 'between' a list and a vector. it
/// has slower access speed than a vector, but faster access speed than a list.
///
- /// unlike a vector, a rope cannot be resize()d
- template <class T, size_t ChunkSize = 32>
- struct rope
+ /// unlike a vector, a chain cannot be resized
+ ///
+ /// this has limited utility outside of the context of a monotonic allocator.
+ /// the reason to use it there is to avoid resizing a vector using a monotonic
+ /// allocator, which is very wasteful. so, the trade-off is slightly slower
+ /// access but ability to extend without resizing. then again, given that the
+ /// main reason to use a monotonic allocator is speed, there may be limited
+ /// application even there.
+ ///
+ template <class T, size_t ChunkSize = 64>
+ struct chain
{
- typedef rope<T,ChunkSize> Rope;
+ typedef chain<T, ChunkSize> Rope;
typedef allocator<T> Allocator;
typedef vector<T> Vector;
typedef list<Vector> Strands;
@@ -32,8 +41,12 @@
typedef const_iter_range<Vector> ConstVectorIterators;
typedef iter_range<Vector> VectorIterators;
+ typedef T value_type;
+ typedef T &reference;
+ typedef const T &const_reference;
+
template <class R, class S, class V, class Derived>
- struct iterator_base //: TODO: add iterator category
+ struct iterator_base : boost::iterator<random_access_traversal_tag, T>
{
typedef R Rope;
typedef S StrandIterators;
@@ -43,7 +56,8 @@
VectorIterators vec;
iterator_base() { }
- iterator_base(Rope &P) : parent(&P) { }
+ iterator_base(Rope &P)
+ : parent(&P) { }
iterator_base(Rope &P, StrandIterators const &S)
: parent(&P), strand(S) { }
iterator_base(Rope &P, StrandIterators const &S, VectorIterators const &V)
@@ -64,6 +78,12 @@
}
return This();
}
+ Derived operator++(int)
+ {
+ Derived tmp = This();
+ ++*this;
+ return tmp;
+ }
bool operator==(iterator_base const &B) const
{
return parent == B.parent && strand == B.strand && vec == B.vec;
@@ -92,13 +112,14 @@
return *Parent::vec;
}
};
+ typedef iterator Iter;
struct const_iterator : iterator_base<Rope const, ConstStrandsIterators, ConstVectorIterators, const_iterator>
{
typedef iterator_base<Rope const, ConstStrandsIterators, ConstVectorIterators, const_iterator> Parent;
const_iterator() { }
const_iterator(Rope const &P)
: Parent(P) { }
- const_iterator(iterator const &X)
+ const_iterator(Iter const &X)
: Parent(*X.parent, X.strand, X.vec)
{ }
const_iterator(Rope const &P, ConstStrandsIterators const &S)
@@ -116,19 +137,31 @@
Allocator alloc;
public:
- rope() { }
- rope(Allocator const &A)
+ chain() { }
+ chain(Allocator const &A)
: alloc(A), strands(A) { }
- rope(size_t N, T const &X, Allocator const &A)
+ chain(size_t len, Allocator const &A)
+ : alloc(A), strands(A)
+ {
+ // TODO
+ }
+ chain(size_t len, T const &X, Allocator const &A)
: alloc(A), strands(A)
{
- //TODO
+ strands.push_back(Vector(alloc));
+ strands.back().resize(len, X);
}
template <class II>
- rope(II F, II L, Allocator const &A)
+ chain(II F, II L, Allocator const &A)
: alloc(A), strands(A)
{
- //TODO
+ strands.push_back(Vector(alloc));
+ Vector &vec = strands.back();
+ size_t len = std::distance(F,L);
+ vec.resize(len);
+ Vector::iterator G = vec.begin();
+ for (size_t N = 0; N < len; ++F, ++G)
+ *G = *F;
}
size_t size() const
@@ -180,45 +213,45 @@
strands.back().push_back(X);
}
- T &at(size_t N)
+ T &at(size_t index)
{
size_t offset = 0;
BOOST_FOREACH(Vector &vec, strands)
{
- size_t local = N - offset;
+ size_t local = index - offset;
if (local < vec.size())
{
return vec.at(local);
}
offset += vec.size();
- if (offset > N)
+ if (offset > index)
break;
}
- throw std::out_of_range("rope");
+ throw std::out_of_range("chain");
}
- T const &at(size_t N) const
+ T const &at(size_t index) const
{
size_t offset = 0;
BOOST_FOREACH(Vector const &vec, strands)
{
- size_t local = N - offset;
+ size_t local = index - offset;
if (local < vec.size())
{
return vec.at(local);
}
offset += vec.size();
- if (offset < N)
+ if (offset < index)
break;
}
- throw std::out_of_range("rope");
+ throw std::out_of_range("chain");
}
- T &operator[](size_t N)
+ T &operator[](size_t index)
{
- return at(N);
+ return at(index);
}
- T const &operator[](size_t N) const
+ T const &operator[](size_t index) const
{
- return at(N);
+ return at(index);
}
};
}
Modified: sandbox/monotonic/boost/utility/iter_range.h
==============================================================================
--- sandbox/monotonic/boost/utility/iter_range.h (original)
+++ sandbox/monotonic/boost/utility/iter_range.h 2009-06-15 02:07:40 EDT (Mon, 15 Jun 2009)
@@ -78,6 +78,17 @@
: Parent(A,A) { }
iter_range(iterator A, iterator B)
: Parent(A,B) { }
+ iter_range& operator++()
+ {
+ Parent::operator++();
+ return *this;
+ }
+ iter_range operator++(int)
+ {
+ iter_range tmp(*this);
+ Parent::operator++(0);
+ return tmp;
+ }
typename Value &operator*() const
{
return *first;
@@ -102,6 +113,17 @@
: Parent(A,A) { }
const_iter_range(const_iterator A, const_iterator B)
: Parent(A,B) { }
+ const_iter_range& operator++()
+ {
+ Parent::operator++();
+ return *this;
+ }
+ const_iter_range operator++(int)
+ {
+ const_iter_range tmp(*this);
+ Parent::operator++(0);
+ return tmp;
+ }
typename const Value &operator*() const
{
return *first;
Modified: sandbox/monotonic/libs/monotonic/test/main.cpp
==============================================================================
--- sandbox/monotonic/libs/monotonic/test/main.cpp (original)
+++ sandbox/monotonic/libs/monotonic/test/main.cpp 2009-06-15 02:07:40 EDT (Mon, 15 Jun 2009)
@@ -10,18 +10,72 @@
#include <boost/monotonic/map.h>
#include <boost/monotonic/set.h>
+#include <boost/iterator/counting_iterator.hpp>
+
+#include <boost/monotonic/rope.h>
+
#include <boost/timer.hpp>
#include <boost/foreach.hpp>
#include <iostream>
+#include <deque>
#include <boost/range.hpp>
#include <boost/iterator/counting_iterator.hpp>
#include <boost/array.hpp>
#include <boost/scoped_ptr.hpp>
+template <class T
+, size_t C = 64
+, class Al = std::allocator<T>
+, class Link = std::vector<T, Al>
+, class Links = std::deque<Link, Al>
+>
+struct chain;
+
+
using namespace std;
using namespace boost;
+void test_deque()
+{
+ monotonic::inline_storage<4000> storage; // create local storage on the stack
+ {
+ {
+ std::list<int, boost::monotonic::allocator<int> > list(storage);
+ fill_n(back_inserter(list), 100, 42);
+ cout << "list: " << storage.used() << endl;
+ }
+ storage.reset();
+ {
+ std::deque<int, boost::monotonic::allocator<int> > deque(storage);
+ fill_n(back_inserter(deque), 100, 42);
+ cout << "deque: " << storage.used() << endl;
+ }
+ storage.reset();
+
+ {
+ std::vector<int, boost::monotonic::allocator<int> > vector(storage);
+ fill_n(back_inserter(vector), 100, 42);
+ cout << "vector: " << storage.used() << endl;
+ }
+ storage.reset();
+
+ {
+ monotonic::chain<int> rope(storage);
+ fill_n(back_inserter(rope), 100, 42);
+ cout << "default chain: " << storage.used() << endl;
+ }
+ storage.reset();
+
+ {
+ monotonic::chain<int, 100> rope(storage);
+ fill_n(back_inserter(rope), 100, 42);
+ cout << "chain<100>: " << storage.used() << endl;
+ }
+ storage.reset();
+ }
+}
+
void test_basic()
{
monotonic::inline_storage<1000*sizeof(int)> storage1; // create local storage on the stack
@@ -430,16 +484,69 @@
}
void test_rope();
+void test_chain();
+
+template <class List>
+void test_bubble_sort_impl(size_t length, List &list)
+{
+ for (size_t n = 0; n < length; ++n)
+ list.push_back(length - n);
+ bool swapped = false;
+ do
+ {
+ swapped = false;
+ List::iterator A = list.begin(), B = --list.end();
+ for (--B; A != B; ++A)
+ {
+ List::iterator C = A;
+ ++C;
+ if (*A > *C)
+ {
+ std::swap(*A, *C);
+ swapped = true;
+ }
+ }
+ }
+ while (swapped);
+}
+
+void test_bubble_sort()
+{
+ monotonic::inline_storage<100000> storage;
+ const size_t count = 50000;
+ const size_t length = 20;
+
+ boost::timer mono_timer;
+ for (size_t n = 0; n < count; ++n)
+ {
+ test_bubble_sort_impl(length, std::list<int, monotonic::allocator<int> >(storage));
+ storage.reset();
+ }
+ double mono_total = mono_timer.elapsed();
+ cout << "mono bubble sort: " << 1000*1000*mono_total/count << "us" << endl;
+
+ boost::timer std_timer;
+ for (size_t n = 0; n < count; ++n)
+ {
+ test_bubble_sort_impl(length, std::list<int>());
+ }
+ double std_total = std_timer.elapsed();
+ cout << "std bubble sort: " << 1000*1000*std_total/count << "us" << endl;
+}
int main()
{
+ test_bubble_sort();
+ //test_map_list_realtime();
+ return 0;
+ //test_chain();
+ test_deque();
//test_rope();
test_shared_allocators();
test_alignment();
test_auto_buffer();
test_speed();
test_speed_heap();
- test_map_list_realtime();
test_basic();
test_copy();
test_ctors();
Modified: sandbox/monotonic/libs/monotonic/test/monotonic.vcproj
==============================================================================
--- sandbox/monotonic/libs/monotonic/test/monotonic.vcproj (original)
+++ sandbox/monotonic/libs/monotonic/test/monotonic.vcproj 2009-06-15 02:07:40 EDT (Mon, 15 Jun 2009)
@@ -218,14 +218,42 @@
Name="utility"
>
<File
+ RelativePath="..\..\..\boost\utility\chain.h"
+ >
+ </File>
+ <File
RelativePath="..\..\..\boost\utility\iter_range.h"
>
</File>
</Filter>
</Filter>
+ <Filter
+ Name="doc"
+ >
+ <File
+ RelativePath="..\doc\index.html"
+ >
+ </File>
+ </Filter>
<File
- RelativePath="..\doc\index.html"
+ RelativePath=".\chain.cpp"
>
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
</File>
<File
RelativePath=".\main.cpp"
Modified: sandbox/monotonic/libs/monotonic/test/rope.cpp
==============================================================================
--- sandbox/monotonic/libs/monotonic/test/rope.cpp (original)
+++ sandbox/monotonic/libs/monotonic/test/rope.cpp 2009-06-15 02:07:40 EDT (Mon, 15 Jun 2009)
@@ -18,6 +18,7 @@
#include <boost/iterator/counting_iterator.hpp>
#include <boost/array.hpp>
#include <boost/scoped_ptr.hpp>
+#include <boost/noncopyable.hpp>
#include <boost/monotonic/rope.h>
@@ -28,13 +29,41 @@
{
std::vector<int> v(10);
boost::iter_range<std::vector<int> > r(v);
+ *r = 10;
+ *r++ = 10;
+ //while (r)
+ //{
+ // *r++ = 10;
+ //}
boost::const_iter_range<std::vector<int> > c(r);
}
+
+struct Foo : boost::noncopyable
+{
+ int n;
+ Foo(int N) : n(N) { }
+};
+
void test_rope()
{
+ {
+ monotonic::inline_storage<4000> storage; // create local storage on the stack
+ {
+ monotonic::chain<int, 100> rope(storage);
+ for (int n = 0; n < 200; ++n)
+ {
+ rope.push_back(n);
+ }
+ }
+ }
+
+
monotonic::inline_storage<1000> storage;
{
- typedef monotonic::rope<int, 2> Rope;
+ typedef monotonic::chain<Foo, 2> Rope2;
+ Rope2 foo(4, storage);
+
+ typedef monotonic::chain<int, 2> Rope;
Rope rope(storage);
rope.push_back(0);
rope.push_back(1);
@@ -46,25 +75,28 @@
{
*A *= 2;
}
+ Rope::iterator Q = rope.begin();
+ *Q++ = 13;
+
Rope::const_iterator C = rope.begin(), D = rope.end();
for (; C != D; ++C)
{
cout << *C;
}
- //BOOST_FOREACH(int n, rope)
- //{
- // cout << n << endl;
- //}
-
- //BOOST_FOREACH(int &n, rope)
- //{
- // n *= 2;
- //}
- //BOOST_FOREACH(int n, rope)
- //{
- // cout << n << endl;
- //}
+ BOOST_FOREACH(int n, rope)
+ {
+ cout << n << endl;
+ }
+
+ BOOST_FOREACH(int &n, rope)
+ {
+ n *= 2;
+ }
+ BOOST_FOREACH(int n, rope)
+ {
+ cout << n << endl;
+ }
rope[0] = 0;
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk