Documentation fix. Ticket 6499
[boost:cmake.git] / boost / container / stable_vector.hpp
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://www.boost.org/libs/container for documentation.
8 //
9 //////////////////////////////////////////////////////////////////////////////
10 // Stable vector.
11 //
12 // Copyright 2008 Joaquin M Lopez Munoz.
13 // Distributed under the Boost Software License, Version 1.0.
14 // (See accompanying file LICENSE_1_0.txt or copy at
15 // http://www.boost.org/LICENSE_1_0.txt)
16 //
17 //////////////////////////////////////////////////////////////////////////////
18
19 #ifndef BOOST_CONTAINER_STABLE_VECTOR_HPP
20 #define BOOST_CONTAINER_STABLE_VECTOR_HPP
21
22 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
23 #  pragma once
24 #endif
25
26 #include <boost/container/detail/config_begin.hpp>
27 #include <boost/container/detail/workaround.hpp>
28 #include <boost/container/container_fwd.hpp>
29 #include <boost/mpl/bool.hpp>
30 #include <boost/mpl/not.hpp>
31 #include <boost/type_traits/is_integral.hpp>
32 #include <boost/container/detail/version_type.hpp>
33 #include <boost/container/detail/multiallocation_chain.hpp>
34 #include <boost/container/detail/utilities.hpp>
35 #include <boost/container/detail/iterators.hpp>
36 #include <boost/container/detail/algorithms.hpp>
37 #include <boost/container/allocator/allocator_traits.hpp>
38 #include <boost/intrusive/pointer_traits.hpp>
39
40 #include <algorithm>
41 #include <stdexcept>
42 #include <memory>
43
44 ///@cond
45
46 #include <boost/container/vector.hpp>
47
48 //#define STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
49
50 #if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
51 #include <boost/assert.hpp>
52 #endif
53
54 ///@endcond
55
56 namespace boost {
57 namespace container {
58
59 ///@cond
60
61 namespace stable_vector_detail{
62
63 template<class SmartPtr>
64 struct smart_ptr_type
65 {
66    typedef typename SmartPtr::value_type value_type;
67    typedef value_type *pointer;
68    static pointer get (const SmartPtr &smartptr)
69    {  return smartptr.get();}
70 };
71
72 template<class T>
73 struct smart_ptr_type<T*>
74 {
75    typedef T value_type;
76    typedef value_type *pointer;
77    static pointer get (pointer ptr)
78    {  return ptr;}
79 };
80
81 template<class Ptr>
82 inline typename smart_ptr_type<Ptr>::pointer to_raw_pointer(const Ptr &ptr)
83 {  return smart_ptr_type<Ptr>::get(ptr);   }
84
85 template <class C>
86 class clear_on_destroy
87 {
88    public:
89    clear_on_destroy(C &c)
90       :  c_(c), do_clear_(true)
91    {}
92
93    void release()
94    {  do_clear_ = false; }
95
96    ~clear_on_destroy()
97    {
98       if(do_clear_){
99          c_.clear();
100          c_.clear_pool();  
101       }
102    }
103
104    private:
105    clear_on_destroy(const clear_on_destroy &);
106    clear_on_destroy &operator=(const clear_on_destroy &);
107    C &c_;
108    bool do_clear_;
109 };
110
111 template<class VoidPtr>
112 struct node_type_base
113 {/*
114    node_type_base(VoidPtr p)
115       : up(p)
116    {}*/
117    node_type_base()
118    {}
119    void set_pointer(VoidPtr p)
120    {  up = p; }
121
122    VoidPtr up;
123 };
124
125 template<typename VoidPointer, typename T>
126 struct node_type
127    : public node_type_base<VoidPointer>
128 {
129    node_type()
130       : value()
131    {}
132
133    #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
134
135    template<class ...Args>
136    node_type(Args &&...args)
137       : value(boost::forward<Args>(args)...)
138    {}
139
140    #else //BOOST_CONTAINER_PERFECT_FORWARDING
141
142    #define BOOST_PP_LOCAL_MACRO(n)                                                           \
143    BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)    \
144    node_type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                             \
145       : value(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))                         \
146    {}                                                                                        \
147    //!
148    #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
149    #include BOOST_PP_LOCAL_ITERATE()
150
151    #endif//BOOST_CONTAINER_PERFECT_FORWARDING
152    
153    void set_pointer(VoidPointer p)
154    {  node_type_base<VoidPointer>::set_pointer(p); }
155
156    T value;
157 };
158
159 template<typename T, typename Reference, typename Pointer>
160 class iterator
161    : public std::iterator< std::random_access_iterator_tag
162                          , T
163                          , typename boost::intrusive::
164                               pointer_traits<Pointer>::difference_type
165                          , Pointer
166                          , Reference>
167 {
168    typedef typename boost::intrusive::
169       pointer_traits<Pointer>::template
170          rebind_pointer<void>::type                void_ptr;
171    typedef typename boost::intrusive::
172       pointer_traits<Pointer>::template
173          rebind_pointer<const void>::type          const_void_ptr;
174    typedef node_type<void_ptr, T>                  node_type_t;
175    typedef typename boost::intrusive::
176       pointer_traits<Pointer>::template
177          rebind_pointer<node_type_t>::type         node_type_ptr_t;
178    typedef typename boost::intrusive::
179       pointer_traits<Pointer>::template
180          rebind_pointer<const node_type_t>::type   const_node_type_ptr_t;
181    typedef typename boost::intrusive::
182       pointer_traits<Pointer>::template
183          rebind_pointer<void_ptr>::type            void_ptr_ptr;
184
185    friend class iterator<T, const T, typename boost::intrusive::pointer_traits<Pointer>::template rebind_pointer<T>::type>;
186
187    public:
188    typedef std::random_access_iterator_tag      iterator_category;
189    typedef T                                    value_type;
190    typedef typename boost::intrusive::
191       pointer_traits<Pointer>::difference_type  difference_type;
192    typedef Pointer                              pointer;
193    typedef Reference                            reference;
194
195    iterator()
196    {}
197
198    explicit iterator(node_type_ptr_t pn)
199       : pn(pn)
200    {}
201
202    iterator(const iterator<T, T&, typename boost::intrusive::pointer_traits<Pointer>::template rebind_pointer<T>::type>& x)
203       : pn(x.pn)
204    {}
205    
206    private:
207    static node_type_ptr_t node_ptr_cast(const void_ptr &p)
208    {
209       return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
210    }
211
212    static const_node_type_ptr_t node_ptr_cast(const const_void_ptr &p)
213    {
214       return const_node_type_ptr_t(static_cast<const node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
215    }
216
217    static void_ptr_ptr void_ptr_ptr_cast(const void_ptr &p)
218    {
219       return void_ptr_ptr(static_cast<void_ptr*>(stable_vector_detail::to_raw_pointer(p)));
220    }
221
222    reference dereference() const
223    {  return pn->value; }
224    bool equal(const iterator& x) const
225    {  return pn==x.pn;  }
226    void increment()
227    {  pn = node_ptr_cast(*(void_ptr_ptr_cast(pn->up)+1)); }
228    void decrement()
229    {  pn = node_ptr_cast(*(void_ptr_ptr_cast(pn->up)-1)); }
230    void advance(difference_type n)
231    {  pn = node_ptr_cast(*(void_ptr_ptr_cast(pn->up)+n)); }
232    difference_type distance_to(const iterator& x)const
233    {  return void_ptr_ptr_cast(x.pn->up) - void_ptr_ptr_cast(pn->up);   }
234
235    public:
236    //Pointer like operators
237    reference operator*()  const {  return  this->dereference();  }
238    pointer   operator->() const {  return  pointer(&this->dereference());  }
239
240    //Increment / Decrement
241    iterator& operator++()  
242    {  this->increment(); return *this;  }
243
244    iterator operator++(int)
245    {  iterator tmp(*this);  ++*this; return iterator(tmp); }
246
247    iterator& operator--()
248    {  this->decrement(); return *this;  }
249
250    iterator operator--(int)
251    {  iterator tmp(*this);  --*this; return iterator(tmp);  }
252
253    reference operator[](difference_type off) const
254    {
255       iterator tmp(*this);
256       tmp += off;
257       return *tmp;
258    }
259
260    iterator& operator+=(difference_type off)
261    {
262       pn = node_ptr_cast(*(void_ptr_ptr_cast(pn->up)+off));
263       return *this;
264    }
265
266    friend iterator operator+(const iterator &left, difference_type off)
267    {
268       iterator tmp(left);
269       tmp += off;
270       return tmp;
271    }
272
273    friend iterator operator+(difference_type off, const iterator& right)
274    {
275       iterator tmp(right);
276       tmp += off;
277       return tmp;
278    }
279
280    iterator& operator-=(difference_type off)
281    {  *this += -off; return *this;   }
282
283    friend iterator operator-(const iterator &left, difference_type off)
284    {
285       iterator tmp(left);
286       tmp -= off;
287       return tmp;
288    }
289
290    friend difference_type operator-(const iterator& left, const iterator& right)
291    {
292       return void_ptr_ptr_cast(left.pn->up) - void_ptr_ptr_cast(right.pn->up);
293    }
294
295    //Comparison operators
296    friend bool operator==   (const iterator& l, const iterator& r)
297    {  return l.pn == r.pn;  }
298
299    friend bool operator!=   (const iterator& l, const iterator& r)
300    {  return l.pn != r.pn;  }
301
302    friend bool operator<    (const iterator& l, const iterator& r)
303    {  return void_ptr_ptr_cast(l.pn->up) < void_ptr_ptr_cast(r.pn->up);  }
304
305    friend bool operator<=   (const iterator& l, const iterator& r)
306    {  return void_ptr_ptr_cast(l.pn->up) <= void_ptr_ptr_cast(r.pn->up);  }
307
308    friend bool operator>    (const iterator& l, const iterator& r)
309    {  return void_ptr_ptr_cast(l.pn->up) > void_ptr_ptr_cast(r.pn->up);  }
310
311    friend bool operator>=   (const iterator& l, const iterator& r)
312    {  return void_ptr_ptr_cast(l.pn->up) >= void_ptr_ptr_cast(r.pn->up);  }
313
314    node_type_ptr_t pn;
315 };
316
317 template<class A, unsigned int Version>
318 struct select_multiallocation_chain
319 {
320    typedef typename A::multiallocation_chain type;
321 };
322
323 template<class A>
324 struct select_multiallocation_chain<A, 1>
325 {
326    typedef typename boost::intrusive::pointer_traits
327       <typename allocator_traits<A>::pointer>::
328          template rebind_pointer<void>::type                void_ptr;
329    typedef container_detail::basic_multiallocation_chain
330       <void_ptr>                                            multialloc_cached_counted;
331    typedef boost::container::container_detail::
332       transform_multiallocation_chain
333          < multialloc_cached_counted
334          , typename allocator_traits<A>::value_type>        type;
335 };
336
337 } //namespace stable_vector_detail
338
339 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
340
341 #if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
342
343 #define STABLE_VECTOR_CHECK_INVARIANT \
344 invariant_checker BOOST_JOIN(check_invariant_,__LINE__)(*this); \
345 BOOST_JOIN(check_invariant_,__LINE__).touch();
346 #else
347
348 #define STABLE_VECTOR_CHECK_INVARIANT
349
350 #endif   //#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
351
352 #endif   //#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
353
354 /// @endcond
355
356 //!Originally developed by Joaquin M. Lopez Munoz, stable_vector is std::vector
357 //!drop-in replacement implemented as a node container, offering iterator and reference
358 //!stability.
359 //!
360 //!More details taken the author's blog: (<a href="http://bannalia.blogspot.com/2008/09/introducing-stablevector.html" > Introducing stable_vector</a>)
361 //!
362 //!We present stable_vector, a fully STL-compliant stable container that provides
363 //!most of the features of std::vector except element contiguity. 
364 //!
365 //!General properties: stable_vector satisfies all the requirements of a container,
366 //!a reversible container and a sequence and provides all the optional operations
367 //!present in std::vector. Like std::vector,  iterators are random access.
368 //!stable_vector does not provide element contiguity; in exchange for this absence,
369 //!the container is stable, i.e. references and iterators to an element of a stable_vector
370 //!remain valid as long as the element is not erased, and an iterator that has been
371 //!assigned the return value of end() always remain valid until the destruction of
372 //!the associated  stable_vector.
373 //!
374 //!Operation complexity: The big-O complexities of stable_vector operations match
375 //!exactly those of std::vector. In general, insertion/deletion is constant time at
376 //!the end of the sequence and linear elsewhere. Unlike std::vector, stable_vector
377 //!does not internally perform any value_type destruction, copy or assignment
378 //!operations other than those exactly corresponding to the insertion of new
379 //!elements or deletion of stored elements, which can sometimes compensate in terms
380 //!of performance for the extra burden of doing more pointer manipulation and an
381 //!additional allocation per element.
382 //!
383 //!Exception safety: As stable_vector does not internally copy elements around, some
384 //!operations provide stronger exception safety guarantees than in std::vector:
385 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
386 template <class T, class A = std::allocator<T> >
387 #else
388 template <class T, class A>
389 #endif
390 class stable_vector
391 {
392    ///@cond
393    typedef allocator_traits<A>                        allocator_traits_type;
394    typedef typename container_detail::
395       move_const_ref_type<T>::type                    insert_const_ref_type;
396    typedef typename boost::intrusive::pointer_traits
397       <typename allocator_traits_type::pointer>::
398          template rebind_pointer<void>::type          void_ptr;
399    typedef typename boost::intrusive::pointer_traits
400       <void_ptr>::template
401          rebind_pointer<const void>::type             const_void_ptr;
402    typedef typename boost::intrusive::pointer_traits
403       <void_ptr>::template
404          rebind_pointer<void_ptr>::type               void_ptr_ptr;
405    typedef typename boost::intrusive::pointer_traits
406       <void_ptr>::template
407          rebind_pointer<const void_ptr>::type         const_void_ptr_ptr;
408    typedef stable_vector_detail::node_type
409       <void_ptr, T>                                   node_type_t;
410    typedef typename boost::intrusive::pointer_traits
411       <void_ptr>::template
412          rebind_pointer<node_type_t>::type            node_type_ptr_t;
413    typedef stable_vector_detail::node_type_base
414       <void_ptr>                                      node_type_base_t;
415    typedef typename boost::intrusive::pointer_traits
416       <void_ptr>::template
417          rebind_pointer<node_type_base_t>::type       node_type_base_ptr_t;
418    typedef ::boost::container::vector<void_ptr,
419       typename allocator_traits_type::
420          template portable_rebind_alloc
421             <void_ptr>::type>                         impl_type;
422    typedef typename impl_type::iterator               impl_iterator;
423    typedef typename impl_type::const_iterator         const_impl_iterator;
424
425    typedef ::boost::container::container_detail::
426       integral_constant<unsigned, 1>                  allocator_v1;
427    typedef ::boost::container::container_detail::
428       integral_constant<unsigned, 2>                  allocator_v2;
429    typedef ::boost::container::container_detail::integral_constant 
430       <unsigned, boost::container::container_detail::
431       version<A>::value>                              alloc_version;
432    typedef typename allocator_traits_type::
433       template portable_rebind_alloc
434          <node_type_t>::type                          node_allocator_type;
435
436    node_type_ptr_t allocate_one()
437    {  return this->allocate_one(alloc_version());   }
438
439    template<class AllocatorVersion>
440    node_type_ptr_t allocate_one(AllocatorVersion,
441       typename boost::container::container_detail::enable_if_c
442          <boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
443             ::value>::type * = 0)
444    {  return node_alloc().allocate(1);   }
445
446    template<class AllocatorVersion>
447    node_type_ptr_t allocate_one(AllocatorVersion,
448       typename boost::container::container_detail::enable_if_c
449          <!boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
450             ::value>::type * = 0)
451    {  return node_alloc().allocate_one();   }
452
453    void deallocate_one(node_type_ptr_t p)
454    {  return this->deallocate_one(p, alloc_version());   }
455
456    template<class AllocatorVersion>
457    void deallocate_one(node_type_ptr_t p, AllocatorVersion,
458       typename boost::container::container_detail::enable_if_c
459          <boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
460             ::value>::type * = 0)
461    {  node_alloc().deallocate(p, 1);   }
462
463    template<class AllocatorVersion>
464    void deallocate_one(node_type_ptr_t p, AllocatorVersion,
465       typename boost::container::container_detail::enable_if_c
466          <!boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
467             ::value>::type * = 0)
468    {  node_alloc().deallocate_one(p);   }
469
470    friend class stable_vector_detail::clear_on_destroy<stable_vector>;
471    ///@endcond
472    public:
473
474
475    // types:
476
477    typedef typename allocator_traits_type::reference              reference;
478    typedef typename allocator_traits_type::const_reference        const_reference;
479    typedef typename allocator_traits_type::pointer                pointer;
480    typedef typename allocator_traits_type::const_pointer          const_pointer;
481    typedef stable_vector_detail::iterator
482       <T,T&, pointer>                                 iterator;
483    typedef stable_vector_detail::iterator
484       <T,const T&, const_pointer>                     const_iterator;
485    typedef typename impl_type::size_type              size_type;
486    typedef typename iterator::difference_type         difference_type;
487    typedef T                                          value_type;
488    typedef A                                          allocator_type;
489    typedef std::reverse_iterator<iterator>            reverse_iterator;
490    typedef std::reverse_iterator<const_iterator>      const_reverse_iterator;
491    typedef node_allocator_type                        stored_allocator_type;
492
493    ///@cond
494    private:
495    BOOST_COPYABLE_AND_MOVABLE(stable_vector)
496    static const size_type ExtraPointers = 3;
497    //This container stores metadata at the end of the void_ptr vector with additional 3 pointers:
498    //    back() is impl.back() - ExtraPointers;
499    //    end node index is impl.end()[-3]
500    //    Node cache first is impl.end()[-2];
501    //    Node cache last is  *impl.back();
502
503    typedef typename stable_vector_detail::
504       select_multiallocation_chain
505       < node_allocator_type
506       , alloc_version::value
507       >::type                                         multiallocation_chain;
508    ///@endcond
509    public:
510
511    //! <b>Effects</b>: Default constructs a stable_vector.
512    //! 
513    //! <b>Throws</b>: If allocator_type's default constructor throws.
514    //! 
515    //! <b>Complexity</b>: Constant.
516    stable_vector()
517       : internal_data(), impl()
518    {
519       STABLE_VECTOR_CHECK_INVARIANT;
520    }
521
522    //! <b>Effects</b>: Constructs a stable_vector taking the allocator as parameter.
523    //! 
524    //! <b>Throws</b>: If allocator_type's copy constructor throws.
525    //! 
526    //! <b>Complexity</b>: Constant.
527    explicit stable_vector(const A& al)
528       : internal_data(al),impl(al)
529    {
530       STABLE_VECTOR_CHECK_INVARIANT;
531    }
532
533    //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
534    //!   and inserts n default contructed values.
535    //!
536    //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
537    //!   throws or T's default or copy constructor throws.
538    //! 
539    //! <b>Complexity</b>: Linear to n.
540    explicit stable_vector(size_type n)
541       : internal_data(A()),impl(A())
542    {
543       stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
544       this->resize(n);
545       STABLE_VECTOR_CHECK_INVARIANT;
546       cod.release();
547    }
548
549    //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
550    //!   and inserts n copies of value.
551    //!
552    //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
553    //!   throws or T's default or copy constructor throws.
554    //! 
555    //! <b>Complexity</b>: Linear to n.
556    stable_vector(size_type n, const T& t, const A& al=A())
557       : internal_data(al),impl(al)
558    {
559       stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
560       this->insert(this->cbegin(), n, t);
561       STABLE_VECTOR_CHECK_INVARIANT;
562       cod.release();
563    }
564
565    //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
566    //!   and inserts a copy of the range [first, last) in the stable_vector.
567    //!
568    //! <b>Throws</b>: If allocator_type's default constructor or copy constructor
569    //!   throws or T's constructor taking an dereferenced InIt throws.
570    //!
571    //! <b>Complexity</b>: Linear to the range [first, last).
572    template <class InputIterator>
573    stable_vector(InputIterator first,InputIterator last,const A& al=A())
574       : internal_data(al),impl(al)
575    {
576       stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
577       this->insert(this->cbegin(), first, last);
578       STABLE_VECTOR_CHECK_INVARIANT;
579       cod.release();
580    }
581
582    //! <b>Effects</b>: Copy constructs a stable_vector.
583    //!
584    //! <b>Postcondition</b>: x == *this.
585    //! 
586    //! <b>Complexity</b>: Linear to the elements x contains.
587    stable_vector(const stable_vector& x)
588       : internal_data(allocator_traits<node_allocator_type>::
589          select_on_container_copy_construction(x.node_alloc()))
590       , impl(allocator_traits<allocator_type>::
591          select_on_container_copy_construction(x.impl.get_stored_allocator()))
592    {
593       stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
594       this->insert(this->cbegin(), x.begin(), x.end());
595       STABLE_VECTOR_CHECK_INVARIANT;
596       cod.release();
597    }
598
599    //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
600    //!
601    //! <b>Throws</b>: If allocator_type's copy constructor throws.
602    //! 
603    //! <b>Complexity</b>: Constant.
604    stable_vector(BOOST_RV_REF(stable_vector) x)
605       : internal_data(boost::move(x.node_alloc())), impl(boost::move(x.impl))
606    {
607       this->priv_swap_members(x);
608    }
609
610    //! <b>Effects</b>: Destroys the stable_vector. All stored values are destroyed
611    //!   and used memory is deallocated.
612    //!
613    //! <b>Throws</b>: Nothing.
614    //!
615    //! <b>Complexity</b>: Linear to the number of elements.
616    ~stable_vector()
617    {
618       this->clear();
619       clear_pool();  
620    }
621
622    //! <b>Effects</b>: Makes *this contain the same elements as x.
623    //!
624    //! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy 
625    //! of each of x's elements. 
626    //!
627    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
628    //!
629    //! <b>Complexity</b>: Linear to the number of elements in x.
630    stable_vector& operator=(BOOST_COPY_ASSIGN_REF(stable_vector) x)
631    {
632       STABLE_VECTOR_CHECK_INVARIANT;
633       if (&x != this){
634          node_allocator_type &this_alloc     = this->node_alloc();
635          const node_allocator_type &x_alloc  = x.node_alloc();
636          container_detail::bool_<allocator_traits_type::
637             propagate_on_container_copy_assignment::value> flag;
638          if(flag && this_alloc != x_alloc){
639             this->clear();
640             this->shrink_to_fit();
641          }
642          container_detail::assign_alloc(this->node_alloc(), x.node_alloc(), flag);
643          container_detail::assign_alloc(this->impl.get_stored_allocator(), x.impl.get_stored_allocator(), flag);
644          this->assign(x.begin(), x.end());
645       }
646       return *this;
647    }
648
649    //! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
650    //!
651    //! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
652    //!   before the function.
653    //!
654    //! <b>Throws</b>: If allocator_type's copy constructor throws.
655    //!
656    //! <b>Complexity</b>: Linear.
657    stable_vector& operator=(BOOST_RV_REF(stable_vector) x)
658    {
659       if (&x != this){
660          node_allocator_type &this_alloc = this->node_alloc();
661          node_allocator_type &x_alloc    = x.node_alloc();
662          //If allocators are equal we can just swap pointers
663          if(this_alloc == x_alloc){
664             //Destroy objects but retain memory
665             this->clear();
666             this->impl = boost::move(x.impl);
667             this->priv_swap_members(x);
668             //Move allocator if needed
669             container_detail::bool_<allocator_traits_type::
670                propagate_on_container_move_assignment::value> flag;
671             container_detail::move_alloc(this->node_alloc(), x.node_alloc(), flag);
672          }
673          //If unequal allocators, then do a one by one move
674          else{
675             typedef typename std::iterator_traits<iterator>::iterator_category ItCat;
676             this->assign( boost::make_move_iterator(x.begin())
677                         , boost::make_move_iterator(x.end()));
678          }
679       }
680       return *this;
681    }
682
683    //! <b>Effects</b>: Assigns the the range [first, last) to *this.
684    //!
685    //! <b>Throws</b>: If memory allocation throws or
686    //!   T's constructor from dereferencing InpIt throws.
687    //!
688    //! <b>Complexity</b>: Linear to n.
689    template<typename InputIterator>
690    void assign(InputIterator first,InputIterator last)
691    {
692       assign_dispatch(first, last, boost::is_integral<InputIterator>());
693    }
694
695
696    //! <b>Effects</b>: Assigns the n copies of val to *this.
697    //!
698    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
699    //!
700    //! <b>Complexity</b>: Linear to n.
701    void assign(size_type n,const T& t)
702    {
703       typedef constant_iterator<value_type, difference_type> cvalue_iterator;
704       return assign_dispatch(cvalue_iterator(t, n), cvalue_iterator(), boost::mpl::false_());
705    }
706
707    //! <b>Effects</b>: Returns a copy of the internal allocator.
708    //! 
709    //! <b>Throws</b>: If allocator's copy constructor throws.
710    //! 
711    //! <b>Complexity</b>: Constant.
712    allocator_type get_allocator()const  {return node_alloc();}
713
714    //! <b>Effects</b>: Returns a reference to the internal allocator.
715    //! 
716    //! <b>Throws</b>: Nothing
717    //! 
718    //! <b>Complexity</b>: Constant.
719    //! 
720    //! <b>Note</b>: Non-standard extension.
721    const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
722    {  return node_alloc(); }
723
724    //! <b>Effects</b>: Returns a reference to the internal allocator.
725    //! 
726    //! <b>Throws</b>: Nothing
727    //! 
728    //! <b>Complexity</b>: Constant.
729    //! 
730    //! <b>Note</b>: Non-standard extension.
731    stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
732    {  return node_alloc(); }
733
734
735    //! <b>Effects</b>: Returns an iterator to the first element contained in the stable_vector.
736    //! 
737    //! <b>Throws</b>: Nothing.
738    //! 
739    //! <b>Complexity</b>: Constant.
740    iterator  begin()
741    {   return (impl.empty()) ? end(): iterator(node_ptr_cast(impl.front())) ;   }
742
743    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the stable_vector.
744    //! 
745    //! <b>Throws</b>: Nothing.
746    //! 
747    //! <b>Complexity</b>: Constant.
748    const_iterator  begin()const
749    {   return (impl.empty()) ? cend() : const_iterator(node_ptr_cast(impl.front())) ;   }
750
751    //! <b>Effects</b>: Returns an iterator to the end of the stable_vector.
752    //! 
753    //! <b>Throws</b>: Nothing.
754    //! 
755    //! <b>Complexity</b>: Constant.
756    iterator        end()                {return iterator(get_end_node());}
757
758    //! <b>Effects</b>: Returns a const_iterator to the end of the stable_vector.
759    //! 
760    //! <b>Throws</b>: Nothing.
761    //! 
762    //! <b>Complexity</b>: Constant.
763    const_iterator  end()const           {return const_iterator(get_end_node());}
764
765    //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning 
766    //! of the reversed stable_vector. 
767    //! 
768    //! <b>Throws</b>: Nothing.
769    //! 
770    //! <b>Complexity</b>: Constant.
771    reverse_iterator       rbegin()      {return reverse_iterator(this->end());}
772
773    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning 
774    //! of the reversed stable_vector. 
775    //! 
776    //! <b>Throws</b>: Nothing.
777    //! 
778    //! <b>Complexity</b>: Constant.
779    const_reverse_iterator rbegin()const {return const_reverse_iterator(this->end());}
780
781    //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
782    //! of the reversed stable_vector. 
783    //! 
784    //! <b>Throws</b>: Nothing.
785    //! 
786    //! <b>Complexity</b>: Constant.
787    reverse_iterator       rend()        {return reverse_iterator(this->begin());}
788
789    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
790    //! of the reversed stable_vector. 
791    //! 
792    //! <b>Throws</b>: Nothing.
793    //! 
794    //! <b>Complexity</b>: Constant.
795    const_reverse_iterator rend()const   {return const_reverse_iterator(this->begin());}
796
797    //! <b>Effects</b>: Returns a const_iterator to the first element contained in the stable_vector.
798    //! 
799    //! <b>Throws</b>: Nothing.
800    //! 
801    //! <b>Complexity</b>: Constant.
802    const_iterator         cbegin()const {return this->begin();}
803
804    //! <b>Effects</b>: Returns a const_iterator to the end of the stable_vector.
805    //! 
806    //! <b>Throws</b>: Nothing.
807    //! 
808    //! <b>Complexity</b>: Constant.
809    const_iterator         cend()const   {return this->end();}
810
811    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning 
812    //! of the reversed stable_vector. 
813    //! 
814    //! <b>Throws</b>: Nothing.
815    //! 
816    //! <b>Complexity</b>: Constant.
817    const_reverse_iterator crbegin()const{return this->rbegin();}
818
819    //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
820    //! of the reversed stable_vector. 
821    //! 
822    //! <b>Throws</b>: Nothing.
823    //! 
824    //! <b>Complexity</b>: Constant.
825    const_reverse_iterator crend()const  {return this->rend();}
826
827    //! <b>Effects</b>: Returns the number of the elements contained in the stable_vector.
828    //! 
829    //! <b>Throws</b>: Nothing.
830    //! 
831    //! <b>Complexity</b>: Constant.
832    size_type size() const
833    {  return impl.empty() ? 0 : (impl.size() - ExtraPointers);   }
834
835    //! <b>Effects</b>: Returns the largest possible size of the stable_vector.
836    //! 
837    //! <b>Throws</b>: Nothing.
838    //! 
839    //! <b>Complexity</b>: Constant.
840    size_type max_size() const
841    {  return impl.max_size() - ExtraPointers;  }
842
843    //! <b>Effects</b>: Number of elements for which memory has been allocated.
844    //!   capacity() is always greater than or equal to size().
845    //! 
846    //! <b>Throws</b>: Nothing.
847    //! 
848    //! <b>Complexity</b>: Constant.
849    size_type capacity() const
850    {
851       if(!impl.capacity()){
852          return 0;
853       }
854       else{
855          const size_type num_nodes = this->impl.size() + this->internal_data.pool_size;
856          const size_type num_buck  = this->impl.capacity();
857          return (num_nodes < num_buck) ? num_nodes : num_buck;
858       }
859    }
860
861    //! <b>Effects</b>: Returns true if the stable_vector contains no elements.
862    //! 
863    //! <b>Throws</b>: Nothing.
864    //! 
865    //! <b>Complexity</b>: Constant.
866    bool empty() const
867    {  return impl.empty() || impl.size() == ExtraPointers;  }
868
869    //! <b>Effects</b>: Inserts or erases elements at the end such that
870    //!   the size becomes n. New elements are copy constructed from x.
871    //!
872    //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
873    //!
874    //! <b>Complexity</b>: Linear to the difference between size() and new_size.
875    void resize(size_type n, const T& t)
876    {
877       STABLE_VECTOR_CHECK_INVARIANT;
878       if(n > size())
879          this->insert(this->cend(), n - this->size(), t);
880       else if(n < this->size())
881          this->erase(this->cbegin() + n, this->cend());
882    }
883
884    //! <b>Effects</b>: Inserts or erases elements at the end such that
885    //!   the size becomes n. New elements are default constructed.
886    //!
887    //! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
888    //!
889    //! <b>Complexity</b>: Linear to the difference between size() and new_size.
890    void resize(size_type n)
891    {
892       typedef default_construct_iterator<value_type, difference_type> default_iterator;
893       STABLE_VECTOR_CHECK_INVARIANT;
894       if(n > size())
895          this->insert(this->cend(), default_iterator(n - this->size()), default_iterator());
896       else if(n < this->size())
897          this->erase(this->cbegin() + n, this->cend());
898    }
899
900    //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
901    //!   effect. Otherwise, it is a request for allocation of additional memory.
902    //!   If the request is successful, then capacity() is greater than or equal to
903    //!   n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
904    //! 
905    //! <b>Throws</b>: If memory allocation allocation throws.
906    void reserve(size_type n)
907    {
908       STABLE_VECTOR_CHECK_INVARIANT;
909       if(n > this->max_size())
910          throw std::bad_alloc();
911
912       size_type size = this->size();   
913       size_type old_capacity = this->capacity();
914       if(n > old_capacity){
915          this->initialize_end_node(n);
916          const void * old_ptr = &impl[0];
917          impl.reserve(n + ExtraPointers);
918          bool realloced = &impl[0] != old_ptr;
919          //Fix the pointers for the newly allocated buffer
920          if(realloced){
921             this->align_nodes(impl.begin(), impl.begin()+size+1);
922          }
923          //Now fill pool if data is not enough
924          if((n - size) > this->internal_data.pool_size){
925             this->add_to_pool((n - size) - this->internal_data.pool_size);
926          }
927       }
928    }
929
930    //! <b>Requires</b>: size() > n.
931    //!
932    //! <b>Effects</b>: Returns a reference to the nth element 
933    //!   from the beginning of the container.
934    //! 
935    //! <b>Throws</b>: Nothing.
936    //! 
937    //! <b>Complexity</b>: Constant.
938    reference operator[](size_type n){return value(impl[n]);}
939
940    //! <b>Requires</b>: size() > n.
941    //!
942    //! <b>Effects</b>: Returns a const reference to the nth element 
943    //!   from the beginning of the container.
944    //! 
945    //! <b>Throws</b>: Nothing.
946    //! 
947    //! <b>Complexity</b>: Constant.
948    const_reference operator[](size_type n)const{return value(impl[n]);}
949
950    //! <b>Requires</b>: size() > n.
951    //!
952    //! <b>Effects</b>: Returns a reference to the nth element 
953    //!   from the beginning of the container.
954    //! 
955    //! <b>Throws</b>: std::range_error if n >= size()
956    //! 
957    //! <b>Complexity</b>: Constant.
958    reference at(size_type n)
959    {
960       if(n>=size())
961          throw std::out_of_range("invalid subscript at stable_vector::at");
962       return operator[](n);
963    }
964
965    //! <b>Requires</b>: size() > n.
966    //!
967    //! <b>Effects</b>: Returns a const reference to the nth element 
968    //!   from the beginning of the container.
969    //! 
970    //! <b>Throws</b>: std::range_error if n >= size()
971    //! 
972    //! <b>Complexity</b>: Constant.
973    const_reference at(size_type n)const
974    {
975       if(n>=size())
976          throw std::out_of_range("invalid subscript at stable_vector::at");
977       return operator[](n);
978    }
979
980    //! <b>Requires</b>: !empty()
981    //!
982    //! <b>Effects</b>: Returns a reference to the first
983    //!   element of the container.
984    //! 
985    //! <b>Throws</b>: Nothing.
986    //! 
987    //! <b>Complexity</b>: Constant.
988    reference front()
989    {  return value(impl.front());   }
990
991    //! <b>Requires</b>: !empty()
992    //!
993    //! <b>Effects</b>: Returns a const reference to the first
994    //!   element of the container.
995    //! 
996    //! <b>Throws</b>: Nothing.
997    //! 
998    //! <b>Complexity</b>: Constant.
999    const_reference front()const
1000    {  return value(impl.front());   }
1001
1002    //! <b>Requires</b>: !empty()
1003    //!
1004    //! <b>Effects</b>: Returns a reference to the last
1005    //!   element of the container.
1006    //! 
1007    //! <b>Throws</b>: Nothing.
1008    //! 
1009    //! <b>Complexity</b>: Constant.
1010    reference back()
1011    {  return value(*(&impl.back() - ExtraPointers)); }
1012
1013    //! <b>Requires</b>: !empty()
1014    //!
1015    //! <b>Effects</b>: Returns a const reference to the last
1016    //!   element of the container.
1017    //! 
1018    //! <b>Throws</b>: Nothing.
1019    //! 
1020    //! <b>Complexity</b>: Constant.
1021    const_reference back()const
1022    {  return value(*(&impl.back() - ExtraPointers)); }
1023
1024    //! <b>Effects</b>: Inserts a copy of x at the end of the stable_vector.
1025    //!
1026    //! <b>Throws</b>: If memory allocation throws or
1027    //!   T's copy constructor throws.
1028    //!
1029    //! <b>Complexity</b>: Amortized constant time.
1030    void push_back(insert_const_ref_type x) 
1031    {  return priv_push_back(x);  }
1032
1033    #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1034    void push_back(T &x) { push_back(const_cast<const T &>(x)); }
1035
1036    template<class U>
1037    void push_back(const U &u, typename container_detail::enable_if_c
1038                   <container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
1039    { return priv_push_back(u); }
1040    #endif
1041
1042    //! <b>Effects</b>: Constructs a new element in the end of the stable_vector
1043    //!   and moves the resources of mx to this new element.
1044    //!
1045    //! <b>Throws</b>: If memory allocation throws.
1046    //!
1047    //! <b>Complexity</b>: Amortized constant time.
1048    void push_back(BOOST_RV_REF(T) t) 
1049    {  this->insert(end(), boost::move(t));  }
1050
1051    //! <b>Effects</b>: Removes the last element from the stable_vector.
1052    //!
1053    //! <b>Throws</b>: Nothing.
1054    //!
1055    //! <b>Complexity</b>: Constant time.
1056    void pop_back()
1057    {  this->erase(this->end()-1);   }
1058
1059    //! <b>Requires</b>: position must be a valid iterator of *this.
1060    //!
1061    //! <b>Effects</b>: Insert a copy of x before position.
1062    //!
1063    //! <b>Throws</b>: If memory allocation throws or x's copy constructor throws.
1064    //!
1065    //! <b>Complexity</b>: If position is end(), amortized constant time
1066    //!   Linear time otherwise.
1067    iterator insert(const_iterator position, insert_const_ref_type x) 
1068    {  return this->priv_insert(position, x); }
1069
1070    #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1071    iterator insert(const_iterator position, T &x) { return this->insert(position, const_cast<const T &>(x)); }
1072
1073    template<class U>
1074    iterator insert(const_iterator position, const U &u, typename container_detail::enable_if_c
1075                   <container_detail::is_same<T, U>::value && !::boost::has_move_emulation_enabled<U>::value >::type* =0)
1076    {  return this->priv_insert(position, u); }
1077    #endif
1078
1079    //! <b>Requires</b>: position must be a valid iterator of *this.
1080    //!
1081    //! <b>Effects</b>: Insert a new element before position with mx's resources.
1082    //!
1083    //! <b>Throws</b>: If memory allocation throws.
1084    //!
1085    //! <b>Complexity</b>: If position is end(), amortized constant time
1086    //!   Linear time otherwise.
1087    iterator insert(const_iterator position, BOOST_RV_REF(T) x) 
1088    {
1089       typedef repeat_iterator<T, difference_type>           repeat_it;
1090       typedef boost::move_iterator<repeat_it> repeat_move_it;
1091       //Just call more general insert(pos, size, value) and return iterator
1092       size_type pos_n = position - cbegin();
1093       this->insert(position
1094          ,repeat_move_it(repeat_it(x, 1))
1095          ,repeat_move_it(repeat_it()));
1096       return iterator(this->begin() + pos_n);
1097    }
1098
1099    //! <b>Requires</b>: pos must be a valid iterator of *this.
1100    //!
1101    //! <b>Effects</b>: Insert n copies of x before pos.
1102    //!
1103    //! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
1104    //!
1105    //! <b>Complexity</b>: Linear to n.
1106    void insert(const_iterator position, size_type n, const T& t)
1107    {
1108       STABLE_VECTOR_CHECK_INVARIANT;
1109       this->insert_not_iter(position, n, t);
1110    }
1111
1112    //! <b>Requires</b>: pos must be a valid iterator of *this.
1113    //!
1114    //! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
1115    //!
1116    //! <b>Throws</b>: If memory allocation throws, T's constructor from a
1117    //!   dereferenced InpIt throws or T's copy constructor throws.
1118    //!
1119    //! <b>Complexity</b>: Linear to std::distance [first, last).
1120    template <class InputIterator>
1121    void insert(const_iterator position,InputIterator first, InputIterator last)
1122    {
1123       STABLE_VECTOR_CHECK_INVARIANT;
1124       this->insert_iter(position,first,last,
1125                         boost::mpl::not_<boost::is_integral<InputIterator> >());
1126    }
1127
1128    #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1129
1130    //! <b>Effects</b>: Inserts an object of type T constructed with
1131    //!   std::forward<Args>(args)... in the end of the stable_vector.
1132    //!
1133    //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
1134    //!
1135    //! <b>Complexity</b>: Amortized constant time.
1136    template<class ...Args>
1137    void emplace_back(Args &&...args)
1138    {
1139       typedef emplace_functor<Args...>         EmplaceFunctor;
1140       typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
1141       EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
1142       this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator());
1143    }
1144
1145    //! <b>Requires</b>: position must be a valid iterator of *this.
1146    //!
1147    //! <b>Effects</b>: Inserts an object of type T constructed with
1148    //!   std::forward<Args>(args)... before position
1149    //!
1150    //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws.
1151    //!
1152    //! <b>Complexity</b>: If position is end(), amortized constant time
1153    //!   Linear time otherwise.
1154    template<class ...Args>
1155    iterator emplace(const_iterator position, Args && ...args)
1156    {
1157       //Just call more general insert(pos, size, value) and return iterator
1158       size_type pos_n = position - cbegin();
1159       typedef emplace_functor<Args...>         EmplaceFunctor;
1160       typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type> EmplaceIterator;
1161       EmplaceFunctor &&ef = EmplaceFunctor(boost::forward<Args>(args)...);
1162       this->insert(position, EmplaceIterator(ef), EmplaceIterator());
1163       return iterator(this->begin() + pos_n);
1164    }
1165
1166    #else
1167
1168    #define BOOST_PP_LOCAL_MACRO(n)                                                              \
1169    BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)       \
1170    void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                        \
1171    {                                                                                            \
1172       typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg)                               \
1173          BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >)               \
1174             EmplaceFunctor;                                                                     \
1175       typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type>  EmplaceIterator;  \
1176       EmplaceFunctor ef BOOST_PP_LPAREN_IF(n)                                                   \
1177                         BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)                   \
1178                         BOOST_PP_RPAREN_IF(n);                                                  \
1179       this->insert(this->cend() , EmplaceIterator(ef), EmplaceIterator());                      \
1180    }                                                                                            \
1181                                                                                                 \
1182    BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)       \
1183    iterator emplace(const_iterator pos                                                          \
1184            BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                         \
1185    {                                                                                            \
1186       typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg)                               \
1187          BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >)               \
1188             EmplaceFunctor;                                                                     \
1189       typedef emplace_iterator<node_type_t, EmplaceFunctor, difference_type>  EmplaceIterator;  \
1190       EmplaceFunctor ef BOOST_PP_LPAREN_IF(n)                                                   \
1191                         BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)                   \
1192                         BOOST_PP_RPAREN_IF(n);                                                  \
1193       size_type pos_n = pos - this->cbegin();                                                   \
1194       this->insert(pos, EmplaceIterator(ef), EmplaceIterator());                                \
1195       return iterator(this->begin() + pos_n);                                                   \
1196    }                                                                                            \
1197    //!
1198    #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
1199    #include BOOST_PP_LOCAL_ITERATE()
1200
1201    #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
1202
1203    //! <b>Effects</b>: Erases the element at position pos.
1204    //!
1205    //! <b>Throws</b>: Nothing.
1206    //!
1207    //! <b>Complexity</b>: Linear to the elements between pos and the 
1208    //!   last element. Constant if pos is the last element.
1209    iterator erase(const_iterator position)
1210    {
1211       STABLE_VECTOR_CHECK_INVARIANT;
1212       difference_type d = position - this->cbegin();
1213       impl_iterator   it = impl.begin() + d;
1214       this->delete_node(*it);
1215       it = impl.erase(it);
1216       this->align_nodes(it, get_last_align());
1217       return this->begin()+d;
1218    }
1219
1220    //! <b>Effects</b>: Erases the elements pointed by [first, last).
1221    //!
1222    //! <b>Throws</b>: Nothing.
1223    //!
1224    //! <b>Complexity</b>: Linear to the distance between first and last
1225    //!   plus linear to the elements between pos and the last element.
1226    iterator erase(const_iterator first, const_iterator last)
1227    {   return priv_erase(first, last, alloc_version());  }
1228
1229    //! <b>Effects</b>: Swaps the contents of *this and x.
1230    //!
1231    //! <b>Throws</b>: Nothing.
1232    //!
1233    //! <b>Complexity</b>: Constant.
1234    void swap(stable_vector & x)
1235    {
1236       STABLE_VECTOR_CHECK_INVARIANT;
1237       container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
1238       container_detail::swap_alloc(this->node_alloc(), x.node_alloc(), flag);
1239       //vector's allocator is swapped here
1240       this->impl.swap(x.impl);
1241       this->priv_swap_members(x);
1242    }
1243
1244    //! <b>Effects</b>: Erases all the elements of the stable_vector.
1245    //!
1246    //! <b>Throws</b>: Nothing.
1247    //!
1248    //! <b>Complexity</b>: Linear to the number of elements in the stable_vector.
1249    void clear()
1250    {   this->erase(this->cbegin(),this->cend()); }
1251
1252    //! <b>Effects</b>: Tries to deallocate the excess of memory created
1253    //!   with previous allocations. The size of the stable_vector is unchanged
1254    //!
1255    //! <b>Throws</b>: If memory allocation throws.
1256    //!
1257    //! <b>Complexity</b>: Linear to size().
1258    void shrink_to_fit()
1259    {
1260       if(this->capacity()){
1261          //First empty allocated node pool
1262          this->clear_pool();
1263          //If empty completely destroy the index, let's recover default-constructed state
1264          if(this->empty()){
1265             this->impl.clear();
1266             this->impl.shrink_to_fit();
1267             this->internal_data.set_end_pointer_to_default_constructed();
1268          }
1269          //Otherwise, try to shrink-to-fit the index and readjust pointers if necessary
1270          else{
1271             const size_type size = this->size();
1272             const void* old_ptr = &impl[0];
1273             this->impl.shrink_to_fit();
1274             bool realloced = &impl[0] != old_ptr;
1275             //Fix the pointers for the newly allocated buffer
1276             if(realloced){
1277                this->align_nodes(impl.begin(), impl.begin()+size+1);
1278             }
1279          }
1280       }
1281    }
1282
1283    /// @cond
1284
1285    iterator priv_insert(const_iterator position, const value_type &t)
1286    {
1287       typedef constant_iterator<value_type, difference_type> cvalue_iterator;
1288       return this->insert_iter(position, cvalue_iterator(t, 1), cvalue_iterator(), std::forward_iterator_tag());
1289    }
1290
1291    void priv_push_back(const value_type &t)
1292    {  this->insert(end(), t);  }
1293
1294    template<class AllocatorVersion>
1295    void clear_pool(AllocatorVersion,
1296       typename boost::container::container_detail::enable_if_c
1297          <boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
1298             ::value>::type * = 0)
1299    {
1300       if(!impl.empty() && impl.back()){
1301          void_ptr &pool_first_ref = impl.end()[-2];
1302          void_ptr &pool_last_ref = impl.back();
1303
1304          multiallocation_chain holder;
1305          holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, this->internal_data.pool_size);
1306          while(!holder.empty()){
1307             node_type_ptr_t n = holder.front();
1308             holder.pop_front();
1309             this->deallocate_one(n);
1310          }
1311          pool_first_ref = pool_last_ref = 0;
1312          this->internal_data.pool_size = 0;
1313       }
1314    }
1315
1316    template<class AllocatorVersion>
1317    void clear_pool(AllocatorVersion,
1318       typename boost::container::container_detail::enable_if_c
1319          <!boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
1320             ::value>::type * = 0)
1321    {
1322       if(!impl.empty() && impl.back()){
1323          void_ptr &pool_first_ref = impl.end()[-2];
1324          void_ptr &pool_last_ref = impl.back();
1325          multiallocation_chain holder;
1326          holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, internal_data.pool_size);
1327          node_alloc().deallocate_individual(boost::move(holder));
1328          pool_first_ref = pool_last_ref = 0;
1329          this->internal_data.pool_size = 0;
1330       }
1331    }
1332
1333    void clear_pool()
1334    {
1335       this->clear_pool(alloc_version());
1336    }
1337
1338    void add_to_pool(size_type n)
1339    {
1340       this->add_to_pool(n, alloc_version());
1341    }
1342
1343    template<class AllocatorVersion>
1344    void add_to_pool(size_type n, AllocatorVersion,
1345       typename boost::container::container_detail::enable_if_c
1346          <boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
1347             ::value>::type * = 0)
1348    {
1349       size_type remaining = n;
1350       while(remaining--){
1351          this->put_in_pool(this->allocate_one());
1352       }
1353    }
1354
1355    template<class AllocatorVersion>
1356    void add_to_pool(size_type n, AllocatorVersion,
1357       typename boost::container::container_detail::enable_if_c
1358          <!boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
1359             ::value>::type * = 0)
1360    {
1361       void_ptr &pool_first_ref = impl.end()[-2];
1362       void_ptr &pool_last_ref = impl.back();
1363       multiallocation_chain holder;
1364       holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, internal_data.pool_size);
1365       //BOOST_STATIC_ASSERT((::boost::has_move_emulation_enabled<multiallocation_chain>::value == true));
1366       multiallocation_chain m (node_alloc().allocate_individual(n));
1367       holder.splice_after(holder.before_begin(), m, m.before_begin(), m.last(), n);
1368       this->internal_data.pool_size += n;
1369       std::pair<void_ptr, void_ptr> data(holder.extract_data());
1370       pool_first_ref = data.first;
1371       pool_last_ref = data.second;
1372    }
1373
1374    void put_in_pool(node_type_ptr_t p)
1375    {
1376       void_ptr &pool_first_ref = impl.end()[-2];
1377       void_ptr &pool_last_ref = impl.back();
1378       multiallocation_chain holder;
1379       holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, internal_data.pool_size);
1380       holder.push_front(p);
1381       ++this->internal_data.pool_size;
1382       std::pair<void_ptr, void_ptr> ret(holder.extract_data());
1383       pool_first_ref = ret.first;
1384       pool_last_ref = ret.second;
1385    }
1386
1387    node_type_ptr_t get_from_pool()
1388    {
1389       if(!impl.back()){
1390          return node_type_ptr_t(0);
1391       }
1392       else{
1393          void_ptr &pool_first_ref = impl.end()[-2];
1394          void_ptr &pool_last_ref = impl.back();
1395          multiallocation_chain holder;
1396          holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, internal_data.pool_size);
1397          node_type_ptr_t ret = holder.front();
1398          holder.pop_front();
1399          --this->internal_data.pool_size;
1400          if(!internal_data.pool_size){
1401             pool_first_ref = pool_last_ref = void_ptr(0);
1402          }
1403          else{
1404             std::pair<void_ptr, void_ptr> data(holder.extract_data());
1405             pool_first_ref = data.first;
1406             pool_last_ref = data.second;
1407          }
1408          return ret;
1409       }
1410    }
1411
1412    void insert_iter_prolog(size_type n, difference_type d)
1413    {
1414       initialize_end_node(n);
1415       const void* old_ptr = &impl[0];
1416       //size_type old_capacity = capacity();
1417       //size_type old_size = size();
1418       impl.insert(impl.begin()+d, n, 0);
1419       bool realloced = &impl[0] != old_ptr;
1420       //Fix the pointers for the newly allocated buffer
1421       if(realloced){
1422          align_nodes(impl.begin(), impl.begin()+d);
1423       }
1424    }
1425
1426    template<typename InputIterator>
1427    void assign_dispatch(InputIterator first, InputIterator last, boost::mpl::false_)
1428    {
1429       STABLE_VECTOR_CHECK_INVARIANT;
1430       iterator first1   = this->begin();
1431       iterator last1    = this->end();
1432       for ( ; first1 != last1 && first != last; ++first1, ++first)
1433          *first1 = *first;
1434       if (first == last){
1435          this->erase(first1, last1);
1436       }
1437       else{
1438          this->insert(last1, first, last);
1439       }
1440    }
1441
1442    template<typename Integer>
1443    void assign_dispatch(Integer n, Integer t, boost::mpl::true_)
1444    {
1445       typedef constant_iterator<value_type, difference_type> cvalue_iterator;
1446       this->assign_dispatch(cvalue_iterator(t, n), cvalue_iterator(), boost::mpl::false_());
1447    }
1448
1449    iterator priv_erase(const_iterator first, const_iterator last, allocator_v1)
1450    {
1451       STABLE_VECTOR_CHECK_INVARIANT;
1452       difference_type d1 = first - this->cbegin(), d2 = last - this->cbegin();
1453       if(d1 != d2){
1454          impl_iterator it1(impl.begin() + d1), it2(impl.begin() + d2);
1455          for(impl_iterator it = it1; it != it2; ++it)
1456             this->delete_node(*it);
1457          impl_iterator e = impl.erase(it1, it2);
1458          this->align_nodes(e, get_last_align());
1459       }
1460       return iterator(this->begin() + d1);
1461    }
1462
1463    impl_iterator get_last_align()
1464    {
1465       return impl.end() - (ExtraPointers - 1);
1466    }
1467
1468    const_impl_iterator get_last_align() const
1469    {
1470       return impl.cend() - (ExtraPointers - 1);
1471    }
1472
1473    template<class AllocatorVersion>
1474    iterator priv_erase(const_iterator first, const_iterator last, AllocatorVersion,
1475       typename boost::container::container_detail::enable_if_c
1476          <!boost::container::container_detail::is_same<AllocatorVersion, allocator_v1>
1477             ::value>::type * = 0)
1478    {
1479       STABLE_VECTOR_CHECK_INVARIANT;
1480       return priv_erase(first, last, allocator_v1());
1481    }
1482
1483    static node_type_ptr_t node_ptr_cast(const void_ptr &p)
1484    {
1485       return node_type_ptr_t(static_cast<node_type_t*>(stable_vector_detail::to_raw_pointer(p)));
1486    }
1487
1488    static node_type_base_ptr_t node_base_ptr_cast(const void_ptr &p)
1489    {
1490       return node_type_base_ptr_t(static_cast<node_type_base_t*>(stable_vector_detail::to_raw_pointer(p)));
1491    }
1492
1493    static value_type& value(const void_ptr &p)
1494    {
1495       return node_ptr_cast(p)->value;
1496    }
1497
1498    void initialize_end_node(size_type impl_capacity = 0)
1499    {
1500       if(impl.empty()){
1501          impl.reserve(impl_capacity + ExtraPointers);
1502          impl.resize (ExtraPointers, void_ptr(0));
1503          impl[0] = &this->internal_data.end_node;
1504          this->internal_data.end_node.up = &impl[0];
1505       }
1506    }
1507
1508    void readjust_end_node()
1509    {
1510       if(!this->impl.empty()){
1511          void_ptr &end_node_ref = *(this->get_last_align()-1);
1512          end_node_ref = this->get_end_node();
1513          this->internal_data.end_node.up = &end_node_ref;
1514       }
1515       else{
1516          this->internal_data.end_node.up = void_ptr(&this->internal_data.end_node.up);
1517       }
1518    }
1519
1520    node_type_ptr_t get_end_node() const
1521    {
1522       const node_type_base_t* cp = &this->internal_data.end_node;
1523       node_type_base_t* p = const_cast<node_type_base_t*>(cp);
1524       return node_ptr_cast(p);
1525    }
1526
1527    template<class Iter>
1528    void_ptr new_node(const void_ptr &up, Iter it)
1529    {
1530       node_type_ptr_t p = this->allocate_one();
1531       try{
1532          boost::container::construct_in_place(this->node_alloc(), &*p, it);
1533          p->set_pointer(up);
1534       }
1535       catch(...){
1536          this->deallocate_one(p);
1537          throw;
1538       }
1539       return p;
1540    }
1541
1542    void delete_node(const void_ptr &p)
1543    {
1544       node_type_ptr_t n(node_ptr_cast(p));
1545       allocator_traits<node_allocator_type>::
1546          destroy(this->node_alloc(), container_detail::to_raw_pointer(n));
1547       this->put_in_pool(n);
1548    }
1549
1550    static void align_nodes(impl_iterator first, impl_iterator last)
1551    {
1552       while(first!=last){
1553          node_ptr_cast(*first)->up = void_ptr(&*first);
1554          ++first;
1555       }
1556    }
1557
1558    void insert_not_iter(const_iterator position, size_type n, const T& t)
1559    {
1560       typedef constant_iterator<value_type, difference_type> cvalue_iterator;
1561       this->insert_iter(position, cvalue_iterator(t, n), cvalue_iterator(), std::forward_iterator_tag());
1562    }
1563
1564    template <class InputIterator>
1565    void insert_iter(const_iterator position,InputIterator first,InputIterator last, boost::mpl::true_)
1566    {
1567       typedef typename std::iterator_traits<InputIterator>::iterator_category category;
1568       this->insert_iter(position, first, last, category());
1569    }
1570
1571    template <class InputIterator>
1572    void insert_iter(const_iterator position,InputIterator first,InputIterator last,std::input_iterator_tag)
1573    {
1574       for(; first!=last; ++first){
1575          this->insert(position, *first);
1576       }    
1577    }
1578
1579    template <class InputIterator>
1580    iterator insert_iter(const_iterator position, InputIterator first, InputIterator last, std::forward_iterator_tag)
1581    {
1582       size_type       n = (size_type)std::distance(first,last);
1583       difference_type d = position-this->cbegin();
1584       if(n){
1585          this->insert_iter_prolog(n, d);
1586          const impl_iterator it(impl.begin() + d);
1587          this->insert_iter_fwd(it, first, last, n);
1588          //Fix the pointers for the newly allocated buffer
1589          this->align_nodes(it + n, get_last_align());
1590       }
1591       return this->begin() + d;
1592    }
1593
1594    template <class FwdIterator>
1595    void insert_iter_fwd_alloc(const impl_iterator it, FwdIterator first, FwdIterator last, difference_type n, allocator_v1)
1596    {
1597       size_type i=0;
1598       try{
1599          while(first!=last){
1600             it[i] = this->new_node(void_ptr_ptr(&it[i]), first);
1601             ++first;
1602             ++i;
1603          }
1604       }
1605       catch(...){
1606          impl_iterator e = impl.erase(it + i, it + n);
1607          this->align_nodes(e, get_last_align());
1608          throw;
1609       }
1610    }
1611
1612    template <class FwdIterator>
1613    void insert_iter_fwd_alloc(const impl_iterator it, FwdIterator first, FwdIterator last, difference_type n, allocator_v2)
1614    {
1615       multiallocation_chain mem(node_alloc().allocate_individual(n));
1616
1617       size_type i = 0;
1618       node_type_ptr_t p = 0;
1619       try{
1620          while(first != last){
1621             p = mem.front();
1622             mem.pop_front();
1623             //This can throw
1624             boost::container::construct_in_place(this->node_alloc(), &*p, first);
1625             p->set_pointer(void_ptr_ptr(&it[i]));
1626             ++first;
1627             it[i] = p;
1628             ++i;
1629          }
1630       }
1631       catch(...){
1632          node_alloc().deallocate_one(p);
1633          node_alloc().deallocate_many(boost::move(mem));
1634          impl_iterator e = impl.erase(it+i, it+n);
1635          this->align_nodes(e, get_last_align());
1636          throw;
1637       }
1638    }
1639
1640    template <class FwdIterator>
1641    void insert_iter_fwd(const impl_iterator it, FwdIterator first, FwdIterator last, difference_type n)
1642    {
1643       size_type i = 0;
1644       node_type_ptr_t p = 0;
1645       try{
1646          while(first != last){
1647             p = this->get_from_pool();
1648             if(!p){
1649                insert_iter_fwd_alloc(it+i, first, last, n-i, alloc_version());
1650                break;
1651             }
1652             //This can throw
1653             boost::container::construct_in_place(this->node_alloc(), &*p, first);
1654             p->set_pointer(void_ptr_ptr(&it[i]));
1655             ++first;
1656             it[i]=p;
1657             ++i;
1658          }
1659       }
1660       catch(...){
1661          put_in_pool(p);
1662          impl_iterator e = impl.erase(it+i, it+n);
1663          this->align_nodes(e, get_last_align());
1664          throw;
1665       }
1666    }
1667
1668    template <class InputIterator>
1669    void insert_iter(const_iterator position, InputIterator first, InputIterator last, boost::mpl::false_)
1670    {
1671       this->insert_not_iter(position, first, last);
1672    }
1673
1674    #if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
1675    bool invariant()const
1676    {
1677       if(impl.empty())
1678          return !capacity() && !size();
1679       if(get_end_node() != *(impl.end() - ExtraPointers)){
1680          return false;
1681       }
1682       for(const_impl_iterator it = impl.begin(), it_end = get_last_align(); it != it_end; ++it){
1683          if(const_void_ptr(node_ptr_cast(*it)->up) != 
1684                const_void_ptr(const_void_ptr_ptr(&*it)))
1685             return false;
1686       }
1687       size_type n = capacity()-size();
1688       const void_ptr &pool_head = impl.back();
1689       size_type num_pool = 0;
1690       node_type_ptr_t p = node_ptr_cast(pool_head);
1691       while(p){
1692          ++num_pool;
1693          p = node_ptr_cast(p->up);
1694       }
1695       return n >= num_pool;
1696    }
1697
1698    class invariant_checker
1699    {
1700       invariant_checker(const invariant_checker &);
1701       invariant_checker & operator=(const invariant_checker &);
1702       const stable_vector* p;
1703
1704       public:
1705       invariant_checker(const stable_vector& v):p(&v){}
1706       ~invariant_checker(){BOOST_ASSERT(p->invariant());}
1707       void touch(){}
1708    };
1709    #endif
1710
1711    class ebo_holder
1712       : public node_allocator_type
1713    {
1714       private:
1715       BOOST_MOVABLE_BUT_NOT_COPYABLE(ebo_holder)
1716       public:
1717 /*
1718       explicit ebo_holder(BOOST_RV_REF(ebo_holder) x)
1719          : node_allocator_type(boost::move(static_cast<node_allocator_type&>(x)))
1720          , pool_size(0)
1721          , end_node()
1722       {}
1723 */
1724       template<class AllocatorRLValue>
1725       explicit ebo_holder(BOOST_FWD_REF(AllocatorRLValue) a)
1726          : node_allocator_type(boost::forward<AllocatorRLValue>(a))
1727          , pool_size(0)
1728          , end_node()
1729       {
1730          this->set_end_pointer_to_default_constructed();
1731       }
1732
1733       ebo_holder()
1734          : node_allocator_type()
1735          , pool_size(0)
1736          , end_node()
1737       {
1738          this->set_end_pointer_to_default_constructed();
1739       }
1740
1741       void set_end_pointer_to_default_constructed()
1742       {
1743          end_node.set_pointer(void_ptr(&end_node.up));
1744       }
1745
1746       size_type pool_size;
1747       node_type_base_t end_node;
1748    } internal_data;
1749
1750    void priv_swap_members(stable_vector &x)
1751    {
1752       container_detail::do_swap(this->internal_data.pool_size, x.internal_data.pool_size);
1753       this->readjust_end_node();
1754       x.readjust_end_node();
1755    }
1756
1757    node_allocator_type &node_alloc()              { return internal_data;  }
1758    const node_allocator_type &node_alloc() const  { return internal_data;  }
1759
1760    impl_type                           impl;
1761    /// @endcond
1762 };
1763
1764 template <typename T,typename A>
1765 bool operator==(const stable_vector<T,A>& x,const stable_vector<T,A>& y)
1766 {
1767    return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
1768 }
1769
1770 template <typename T,typename A>
1771 bool operator< (const stable_vector<T,A>& x,const stable_vector<T,A>& y)
1772 {
1773    return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
1774 }
1775
1776 template <typename T,typename A>
1777 bool operator!=(const stable_vector<T,A>& x,const stable_vector<T,A>& y)
1778 {
1779    return !(x==y);
1780 }
1781
1782 template <typename T,typename A>
1783 bool operator> (const stable_vector<T,A>& x,const stable_vector<T,A>& y)
1784 {
1785    return y<x;
1786 }
1787
1788 template <typename T,typename A>
1789 bool operator>=(const stable_vector<T,A>& x,const stable_vector<T,A>& y)
1790 {
1791    return !(x<y);
1792 }
1793
1794 template <typename T,typename A>
1795 bool operator<=(const stable_vector<T,A>& x,const stable_vector<T,A>& y)
1796 {
1797    return !(x>y);
1798 }
1799
1800 // specialized algorithms:
1801
1802 template <typename T, typename A>
1803 void swap(stable_vector<T,A>& x,stable_vector<T,A>& y)
1804 {
1805    x.swap(y);
1806 }
1807
1808 /// @cond
1809
1810 #undef STABLE_VECTOR_CHECK_INVARIANT
1811
1812 /// @endcond
1813
1814 }}
1815
1816 #include <boost/container/detail/config_end.hpp>
1817
1818 #endif   //BOOST_CONTAINER_STABLE_VECTOR_HPP