Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r54005 - in sandbox/monotonic: boost/monotonic libs/monotonic/test
From: christian.schladetsch_at_[hidden]
Date: 2009-06-17 05:03:00


Author: cschladetsch
Date: 2009-06-17 05:02:58 EDT (Wed, 17 Jun 2009)
New Revision: 54005
URL: http://svn.boost.org/trac/boost/changeset/54005

Log:
added container.hpp, exceptions.hpp

Added:
   sandbox/monotonic/boost/monotonic/container.hpp (contents, props changed)
   sandbox/monotonic/boost/monotonic/exceptions.hpp (contents, props changed)
Text files modified:
   sandbox/monotonic/boost/monotonic/allocator.hpp | 11 +++
   sandbox/monotonic/boost/monotonic/fixed_storage.hpp | 1
   sandbox/monotonic/boost/monotonic/list.hpp | 90 +++++++++++++++++++++++++++++--
   sandbox/monotonic/boost/monotonic/map.hpp | 102 +++++++++++++++++++++++++++++++++---
   sandbox/monotonic/boost/monotonic/vector.hpp | 112 +++++++++++++++++++++++++++++++++++++--
   sandbox/monotonic/libs/monotonic/test/main.cpp | 66 +++++++++++++++++++----
   sandbox/monotonic/libs/monotonic/test/monotonic.vcproj | 10 +++
   sandbox/monotonic/libs/monotonic/test/test_map_list.cpp | 30 +++++-----
   8 files changed, 371 insertions(+), 51 deletions(-)

Modified: sandbox/monotonic/boost/monotonic/allocator.hpp
==============================================================================
--- sandbox/monotonic/boost/monotonic/allocator.hpp (original)
+++ sandbox/monotonic/boost/monotonic/allocator.hpp 2009-06-17 05:02:58 EDT (Wed, 17 Jun 2009)
@@ -11,6 +11,7 @@
 #include <boost/type_traits/has_trivial_destructor.hpp>
 
 #include <boost/monotonic/static_storage.hpp>
+#include <boost/monotonic/container.hpp>
 
 namespace boost
 {
@@ -108,9 +109,19 @@
 
                         void construct(pointer ptr)
                         {
+ construct(ptr, detail::IsMonotonic<T>);
+ }
+
+ void construct(pointer ptr, const boost::false_type &)
+ {
                                 new (ptr) value_type();
                         }
 
+ void construct(pointer ptr, const boost::true_type &)
+ {
+ new (ptr) value_type(*this);
+ }
+
                         void construct(pointer ptr, const T& val)
                         {
                                 new (ptr) value_type(val);

Added: sandbox/monotonic/boost/monotonic/container.hpp
==============================================================================
--- (empty file)
+++ sandbox/monotonic/boost/monotonic/container.hpp 2009-06-17 05:02:58 EDT (Wed, 17 Jun 2009)
@@ -0,0 +1,84 @@
+// Copyright (C) 2009 Christian Schladetsch
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MONOTONIC_CONTAINER_HPP
+#define BOOST_MONOTONIC_CONTAINER_HPP
+
+#include <vector>
+#include <list>
+#include <map>
+#include <set>
+#include <boost/monotonic/allocator.hpp>
+
+namespace boost
+{
+ namespace monotonic
+ {
+ namespace detail
+ {
+ template <bool, class T>
+ struct Creator;
+
+ template <class Impl>
+ struct MonotonicContainer;
+
+ template <class>
+ struct IsMonotonic : boost::mpl::false_ { };
+
+ template <class Impl>
+ struct IsMonotonic<MonotonicContainer<Impl> > : boost::mpl::true_ { };
+
+ template <class Impl>
+ struct MonotonicContainer
+ {
+ typedef Impl Derived;
+
+ storage_base &GetStorage() const
+ {
+ Derived const &self = static_cast<Derived const &>(*this);
+ storage_base *store = self.get_allocator().get_storage();
+ if (store == 0)
+ throw_exception(no_storage());
+ return *store;
+ }
+ };
+
+ template <bool is_monotonic_container, class T>
+ struct Creator
+ {
+ static T Create(storage_base &)
+ {
+ return T();
+ }
+ };
+ template <class T>
+ struct Creator<true, T>
+ {
+ static T Create(storage_base &storage)
+ {
+ return T(storage);
+ }
+ };
+
+ // match against the standard containers
+
+ template <class T, class U>
+ struct IsMonotonic<std::list<T, allocator<U> > > : boost::mpl::true_ { };
+
+ template <class T, class U>
+ struct IsMonotonic<std::vector<T, allocator<U> > > : boost::mpl::true_ { };
+
+ template <class K, class T, class Pred, class U>
+ struct IsMonotonic<std::map<K, T, Pred, allocator<U> > > : boost::mpl::true_ { };
+
+ template <class T, class Pred, class U>
+ struct IsMonotonic<std::set<T, Pred, allocator<U> > > : boost::mpl::true_ { };
+ }
+ }
+}
+
+#endif // BOOST_MONOTONIC_CONTAINER_HPP
+
+//EOF

Added: sandbox/monotonic/boost/monotonic/exceptions.hpp
==============================================================================
--- (empty file)
+++ sandbox/monotonic/boost/monotonic/exceptions.hpp 2009-06-17 05:02:58 EDT (Wed, 17 Jun 2009)
@@ -0,0 +1,29 @@
+// Copyright (C) 2009 Christian Schladetsch
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MONOTONIC_EXCEPTIONS_HPP
+#define BOOST_MONOTONIC_EXCEPTIONS_HPP
+
+#include <boost/monotonic/config.hpp>
+#include <boost/exception.hpp>
+
+namespace boost
+{
+ namespace monotonic
+ {
+ /// a request was made for a reference to storage that does not exist
+ struct no_storage : std::exception
+ {
+ no_storage() { }
+ no_storage(const char *text) : std::exception(text) { }
+ };
+
+ } // namespace monotonic
+
+} // namespace boost
+
+#endif // BOOST_MONOTONIC_EXCEPTIONS_HPP
+
+//EOF

Modified: sandbox/monotonic/boost/monotonic/fixed_storage.hpp
==============================================================================
--- sandbox/monotonic/boost/monotonic/fixed_storage.hpp (original)
+++ sandbox/monotonic/boost/monotonic/fixed_storage.hpp 2009-06-17 05:02:58 EDT (Wed, 17 Jun 2009)
@@ -9,6 +9,7 @@
 #include <boost/array.hpp>
 #include <boost/aligned_storage.hpp>
 #include <boost/monotonic/forward_declarations.hpp>
+#include <boost/monotonic/exceptions.hpp>
 #include <boost/monotonic/storage_base.hpp>
 
 namespace boost

Modified: sandbox/monotonic/boost/monotonic/list.hpp
==============================================================================
--- sandbox/monotonic/boost/monotonic/list.hpp (original)
+++ sandbox/monotonic/boost/monotonic/list.hpp 2009-06-17 05:02:58 EDT (Wed, 17 Jun 2009)
@@ -8,27 +8,103 @@
 
 #include <list>
 #include <boost/monotonic/allocator.hpp>
+#include <boost/monotonic/container.hpp>
 
 namespace boost
 {
         namespace monotonic
         {
- /// A std::list<T> that uses a monotonic allocator
+ /// A list that uses a monotonic allocator by default
                 template <class T>
- struct list : std::list<T, allocator<T> >
+ struct list : detail::MonotonicContainer<list<T> >
                 {
                         typedef allocator<T> Allocator;
- typedef std::list<T, Allocator> List;
+ typedef std::list<T, Allocator> List, Implementation;
+ typedef detail::MonotonicContainer<std::list<T, Allocator> > Parent;
+ typedef typename List::iterator iterator;
+ typedef typename List::const_iterator const_iterator;
+ typedef typename List::size_type size_type;
+ typedef typename List::value_type value_type;
+ typedef typename List::reference reference;
+ typedef typename List::const_reference const_reference;
+ typedef list<T> This;
 
+ private:
+ Implementation impl;
+
+ public:
                         list() { }
                         list(Allocator const &A)
- : List(A) { }
+ : impl(A) { }
                         template <class II>
                         list(II F, II L, Allocator const &A)
- : List(F,L,A) { }
+ : impl(F,L,A) { }
+
+ Allocator get_allocator()
+ {
+ return impl.get_allocator();
+ }
+ bool empty() const
+ {
+ return impl.empty();
+ }
+ size_type size() const
+ {
+ return impl.size();
+ }
+ void push_back(value_type const &value)
+ {
+ impl.push_back(value);
+ }
+ void pop_back()
+ {
+ impl.pop_back();
+ }
+ void push_front(value_type const &value)
+ {
+ impl.push_front(value);
+ }
+ void pop_front()
+ {
+ impl.pop_front();
+ }
+ iterator begin()
+ {
+ return impl.begin();
+ }
+ iterator end()
+ {
+ return impl.end();
+ }
+ const_iterator begin() const
+ {
+ return impl.begin();
+ }
+ const_iterator end() const
+ {
+ return impl.end();
+ }
+ value_type const &front() const
+ {
+ return impl.front();
+ }
+ value_type &front()
+ {
+ return impl.front();
+ }
+ value_type const &back() const
+ {
+ return impl.back();
+ }
+ value_type &back()
+ {
+ return impl.back();
+ }
                 };
- }
-}
+
+ } // namespace monotonic
+
+} // namespace boost
 
 #endif // BOOST_MONOTONIC_LIST_H
 

Modified: sandbox/monotonic/boost/monotonic/map.hpp
==============================================================================
--- sandbox/monotonic/boost/monotonic/map.hpp (original)
+++ sandbox/monotonic/boost/monotonic/map.hpp 2009-06-17 05:02:58 EDT (Wed, 17 Jun 2009)
@@ -6,33 +6,117 @@
 #ifndef BOOST_MONOTONIC_MAP_H
 #define BOOST_MONOTONIC_MAP_H
 
-#include <map>
 #include <boost/monotonic/allocator.hpp>
+#include <boost/monotonic/container.hpp>
 
 namespace boost
 {
         namespace monotonic
         {
- /// A std::map<K,T,P> that uses a monotonic allocator
+ /// A map that uses a monotonic allocator, and respects that allocator
+ /// when creating new referent instances
                 template <class K, class T, class P = std::less<K> >
- struct map : std::map<K,T,P, allocator<K> >
+ struct map : detail::MonotonicContainer<map<K,T,P> >
                 {
- typedef allocator<K> Allocator;
- typedef std::map<K,T,P,Allocator > Map;
+ typedef detail::MonotonicContainer<std::map<K,T,P, allocator<K> > > Parent;
+ typedef detail::Creator<detail::IsMonotonic<T>::value, T> Creator;
+
                         typedef P Predicate;
+ typedef allocator<K> Allocator;
+ typedef std::map<K,T,P,Allocator > Map, Implementation;
+ typedef typename Map::iterator iterator;
+ typedef typename Map::const_iterator const_iterator;
+ typedef typename Map::mapped_type mapped_type;
+ typedef typename Map::value_type value_type;
+ typedef typename Map::key_type key_type;
+ typedef typename Map::size_type size_type;
+
+ private:
+ Implementation impl;
+ Predicate pred;
+
+ public:
 
                         map() { }
                         map(Allocator const &A)
- : Map(Predicate(), A) { }
+ : impl(Predicate(), A) { }
                         map(Predicate Pr, Allocator const &A)
- : Map(Pr, A) { }
+ : impl(Pr, A), pred(Pr) { }
                         template <class II>
                         map(II F, II L, Allocator const &A, Predicate const &Pr = Predicate())
- : Map(F,L,Pr,A) { }
+ : impl(F,L,Pr,A), pred(Pr) { }
                         template <class II>
                         map(II F, II L, Predicate const &Pr, Allocator const &A)
- : Map(F,L,Pr,A) { }
+ : impl(F,L,Pr,A), pred(Pr) { }
+
+ Allocator get_allocator() const
+ {
+ return impl.get_allocator();
+ }
+ void clear()
+ {
+ impl.clear();
+ }
+ size_type size() const
+ {
+ return impl.size();
+ }
+ bool empty() const
+ {
+ return impl.empty();
+ }
+ iterator begin()
+ {
+ return impl.begin();
+ }
+ iterator end()
+ {
+ return impl.end();
+ }
+ const_iterator begin() const
+ {
+ return impl.begin();
+ }
+ const_iterator end() const
+ {
+ return impl.end();
+ }
+
+ void insert(const value_type& value)
+ {
+ impl.insert(value);
+ }
+ void erase(iterator first)
+ {
+ impl.erase(first);
+ }
+ void erase(iterator first, iterator last)
+ {
+ impl.erase(first, last);
+ }
+ size_type erase(key_type const &key)
+ {
+ return impl.erase(key);
+ }
+ mapped_type& operator[](const key_type& key)
+ {
+ iterator where = impl.lower_bound(key);
+ if (where == impl.end() || pred(key, where->first))
+ {
+ where = impl.insert(where, value_type(key, Creator::Create(GetStorage())));
+ }
+ return where->second;
+ }
+ iterator find(key_type const &key)
+ {
+ return impl.find(key);
+ }
+ const_iterator find(key_type const &key) const
+ {
+ return impl.find(key);
+ }
                 };
+
         }
 }
 

Modified: sandbox/monotonic/boost/monotonic/vector.hpp
==============================================================================
--- sandbox/monotonic/boost/monotonic/vector.hpp (original)
+++ sandbox/monotonic/boost/monotonic/vector.hpp 2009-06-17 05:02:58 EDT (Wed, 17 Jun 2009)
@@ -6,31 +6,127 @@
 #ifndef BOOST_MONOTONIC_VECTOR_H
 #define BOOST_MONOTONIC_VECTOR_H
 
-#include <vector>
 #include <boost/monotonic/allocator.hpp>
+#include <boost/monotonic/container.hpp>
 
 namespace boost
 {
         namespace monotonic
         {
- /// a std::vector<T> that uses a monotonic allocator
+ /// a vector that uses a monotonic allocator by default
                 template <class T>
- struct vector : std::vector<T, allocator<T> >
+ struct vector : detail::MonotonicContainer<vector<T> >
                 {
+ typedef detail::MonotonicContainer<std::vector<T, allocator<T> > > Parent;
+ typedef detail::Creator<detail::IsMonotonic<T>::value, T> Creator;
                         typedef allocator<T> Allocator;
                         typedef std::vector<T,Allocator> Vector;
+ typedef typename Vector::iterator iterator;
+ typedef typename Vector::const_iterator const_iterator;
+ typedef typename Vector::size_type size_type;
+ typedef typename Vector::value_type value_type;
+ typedef typename Vector::reference reference;
+ typedef typename Vector::const_reference const_reference;
 
+
+ private:
+ Vector impl;
+
+ public:
                         vector() { }
                         vector(Allocator const &A)
- : Vector(A) { }
+ : impl(A) { }
                         vector(size_t N, T const &X, Allocator const &A)
- : Vector(N,X,A) { }
+ : impl(N,X,A) { }
                         template <class II>
                         vector(II F, II L, Allocator const &A)
- : Vector(F,L,A) { }
+ : impl(F,L,A) { }
+
+ Allocator get_allocator() const
+ {
+ return impl.get_allocator();
+ }
+ bool empty() const
+ {
+ return impl.empty();
+ }
+ size_type size() const
+ {
+ return impl.size();
+ }
+ void resize(size_type size)
+ {
+ impl.resize(size);//, Creator::Create(GetStorage()));
+ }
+ void reserve(size_type size)
+ {
+ impl.reserve(size);
+ }
+ size_type capacity() const
+ {
+ return impl.capacity();
+ }
+ reference at(size_type index)
+ {
+ return impl.at(index);
+ }
+ const_reference at(size_type index) const
+ {
+ return impl.at(index);
+ }
+ reference operator[](size_type index)
+ {
+ return impl[index];
+ }
+ const_reference operator[](size_type index) const
+ {
+ return impl[index];
+ }
+ void push_back(value_type const &value)
+ {
+ impl.push_back(value);
+ }
+ void pop_back()
+ {
+ impl.pop_back();
+ }
+ iterator begin()
+ {
+ return impl.begin();
+ }
+ iterator end()
+ {
+ return impl.end();
+ }
+ const_iterator begin() const
+ {
+ return impl.begin();
+ }
+ const_iterator end() const
+ {
+ return impl.end();
+ }
+ value_type const &front() const
+ {
+ return impl.front();
+ }
+ value_type &front()
+ {
+ return impl.front();
+ }
+ value_type const &back() const
+ {
+ return impl.back();
+ }
+ value_type &back()
+ {
+ return impl.back();
+ }
                 };
- }
-}
+
+ } // namespace monotonic
+
+} // namespace boost
 
 #endif // BOOST_MONOTONIC_VECTOR_H
 

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-17 05:02:58 EDT (Wed, 17 Jun 2009)
@@ -177,8 +177,8 @@
         template<typename C>
         void test_loop_monotonic()
         {
- boost::monotonic::fixed_storage<100000> storage;
- boost::monotonic::vector<Foo<C> > vec(storage);
+ boost::monotonic::storage<100000> storage;
+ std::vector<Foo<C>, monotonic::allocator<Foo<C> > > vec(storage);
                 Foo<C> orig = { 'A', 65 };
                 vec.assign(ELEM_COUNT, orig);
                 boost::timer timer;
@@ -283,13 +283,14 @@
 #include "test_chained_storage.cpp"
 #include "test_shared_storage.cpp"
 
-namespace boost { namespace monotonic {
-
-static_storage_base<> static_storage;
-
-//storage<> static_storage_base<storage<> >::global;
-
-}}
+namespace boost
+{
+ namespace monotonic
+ {
+ static_storage_base<> static_storage;
+ //storage<> static_storage_base<storage<> >::global;
+ }
+}
 
 void test_static_storage()
 {
@@ -323,13 +324,54 @@
         //test_chain();
         test_deque();
         test_alignment();
- test_speed();
- test_speed_heap();
+ //test_speed();
+ //test_speed_heap();
 }
 
+void test_mono_map()
+{
+ monotonic::storage<> store;
+ {
+ typedef std::vector<std::list<int, monotonic::allocator<int> >, monotonic::allocator<std::list<int, monotonic::allocator<int> > > > Vector;
+ Vector vec(store);
+ vec.resize(1);
+ BOOST_ASSERT(vec[0].get_allocator().get_storage() == vec.get_allocator().get_storage());
+ vec[0].push_back(42);
+ }
+
+ {
+ typedef monotonic::map<int, monotonic::list<int> > Map;
+ Map map(store);
+ map[42].push_back(123);
+ }
+
+ {
+ typedef monotonic::map<int, monotonic::map<int, monotonic::list<int> > > Map;
+ Map map(store);
+ map[42][64].push_back(13);
+
+ }
+}
+
+#ifdef WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+//warning C4297: 'straight_to_debugger' : function assumed not to throw an exception but does
+#pragma warning(disable:4297)
+extern "C" void straight_to_debugger(unsigned int, EXCEPTION_POINTERS*)
+{
+ throw;
+}
+#endif
+
 int main()
 {
- test_map_list_heap_stack();
+#ifdef WIN32
+ _set_se_translator(straight_to_debugger);
+#endif
+
+ test_mono_map();
+ //test_map_list_heap_stack();
         //test_static_storage();
         //run_all_tests();
 }

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-17 05:02:58 EDT (Wed, 17 Jun 2009)
@@ -44,6 +44,7 @@
                                 AdditionalIncludeDirectories="$(ProjectDir)/../../.."
                                 PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
                                 MinimalRebuild="true"
+ ExceptionHandling="2"
                                 BasicRuntimeChecks="3"
                                 RuntimeLibrary="3"
                                 UsePrecompiledHeader="0"
@@ -117,6 +118,7 @@
                                 EnableIntrinsicFunctions="true"
                                 AdditionalIncludeDirectories="$(ProjectDir)/../../.."
                                 PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ ExceptionHandling="2"
                                 RuntimeLibrary="2"
                                 EnableFunctionLevelLinking="true"
                                 UsePrecompiledHeader="0"
@@ -186,6 +188,14 @@
>
                                 </File>
                                 <File
+ RelativePath="..\..\..\boost\monotonic\container.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\boost\monotonic\exceptions.hpp"
+ >
+ </File>
+ <File
                                         RelativePath="..\..\..\boost\monotonic\fixed_storage.hpp"
>
                                 </File>

Modified: sandbox/monotonic/libs/monotonic/test/test_map_list.cpp
==============================================================================
--- sandbox/monotonic/libs/monotonic/test/test_map_list.cpp (original)
+++ sandbox/monotonic/libs/monotonic/test/test_map_list.cpp 2009-06-17 05:02:58 EDT (Wed, 17 Jun 2009)
@@ -24,8 +24,6 @@
         double mono;
         double standard;
         double static_monotonic;
- Result() : mono(0), standard(0), static_monotonic(0) { }
- Result(double a, double b, double c) : mono(a), standard(b), static_monotonic(c) { }
 };
 
 Result test_map_list(size_t outter_loops, size_t inner_loops, monotonic::storage_base &storage)
@@ -35,48 +33,50 @@
 
         Result result;
 
- // use standard allocator
+
+ // use monotonic allocator with supplied storage
         {
                 boost::timer timer;
                 for (size_t n = 0; n < outter_loops; ++n)
                 {
                         {
- Map map;
+ MonoMap map(std::less<int>(), storage);
                                 test_map_list_impl(inner_loops, map);
                         }
+ storage.reset();
                 }
- result.standard = timer.elapsed();
+ result.mono = timer.elapsed();
         }
 
- // use static monotonic allocator
+ // use standard allocator
         {
                 boost::timer timer;
- monotonic::static_storage.reset();
                 for (size_t n = 0; n < outter_loops; ++n)
                 {
                         {
- MonoMap map;
+ Map map;
                                 test_map_list_impl(inner_loops, map);
                         }
- monotonic::static_storage.reset();
                 }
- result.static_monotonic = timer.elapsed();
+ result.standard = timer.elapsed();
         }
 
- // use monotonic allocator with supplied storage
+ // use static monotonic allocator
         {
                 boost::timer timer;
+ monotonic::static_storage.reset();
                 for (size_t n = 0; n < outter_loops; ++n)
                 {
                         {
- MonoMap map(std::less<int>(), storage);
+ MonoMap map;
                                 test_map_list_impl(inner_loops, map);
                         }
- storage.reset();
+ monotonic::static_storage.reset();
                 }
- result.mono = timer.elapsed();
+ result.static_monotonic = timer.elapsed();
         }
 
+
         cout << "test_map_list: " << inner_loops << ": " << result.mono << ", " << result.static_monotonic << ", " << result.standard << endl;
         return result;
 }
@@ -86,10 +86,10 @@
         const size_t outter_loops = 10*1000;
         const size_t inner_loops = 10000;
 
- monotonic::storage<> storage;
         typedef std::map<size_t, Result > Results;
         Results results;
 
+ monotonic::storage<> storage;
         for (size_t inner = 100; inner < inner_loops; inner += 1000)
         {
                 results[inner] = test_map_list(outter_loops, inner, storage);


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