1 // Boost.Container static_vector
2 //
3 // Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
4 // Copyright (c) 2011-2013 Andrew Hundt.
5 // Copyright (c) 2013-2014 Ion Gaztanaga
6 //
7 // Use, modification and distribution is subject to the Boost Software License,
8 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 
11 #ifndef BOOST_CONTAINER_STATIC_VECTOR_HPP
12 #define BOOST_CONTAINER_STATIC_VECTOR_HPP
13 
14 #ifndef BOOST_CONFIG_HPP
15 #  include <boost/config.hpp>
16 #endif
17 
18 #if defined(BOOST_HAS_PRAGMA_ONCE)
19 #  pragma once
20 #endif
21 
22 #include <boost/container/detail/config_begin.hpp>
23 #include <boost/container/detail/workaround.hpp>
24 #include <boost/container/detail/type_traits.hpp>
25 #include <boost/container/vector.hpp>
26 
27 #include <cstddef>
28 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
29 #include <initializer_list>
30 #endif
31 
32 namespace boost { namespace container {
33 
34 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
35 
36 namespace dtl {
37 
38 template<class T, std::size_t N, std::size_t InplaceAlignment, bool ThrowOnOverflow>
39 class static_storage_allocator
40 {
41    typedef bool_<ThrowOnOverflow> throw_on_overflow_t;
42 
on_capacity_overflow(true_type)43    static BOOST_NORETURN BOOST_CONTAINER_FORCEINLINE void on_capacity_overflow(true_type)
44    {
45       (throw_bad_alloc)();
46    }
47 
on_capacity_overflow(false_type)48    static BOOST_CONTAINER_FORCEINLINE void on_capacity_overflow(false_type)
49    {
50       BOOST_ASSERT_MSG(false, "ERROR: static vector capacity overflow");
51    }
52 
53    public:
54    typedef T value_type;
55 
static_storage_allocator()56    BOOST_CONTAINER_FORCEINLINE static_storage_allocator() BOOST_NOEXCEPT_OR_NOTHROW
57    {}
58 
static_storage_allocator(const static_storage_allocator &)59    BOOST_CONTAINER_FORCEINLINE static_storage_allocator(const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
60    {}
61 
operator =(const static_storage_allocator &)62    BOOST_CONTAINER_FORCEINLINE static_storage_allocator & operator=(const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
63    {  return *this;  }
64 
internal_storage() const65    BOOST_CONTAINER_FORCEINLINE T* internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW
66    {  return const_cast<T*>(static_cast<const T*>(static_cast<const void*>(storage.data)));  }
67 
internal_storage()68    BOOST_CONTAINER_FORCEINLINE T* internal_storage() BOOST_NOEXCEPT_OR_NOTHROW
69    {  return static_cast<T*>(static_cast<void*>(storage.data));  }
70 
71    static const std::size_t internal_capacity = N;
72 
max_size() const73    std::size_t max_size() const
74    {  return N;   }
75 
on_capacity_overflow()76    static BOOST_CONTAINER_FORCEINLINE void on_capacity_overflow()
77    {
78       (on_capacity_overflow)(throw_on_overflow_t());
79    }
80 
81    typedef boost::container::dtl::version_type<static_storage_allocator, 0>   version;
82 
operator ==(const static_storage_allocator &,const static_storage_allocator &)83    BOOST_CONTAINER_FORCEINLINE friend bool operator==(const static_storage_allocator &, const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
84    {  return false;  }
85 
operator !=(const static_storage_allocator &,const static_storage_allocator &)86    BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const static_storage_allocator &, const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
87    {  return true;  }
88 
89    private:
90    BOOST_STATIC_ASSERT_MSG(!InplaceAlignment || (InplaceAlignment & (InplaceAlignment-1)) == 0, "Alignment option must be zero or power of two");
91    static const std::size_t final_alignment = InplaceAlignment ? InplaceAlignment : dtl::alignment_of<T>::value;
92    typename dtl::aligned_storage<sizeof(T)*N, final_alignment>::type storage;
93 };
94 
95 template<class Options>
96 struct get_static_vector_opt
97 {
98    typedef Options type;
99 };
100 
101 template<>
102 struct get_static_vector_opt<void>
103 {
104    typedef static_vector_null_opt type;
105 };
106 
107 template <typename T, std::size_t Capacity, class Options>
108 struct get_static_vector_allocator
109 {
110    typedef typename  get_static_vector_opt<Options>::type options_t;
111    typedef dtl::static_storage_allocator
112       < T
113       , Capacity
114       , options_t::inplace_alignment
115       , options_t::throw_on_overflow
116       > type;
117 };
118 
119 
120 }  //namespace dtl {
121 
122 #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
123 
124 //!
125 //!@brief A variable-size array container with fixed capacity.
126 //!
127 //!static_vector is a sequence container like boost::container::vector with contiguous storage that can
128 //!change in size, along with the static allocation, low overhead, and fixed capacity of boost::array.
129 //!
130 //!A static_vector is a sequence that supports random access to elements, constant time insertion and
131 //!removal of elements at the end, and linear time insertion and removal of elements at the beginning or
132 //!in the middle. The number of elements in a static_vector may vary dynamically up to a fixed capacity
133 //!because elements are stored within the object itself similarly to an array. However, objects are
134 //!initialized as they are inserted into static_vector unlike C arrays or std::array which must construct
135 //!all elements on instantiation. The behavior of static_vector enables the use of statically allocated
136 //!elements in cases with complex object lifetime requirements that would otherwise not be trivially
137 //!possible.
138 //!
139 //!@par Error Handling
140 //! Insertion beyond the capacity result in throwing std::bad_alloc() if exceptions are enabled or
141 //! calling throw_bad_alloc() if not enabled.
142 //!
143 //! std::out_of_range is thrown if out of bounds access is performed in <code>at()</code> if exceptions are
144 //! enabled, throw_out_of_range() if not enabled.
145 //!
146 //!@tparam T    The type of element that will be stored.
147 //!@tparam Capacity The maximum number of elements static_vector can store, fixed at compile time.
148 //!@tparam Options A type produced from \c boost::container::static_vector_options.
149 template <typename T, std::size_t Capacity, class Options BOOST_CONTAINER_DOCONLY(= void) >
150 class static_vector
151     : public vector<T, typename dtl::get_static_vector_allocator< T, Capacity, Options>::type>
152 {
153    public:
154    #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
155    typedef typename dtl::get_static_vector_allocator< T, Capacity, Options>::type allocator_type;
156    typedef vector<T, allocator_type > base_t;
157 
158    BOOST_COPYABLE_AND_MOVABLE(static_vector)
159 
160    template<class U, std::size_t OtherCapacity, class OtherOptions>
161    friend class static_vector;
162 
163    public:
164    #endif   //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
165 
166 public:
167     //! @brief The type of elements stored in the container.
168     typedef typename base_t::value_type value_type;
169     //! @brief The unsigned integral type used by the container.
170     typedef typename base_t::size_type size_type;
171     //! @brief The pointers difference type.
172     typedef typename base_t::difference_type difference_type;
173     //! @brief The pointer type.
174     typedef typename base_t::pointer pointer;
175     //! @brief The const pointer type.
176     typedef typename base_t::const_pointer const_pointer;
177     //! @brief The value reference type.
178     typedef typename base_t::reference reference;
179     //! @brief The value const reference type.
180     typedef typename base_t::const_reference const_reference;
181     //! @brief The iterator type.
182     typedef typename base_t::iterator iterator;
183     //! @brief The const iterator type.
184     typedef typename base_t::const_iterator const_iterator;
185     //! @brief The reverse iterator type.
186     typedef typename base_t::reverse_iterator reverse_iterator;
187     //! @brief The const reverse iterator.
188     typedef typename base_t::const_reverse_iterator const_reverse_iterator;
189 
190     //! @brief The capacity/max size of the container
191     static const size_type static_capacity = Capacity;
192 
193     //! @brief Constructs an empty static_vector.
194     //!
195     //! @par Throws
196     //!   Nothing.
197     //!
198     //! @par Complexity
199     //!   Constant O(1).
static_vector()200     BOOST_CONTAINER_FORCEINLINE static_vector() BOOST_NOEXCEPT_OR_NOTHROW
201         : base_t()
202     {}
203 
204     //! @pre <tt>count <= capacity()</tt>
205     //!
206     //! @brief Constructs a static_vector containing count value initialized values.
207     //!
208     //! @param count    The number of values which will be contained in the container.
209     //!
210     //! @par Throws
211     //!   If T's value initialization throws.
212     //!
213     //! @par Complexity
214     //!   Linear O(N).
static_vector(size_type count)215     BOOST_CONTAINER_FORCEINLINE explicit static_vector(size_type count)
216         : base_t(count)
217     {}
218 
219     //! @pre <tt>count <= capacity()</tt>
220     //!
221     //! @brief Constructs a static_vector containing count default initialized values.
222     //!
223     //! @param count    The number of values which will be contained in the container.
224     //!
225     //! @par Throws
226     //!   If T's default initialization throws.
227     //!
228     //! @par Complexity
229     //!   Linear O(N).
230     //!
231     //! @par Note
232     //!   Non-standard extension
static_vector(size_type count,default_init_t)233     BOOST_CONTAINER_FORCEINLINE static_vector(size_type count, default_init_t)
234         : base_t(count, default_init_t())
235     {}
236 
237     //! @pre <tt>count <= capacity()</tt>
238     //!
239     //! @brief Constructs a static_vector containing count copies of value.
240     //!
241     //! @param count    The number of copies of a values that will be contained in the container.
242     //! @param value    The value which will be used to copy construct values.
243     //!
244     //! @par Throws
245     //!   If T's copy constructor throws.
246     //!
247     //! @par Complexity
248     //!   Linear O(N).
static_vector(size_type count,value_type const & value)249     BOOST_CONTAINER_FORCEINLINE static_vector(size_type count, value_type const& value)
250         : base_t(count, value)
251     {}
252 
253     //! @pre
254     //!  @li <tt>distance(first, last) <= capacity()</tt>
255     //!  @li Iterator must meet the \c ForwardTraversalIterator concept.
256     //!
257     //! @brief Constructs a static_vector containing copy of a range <tt>[first, last)</tt>.
258     //!
259     //! @param first    The iterator to the first element in range.
260     //! @param last     The iterator to the one after the last element in range.
261     //!
262     //! @par Throws
263     //!   If T's constructor taking a dereferenced Iterator throws.
264     //!
265     //! @par Complexity
266     //!   Linear O(N).
267     template <typename Iterator>
static_vector(Iterator first,Iterator last)268     BOOST_CONTAINER_FORCEINLINE static_vector(Iterator first, Iterator last)
269         : base_t(first, last)
270     {}
271 
272 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
273     //! @pre
274     //!  @li <tt>distance(il.begin(), il.end()) <= capacity()</tt>
275     //!
276     //! @brief Constructs a static_vector containing copy of a range <tt>[il.begin(), il.end())</tt>.
277     //!
278     //! @param il       std::initializer_list with values to initialize vector.
279     //!
280     //! @par Throws
281     //!   If T's constructor taking a dereferenced std::initializer_list throws.
282     //!
283     //! @par Complexity
284     //!   Linear O(N).
static_vector(std::initializer_list<value_type> il)285     BOOST_CONTAINER_FORCEINLINE static_vector(std::initializer_list<value_type> il)
286         : base_t(il)
287     {}
288 #endif
289 
290     //! @brief Constructs a copy of other static_vector.
291     //!
292     //! @param other    The static_vector which content will be copied to this one.
293     //!
294     //! @par Throws
295     //!   If T's copy constructor throws.
296     //!
297     //! @par Complexity
298     //!   Linear O(N).
static_vector(static_vector const & other)299     BOOST_CONTAINER_FORCEINLINE static_vector(static_vector const& other)
300         : base_t(other)
301     {}
302 
static_vector(static_vector const & other,const allocator_type &)303     BOOST_CONTAINER_FORCEINLINE static_vector(static_vector const& other, const allocator_type &)
304        : base_t(other)
305     {}
306 
static_vector(BOOST_RV_REF (static_vector)other,const allocator_type &)307     BOOST_CONTAINER_FORCEINLINE static_vector(BOOST_RV_REF(static_vector) other,  const allocator_type &)
308        BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<value_type>::value)
309        : base_t(BOOST_MOVE_BASE(base_t, other))
310     {}
311 
static_vector(const allocator_type &)312     BOOST_CONTAINER_FORCEINLINE explicit static_vector(const allocator_type &)
313        : base_t()
314     {}
315 
316     //! @pre <tt>other.size() <= capacity()</tt>.
317     //!
318     //! @brief Constructs a copy of other static_vector.
319     //!
320     //! @param other    The static_vector which content will be copied to this one.
321     //!
322     //! @par Throws
323     //!   If T's copy constructor throws.
324     //!
325     //! @par Complexity
326     //!   Linear O(N).
327     template <std::size_t C, class O>
static_vector(static_vector<T,C,O> const & other)328     BOOST_CONTAINER_FORCEINLINE static_vector(static_vector<T, C, O> const& other)
329         : base_t(other)
330     {}
331 
332     //! @brief Move constructor. Moves Values stored in the other static_vector to this one.
333     //!
334     //! @param other    The static_vector which content will be moved to this one.
335     //!
336     //! @par Throws
337     //!   @li If \c has_nothrow_move<T>::value is \c true and T's move constructor throws.
338     //!   @li If \c has_nothrow_move<T>::value is \c false and T's copy constructor throws.
339     //!
340     //! @par Complexity
341     //!   Linear O(N).
static_vector(BOOST_RV_REF (static_vector)other)342     BOOST_CONTAINER_FORCEINLINE static_vector(BOOST_RV_REF(static_vector) other)
343       BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_constructible<value_type>::value)
344         : base_t(BOOST_MOVE_BASE(base_t, other))
345     {}
346 
347     //! @pre <tt>other.size() <= capacity()</tt>
348     //!
349     //! @brief Move constructor. Moves Values stored in the other static_vector to this one.
350     //!
351     //! @param other    The static_vector which content will be moved to this one.
352     //!
353     //! @par Throws
354     //!   @li If \c has_nothrow_move<T>::value is \c true and T's move constructor throws.
355     //!   @li If \c has_nothrow_move<T>::value is \c false and T's copy constructor throws.
356     //!
357     //! @par Complexity
358     //!   Linear O(N).
359     template <std::size_t C, class O>
static_vector(BOOST_RV_REF_BEG static_vector<T,C,O> BOOST_RV_REF_END other)360     BOOST_CONTAINER_FORCEINLINE static_vector(BOOST_RV_REF_BEG static_vector<T, C, O> BOOST_RV_REF_END other)
361         : base_t(BOOST_MOVE_BASE(typename static_vector<T BOOST_MOVE_I C>::base_t, other))
362     {}
363 
364     //! @brief Copy assigns Values stored in the other static_vector to this one.
365     //!
366     //! @param other    The static_vector which content will be copied to this one.
367     //!
368     //! @par Throws
369     //!   If T's copy constructor or copy assignment throws.
370     //!
371     //! @par Complexity
372     //! Linear O(N).
operator =(BOOST_COPY_ASSIGN_REF (static_vector)other)373     BOOST_CONTAINER_FORCEINLINE static_vector & operator=(BOOST_COPY_ASSIGN_REF(static_vector) other)
374     {
375         return static_cast<static_vector&>(base_t::operator=(static_cast<base_t const&>(other)));
376     }
377 
378 #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
379     //! @brief Copy assigns Values stored in std::initializer_list to *this.
380     //!
381     //! @param il    The std::initializer_list which content will be copied to this one.
382     //!
383     //! @par Throws
384     //!   If T's copy constructor or copy assignment throws.
385     //!
386     //! @par Complexity
387     //! Linear O(N).
operator =(std::initializer_list<value_type> il)388     BOOST_CONTAINER_FORCEINLINE static_vector & operator=(std::initializer_list<value_type> il)
389     { return static_cast<static_vector&>(base_t::operator=(il));  }
390 #endif
391 
392     //! @pre <tt>other.size() <= capacity()</tt>
393     //!
394     //! @brief Copy assigns Values stored in the other static_vector to this one.
395     //!
396     //! @param other    The static_vector which content will be copied to this one.
397     //!
398     //! @par Throws
399     //!   If T's copy constructor or copy assignment throws.
400     //!
401     //! @par Complexity
402     //!   Linear O(N).
403     template <std::size_t C, class O>
operator =(static_vector<T,C,O> const & other)404     BOOST_CONTAINER_FORCEINLINE static_vector & operator=(static_vector<T, C, O> const& other)
405     {
406         return static_cast<static_vector&>(base_t::operator=
407             (static_cast<typename static_vector<T, C, O>::base_t const&>(other)));
408     }
409 
410     //! @brief Move assignment. Moves Values stored in the other static_vector to this one.
411     //!
412     //! @param other    The static_vector which content will be moved to this one.
413     //!
414     //! @par Throws
415     //!   @li If \c has_nothrow_move<T>::value is \c true and T's move constructor or move assignment throws.
416     //!   @li If \c has_nothrow_move<T>::value is \c false and T's copy constructor or copy assignment throws.
417     //!
418     //! @par Complexity
419     //!   Linear O(N).
operator =(BOOST_RV_REF (static_vector)other)420     BOOST_CONTAINER_FORCEINLINE static_vector & operator=(BOOST_RV_REF(static_vector) other)
421        BOOST_NOEXCEPT_IF(boost::container::dtl::is_nothrow_move_assignable<value_type>::value)
422     {
423         return static_cast<static_vector&>(base_t::operator=(BOOST_MOVE_BASE(base_t, other)));
424     }
425 
426     //! @pre <tt>other.size() <= capacity()</tt>
427     //!
428     //! @brief Move assignment. Moves Values stored in the other static_vector to this one.
429     //!
430     //! @param other    The static_vector which content will be moved to this one.
431     //!
432     //! @par Throws
433     //!   @li If \c has_nothrow_move<T>::value is \c true and T's move constructor or move assignment throws.
434     //!   @li If \c has_nothrow_move<T>::value is \c false and T's copy constructor or copy assignment throws.
435     //!
436     //! @par Complexity
437     //!   Linear O(N).
438     template <std::size_t C, class O>
operator =(BOOST_RV_REF_BEG static_vector<T,C,O> BOOST_RV_REF_END other)439     BOOST_CONTAINER_FORCEINLINE static_vector & operator=(BOOST_RV_REF_BEG static_vector<T, C, O> BOOST_RV_REF_END other)
440     {
441         return static_cast<static_vector&>(base_t::operator=
442          (BOOST_MOVE_BASE(typename static_vector<T BOOST_MOVE_I C>::base_t, other)));
443     }
444 
445 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
446 
447     //! @brief Destructor. Destroys Values stored in this container.
448     //!
449     //! @par Throws
450     //!   Nothing
451     //!
452     //! @par Complexity
453     //!   Linear O(N).
454     ~static_vector();
455 
456     //! @brief Swaps contents of the other static_vector and this one.
457     //!
458     //! @param other    The static_vector which content will be swapped with this one's content.
459     //!
460     //! @par Throws
461     //!   @li If \c has_nothrow_move<T>::value is \c true and T's move constructor or move assignment throws,
462     //!   @li If \c has_nothrow_move<T>::value is \c false and T's copy constructor or copy assignment throws,
463     //!
464     //! @par Complexity
465     //!   Linear O(N).
466     void swap(static_vector & other);
467 
468     //! @pre <tt>other.size() <= capacity() && size() <= other.capacity()</tt>
469     //!
470     //! @brief Swaps contents of the other static_vector and this one.
471     //!
472     //! @param other    The static_vector which content will be swapped with this one's content.
473     //!
474     //! @par Throws
475     //!   @li If \c has_nothrow_move<T>::value is \c true and T's move constructor or move assignment throws,
476     //!   @li If \c has_nothrow_move<T>::value is \c false and T's copy constructor or copy assignment throws,
477     //!
478     //! @par Complexity
479     //!   Linear O(N).
480     template <std::size_t C, class O>
481     void swap(static_vector<T, C, O> & other);
482 
483     //! @pre <tt>count <= capacity()</tt>
484     //!
485     //! @brief Inserts or erases elements at the end such that
486     //!   the size becomes count. New elements are value initialized.
487     //!
488     //! @param count    The number of elements which will be stored in the container.
489     //!
490     //! @par Throws
491     //!   If T's value initialization throws.
492     //!
493     //! @par Complexity
494     //!   Linear O(N).
495     void resize(size_type count);
496 
497     //! @pre <tt>count <= capacity()</tt>
498     //!
499     //! @brief Inserts or erases elements at the end such that
500     //!   the size becomes count. New elements are default initialized.
501     //!
502     //! @param count    The number of elements which will be stored in the container.
503     //!
504     //! @par Throws
505     //!   If T's default initialization throws.
506     //!
507     //! @par Complexity
508     //!   Linear O(N).
509     //!
510     //! @par Note
511     //!   Non-standard extension
512     void resize(size_type count, default_init_t);
513 
514     //! @pre <tt>count <= capacity()</tt>
515     //!
516     //! @brief Inserts or erases elements at the end such that
517     //!   the size becomes count. New elements are copy constructed from value.
518     //!
519     //! @param count    The number of elements which will be stored in the container.
520     //! @param value    The value used to copy construct the new element.
521     //!
522     //! @par Throws
523     //!   If T's copy constructor throws.
524     //!
525     //! @par Complexity
526     //!   Linear O(N).
527     void resize(size_type count, value_type const& value);
528 
529     //! @pre <tt>count <= capacity()</tt>
530     //!
531     //! @brief This call has no effect because the Capacity of this container is constant.
532     //!
533     //! @param count    The number of elements which the container should be able to contain.
534     //!
535     //! @par Throws
536     //!   Nothing.
537     //!
538     //! @par Complexity
539     //!   Linear O(N).
540     void reserve(size_type count)  BOOST_NOEXCEPT_OR_NOTHROW;
541 
542     //! @pre <tt>size() < capacity()</tt>
543     //!
544     //! @brief Adds a copy of value at the end.
545     //!
546     //! @param value    The value used to copy construct the new element.
547     //!
548     //! @par Throws
549     //!   If T's copy constructor throws.
550     //!
551     //! @par Complexity
552     //!   Constant O(1).
553     void push_back(value_type const& value);
554 
555     //! @pre <tt>size() < capacity()</tt>
556     //!
557     //! @brief Moves value to the end.
558     //!
559     //! @param value    The value to move construct the new element.
560     //!
561     //! @par Throws
562     //!   If T's move constructor throws.
563     //!
564     //! @par Complexity
565     //!   Constant O(1).
566     void push_back(BOOST_RV_REF(value_type) value);
567 
568     //! @pre <tt>!empty()</tt>
569     //!
570     //! @brief Destroys last value and decreases the size.
571     //!
572     //! @par Throws
573     //!   Nothing by default.
574     //!
575     //! @par Complexity
576     //!   Constant O(1).
577     void pop_back();
578 
579     //! @pre
580     //!  @li \c p must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
581     //!  @li <tt>size() < capacity()</tt>
582     //!
583     //! @brief Inserts a copy of element at p.
584     //!
585     //! @param p     The position at which the new value will be inserted.
586     //! @param value The value used to copy construct the new element.
587     //!
588     //! @par Throws
589     //!   @li If T's copy constructor or copy assignment throws
590     //!   @li If T's move constructor or move assignment throws.
591     //!
592     //! @par Complexity
593     //!   Constant or linear.
594     iterator insert(const_iterator p, value_type const& value);
595 
596     //! @pre
597     //!  @li \c p must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
598     //!  @li <tt>size() < capacity()</tt>
599     //!
600     //! @brief Inserts a move-constructed element at p.
601     //!
602     //! @param p     The position at which the new value will be inserted.
603     //! @param value The value used to move construct the new element.
604     //!
605     //! @par Throws
606     //!   If T's move constructor or move assignment throws.
607     //!
608     //! @par Complexity
609     //!   Constant or linear.
610     iterator insert(const_iterator p, BOOST_RV_REF(value_type) value);
611 
612     //! @pre
613     //!  @li \c p must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
614     //!  @li <tt>size() + count <= capacity()</tt>
615     //!
616     //! @brief Inserts a count copies of value at p.
617     //!
618     //! @param p     The position at which new elements will be inserted.
619     //! @param count The number of new elements which will be inserted.
620     //! @param value The value used to copy construct new elements.
621     //!
622     //! @par Throws
623     //!   @li If T's copy constructor or copy assignment throws.
624     //!   @li If T's move constructor or move assignment throws.
625     //!
626     //! @par Complexity
627     //!   Linear O(N).
628     iterator insert(const_iterator p, size_type count, value_type const& value);
629 
630     //! @pre
631     //!  @li \c p must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
632     //!  @li <tt>distance(first, last) <= capacity()</tt>
633     //!  @li \c Iterator must meet the \c ForwardTraversalIterator concept.
634     //!
635     //! @brief Inserts a copy of a range <tt>[first, last)</tt> at p.
636     //!
637     //! @param p     The position at which new elements will be inserted.
638     //! @param first The iterator to the first element of a range used to construct new elements.
639     //! @param last  The iterator to the one after the last element of a range used to construct new elements.
640     //!
641     //! @par Throws
642     //!   @li If T's constructor and assignment taking a dereferenced \c Iterator.
643     //!   @li If T's move constructor or move assignment throws.
644     //!
645     //! @par Complexity
646     //!   Linear O(N).
647     template <typename Iterator>
648     iterator insert(const_iterator p, Iterator first, Iterator last);
649 
650     //! @pre
651     //!  @li \c p must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>.
652     //!  @li <tt>distance(il.begin(), il.end()) <= capacity()</tt>
653     //!
654     //! @brief Inserts a copy of a range <tt>[il.begin(), il.end())</tt> at p.
655     //!
656     //! @param p     The position at which new elements will be inserted.
657     //! @param il    The std::initializer_list which contains elements that will be inserted.
658     //!
659     //! @par Throws
660     //!   @li If T's constructor and assignment taking a dereferenced std::initializer_list iterator.
661     //!
662     //! @par Complexity
663     //!   Linear O(N).
664     iterator insert(const_iterator p, std::initializer_list<value_type> il);
665 
666     //! @pre \c p must be a valid iterator of \c *this in range <tt>[begin(), end())</tt>
667     //!
668     //! @brief Erases T from p.
669     //!
670     //! @param p    The position of the element which will be erased from the container.
671     //!
672     //! @par Throws
673     //!   If T's move assignment throws.
674     //!
675     //! @par Complexity
676     //!   Linear O(N).
677     iterator erase(const_iterator p);
678 
679     //! @pre
680     //!  @li \c first and \c last must define a valid range
681     //!  @li iterators must be in range <tt>[begin(), end()]</tt>
682     //!
683     //! @brief Erases Values from a range <tt>[first, last)</tt>.
684     //!
685     //! @param first    The position of the first element of a range which will be erased from the container.
686     //! @param last     The position of the one after the last element of a range which will be erased from the container.
687     //!
688     //! @par Throws
689     //!   If T's move assignment throws.
690     //!
691     //! @par Complexity
692     //!   Linear O(N).
693     iterator erase(const_iterator first, const_iterator last);
694 
695     //! @pre <tt>distance(first, last) <= capacity()</tt>
696     //!
697     //! @brief Assigns a range <tt>[first, last)</tt> of Values to this container.
698     //!
699     //! @param first       The iterator to the first element of a range used to construct new content of this container.
700     //! @param last        The iterator to the one after the last element of a range used to construct new content of this container.
701     //!
702     //! @par Throws
703     //!   If T's copy constructor or copy assignment throws,
704     //!
705     //! @par Complexity
706     //!   Linear O(N).
707     template <typename Iterator>
708     void assign(Iterator first, Iterator last);
709 
710     //! @pre <tt>distance(il.begin(), il.end()) <= capacity()</tt>
711     //!
712     //! @brief Assigns a range <tt>[il.begin(), il.end())</tt> of Values to this container.
713     //!
714     //! @param il       std::initializer_list with values used to construct new content of this container.
715     //!
716     //! @par Throws
717     //!   If T's copy constructor or copy assignment throws,
718     //!
719     //! @par Complexity
720     //!   Linear O(N).
721     void assign(std::initializer_list<value_type> il);
722 
723     //! @pre <tt>count <= capacity()</tt>
724     //!
725     //! @brief Assigns a count copies of value to this container.
726     //!
727     //! @param count       The new number of elements which will be container in the container.
728     //! @param value       The value which will be used to copy construct the new content.
729     //!
730     //! @par Throws
731     //!   If T's copy constructor or copy assignment throws.
732     //!
733     //! @par Complexity
734     //!   Linear O(N).
735     void assign(size_type count, value_type const& value);
736 
737     //! @pre <tt>size() < capacity()</tt>
738     //!
739     //! @brief Inserts a T constructed with
740     //!   \c std::forward<Args>(args)... in the end of the container.
741     //!
742     //! @return A reference to the created object.
743     //!
744     //! @param args     The arguments of the constructor of the new element which will be created at the end of the container.
745     //!
746     //! @par Throws
747     //!   If in-place constructor throws or T's move constructor throws.
748     //!
749     //! @par Complexity
750     //!   Constant O(1).
751     template<class ...Args>
752     reference emplace_back(Args &&...args);
753 
754     //! @pre
755     //!  @li \c p must be a valid iterator of \c *this in range <tt>[begin(), end()]</tt>
756     //!  @li <tt>size() < capacity()</tt>
757     //!
758     //! @brief Inserts a T constructed with
759     //!   \c std::forward<Args>(args)... before p
760     //!
761     //! @param p     The position at which new elements will be inserted.
762     //! @param args  The arguments of the constructor of the new element.
763     //!
764     //! @par Throws
765     //!   If in-place constructor throws or if T's move constructor or move assignment throws.
766     //!
767     //! @par Complexity
768     //!   Constant or linear.
769     template<class ...Args>
770     iterator emplace(const_iterator p, Args &&...args);
771 
772     //! @brief Removes all elements from the container.
773     //!
774     //! @par Throws
775     //!   Nothing.
776     //!
777     //! @par Complexity
778     //!   Constant O(1).
779     void clear()  BOOST_NOEXCEPT_OR_NOTHROW;
780 
781     //! @pre <tt>i < size()</tt>
782     //!
783     //! @brief Returns reference to the i-th element.
784     //!
785     //! @param i    The element's index.
786     //!
787     //! @return reference to the i-th element
788     //!   from the beginning of the container.
789     //!
790     //! @par Throws
791     //!   \c std::out_of_range exception by default.
792     //!
793     //! @par Complexity
794     //!   Constant O(1).
795     reference at(size_type i);
796 
797     //! @pre <tt>i < size()</tt>
798     //!
799     //! @brief Returns const reference to the i-th element.
800     //!
801     //! @param i    The element's index.
802     //!
803     //! @return const reference to the i-th element
804     //!   from the beginning of the container.
805     //!
806     //! @par Throws
807     //!   \c std::out_of_range exception by default.
808     //!
809     //! @par Complexity
810     //!   Constant O(1).
811     const_reference at(size_type i) const;
812 
813     //! @pre <tt>i < size()</tt>
814     //!
815     //! @brief Returns reference to the i-th element.
816     //!
817     //! @param i    The element's index.
818     //!
819     //! @return reference to the i-th element
820     //!   from the beginning of the container.
821     //!
822     //! @par Throws
823     //!   Nothing by default.
824     //!
825     //! @par Complexity
826     //!   Constant O(1).
827     reference operator[](size_type i);
828 
829     //! @pre <tt>i < size()</tt>
830     //!
831     //! @brief Returns const reference to the i-th element.
832     //!
833     //! @param i    The element's index.
834     //!
835     //! @return const reference to the i-th element
836     //!   from the beginning of the container.
837     //!
838     //! @par Throws
839     //!   Nothing by default.
840     //!
841     //! @par Complexity
842     //!   Constant O(1).
843     const_reference operator[](size_type i) const;
844 
845     //! @pre <tt>i =< size()</tt>
846     //!
847     //! @brief Returns a iterator to the i-th element.
848     //!
849     //! @param i    The element's index.
850     //!
851     //! @return a iterator to the i-th element.
852     //!
853     //! @par Throws
854     //!   Nothing by default.
855     //!
856     //! @par Complexity
857     //!   Constant O(1).
858     iterator nth(size_type i);
859 
860     //! @pre <tt>i =< size()</tt>
861     //!
862     //! @brief Returns a const_iterator to the i-th element.
863     //!
864     //! @param i    The element's index.
865     //!
866     //! @return a const_iterator to the i-th element.
867     //!
868     //! @par Throws
869     //!   Nothing by default.
870     //!
871     //! @par Complexity
872     //!   Constant O(1).
873     const_iterator nth(size_type i) const;
874 
875     //! @pre <tt>begin() <= p <= end()</tt>
876     //!
877     //! @brief Returns the index of the element pointed by p.
878     //!
879     //! @param p    An iterator to the element.
880     //!
881     //! @return The index of the element pointed by p.
882     //!
883     //! @par Throws
884     //!   Nothing by default.
885     //!
886     //! @par Complexity
887     //!   Constant O(1).
888     size_type index_of(iterator p);
889 
890     //! @pre <tt>begin() <= p <= end()</tt>
891     //!
892     //! @brief Returns the index of the element pointed by p.
893     //!
894     //! @param p    A const_iterator to the element.
895     //!
896     //! @return a const_iterator to the i-th element.
897     //!
898     //! @par Throws
899     //!   Nothing by default.
900     //!
901     //! @par Complexity
902     //!   Constant O(1).
903     size_type index_of(const_iterator p) const;
904 
905     //! @pre \c !empty()
906     //!
907     //! @brief Returns reference to the first element.
908     //!
909     //! @return reference to the first element
910     //!   from the beginning of the container.
911     //!
912     //! @par Throws
913     //!   Nothing by default.
914     //!
915     //! @par Complexity
916     //!   Constant O(1).
917     reference front();
918 
919     //! @pre \c !empty()
920     //!
921     //! @brief Returns const reference to the first element.
922     //!
923     //! @return const reference to the first element
924     //!   from the beginning of the container.
925     //!
926     //! @par Throws
927     //!   Nothing by default.
928     //!
929     //! @par Complexity
930     //!   Constant O(1).
931     const_reference front() const;
932 
933     //! @pre \c !empty()
934     //!
935     //! @brief Returns reference to the last element.
936     //!
937     //! @return reference to the last element
938     //!   from the beginning of the container.
939     //!
940     //! @par Throws
941     //!   Nothing by default.
942     //!
943     //! @par Complexity
944     //!   Constant O(1).
945     reference back();
946 
947     //! @pre \c !empty()
948     //!
949     //! @brief Returns const reference to the first element.
950     //!
951     //! @return const reference to the last element
952     //!   from the beginning of the container.
953     //!
954     //! @par Throws
955     //!   Nothing by default.
956     //!
957     //! @par Complexity
958     //!   Constant O(1).
959     const_reference back() const;
960 
961     //! @brief Pointer such that <tt>[data(), data() + size())</tt> is a valid range.
962     //!   For a non-empty vector <tt>data() == &front()</tt>.
963     //!
964     //! @par Throws
965     //!   Nothing.
966     //!
967     //! @par Complexity
968     //!   Constant O(1).
969     T * data() BOOST_NOEXCEPT_OR_NOTHROW;
970 
971     //! @brief Const pointer such that <tt>[data(), data() + size())</tt> is a valid range.
972     //!   For a non-empty vector <tt>data() == &front()</tt>.
973     //!
974     //! @par Throws
975     //!   Nothing.
976     //!
977     //! @par Complexity
978     //!   Constant O(1).
979     const T * data() const BOOST_NOEXCEPT_OR_NOTHROW;
980 
981     //! @brief Returns iterator to the first element.
982     //!
983     //! @return iterator to the first element contained in the vector.
984     //!
985     //! @par Throws
986     //!   Nothing.
987     //!
988     //! @par Complexity
989     //!   Constant O(1).
990     iterator begin() BOOST_NOEXCEPT_OR_NOTHROW;
991 
992     //! @brief Returns const iterator to the first element.
993     //!
994     //! @return const_iterator to the first element contained in the vector.
995     //!
996     //! @par Throws
997     //!   Nothing.
998     //!
999     //! @par Complexity
1000     //!   Constant O(1).
1001     const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW;
1002 
1003     //! @brief Returns const iterator to the first element.
1004     //!
1005     //! @return const_iterator to the first element contained in the vector.
1006     //!
1007     //! @par Throws
1008     //!   Nothing.
1009     //!
1010     //! @par Complexity
1011     //!   Constant O(1).
1012     const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
1013 
1014     //! @brief Returns iterator to the one after the last element.
1015     //!
1016     //! @return iterator pointing to the one after the last element contained in the vector.
1017     //!
1018     //! @par Throws
1019     //!   Nothing.
1020     //!
1021     //! @par Complexity
1022     //!   Constant O(1).
1023     iterator end() BOOST_NOEXCEPT_OR_NOTHROW;
1024 
1025     //! @brief Returns const iterator to the one after the last element.
1026     //!
1027     //! @return const_iterator pointing to the one after the last element contained in the vector.
1028     //!
1029     //! @par Throws
1030     //!   Nothing.
1031     //!
1032     //! @par Complexity
1033     //!   Constant O(1).
1034     const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW;
1035 
1036     //! @brief Returns const iterator to the one after the last element.
1037     //!
1038     //! @return const_iterator pointing to the one after the last element contained in the vector.
1039     //!
1040     //! @par Throws
1041     //!   Nothing.
1042     //!
1043     //! @par Complexity
1044     //!   Constant O(1).
1045     const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW;
1046 
1047     //! @brief Returns reverse iterator to the first element of the reversed container.
1048     //!
1049     //! @return reverse_iterator pointing to the beginning
1050     //! of the reversed static_vector.
1051     //!
1052     //! @par Throws
1053     //!   Nothing.
1054     //!
1055     //! @par Complexity
1056     //!   Constant O(1).
1057     reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW;
1058 
1059     //! @brief Returns const reverse iterator to the first element of the reversed container.
1060     //!
1061     //! @return const_reverse_iterator pointing to the beginning
1062     //! of the reversed static_vector.
1063     //!
1064     //! @par Throws
1065     //!   Nothing.
1066     //!
1067     //! @par Complexity
1068     //!   Constant O(1).
1069     const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
1070 
1071     //! @brief Returns const reverse iterator to the first element of the reversed container.
1072     //!
1073     //! @return const_reverse_iterator pointing to the beginning
1074     //! of the reversed static_vector.
1075     //!
1076     //! @par Throws
1077     //!   Nothing.
1078     //!
1079     //! @par Complexity
1080     //!   Constant O(1).
1081     const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
1082 
1083     //! @brief Returns reverse iterator to the one after the last element of the reversed container.
1084     //!
1085     //! @return reverse_iterator pointing to the one after the last element
1086     //! of the reversed static_vector.
1087     //!
1088     //! @par Throws
1089     //!   Nothing.
1090     //!
1091     //! @par Complexity
1092     //!   Constant O(1).
1093     reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW;
1094 
1095     //! @brief Returns const reverse iterator to the one after the last element of the reversed container.
1096     //!
1097     //! @return const_reverse_iterator pointing to the one after the last element
1098     //! of the reversed static_vector.
1099     //!
1100     //! @par Throws
1101     //!   Nothing.
1102     //!
1103     //! @par Complexity
1104     //!   Constant O(1).
1105     const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW;
1106 
1107     //! @brief Returns const reverse iterator to the one after the last element of the reversed container.
1108     //!
1109     //! @return const_reverse_iterator pointing to the one after the last element
1110     //! of the reversed static_vector.
1111     //!
1112     //! @par Throws
1113     //!   Nothing.
1114     //!
1115     //! @par Complexity
1116     //!   Constant O(1).
1117     const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW;
1118 
1119    #endif   //#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
1120 
1121    //! @brief Returns container's capacity.
1122    //!
1123    //! @return container's capacity.
1124    //!
1125    //! @par Throws
1126    //!   Nothing.
1127    //!
1128    //! @par Complexity
1129    //!   Constant O(1).
capacity()1130    BOOST_CONTAINER_FORCEINLINE static size_type capacity() BOOST_NOEXCEPT_OR_NOTHROW
1131    { return static_capacity; }
1132 
1133    //! @brief Returns container's capacity.
1134    //!
1135    //! @return container's capacity.
1136    //!
1137    //! @par Throws
1138    //!   Nothing.
1139    //!
1140    //! @par Complexity
1141    //!   Constant O(1).
max_size()1142    BOOST_CONTAINER_FORCEINLINE static size_type max_size() BOOST_NOEXCEPT_OR_NOTHROW
1143    { return static_capacity; }
1144 
1145    #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
1146 
1147     //! @brief Returns the number of stored elements.
1148     //!
1149     //! @return Number of elements contained in the container.
1150     //!
1151     //! @par Throws
1152     //!   Nothing.
1153     //!
1154     //! @par Complexity
1155     //!   Constant O(1).
1156     size_type size() const BOOST_NOEXCEPT_OR_NOTHROW;
1157 
1158     //! @brief Queries if the container contains elements.
1159     //!
1160     //! @return true if the number of elements contained in the
1161     //!   container is equal to 0.
1162     //!
1163     //! @par Throws
1164     //!   Nothing.
1165     //!
1166     //! @par Complexity
1167     //!   Constant O(1).
1168     bool empty() const BOOST_NOEXCEPT_OR_NOTHROW;
1169 #else
1170 
swap(static_vector & x,static_vector & y)1171    BOOST_CONTAINER_FORCEINLINE friend void swap(static_vector &x, static_vector &y)
1172    {
1173       x.swap(y);
1174    }
1175 
1176 #endif // BOOST_CONTAINER_DOXYGEN_INVOKED
1177 
1178 };
1179 
1180 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
1181 
1182 //! @brief Checks if contents of two static_vectors are equal.
1183 //!
1184 //! @ingroup static_vector_non_member
1185 //!
1186 //! @param x    The first static_vector.
1187 //! @param y    The second static_vector.
1188 //!
1189 //! @return     \c true if containers have the same size and elements in both containers are equal.
1190 //!
1191 //! @par Complexity
1192 //!   Linear O(N).
1193 template<typename V, std::size_t C1, std::size_t C2, class O1, class O2>
1194 bool operator== (static_vector<V, C1, O1> const& x, static_vector<V, C2, O2> const& y);
1195 
1196 //! @brief Checks if contents of two static_vectors are not equal.
1197 //!
1198 //! @ingroup static_vector_non_member
1199 //!
1200 //! @param x    The first static_vector.
1201 //! @param y    The second static_vector.
1202 //!
1203 //! @return     \c true if containers have different size or elements in both containers are not equal.
1204 //!
1205 //! @par Complexity
1206 //!   Linear O(N).
1207 template<typename V, std::size_t C1, std::size_t C2, class O1, class O2>
1208 bool operator!= (static_vector<V, C1, O1> const& x, static_vector<V, C2, O2> const& y);
1209 
1210 //! @brief Lexicographically compares static_vectors.
1211 //!
1212 //! @ingroup static_vector_non_member
1213 //!
1214 //! @param x    The first static_vector.
1215 //! @param y    The second static_vector.
1216 //!
1217 //! @return     \c true if x compares lexicographically less than y.
1218 //!
1219 //! @par Complexity
1220 //!   Linear O(N).
1221 template<typename V, std::size_t C1, std::size_t C2, class O1, class O2>
1222 bool operator< (static_vector<V, C1, O1> const& x, static_vector<V, C2, O2> const& y);
1223 
1224 //! @brief Lexicographically compares static_vectors.
1225 //!
1226 //! @ingroup static_vector_non_member
1227 //!
1228 //! @param x    The first static_vector.
1229 //! @param y    The second static_vector.
1230 //!
1231 //! @return     \c true if y compares lexicographically less than x.
1232 //!
1233 //! @par Complexity
1234 //!   Linear O(N).
1235 template<typename V, std::size_t C1, std::size_t C2, class O1, class O2>
1236 bool operator> (static_vector<V, C1, O1> const& x, static_vector<V, C2, O2> const& y);
1237 
1238 //! @brief Lexicographically compares static_vectors.
1239 //!
1240 //! @ingroup static_vector_non_member
1241 //!
1242 //! @param x    The first static_vector.
1243 //! @param y    The second static_vector.
1244 //!
1245 //! @return     \c true if y don't compare lexicographically less than x.
1246 //!
1247 //! @par Complexity
1248 //!   Linear O(N).
1249 template<typename V, std::size_t C1, std::size_t C2, class O1, class O2>
1250 bool operator<= (static_vector<V, C1, O1> const& x, static_vector<V, C2, O2> const& y);
1251 
1252 //! @brief Lexicographically compares static_vectors.
1253 //!
1254 //! @ingroup static_vector_non_member
1255 //!
1256 //! @param x    The first static_vector.
1257 //! @param y    The second static_vector.
1258 //!
1259 //! @return     \c true if x don't compare lexicographically less than y.
1260 //!
1261 //! @par Complexity
1262 //!   Linear O(N).
1263 template<typename V, std::size_t C1, std::size_t C2, class O1, class O2>
1264 bool operator>= (static_vector<V, C1, O1> const& x, static_vector<V, C2, O2> const& y);
1265 
1266 //! @brief Swaps contents of two static_vectors.
1267 //!
1268 //! This function calls static_vector::swap().
1269 //!
1270 //! @ingroup static_vector_non_member
1271 //!
1272 //! @param x    The first static_vector.
1273 //! @param y    The second static_vector.
1274 //!
1275 //! @par Complexity
1276 //!   Linear O(N).
1277 template<typename V, std::size_t C1, std::size_t C2, class O1, class O2>
1278 inline void swap(static_vector<V, C1, O1> & x, static_vector<V, C2, O2> & y);
1279 
1280 #else
1281 
1282 template<typename V, std::size_t C1, std::size_t C2, class O1, class O2>
swap(static_vector<V,C1,O1> & x,static_vector<V,C2,O2> & y,typename dtl::enable_if_c<C1!=C2>::type * =0)1283 inline void swap(static_vector<V, C1, O1> & x, static_vector<V, C2, O2> & y
1284       , typename dtl::enable_if_c< C1 != C2>::type * = 0)
1285 {
1286    x.swap(y);
1287 }
1288 
1289 #endif // BOOST_CONTAINER_DOXYGEN_INVOKED
1290 
1291 }} // namespace boost::container
1292 
1293 #include <boost/container/detail/config_end.hpp>
1294 
1295 #endif // BOOST_CONTAINER_STATIC_VECTOR_HPP
1296