Boost logo

Boost-Commit :

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


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