diff options
Diffstat (limited to 'boost/container/static_vector.hpp')
-rw-r--r-- | boost/container/static_vector.hpp | 214 |
1 files changed, 130 insertions, 84 deletions
diff --git a/boost/container/static_vector.hpp b/boost/container/static_vector.hpp index 059640e937..2c08be88b6 100644 --- a/boost/container/static_vector.hpp +++ b/boost/container/static_vector.hpp @@ -35,9 +35,21 @@ namespace boost { namespace container { namespace dtl { -template<class T, std::size_t N> +template<class T, std::size_t N, std::size_t InplaceAlignment, bool ThrowOnOverflow> class static_storage_allocator { + typedef bool_<ThrowOnOverflow> throw_on_overflow_t; + + static BOOST_NORETURN BOOST_CONTAINER_FORCEINLINE void on_capacity_overflow(true_type) + { + (throw_bad_alloc)(); + } + + static BOOST_CONTAINER_FORCEINLINE void on_capacity_overflow(false_type) + { + BOOST_ASSERT_MSG(false, "ERROR: static vector capacity overflow"); + } + public: typedef T value_type; @@ -61,6 +73,11 @@ class static_storage_allocator std::size_t max_size() const { return N; } + static BOOST_CONTAINER_FORCEINLINE void on_capacity_overflow() + { + (on_capacity_overflow)(throw_on_overflow_t()); + } + typedef boost::container::dtl::version_type<static_storage_allocator, 0> version; BOOST_CONTAINER_FORCEINLINE friend bool operator==(const static_storage_allocator &, const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW @@ -70,9 +87,36 @@ class static_storage_allocator { return true; } private: - typename aligned_storage<sizeof(T)*N, alignment_of<T>::value>::type storage; + BOOST_STATIC_ASSERT_MSG(!InplaceAlignment || (InplaceAlignment & (InplaceAlignment-1)) == 0, "Alignment option must be zero or power of two"); + static const std::size_t final_alignment = InplaceAlignment ? InplaceAlignment : dtl::alignment_of<T>::value; + typename dtl::aligned_storage<sizeof(T)*N, final_alignment>::type storage; +}; + +template<class Options> +struct get_static_vector_opt +{ + typedef Options type; +}; + +template<> +struct get_static_vector_opt<void> +{ + typedef static_vector_null_opt type; }; +template <typename T, std::size_t Capacity, class Options> +struct get_static_vector_allocator +{ + typedef typename get_static_vector_opt<Options>::type options_t; + typedef dtl::static_storage_allocator + < T + , Capacity + , options_t::inplace_alignment + , options_t::throw_on_overflow + > type; +}; + + } //namespace dtl { #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -99,22 +143,24 @@ class static_storage_allocator //! std::out_of_range is thrown if out of bounds access is performed in <code>at()</code> if exceptions are //! enabled, throw_out_of_range() if not enabled. //! -//!@tparam Value The type of element that will be stored. +//!@tparam T The type of element that will be stored. //!@tparam Capacity The maximum number of elements static_vector can store, fixed at compile time. -template <typename Value, std::size_t Capacity> +//!@tparam Options A type produced from \c boost::container::static_vector_options. +template <typename T, std::size_t Capacity, class Options BOOST_CONTAINER_DOCONLY(= void) > class static_vector - : public vector<Value, dtl::static_storage_allocator<Value, Capacity> > + : public vector<T, typename dtl::get_static_vector_allocator< T, Capacity, Options>::type> { + public: #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED - typedef vector<Value, dtl::static_storage_allocator<Value, Capacity> > base_t; + typedef typename dtl::get_static_vector_allocator< T, Capacity, Options>::type allocator_type; + typedef vector<T, allocator_type > base_t; BOOST_COPYABLE_AND_MOVABLE(static_vector) - template<class U, std::size_t OtherCapacity> + template<class U, std::size_t OtherCapacity, class OtherOptions> friend class static_vector; public: - typedef dtl::static_storage_allocator<Value, Capacity> allocator_type; #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -162,7 +208,7 @@ public: //! @param count The number of values which will be contained in the container. //! //! @par Throws - //! If Value's value initialization throws. + //! If T's value initialization throws. //! //! @par Complexity //! Linear O(N). @@ -177,7 +223,7 @@ public: //! @param count The number of values which will be contained in the container. //! //! @par Throws - //! If Value's default initialization throws. + //! If T's default initialization throws. //! //! @par Complexity //! Linear O(N). @@ -196,7 +242,7 @@ public: //! @param value The value which will be used to copy construct values. //! //! @par Throws - //! If Value's copy constructor throws. + //! If T's copy constructor throws. //! //! @par Complexity //! Linear O(N). @@ -214,7 +260,7 @@ public: //! @param last The iterator to the one after the last element in range. //! //! @par Throws - //! If Value's constructor taking a dereferenced Iterator throws. + //! If T's constructor taking a dereferenced Iterator throws. //! //! @par Complexity //! Linear O(N). @@ -232,7 +278,7 @@ public: //! @param il std::initializer_list with values to initialize vector. //! //! @par Throws - //! If Value's constructor taking a dereferenced std::initializer_list throws. + //! If T's constructor taking a dereferenced std::initializer_list throws. //! //! @par Complexity //! Linear O(N). @@ -246,7 +292,7 @@ public: //! @param other The static_vector which content will be copied to this one. //! //! @par Throws - //! If Value's copy constructor throws. + //! If T's copy constructor throws. //! //! @par Complexity //! Linear O(N). @@ -274,12 +320,12 @@ public: //! @param other The static_vector which content will be copied to this one. //! //! @par Throws - //! If Value's copy constructor throws. + //! If T's copy constructor throws. //! //! @par Complexity //! Linear O(N). - template <std::size_t C> - BOOST_CONTAINER_FORCEINLINE static_vector(static_vector<value_type, C> const& other) + template <std::size_t C, class O> + BOOST_CONTAINER_FORCEINLINE static_vector(static_vector<T, C, O> const& other) : base_t(other) {} @@ -288,8 +334,8 @@ public: //! @param other The static_vector which content will be moved to this one. //! //! @par Throws - //! @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor throws. - //! @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor throws. + //! @li If \c has_nothrow_move<T>::value is \c true and T's move constructor throws. + //! @li If \c has_nothrow_move<T>::value is \c false and T's copy constructor throws. //! //! @par Complexity //! Linear O(N). @@ -305,14 +351,14 @@ public: //! @param other The static_vector which content will be moved to this one. //! //! @par Throws - //! @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor throws. - //! @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor throws. + //! @li If \c has_nothrow_move<T>::value is \c true and T's move constructor throws. + //! @li If \c has_nothrow_move<T>::value is \c false and T's copy constructor throws. //! //! @par Complexity //! Linear O(N). - template <std::size_t C> - BOOST_CONTAINER_FORCEINLINE static_vector(BOOST_RV_REF_BEG static_vector<value_type, C> BOOST_RV_REF_END other) - : base_t(BOOST_MOVE_BASE(typename static_vector<value_type BOOST_MOVE_I C>::base_t, other)) + template <std::size_t C, class O> + BOOST_CONTAINER_FORCEINLINE static_vector(BOOST_RV_REF_BEG static_vector<T, C, O> BOOST_RV_REF_END other) + : base_t(BOOST_MOVE_BASE(typename static_vector<T BOOST_MOVE_I C>::base_t, other)) {} //! @brief Copy assigns Values stored in the other static_vector to this one. @@ -320,7 +366,7 @@ public: //! @param other The static_vector which content will be copied to this one. //! //! @par Throws - //! If Value's copy constructor or copy assignment throws. + //! If T's copy constructor or copy assignment throws. //! //! @par Complexity //! Linear O(N). @@ -335,7 +381,7 @@ public: //! @param il The std::initializer_list which content will be copied to this one. //! //! @par Throws - //! If Value's copy constructor or copy assignment throws. + //! If T's copy constructor or copy assignment throws. //! //! @par Complexity //! Linear O(N). @@ -350,15 +396,15 @@ public: //! @param other The static_vector which content will be copied to this one. //! //! @par Throws - //! If Value's copy constructor or copy assignment throws. + //! If T's copy constructor or copy assignment throws. //! //! @par Complexity //! Linear O(N). - template <std::size_t C> - BOOST_CONTAINER_FORCEINLINE static_vector & operator=(static_vector<value_type, C> const& other) + template <std::size_t C, class O> + BOOST_CONTAINER_FORCEINLINE static_vector & operator=(static_vector<T, C, O> const& other) { return static_cast<static_vector&>(base_t::operator= - (static_cast<typename static_vector<value_type, C>::base_t const&>(other))); + (static_cast<typename static_vector<T, C, O>::base_t const&>(other))); } //! @brief Move assignment. Moves Values stored in the other static_vector to this one. @@ -366,8 +412,8 @@ public: //! @param other The static_vector which content will be moved to this one. //! //! @par Throws - //! @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws. - //! @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws. + //! @li If \c has_nothrow_move<T>::value is \c true and T's move constructor or move assignment throws. + //! @li If \c has_nothrow_move<T>::value is \c false and T's copy constructor or copy assignment throws. //! //! @par Complexity //! Linear O(N). @@ -384,16 +430,16 @@ public: //! @param other The static_vector which content will be moved to this one. //! //! @par Throws - //! @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws. - //! @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws. + //! @li If \c has_nothrow_move<T>::value is \c true and T's move constructor or move assignment throws. + //! @li If \c has_nothrow_move<T>::value is \c false and T's copy constructor or copy assignment throws. //! //! @par Complexity //! Linear O(N). - template <std::size_t C> - BOOST_CONTAINER_FORCEINLINE static_vector & operator=(BOOST_RV_REF_BEG static_vector<value_type, C> BOOST_RV_REF_END other) + template <std::size_t C, class O> + BOOST_CONTAINER_FORCEINLINE static_vector & operator=(BOOST_RV_REF_BEG static_vector<T, C, O> BOOST_RV_REF_END other) { return static_cast<static_vector&>(base_t::operator= - (BOOST_MOVE_BASE(typename static_vector<value_type BOOST_MOVE_I C>::base_t, other))); + (BOOST_MOVE_BASE(typename static_vector<T BOOST_MOVE_I C>::base_t, other))); } #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -412,8 +458,8 @@ public: //! @param other The static_vector which content will be swapped with this one's content. //! //! @par Throws - //! @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws, - //! @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws, + //! @li If \c has_nothrow_move<T>::value is \c true and T's move constructor or move assignment throws, + //! @li If \c has_nothrow_move<T>::value is \c false and T's copy constructor or copy assignment throws, //! //! @par Complexity //! Linear O(N). @@ -426,13 +472,13 @@ public: //! @param other The static_vector which content will be swapped with this one's content. //! //! @par Throws - //! @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws, - //! @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws, + //! @li If \c has_nothrow_move<T>::value is \c true and T's move constructor or move assignment throws, + //! @li If \c has_nothrow_move<T>::value is \c false and T's copy constructor or copy assignment throws, //! //! @par Complexity //! Linear O(N). - template <std::size_t C> - void swap(static_vector<value_type, C> & other); + template <std::size_t C, class O> + void swap(static_vector<T, C, O> & other); //! @pre <tt>count <= capacity()</tt> //! @@ -442,7 +488,7 @@ public: //! @param count The number of elements which will be stored in the container. //! //! @par Throws - //! If Value's value initialization throws. + //! If T's value initialization throws. //! //! @par Complexity //! Linear O(N). @@ -456,7 +502,7 @@ public: //! @param count The number of elements which will be stored in the container. //! //! @par Throws - //! If Value's default initialization throws. + //! If T's default initialization throws. //! //! @par Complexity //! Linear O(N). @@ -474,7 +520,7 @@ public: //! @param value The value used to copy construct the new element. //! //! @par Throws - //! If Value's copy constructor throws. + //! If T's copy constructor throws. //! //! @par Complexity //! Linear O(N). @@ -500,7 +546,7 @@ public: //! @param value The value used to copy construct the new element. //! //! @par Throws - //! If Value's copy constructor throws. + //! If T's copy constructor throws. //! //! @par Complexity //! Constant O(1). @@ -513,7 +559,7 @@ public: //! @param value The value to move construct the new element. //! //! @par Throws - //! If Value's move constructor throws. + //! If T's move constructor throws. //! //! @par Complexity //! Constant O(1). @@ -540,8 +586,8 @@ public: //! @param value The value used to copy construct the new element. //! //! @par Throws - //! @li If Value's copy constructor or copy assignment throws - //! @li If Value's move constructor or move assignment throws. + //! @li If T's copy constructor or copy assignment throws + //! @li If T's move constructor or move assignment throws. //! //! @par Complexity //! Constant or linear. @@ -557,7 +603,7 @@ public: //! @param value The value used to move construct the new element. //! //! @par Throws - //! If Value's move constructor or move assignment throws. + //! If T's move constructor or move assignment throws. //! //! @par Complexity //! Constant or linear. @@ -574,8 +620,8 @@ public: //! @param value The value used to copy construct new elements. //! //! @par Throws - //! @li If Value's copy constructor or copy assignment throws. - //! @li If Value's move constructor or move assignment throws. + //! @li If T's copy constructor or copy assignment throws. + //! @li If T's move constructor or move assignment throws. //! //! @par Complexity //! Linear O(N). @@ -593,8 +639,8 @@ public: //! @param last The iterator to the one after the last element of a range used to construct new elements. //! //! @par Throws - //! @li If Value's constructor and assignment taking a dereferenced \c Iterator. - //! @li If Value's move constructor or move assignment throws. + //! @li If T's constructor and assignment taking a dereferenced \c Iterator. + //! @li If T's move constructor or move assignment throws. //! //! @par Complexity //! Linear O(N). @@ -611,7 +657,7 @@ public: //! @param il The std::initializer_list which contains elements that will be inserted. //! //! @par Throws - //! @li If Value's constructor and assignment taking a dereferenced std::initializer_list iterator. + //! @li If T's constructor and assignment taking a dereferenced std::initializer_list iterator. //! //! @par Complexity //! Linear O(N). @@ -619,12 +665,12 @@ public: //! @pre \c p must be a valid iterator of \c *this in range <tt>[begin(), end())</tt> //! - //! @brief Erases Value from p. + //! @brief Erases T from p. //! //! @param p The position of the element which will be erased from the container. //! //! @par Throws - //! If Value's move assignment throws. + //! If T's move assignment throws. //! //! @par Complexity //! Linear O(N). @@ -640,7 +686,7 @@ public: //! @param last The position of the one after the last element of a range which will be erased from the container. //! //! @par Throws - //! If Value's move assignment throws. + //! If T's move assignment throws. //! //! @par Complexity //! Linear O(N). @@ -654,7 +700,7 @@ public: //! @param last The iterator to the one after the last element of a range used to construct new content of this container. //! //! @par Throws - //! If Value's copy constructor or copy assignment throws, + //! If T's copy constructor or copy assignment throws, //! //! @par Complexity //! Linear O(N). @@ -668,7 +714,7 @@ public: //! @param il std::initializer_list with values used to construct new content of this container. //! //! @par Throws - //! If Value's copy constructor or copy assignment throws, + //! If T's copy constructor or copy assignment throws, //! //! @par Complexity //! Linear O(N). @@ -682,7 +728,7 @@ public: //! @param value The value which will be used to copy construct the new content. //! //! @par Throws - //! If Value's copy constructor or copy assignment throws. + //! If T's copy constructor or copy assignment throws. //! //! @par Complexity //! Linear O(N). @@ -690,7 +736,7 @@ public: //! @pre <tt>size() < capacity()</tt> //! - //! @brief Inserts a Value constructed with + //! @brief Inserts a T constructed with //! \c std::forward<Args>(args)... in the end of the container. //! //! @return A reference to the created object. @@ -698,7 +744,7 @@ public: //! @param args The arguments of the constructor of the new element which will be created at the end of the container. //! //! @par Throws - //! If in-place constructor throws or Value's move constructor throws. + //! If in-place constructor throws or T's move constructor throws. //! //! @par Complexity //! Constant O(1). @@ -709,14 +755,14 @@ public: //! @li \c p must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt> //! @li <tt>size() < capacity()</tt> //! - //! @brief Inserts a Value constructed with + //! @brief Inserts a T constructed with //! \c std::forward<Args>(args)... before p //! //! @param p The position at which new elements will be inserted. //! @param args The arguments of the constructor of the new element. //! //! @par Throws - //! If in-place constructor throws or if Value's move constructor or move assignment throws. + //! If in-place constructor throws or if T's move constructor or move assignment throws. //! //! @par Complexity //! Constant or linear. @@ -920,7 +966,7 @@ public: //! //! @par Complexity //! Constant O(1). - Value * data() BOOST_NOEXCEPT_OR_NOTHROW; + T * data() BOOST_NOEXCEPT_OR_NOTHROW; //! @brief Const pointer such that <tt>[data(), data() + size())</tt> is a valid range. //! For a non-empty vector <tt>data() == &front()</tt>. @@ -930,7 +976,7 @@ public: //! //! @par Complexity //! Constant O(1). - const Value * data() const BOOST_NOEXCEPT_OR_NOTHROW; + const T * data() const BOOST_NOEXCEPT_OR_NOTHROW; //! @brief Returns iterator to the first element. //! @@ -1138,8 +1184,8 @@ public: //! //! @par Complexity //! Linear O(N). -template<typename V, std::size_t C1, std::size_t C2> -bool operator== (static_vector<V, C1> const& x, static_vector<V, C2> const& y); +template<typename V, std::size_t C1, std::size_t C2, class O1, class O2> +bool operator== (static_vector<V, C1, O1> const& x, static_vector<V, C2, O2> const& y); //! @brief Checks if contents of two static_vectors are not equal. //! @@ -1152,8 +1198,8 @@ bool operator== (static_vector<V, C1> const& x, static_vector<V, C2> const& y); //! //! @par Complexity //! Linear O(N). -template<typename V, std::size_t C1, std::size_t C2> -bool operator!= (static_vector<V, C1> const& x, static_vector<V, C2> const& y); +template<typename V, std::size_t C1, std::size_t C2, class O1, class O2> +bool operator!= (static_vector<V, C1, O1> const& x, static_vector<V, C2, O2> const& y); //! @brief Lexicographically compares static_vectors. //! @@ -1166,8 +1212,8 @@ bool operator!= (static_vector<V, C1> const& x, static_vector<V, C2> const& y); //! //! @par Complexity //! Linear O(N). -template<typename V, std::size_t C1, std::size_t C2> -bool operator< (static_vector<V, C1> const& x, static_vector<V, C2> const& y); +template<typename V, std::size_t C1, std::size_t C2, class O1, class O2> +bool operator< (static_vector<V, C1, O1> const& x, static_vector<V, C2, O2> const& y); //! @brief Lexicographically compares static_vectors. //! @@ -1180,8 +1226,8 @@ bool operator< (static_vector<V, C1> const& x, static_vector<V, C2> const& y); //! //! @par Complexity //! Linear O(N). -template<typename V, std::size_t C1, std::size_t C2> -bool operator> (static_vector<V, C1> const& x, static_vector<V, C2> const& y); +template<typename V, std::size_t C1, std::size_t C2, class O1, class O2> +bool operator> (static_vector<V, C1, O1> const& x, static_vector<V, C2, O2> const& y); //! @brief Lexicographically compares static_vectors. //! @@ -1194,8 +1240,8 @@ bool operator> (static_vector<V, C1> const& x, static_vector<V, C2> const& y); //! //! @par Complexity //! Linear O(N). -template<typename V, std::size_t C1, std::size_t C2> -bool operator<= (static_vector<V, C1> const& x, static_vector<V, C2> const& y); +template<typename V, std::size_t C1, std::size_t C2, class O1, class O2> +bool operator<= (static_vector<V, C1, O1> const& x, static_vector<V, C2, O2> const& y); //! @brief Lexicographically compares static_vectors. //! @@ -1208,8 +1254,8 @@ bool operator<= (static_vector<V, C1> const& x, static_vector<V, C2> const& y); //! //! @par Complexity //! Linear O(N). -template<typename V, std::size_t C1, std::size_t C2> -bool operator>= (static_vector<V, C1> const& x, static_vector<V, C2> const& y); +template<typename V, std::size_t C1, std::size_t C2, class O1, class O2> +bool operator>= (static_vector<V, C1, O1> const& x, static_vector<V, C2, O2> const& y); //! @brief Swaps contents of two static_vectors. //! @@ -1222,13 +1268,13 @@ bool operator>= (static_vector<V, C1> const& x, static_vector<V, C2> const& y); //! //! @par Complexity //! Linear O(N). -template<typename V, std::size_t C1, std::size_t C2> -inline void swap(static_vector<V, C1> & x, static_vector<V, C2> & y); +template<typename V, std::size_t C1, std::size_t C2, class O1, class O2> +inline void swap(static_vector<V, C1, O1> & x, static_vector<V, C2, O2> & y); #else -template<typename V, std::size_t C1, std::size_t C2> -inline void swap(static_vector<V, C1> & x, static_vector<V, C2> & y +template<typename V, std::size_t C1, std::size_t C2, class O1, class O2> +inline void swap(static_vector<V, C1, O1> & x, static_vector<V, C2, O2> & y , typename dtl::enable_if_c< C1 != C2>::type * = 0) { x.swap(y); |