rnd_index_ptr_array.hpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /* Copyright 2003-2018 Joaquin M Lopez Munoz.
  2. * Distributed under the Boost Software License, Version 1.0.
  3. * (See accompanying file LICENSE_1_0.txt or copy at
  4. * http://www.boost.org/LICENSE_1_0.txt)
  5. *
  6. * See http://www.boost.org/libs/multi_index for library home page.
  7. */
  8. #ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_PTR_ARRAY_HPP
  9. #define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_PTR_ARRAY_HPP
  10. #if defined(_MSC_VER)
  11. #pragma once
  12. #endif
  13. #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
  14. #include <algorithm>
  15. #include <boost/multi_index/detail/allocator_traits.hpp>
  16. #include <boost/multi_index/detail/auto_space.hpp>
  17. #include <boost/multi_index/detail/rnd_index_node.hpp>
  18. #include <boost/noncopyable.hpp>
  19. namespace boost{
  20. namespace multi_index{
  21. namespace detail{
  22. /* pointer structure for use by random access indices */
  23. template<typename Allocator>
  24. class random_access_index_ptr_array:private noncopyable
  25. {
  26. typedef random_access_index_node_impl<
  27. typename rebind_alloc_for<
  28. Allocator,
  29. char
  30. >::type
  31. > node_impl_type;
  32. public:
  33. typedef typename node_impl_type::pointer value_type;
  34. typedef typename rebind_alloc_for<
  35. Allocator,value_type
  36. >::type value_allocator;
  37. typedef allocator_traits<value_allocator> alloc_traits;
  38. typedef typename alloc_traits::pointer pointer;
  39. typedef typename alloc_traits::size_type size_type;
  40. random_access_index_ptr_array(
  41. const Allocator& al,value_type end_,size_type sz):
  42. size_(sz),
  43. capacity_(sz),
  44. spc(al,capacity_+1)
  45. {
  46. *end()=end_;
  47. end_->up()=end();
  48. }
  49. size_type size()const{return size_;}
  50. size_type capacity()const{return capacity_;}
  51. void room_for_one()
  52. {
  53. if(size_==capacity_){
  54. reserve(capacity_<=10?15:capacity_+capacity_/2);
  55. }
  56. }
  57. void reserve(size_type c)
  58. {
  59. if(c>capacity_)set_capacity(c);
  60. }
  61. void shrink_to_fit()
  62. {
  63. if(capacity_>size_)set_capacity(size_);
  64. }
  65. pointer begin()const{return ptrs();}
  66. pointer end()const{return ptrs()+size_;}
  67. pointer at(size_type n)const{return ptrs()+n;}
  68. void push_back(value_type x)
  69. {
  70. *(end()+1)=*end();
  71. (*(end()+1))->up()=end()+1;
  72. *end()=x;
  73. (*end())->up()=end();
  74. ++size_;
  75. }
  76. void erase(value_type x)
  77. {
  78. node_impl_type::extract(x->up(),end()+1);
  79. --size_;
  80. }
  81. void clear()
  82. {
  83. *begin()=*end();
  84. (*begin())->up()=begin();
  85. size_=0;
  86. }
  87. void swap(random_access_index_ptr_array& x)
  88. {
  89. std::swap(size_,x.size_);
  90. std::swap(capacity_,x.capacity_);
  91. spc.swap(x.spc);
  92. }
  93. private:
  94. size_type size_;
  95. size_type capacity_;
  96. auto_space<value_type,Allocator> spc;
  97. pointer ptrs()const
  98. {
  99. return spc.data();
  100. }
  101. void set_capacity(size_type c)
  102. {
  103. auto_space<value_type,Allocator> spc1(spc.get_allocator(),c+1);
  104. node_impl_type::transfer(begin(),end()+1,spc1.data());
  105. spc.swap(spc1);
  106. capacity_=c;
  107. }
  108. };
  109. template<typename Allocator>
  110. void swap(
  111. random_access_index_ptr_array<Allocator>& x,
  112. random_access_index_ptr_array<Allocator>& y)
  113. {
  114. x.swap(y);
  115. }
  116. } /* namespace multi_index::detail */
  117. } /* namespace multi_index */
  118. } /* namespace boost */
  119. #endif