vector 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. // Profiling vector implementation -*- C++ -*-
  2. // Copyright (C) 2009-2018 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. //
  10. // This library is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU General Public License for more details.
  14. // Under Section 7 of GPL version 3, you are granted additional
  15. // permissions described in the GCC Runtime Library Exception, version
  16. // 3.1, as published by the Free Software Foundation.
  17. // You should have received a copy of the GNU General Public License along
  18. // with this library; see the file COPYING3. If not see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file profile/vector
  21. * This file is a GNU profile extension to the Standard C++ Library.
  22. */
  23. #ifndef _GLIBCXX_PROFILE_VECTOR
  24. #define _GLIBCXX_PROFILE_VECTOR 1
  25. #include <vector>
  26. #include <utility>
  27. #include <profile/base.h>
  28. #include <profile/iterator_tracker.h>
  29. namespace std _GLIBCXX_VISIBILITY(default)
  30. {
  31. namespace __profile
  32. {
  33. template<typename _Vector>
  34. class _Vector_profile_pre
  35. {
  36. _Vector&
  37. _M_conjure()
  38. { return *static_cast<_Vector*>(this); }
  39. public:
  40. #if __cplusplus >= 201103L
  41. _Vector_profile_pre() = default;
  42. _Vector_profile_pre(const _Vector_profile_pre&) = default;
  43. _Vector_profile_pre(_Vector_profile_pre&&) = default;
  44. _Vector_profile_pre&
  45. operator=(const _Vector_profile_pre&)
  46. { _M_conjure()._M_profile_destruct(); }
  47. _Vector_profile_pre&
  48. operator=(_Vector_profile_pre&&) noexcept
  49. { _M_conjure()._M_profile_destruct(); }
  50. #endif
  51. };
  52. template<typename _Vector>
  53. class _Vector_profile_post
  54. {
  55. _Vector&
  56. _M_conjure()
  57. { return *static_cast<_Vector*>(this); }
  58. protected:
  59. __gnu_profile::__container_size_info* _M_size_info;
  60. __gnu_profile::__vector2list_info* _M_vect2list_info;
  61. _Vector_profile_post() _GLIBCXX_NOEXCEPT
  62. { _M_profile_construct(); }
  63. #if __cplusplus >= 201103L
  64. _Vector_profile_post(const _Vector_profile_post&) noexcept
  65. : _Vector_profile_post() { }
  66. _Vector_profile_post(_Vector_profile_post&& __other) noexcept
  67. : _Vector_profile_post()
  68. { _M_swap(__other); }
  69. _Vector_profile_post&
  70. operator=(const _Vector_profile_post&) noexcept
  71. { _M_profile_construct(); }
  72. _Vector_profile_post&
  73. operator=(_Vector_profile_post&& __other) noexcept
  74. {
  75. _M_swap(__other);
  76. __other._M_profile_construct();
  77. }
  78. #endif
  79. ~_Vector_profile_post()
  80. { _M_conjure()._M_profile_destruct(); }
  81. public:
  82. void
  83. _M_profile_construct() _GLIBCXX_NOEXCEPT
  84. {
  85. _M_size_info =
  86. __profcxx_vector_size_construct(_M_conjure().capacity());
  87. _M_vect2list_info = __profcxx_vector2list_construct();
  88. }
  89. void
  90. _M_profile_destruct() _GLIBCXX_NOEXCEPT
  91. {
  92. __profcxx_vector2list_destruct(_M_vect2list_info);
  93. _M_vect2list_info = 0;
  94. __profcxx_vector_size_destruct(_M_size_info,
  95. _M_conjure().capacity(),
  96. _M_conjure().size());
  97. _M_size_info = 0;
  98. }
  99. void
  100. _M_swap(_Vector_profile_post& __other) _GLIBCXX_NOEXCEPT
  101. {
  102. std::swap(_M_size_info, __other._M_size_info);
  103. std::swap(_M_vect2list_info, __other._M_vect2list_info);
  104. }
  105. };
  106. template<typename _Tp,
  107. typename _Allocator = std::allocator<_Tp> >
  108. class vector
  109. : public _Vector_profile_pre<vector<_Tp, _Allocator> >,
  110. public _GLIBCXX_STD_C::vector<_Tp, _Allocator>,
  111. public _Vector_profile_post<vector<_Tp, _Allocator> >
  112. {
  113. typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base;
  114. typedef typename _Base::iterator _Base_iterator;
  115. typedef typename _Base::const_iterator _Base_const_iterator;
  116. public:
  117. typedef typename _Base::reference reference;
  118. typedef typename _Base::const_reference const_reference;
  119. typedef __iterator_tracker<_Base_iterator, vector>
  120. iterator;
  121. typedef __iterator_tracker<_Base_const_iterator, vector>
  122. const_iterator;
  123. typedef typename _Base::size_type size_type;
  124. typedef typename _Base::difference_type difference_type;
  125. typedef _Tp value_type;
  126. typedef _Allocator allocator_type;
  127. typedef typename _Base::pointer pointer;
  128. typedef typename _Base::const_pointer const_pointer;
  129. typedef std::reverse_iterator<iterator> reverse_iterator;
  130. typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  131. _Base&
  132. _M_base() _GLIBCXX_NOEXCEPT { return *this; }
  133. const _Base&
  134. _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
  135. // 23.2.4.1 construct/copy/destroy:
  136. #if __cplusplus < 201103L
  137. vector()
  138. { }
  139. vector(const vector& __x)
  140. : _Base(__x) { }
  141. #else
  142. vector() = default;
  143. vector(const vector&) = default;
  144. vector(vector&&) = default;
  145. #endif
  146. explicit
  147. vector(const _Allocator& __a) _GLIBCXX_NOEXCEPT
  148. : _Base(__a) { }
  149. #if __cplusplus >= 201103L
  150. explicit
  151. vector(size_type __n, const _Allocator& __a = _Allocator())
  152. : _Base(__n, __a) { }
  153. vector(size_type __n, const _Tp& __value,
  154. const _Allocator& __a = _Allocator())
  155. : _Base(__n, __value, __a) { }
  156. #else
  157. explicit
  158. vector(size_type __n, const _Tp& __value = _Tp(),
  159. const _Allocator& __a = _Allocator())
  160. : _Base(__n, __value, __a) { }
  161. #endif
  162. #if __cplusplus >= 201103L
  163. template<typename _InputIterator,
  164. typename = std::_RequireInputIter<_InputIterator>>
  165. #else
  166. template<typename _InputIterator>
  167. #endif
  168. vector(_InputIterator __first, _InputIterator __last,
  169. const _Allocator& __a = _Allocator())
  170. : _Base(__first, __last, __a) { }
  171. /// Construction from a normal-mode vector
  172. vector(const _Base& __x)
  173. : _Base(__x) { }
  174. #if __cplusplus >= 201103L
  175. vector(const _Base& __x, const _Allocator& __a)
  176. : _Base(__x, __a) { }
  177. vector(vector&& __x, const _Allocator& __a)
  178. : _Base(std::move(__x), __a) { }
  179. vector(initializer_list<value_type> __l,
  180. const allocator_type& __a = allocator_type())
  181. : _Base(__l, __a) { }
  182. #endif
  183. #if __cplusplus < 201103L
  184. vector&
  185. operator=(const vector& __x)
  186. {
  187. this->_M_profile_destruct();
  188. _M_base() = __x;
  189. this->_M_profile_construct();
  190. return *this;
  191. }
  192. #else
  193. vector&
  194. operator=(const vector&) = default;
  195. vector&
  196. operator=(vector&&) = default;
  197. vector&
  198. operator=(initializer_list<value_type> __l)
  199. {
  200. this->_M_profile_destruct();
  201. _M_base() = __l;
  202. this->_M_profile_construct();
  203. return *this;
  204. }
  205. #endif
  206. // iterators:
  207. iterator
  208. begin() _GLIBCXX_NOEXCEPT
  209. { return iterator(_Base::begin(), this); }
  210. const_iterator
  211. begin() const _GLIBCXX_NOEXCEPT
  212. { return const_iterator(_Base::begin(), this); }
  213. iterator
  214. end() _GLIBCXX_NOEXCEPT
  215. { return iterator(_Base::end(), this); }
  216. const_iterator
  217. end() const _GLIBCXX_NOEXCEPT
  218. { return const_iterator(_Base::end(), this); }
  219. reverse_iterator
  220. rbegin() _GLIBCXX_NOEXCEPT
  221. { return reverse_iterator(end()); }
  222. const_reverse_iterator
  223. rbegin() const _GLIBCXX_NOEXCEPT
  224. { return const_reverse_iterator(end()); }
  225. reverse_iterator
  226. rend() _GLIBCXX_NOEXCEPT
  227. { return reverse_iterator(begin()); }
  228. const_reverse_iterator
  229. rend() const _GLIBCXX_NOEXCEPT
  230. { return const_reverse_iterator(begin()); }
  231. #if __cplusplus >= 201103L
  232. const_iterator
  233. cbegin() const noexcept
  234. { return const_iterator(_Base::begin(), this); }
  235. const_iterator
  236. cend() const noexcept
  237. { return const_iterator(_Base::end(), this); }
  238. const_reverse_iterator
  239. crbegin() const noexcept
  240. { return const_reverse_iterator(end()); }
  241. const_reverse_iterator
  242. crend() const noexcept
  243. { return const_reverse_iterator(begin()); }
  244. #endif
  245. // 23.2.4.2 capacity:
  246. #if __cplusplus >= 201103L
  247. void
  248. resize(size_type __sz)
  249. {
  250. __profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
  251. _M_profile_resize(this->capacity(), __sz);
  252. _Base::resize(__sz);
  253. }
  254. void
  255. resize(size_type __sz, const _Tp& __c)
  256. {
  257. __profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
  258. _M_profile_resize(this->capacity(), __sz);
  259. _Base::resize(__sz, __c);
  260. }
  261. #else
  262. void
  263. resize(size_type __sz, _Tp __c = _Tp())
  264. {
  265. __profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
  266. _M_profile_resize(this->capacity(), __sz);
  267. _Base::resize(__sz, __c);
  268. }
  269. #endif
  270. // element access:
  271. reference
  272. operator[](size_type __n) _GLIBCXX_NOEXCEPT
  273. {
  274. __profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
  275. return _M_base()[__n];
  276. }
  277. const_reference
  278. operator[](size_type __n) const _GLIBCXX_NOEXCEPT
  279. {
  280. __profcxx_vector2list_invalid_operator(this->_M_vect2list_info);
  281. return _M_base()[__n];
  282. }
  283. // 23.2.4.3 modifiers:
  284. void
  285. push_back(const _Tp& __x)
  286. {
  287. size_type __old_size = this->capacity();
  288. _Base::push_back(__x);
  289. _M_profile_resize(__old_size, this->capacity());
  290. }
  291. #if __cplusplus >= 201103L
  292. void
  293. push_back(_Tp&& __x)
  294. {
  295. size_type __old_size = this->capacity();
  296. _Base::push_back(std::move(__x));
  297. _M_profile_resize(__old_size, this->capacity());
  298. }
  299. #endif
  300. iterator
  301. #if __cplusplus >= 201103L
  302. insert(const_iterator __pos, const _Tp& __x)
  303. #else
  304. insert(iterator __pos, const _Tp& __x)
  305. #endif
  306. {
  307. __profcxx_vector2list_insert(this->_M_vect2list_info,
  308. __pos.base() - _Base::begin(),
  309. this->size());
  310. size_type __old_size = this->capacity();
  311. _Base_iterator __res = _Base::insert(__pos.base(), __x);
  312. _M_profile_resize(__old_size, this->capacity());
  313. return iterator(__res, this);
  314. }
  315. #if __cplusplus >= 201103L
  316. iterator
  317. insert(const_iterator __pos, _Tp&& __x)
  318. {
  319. __profcxx_vector2list_insert(this->_M_vect2list_info,
  320. __pos.base() - _Base::cbegin(),
  321. this->size());
  322. size_type __old_size = this->capacity();
  323. _Base_iterator __res = _Base::insert(__pos.base(), __x);
  324. _M_profile_resize(__old_size, this->capacity());
  325. return iterator(__res, this);
  326. }
  327. template<typename... _Args>
  328. iterator
  329. emplace(const_iterator __pos, _Args&&... __args)
  330. {
  331. _Base_iterator __res = _Base::emplace(__pos.base(),
  332. std::forward<_Args>(__args)...);
  333. return iterator(__res, this);
  334. }
  335. iterator
  336. insert(const_iterator __pos, initializer_list<value_type> __l)
  337. { return this->insert(__pos, __l.begin(), __l.end()); }
  338. #endif
  339. void
  340. swap(vector& __x)
  341. #if __cplusplus >= 201103L
  342. noexcept( noexcept(declval<_Base>().swap(__x)) )
  343. #endif
  344. {
  345. _Base::swap(__x);
  346. this->_M_swap(__x);
  347. }
  348. #if __cplusplus >= 201103L
  349. iterator
  350. insert(const_iterator __pos, size_type __n, const _Tp& __x)
  351. {
  352. __profcxx_vector2list_insert(this->_M_vect2list_info,
  353. __pos.base() - _Base::cbegin(),
  354. this->size());
  355. size_type __old_size = this->capacity();
  356. _Base_iterator __res = _Base::insert(__pos, __n, __x);
  357. _M_profile_resize(__old_size, this->capacity());
  358. return iterator(__res, this);
  359. }
  360. #else
  361. void
  362. insert(iterator __pos, size_type __n, const _Tp& __x)
  363. {
  364. __profcxx_vector2list_insert(this->_M_vect2list_info,
  365. __pos.base() - _Base::begin(),
  366. this->size());
  367. size_type __old_size = this->capacity();
  368. _Base::insert(__pos, __n, __x);
  369. _M_profile_resize(__old_size, this->capacity());
  370. }
  371. #endif
  372. #if __cplusplus >= 201103L
  373. template<typename _InputIterator,
  374. typename = std::_RequireInputIter<_InputIterator>>
  375. iterator
  376. insert(const_iterator __pos,
  377. _InputIterator __first, _InputIterator __last)
  378. {
  379. __profcxx_vector2list_insert(this->_M_vect2list_info,
  380. __pos.base() - _Base::cbegin(),
  381. this->size());
  382. size_type __old_size = this->capacity();
  383. _Base_iterator __res = _Base::insert(__pos, __first, __last);
  384. _M_profile_resize(__old_size, this->capacity());
  385. return iterator(__res, this);
  386. }
  387. #else
  388. template<typename _InputIterator>
  389. void
  390. insert(iterator __pos,
  391. _InputIterator __first, _InputIterator __last)
  392. {
  393. __profcxx_vector2list_insert(this->_M_vect2list_info,
  394. __pos.base() - _Base::begin(),
  395. this->size());
  396. size_type __old_size = this->capacity();
  397. _Base::insert(__pos, __first, __last);
  398. _M_profile_resize(__old_size, this->capacity());
  399. }
  400. #endif
  401. iterator
  402. #if __cplusplus >= 201103L
  403. erase(const_iterator __pos)
  404. #else
  405. erase(iterator __pos)
  406. #endif
  407. { return iterator(_Base::erase(__pos.base()), this); }
  408. iterator
  409. #if __cplusplus >= 201103L
  410. erase(const_iterator __first, const_iterator __last)
  411. #else
  412. erase(iterator __first, iterator __last)
  413. #endif
  414. { return iterator(_Base::erase(__first.base(), __last.base()), this); }
  415. void
  416. clear() _GLIBCXX_NOEXCEPT
  417. {
  418. this->_M_profile_destruct();
  419. _Base::clear();
  420. this->_M_profile_construct();
  421. }
  422. inline void
  423. _M_profile_iterate(int __rewind = 0) const
  424. { __profcxx_vector2list_iterate(this->_M_vect2list_info, __rewind); }
  425. private:
  426. void _M_profile_resize(size_type __old_size, size_type __new_size)
  427. {
  428. if (__old_size < __new_size)
  429. {
  430. __profcxx_vector_size_resize(this->_M_size_info,
  431. this->size(), __new_size);
  432. __profcxx_vector2list_resize(this->_M_vect2list_info,
  433. this->size(), __new_size);
  434. }
  435. }
  436. };
  437. template<typename _Tp, typename _Alloc>
  438. inline bool
  439. operator==(const vector<_Tp, _Alloc>& __lhs,
  440. const vector<_Tp, _Alloc>& __rhs)
  441. { return __lhs._M_base() == __rhs._M_base(); }
  442. template<typename _Tp, typename _Alloc>
  443. inline bool
  444. operator!=(const vector<_Tp, _Alloc>& __lhs,
  445. const vector<_Tp, _Alloc>& __rhs)
  446. { return __lhs._M_base() != __rhs._M_base(); }
  447. template<typename _Tp, typename _Alloc>
  448. inline bool
  449. operator<(const vector<_Tp, _Alloc>& __lhs,
  450. const vector<_Tp, _Alloc>& __rhs)
  451. { return __lhs._M_base() < __rhs._M_base(); }
  452. template<typename _Tp, typename _Alloc>
  453. inline bool
  454. operator<=(const vector<_Tp, _Alloc>& __lhs,
  455. const vector<_Tp, _Alloc>& __rhs)
  456. { return __lhs._M_base() <= __rhs._M_base(); }
  457. template<typename _Tp, typename _Alloc>
  458. inline bool
  459. operator>=(const vector<_Tp, _Alloc>& __lhs,
  460. const vector<_Tp, _Alloc>& __rhs)
  461. { return __lhs._M_base() >= __rhs._M_base(); }
  462. template<typename _Tp, typename _Alloc>
  463. inline bool
  464. operator>(const vector<_Tp, _Alloc>& __lhs,
  465. const vector<_Tp, _Alloc>& __rhs)
  466. { return __lhs._M_base() > __rhs._M_base(); }
  467. template<typename _Tp, typename _Alloc>
  468. inline void
  469. swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
  470. _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))
  471. { __lhs.swap(__rhs); }
  472. } // namespace __profile
  473. #if __cplusplus >= 201103L
  474. // DR 1182.
  475. /// std::hash specialization for vector<bool>.
  476. template<typename _Alloc>
  477. struct hash<__profile::vector<bool, _Alloc>>
  478. : public __hash_base<size_t, __profile::vector<bool, _Alloc>>
  479. {
  480. size_t
  481. operator()(const __profile::vector<bool, _Alloc>& __b) const noexcept
  482. {
  483. return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()(__b._M_base());
  484. }
  485. };
  486. #endif
  487. } // namespace std
  488. #endif