Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r54729 - in sandbox/monotonic: boost/monotonic boost/monotonic/containers libs/monotonic/test/Tests
From: christian.schladetsch_at_[hidden]
Date: 2009-07-06 17:11:18


Author: cschladetsch
Date: 2009-07-06 17:11:17 EDT (Mon, 06 Jul 2009)
New Revision: 54729
URL: http://svn.boost.org/trac/boost/changeset/54729

Log:
added stack iteration

Text files modified:
   sandbox/monotonic/boost/monotonic/containers/chain.hpp | 4
   sandbox/monotonic/boost/monotonic/stack.hpp | 262 ++++++++++++++++++++++++++++++++++++---
   sandbox/monotonic/libs/monotonic/test/Tests/Tests.vcproj | 4
   sandbox/monotonic/libs/monotonic/test/Tests/tests.cpp | 19 +-
   4 files changed, 252 insertions(+), 37 deletions(-)

Modified: sandbox/monotonic/boost/monotonic/containers/chain.hpp
==============================================================================
--- sandbox/monotonic/boost/monotonic/containers/chain.hpp (original)
+++ sandbox/monotonic/boost/monotonic/containers/chain.hpp 2009-07-06 17:11:17 EDT (Mon, 06 Jul 2009)
@@ -6,11 +6,11 @@
 #ifndef BOOST_MONOTONIC_CHAIN_HPP
 #define BOOST_MONOTONIC_CHAIN_HPP
 
-#include <boost/monotonic/detail/prefix.hpp>
 #include <boost/iterator.hpp>
 #include <boost/iterator/iterator_categories.hpp>
-
 #include <boost/utility/iter_range.hpp>
+
+#include <boost/monotonic/detail/prefix.hpp>
 #include <boost/monotonic/containers/vector.hpp>
 #include <boost/monotonic/containers/deque.hpp>
 

Modified: sandbox/monotonic/boost/monotonic/stack.hpp
==============================================================================
--- sandbox/monotonic/boost/monotonic/stack.hpp (original)
+++ sandbox/monotonic/boost/monotonic/stack.hpp 2009-07-06 17:11:17 EDT (Mon, 06 Jul 2009)
@@ -6,6 +6,10 @@
 #ifndef BOOST_MONOTONIC_STACK_HPP
 #define BOOST_MONOTONIC_STACK_HPP
 
+#include <typeinfo>
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/utility/iter_range.hpp>
+
 #include <boost/monotonic/detail/prefix.hpp>
 #include <boost/monotonic/storage.hpp>
 #include <boost/monotonic/containers/vector.hpp>
@@ -17,6 +21,9 @@
 {
         namespace monotonic
         {
+ struct null_pointer {};
+
+ /// a first-class stack object
                 template <size_t InlineSize = DefaultSizes::InlineSize>
                 struct stack
                 {
@@ -25,66 +32,249 @@
                 private:
                         fixed_storage<InlineSize> store;
 
+ template <class>
+ struct element;
+
+ /// an entry on the stack
                         struct element_base
                         {
                                 element_base *previous;
                                 size_t cursor;
- virtual ~element_base() { }
+ bool is_pod;
+ element_base(bool ip = false)
+ : is_pod(ip) { }
+ template <class T>
+ T &cast()
+ {
+ if (get_type() != typeid(T))
+ throw std::bad_cast();
+ return *static_cast<element<T> &>(*this).get_pointer();
+ }
+ template <class T>
+ const T &cast() const
+ {
+ if (get_type() != typeid(T))
+ throw std::bad_cast();
+ return *static_cast<const element<T> &>(*this).get_pointer();
+ }
+ virtual void destroy() {}
+ virtual const std::type_info &get_type() const = 0;
+ };
+ struct impl
+ {
+ /// a class-type element
+ template <class T, bool>
+ struct element : element_base
+ {
+ typedef T type;
+ typedef type *pointer;
+
+ private:
+ pointer ptr;
+ char value[sizeof(T)];
+
+ public:
+ element()
+ : ptr(reinterpret_cast<T *>(value))
+ {
+ }
+ const std::type_info &get_type() const
+ {
+ return typeid(T);
+ }
+ pointer get_pointer()
+ {
+ return ptr;
+ }
+ void destroy()
+ {
+ destroy(ptr, boost::has_trivial_destructor<type>());
+ }
+ void destroy(pointer ptr, const boost::false_type& )
+ {
+ (*ptr).~type();
+ }
+
+ void destroy(pointer, const boost::true_type& )
+ {
+ }
+ };
+
+ /// a pod-type element
+ template <class T>
+ struct element<T, true> : element_base
+ {
+ typedef T type;
+ type val;
+ element()
+ : element_base(true)
+ {
+ }
+ type *get_pointer()
+ {
+ return &val;
+ }
+ const std::type_info &get_type() const
+ {
+ return typeid(T);
+ }
+ };
                         };
+
+ /// an element of a given type on the stack
                         template <class T>
- struct element : element_base
+ struct element
+ : impl::element<T, boost::is_pod<T>::value>
                         {
- typedef T type;
+ };
 
- type *val;
- char value[sizeof(T)];
- element()
+ element_base *previous;
+
+ public:
+ typedef element_base value_type;
+ typedef element_base &reference;
+ typedef element_base const &const_reference;
+ typedef size_t size_type;
+
+ struct const_iterator : boost::iterator<forward_traversal_tag, element_base>
+ {
+ typedef element_base value_type;
+ element_base *current;
+
+ const_iterator(element_base *elem = 0)
+ : current(elem) { }
+
+ const value_type &operator*() const
+ {
+ return *current;
+ }
+ const value_type *operator->() const
+ {
+ return current;
+ }
+ const_iterator &operator++()
                                 {
- val = reinterpret_cast<T *>(value);
+ current = current->previous;
+ return *this;
                                 }
- ~element()
+ const_iterator operator++(int)
                                 {
- val->~T();
+ const_iterator tmp = *this;
+ ++(*this);
+ return tmp;
+ }
+ friend bool operator==(const_iterator left, const_iterator right)
+ {
+ return left.current == right.current;
+ }
+ friend bool operator!=(const_iterator left, const_iterator right)
+ {
+ return left.current != right.current;
                                 }
                         };
 
- element_base *previous;
+ struct iterator : const_iterator
+ {
+ iterator(element_base *elem = 0)
+ : const_iterator(elem) { }
+
+ value_type &operator*()
+ {
+ return *current;
+ }
+ value_type *operator->()
+ {
+ return current;
+ }
+ iterator &operator++()
+ {
+ const_iterator::operator++(0);
+ return *this;
+ }
+ iterator operator++(int)
+ {
+ iterator tmp = *this;
+ const_iterator::operator++(0);
+ return tmp;
+ }
+ friend bool operator==(iterator left, iterator right)
+ {
+ return left.current == right.current;
+ }
+ friend bool operator!=(iterator left, iterator right)
+ {
+ return left.current != right.current;
+ }
+ };
 
                 public:
- stack() : previous(0)
+ stack()
+ : previous(0)
+ {
+ }
+ ~stack()
+ {
+ clear();
+ }
+
+ size_t size() const
+ {
+ size_t len = 0;
+ const_iterator F = begin(), L = end();
+ for (; F != L; ++F)
+ ++len;
+ return len;
+ }
+ const_iterator begin() const
+ {
+ return const_iterator(previous);
+ }
+ const_iterator end() const
+ {
+ return const_iterator(0);
+ }
+ iterator begin()
+ {
+ return iterator(previous);
+ }
+ iterator end()
                         {
+ return iterator(0);
                         }
 
                         template <class T>
                         T &push()
                         {
- size_t cursor = store.get_cursor();
- element<T> &elem = store.create<element<T> >();
- elem.previous = previous;
- elem.cursor = cursor;
- previous = &elem;
- new (elem.val) T();
- return *elem.val;
+ element<T> &elem = push_element<T>();
+ if (!is_pod<T>::value)
+ new (elem.get_pointer()) T();
+ return *elem.get_pointer();
                         }
 
                         template <class T, class A0>
                         T &push(A0 a0)
                         {
- size_t cursor = store.get_cursor();
- element<T> &elem = store.create<element<T> >();
- elem.previous = previous;
- elem.cursor = cursor;
- previous = &elem;
- new (elem.val) T(a0);
- return *elem.val;
+ element<T> &elem = push_element<T>();
+ new (elem.get_pointer()) T(a0);
+ return *elem.get_pointer();
+ }
+
+ template <class T, class A0, class A1>
+ T &push(A0 a0)
+ {
+ element<T> &elem = push_element<T>();
+ new (elem.get_pointer()) T(a0, a1);
+ return *elem.get_pointer();
                         }
+
                         void pop()
                         {
                                 BOOST_ASSERT(previous);
                                 element_base *elem = previous;
                                 previous = elem->previous;
                                 size_t cursor = elem->cursor;
- elem->~element_base();
+ if (!elem->is_pod) // avoid empty virtual call for pods
+ elem->destroy();
                                 store.set_cursor(cursor);
                         }
 
@@ -92,6 +282,26 @@
                         {
                                 return store.get_cursor();
                         }
+
+ void clear()
+ {
+ while (previous != 0)
+ {
+ pop();
+ }
+ }
+
+ private:
+ template <class T>
+ element<T> &push_element()
+ {
+ size_t cursor = store.get_cursor();
+ element<T> &elem = store.create<element<T> >();
+ elem.previous = previous;
+ elem.cursor = cursor;
+ previous = &elem;
+ return elem;
+ }
                 };
         }
 }

Modified: sandbox/monotonic/libs/monotonic/test/Tests/Tests.vcproj
==============================================================================
--- sandbox/monotonic/libs/monotonic/test/Tests/Tests.vcproj (original)
+++ sandbox/monotonic/libs/monotonic/test/Tests/Tests.vcproj 2009-07-06 17:11:17 EDT (Mon, 06 Jul 2009)
@@ -200,10 +200,10 @@
                                 Name="VCCLCompilerTool"
                                 Optimization="3"
                                 AdditionalIncludeDirectories="$(ProjectDir)/../../../..;C:\Lib\tbb21_20080605oss\include;c:/source/boost/sandbox/cloneable;"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
                                 MinimalRebuild="true"
                                 BasicRuntimeChecks="0"
- RuntimeLibrary="3"
+ RuntimeLibrary="2"
                                 UsePrecompiledHeader="0"
                                 WarningLevel="3"
                                 DebugInformationFormat="3"

Modified: sandbox/monotonic/libs/monotonic/test/Tests/tests.cpp
==============================================================================
--- sandbox/monotonic/libs/monotonic/test/Tests/tests.cpp (original)
+++ sandbox/monotonic/libs/monotonic/test/Tests/tests.cpp 2009-07-06 17:11:17 EDT (Mon, 06 Jul 2009)
@@ -92,21 +92,26 @@
         monotonic::stack<> stack;
         {
                 size_t top = stack.top();
- int &n = stack.push<int>();
- stack.pop();
- size_t top2 = stack.top();
- BOOST_ASSERT(top2 == top);
-
                 int &n2 = stack.push<int>();
- int &n3 = stack.push<int>();
+ float &f0 = stack.push<float>();
+ char &n3 = stack.push<char>();
                 Tracked &tracked = stack.push<Tracked>();
                 boost::array<int, 42> &a = stack.push<boost::array<int, 42> >();
+
+ BOOST_ASSERT(stack.size() == 5);
+
                 size_t peak = stack.top();
+ cout << "STACK:" << endl;
+ BOOST_FOREACH(monotonic::stack<>::value_type const &elem, stack)
+ {
+ cout << elem.get_type().name() << endl;
+ }
                 stack.pop();
                 stack.pop();
                 stack.pop();
                 stack.pop();
- top2 = stack.top();
+ stack.pop();
+ size_t top2 = stack.top();
                 BOOST_ASSERT(top2 == top);
                 BOOST_ASSERT(Tracked::count == 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