$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r82372 - in sandbox/static_vector: boost/container boost/container/detail doc example
From: athundt_at_[hidden]
Date: 2013-01-05 21:31:52
Author: ahundt
Date: 2013-01-05 21:31:51 EST (Sat, 05 Jan 2013)
New Revision: 82372
URL: http://svn.boost.org/trac/boost/changeset/82372
Log:
static_vector added Strategy concept check and Iterator concept checks. Simplified example for documentation.
Added:
   sandbox/static_vector/boost/container/detail/static_vector_concept.hpp   (contents, props changed)
Text files modified: 
   sandbox/static_vector/boost/container/detail/static_vector_util.hpp |    13 +++++-----                              
   sandbox/static_vector/boost/container/static_vector.hpp             |    31 +++++++++++++++++++++----               
   sandbox/static_vector/doc/static_vector.qbk                         |     3 +                                       
   sandbox/static_vector/example/static_vector_example.cpp             |    48 +++++++++++++-------------------------- 
   4 files changed, 50 insertions(+), 45 deletions(-)
Added: sandbox/static_vector/boost/container/detail/static_vector_concept.hpp
==============================================================================
--- (empty file)
+++ sandbox/static_vector/boost/container/detail/static_vector_concept.hpp	2013-01-05 21:31:51 EST (Sat, 05 Jan 2013)
@@ -0,0 +1,60 @@
+// Boost.Container StaticVector
+//
+// Copyright (c) 2012 Andrew Hundt.
+// Copyright (c) 2012 Adam Wulkiewicz, Lodz, Poland.
+//
+// Use, modification and distribution is subject to 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_CONTAINER_STATIC_VECTOR_CONCEPT_HPP
+#define BOOST_CONTAINER_STATIC_VECTOR_CONCEPT_HPP
+
+#include <boost/concept_check.hpp>
+
+namespace boost { namespace container { namespace concept {
+  
+/**
+ * StaticVectorStrategyConcept
+ *
+ *  \brief Checks strategy for static_vector<Value,Capacity,Strategy>, which has similarities to std::Allocator 
+ *  \ingroup static_vector
+ */
+template<typename Strategy>
+struct StaticVectorStrategy {
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+    // typedefs are the same as in std::Allocator
+    typedef typename Strategy::value_type      value_type;
+    typedef typename Strategy::size_type       size_type;
+    typedef typename Strategy::difference_type difference_type;
+    typedef typename Strategy::pointer         pointer;
+    typedef typename Strategy::const_pointer   const_pointer;
+    typedef typename Strategy::reference       reference;
+    typedef typename Strategy::const_reference const_reference;
+
+    struct check_methods
+    {
+        static void apply()
+        {
+            Strategy const* str = 0;
+
+            // must implement allocate_failed
+            str->allocate_failed();
+            
+            boost::ignore_unused_variable_warning(str);
+        }
+    };
+
+public :
+    BOOST_CONCEPT_USAGE(StaticVectorStrategy)
+    {
+        check_methods::apply();
+    }
+
+#endif
+};
+
+} /*namespace boost*/ } /*namespace container*/ } /*namespace concept*/
+
+#endif //BOOST_CONTAINER_STATIC_VECTOR_CONCEPT_HPP
Modified: sandbox/static_vector/boost/container/detail/static_vector_util.hpp
==============================================================================
--- sandbox/static_vector/boost/container/detail/static_vector_util.hpp	(original)
+++ sandbox/static_vector/boost/container/detail/static_vector_util.hpp	2013-01-05 21:31:51 EST (Sat, 05 Jan 2013)
@@ -54,23 +54,23 @@
 template <typename I>
 struct are_elements_contiguous : boost::is_pointer<I>
 {};
-
+    
 #if defined(BOOST_CONTAINER_STATIC_VECTOR_ENABLE_VECTORS_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS)
-
+    
 template <typename Pointer>
 struct are_elements_contiguous<
-    boost::container_detail::vector_const_iterator<Pointer>
+    boost::container::container_detail::vector_const_iterator<Pointer>
 > : boost::true_type
 {};
 
 template <typename Pointer>
 struct are_elements_contiguous<
-    boost::container_detail::vector_iterator<Pointer>
+    boost::container::container_detail::vector_iterator<Pointer>
 > : boost::true_type
 {};
 
 #if defined(BOOST_DINKUMWARE_STDLIB)
-
+    
 template <typename T>
 struct are_elements_contiguous<
     std::_Vector_const_iterator<T>
@@ -94,7 +94,6 @@
 #elif defined(_LIBCPP_VERSION)
 
 // TODO - test it first
-
 //template <typename P>
 //struct are_elements_contiguous<
 //    __wrap_iter<P>
@@ -104,7 +103,7 @@
 #else // OTHER_STDLIB
 
 // TODO - add other iterators implementations
-
+    
 #endif // STDLIB
 
 #endif // BOOST_CONTAINER_STATIC_VECTOR_ENABLE_VECTORS_OPTIMIZATION && !BOOST_NO_EXCEPTIONS
Modified: sandbox/static_vector/boost/container/static_vector.hpp
==============================================================================
--- sandbox/static_vector/boost/container/static_vector.hpp	(original)
+++ sandbox/static_vector/boost/container/static_vector.hpp	2013-01-05 21:31:51 EST (Sat, 05 Jan 2013)
@@ -19,6 +19,8 @@
 #include <boost/container/detail/preprocessor.hpp>
 
 #include <boost/container/detail/static_vector_util.hpp>
+#include <boost/container/detail/static_vector_concept.hpp>
+#include <boost/iterator/iterator_concepts.hpp>
 
 #ifndef BOOST_NO_EXCEPTIONS
 #include <stdexcept>
@@ -49,7 +51,16 @@
 class static_vector;
 
 namespace static_vector_detail {
-
+    
+// TODO: Improve error messages
+//       possibly include N in the strategy, and provide size as an optoinal allocate_failed parameter?
+//       Example of current error with reserve(4) when capacity is 3:
+//          "boost/container/static_vector.hpp(66): size can't exceed the capacity"
+//       Could say
+//          "cannot reserve(4) due to fixed capacity of 3 elements"
+    
+    
+// TODO: document strategy concept, possibly define as subset of Allocator concept
 template <typename Value>
 struct default_strategy/*fake_allocator*/
 {
@@ -158,7 +169,9 @@
  * static_vector is a sequence container like boost::container::vector with contiguous storage that can
  * change in size, but provides the static allocation, low overhead, and fixed capacity of boost::array.
  *
- * 
+ * @tparam Value the type of element that will be stored
+ * @tparam Capacity the maximum number of elements static_vector can store, fixed at compile time.
+ * @tparam Strategy 
  */
 template <typename Value, std::size_t Capacity, typename Strategy/*FakeAllocator*/ = static_vector_detail::default_strategy<Value>/*fake_allocator*/ >
 class static_vector
@@ -177,6 +190,8 @@
         (static_vector)
     );
 
+    BOOST_CONCEPT_ASSERT((concept::StaticVectorStrategy<Strategy>));
+
     typedef boost::aligned_storage<
         sizeof(Value[Capacity]),
         boost::alignment_of<Value[Capacity]>::value
@@ -250,6 +265,7 @@
     }
 
     //! <b>Requires</b>: distance(first, last) <= Capacity.
+    //!                  Iterator must meet the ForwardTraversal Iterator concept
     //!
     //! <b>Effects</b>: Constructs a static_vector containing copy of a range [first, last).
     //!
@@ -261,7 +277,8 @@
     static_vector(Iterator first, Iterator last)
         : m_size(0)
     {
-        // TODO - add MPL_ASSERT, check if Iterator is really an iterator
+        BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<Iterator>)); // Make sure you passed a ForwardIterator
+        
         this->assign(first, last);                                                    // may throw
     }
 
@@ -659,6 +676,7 @@
 
     //! <b>Requires</b>: position must be a valid iterator of *this in range [begin(), end()]
     //!   and distance(first, last) <= Capacity.
+    //!   Iterator must meet the ForwardTraversal Iterator concept
     //!
     //! <b>Effects</b>: Inserts a copy of a range [first, last) at position.
     //!
@@ -670,7 +688,7 @@
     template <typename Iterator>
     iterator insert(iterator position, Iterator first, Iterator last)
     {
-        // TODO - add MPL_ASSERT, check if Iterator is really an iterator
+        BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<Iterator>)); // Make sure you passed a ForwardIterator
 
         typedef typename boost::iterator_traversal<Iterator>::type traversal;
         this->insert_dispatch(position, first, last, traversal());
@@ -739,7 +757,7 @@
     template <typename Iterator>
     void assign(Iterator first, Iterator last)
     {
-        // TODO - add MPL_ASSERT, check if Iterator is really an iterator
+        BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<Iterator>)); // Make sure you passed a ForwardIterator
 
         typedef typename boost::iterator_traversal<Iterator>::type traversal;
         this->assign_dispatch(first, last, traversal());                            // may throw
@@ -1348,6 +1366,8 @@
     template <typename Iterator>
     void insert_dispatch(iterator position, Iterator first, Iterator last, boost::random_access_traversal_tag const&)
     {
+        BOOST_CONCEPT_ASSERT((boost_concepts::RandomAccessTraversal<Iterator>)); // Make sure you passed a RandomAccessIterator
+        
         errh::check_iterator_end_eq(*this, position);
         
         typename boost::iterator_difference<Iterator>::type
@@ -1587,6 +1607,7 @@
         errh::check_capacity(*this, count);                                         // may throw
     }
 
+    
     // nothrow
     void reserve(size_type count)
     {
Modified: sandbox/static_vector/doc/static_vector.qbk
==============================================================================
--- sandbox/static_vector/doc/static_vector.qbk	(original)
+++ sandbox/static_vector/doc/static_vector.qbk	2013-01-05 21:31:51 EST (Sat, 05 Jan 2013)
@@ -27,7 +27,8 @@
 static_vector is a sequence container like boost::container::vector with contiguous storage that can
 change in size, but provides the static allocation, low overhead, and fixed capacity of boost::array.
 
-<Insert example here>
+[import ../example/static_vector_example.cpp]
+[static_vector_example_cpp]
 
 static_vector is well suited for use in a buffer or in the internal implementation of of other classes, or use cases where there is a fixed limit to the number of elements that must be stored. Embedded and realtime applications are a particular case where static_vector is most useful, where allocation either may not be available or acceptable. 
 
Modified: sandbox/static_vector/example/static_vector_example.cpp
==============================================================================
--- sandbox/static_vector/example/static_vector_example.cpp	(original)
+++ sandbox/static_vector/example/static_vector_example.cpp	2013-01-05 21:31:51 EST (Sat, 05 Jan 2013)
@@ -13,44 +13,28 @@
  *
  */
  
-#include <iostream>
-#include <string>
-#include <set>
-#include "boost/container/static_vector.hpp"
+//[static_vector_example_cpp
 
-using namespace std;
-using namespace boost;
-
-  
-void print(std::size_t value){
-  cout << " " << value;
-}
+// static_vector_example.cpp
 
+#include "boost/container/static_vector.hpp"
 
 int main(int argc, char** argv){
   
-  // create static_vector with a capacity of 3
-  boost::container::static_vector<std::size_t,3> three; // size: 0 capacity: 3
+  // static_vector of ints, fixed capacity: 3
+  boost::container::static_vector<int,3> three; // size: 0
 
-  three.push_back(5); // size: 1 capacity: 3
-  three.push_back(2); // size: 2 capacity: 3
-  three.push_back(1); // size: 3 capacity: 3
+  three.push_back(1);    // size: 1
+  three.push_back(2);    // size: 2
+  three.push_back(3);    // size: 3
   
-  cout << "Values: ";
-  std::for_each(three.begin(),three.end(),print);
-  cout << "size: " << three.size() << " capacity: "  << three.capacity() << std::endl; // size: 3 capacity: 3
+  //three.reserve(4);    // no effect, fixed capacity: 3
+  //three.push_back(3);  // size: 4, undefined behavior
   
-  // three.push_back(3); // uncomment for undefined behavior, adding a 4th element goes over the end. capacity: 3 size: 3
+  three.pop_back();      // size: 2
+  three.shrink_to_fit(); // no effect, fixed capacity: 3
   
-  std::sort(three.begin(), three.end());
-  cout << "Sorted:";
-  std::for_each(three.begin(),three.end(),print);
-  cout << "size: " << three.size() << " capacity: "  << three.capacity() << std::endl; // size: 3 capacity: 3
-  
-  three.pop_back(); // size: 2 capacity: 3
-  three.shrink_to_fit(); // has no effect, size: 2 capacity: 3
-  
-  cout << "Popped: ";
-  std::for_each(three.begin(),three.end(),print);
-  cout << "  size: " << three.size() << " capacity: "  << three.capacity() << std::endl; // size: 2 capacity: 3
-}
\ No newline at end of file
+  return 0;
+}
+
+//]
\ No newline at end of file