You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1270 lines
48 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: stlsoft/containers/pod_vector.hpp
  3. *
  4. * Purpose: Contains the pod_vector class.
  5. *
  6. * Created: 23rd December 2003
  7. * Updated: 10th August 2009
  8. *
  9. * Thanks to: Chris Newcombe for requesting sufficient enhancements to
  10. * auto_buffer such that pod_vector was born.
  11. *
  12. * Christian Roessel, for spotting the bug in the copy ctor that
  13. * fails an assert if the copied instance is empty
  14. *
  15. * Home: http://stlsoft.org/
  16. *
  17. * Copyright (c) 2003-2009, Matthew Wilson and Synesis Software
  18. * All rights reserved.
  19. *
  20. * Redistribution and use in source and binary forms, with or without
  21. * modification, are permitted provided that the following conditions are met:
  22. *
  23. * - Redistributions of source code must retain the above copyright notice, this
  24. * list of conditions and the following disclaimer.
  25. * - Redistributions in binary form must reproduce the above copyright notice,
  26. * this list of conditions and the following disclaimer in the documentation
  27. * and/or other materials provided with the distribution.
  28. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  29. * any contributors may be used to endorse or promote products derived from
  30. * this software without specific prior written permission.
  31. *
  32. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  33. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  34. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  35. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  36. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  37. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  38. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  39. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  40. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  41. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  42. * POSSIBILITY OF SUCH DAMAGE.
  43. *
  44. * ////////////////////////////////////////////////////////////////////// */
  45. /** \file stlsoft/containers/pod_vector.hpp
  46. *
  47. * \brief [C++ only] Definition of the stlsoft::pod_vector container class
  48. * template
  49. * (\ref group__library__containers "Containers" Library).
  50. */
  51. #ifndef STLSOFT_INCL_STLSOFT_CONTAINERS_HPP_POD_VECTOR
  52. #define STLSOFT_INCL_STLSOFT_CONTAINERS_HPP_POD_VECTOR
  53. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  54. # define STLSOFT_VER_STLSOFT_CONTAINERS_HPP_POD_VECTOR_MAJOR 4
  55. # define STLSOFT_VER_STLSOFT_CONTAINERS_HPP_POD_VECTOR_MINOR 2
  56. # define STLSOFT_VER_STLSOFT_CONTAINERS_HPP_POD_VECTOR_REVISION 2
  57. # define STLSOFT_VER_STLSOFT_CONTAINERS_HPP_POD_VECTOR_EDIT 76
  58. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  59. /* /////////////////////////////////////////////////////////////////////////
  60. * Compatibility
  61. */
  62. /*
  63. [Incompatibilies-start]
  64. STLSOFT_COMPILER_IS_MSVC: _MSC_VER<1200
  65. STLSOFT_COMPILER_IS_WATCOM:
  66. [Incompatibilies-end]
  67. */
  68. /* /////////////////////////////////////////////////////////////////////////
  69. * Includes
  70. */
  71. #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
  72. # include <stlsoft/stlsoft.h>
  73. #endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */
  74. #if defined(STLSOFT_COMPILER_IS_MSVC) && \
  75. _MSC_VER < 1200
  76. # error stlsoft/containers/pod_vector.hpp is not compatible with Visual C++ 5.0 or earlier
  77. #endif /* compiler */
  78. #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER
  79. # include <stlsoft/memory/auto_buffer.hpp>
  80. #endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER */
  81. #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR
  82. # include <stlsoft/memory/allocator_selector.hpp>
  83. #endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR */
  84. #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP
  85. # include <stlsoft/util/std_swap.hpp>
  86. #endif /* !STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP */
  87. #ifndef STLSOFT_INCL_STLSOFT_ALGORITHMS_HPP_POD
  88. # include <stlsoft/algorithms/pod.hpp> // for pod_copy_n(), etc.
  89. #endif /* !STLSOFT_INCL_STLSOFT_ALGORITHMS_HPP_POD */
  90. #ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
  91. # include <stlsoft/collections/util/collections.hpp>
  92. #endif /* !STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS */
  93. #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
  94. # include <stlsoft/util/std/iterator_helper.hpp>
  95. #endif /* !STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER */
  96. #ifndef STLSOFT_INCL_STDEXCEPT
  97. # define STLSOFT_INCL_STDEXCEPT
  98. # include <stdexcept> // for std::out_of_range
  99. #endif /* !STLSOFT_INCL_STDEXCEPT */
  100. /* /////////////////////////////////////////////////////////////////////////
  101. * Namespace
  102. */
  103. #ifndef _STLSOFT_NO_NAMESPACE
  104. namespace stlsoft
  105. {
  106. #endif /* _STLSOFT_NO_NAMESPACE */
  107. /* /////////////////////////////////////////////////////////////////////////
  108. * Classes
  109. */
  110. /** \brief Efficient vector class for use with POD types only
  111. *
  112. * \ingroup group__library__containers
  113. */
  114. template< ss_typename_param_k T
  115. #if defined(STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT) && \
  116. defined(STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_FUNDAMENTAL_ARGUMENT_SUPPORT)
  117. , ss_typename_param_k A = ss_typename_type_def_k allocator_selector<T>::allocator_type
  118. , ss_size_t SPACE = 64
  119. #else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT && STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_FUNDAMENTAL_ARGUMENT_SUPPORT */
  120. , ss_typename_param_k A /* = ss_typename_type_def_k stlsoft_ns_qual(allocator_selector)<T>::allocator_type */
  121. , ss_size_t SPACE /* = 64 */
  122. #endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT && STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_FUNDAMENTAL_ARGUMENT_SUPPORT */
  123. >
  124. class pod_vector
  125. : public stl_collection_tag
  126. {
  127. /// \name Typedefs
  128. /// @{
  129. private:
  130. typedef auto_buffer_old<T, A, SPACE> buffer_type_;
  131. public:
  132. /// The value type
  133. typedef ss_typename_type_k buffer_type_::value_type value_type;
  134. /// The allocator type
  135. typedef ss_typename_type_k buffer_type_::allocator_type allocator_type;
  136. /// The type of the current parameterisation
  137. typedef pod_vector<T, A, SPACE> class_type;
  138. /// The reference type
  139. typedef ss_typename_type_k buffer_type_::reference reference;
  140. /// The non-mutable (const) reference type
  141. typedef ss_typename_type_k buffer_type_::const_reference const_reference;
  142. /// The pointer type
  143. typedef ss_typename_type_k buffer_type_::pointer pointer;
  144. /// The non-mutable (const) pointer type
  145. typedef ss_typename_type_k buffer_type_::const_pointer const_pointer;
  146. /// The iterator type
  147. typedef ss_typename_type_k buffer_type_::iterator iterator;
  148. /// The non-mutable (const) iterator type
  149. typedef ss_typename_type_k buffer_type_::const_iterator const_iterator;
  150. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  151. /// The type of the non-const (mutating) reverse iterator
  152. typedef ss_typename_type_k buffer_type_::reverse_iterator reverse_iterator;
  153. /// The type of the const (non-mutating) reverse iterator
  154. typedef ss_typename_type_k buffer_type_::const_reverse_iterator const_reverse_iterator;
  155. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  156. /// The size type
  157. typedef ss_typename_type_k buffer_type_::size_type size_type;
  158. /// The difference type
  159. typedef ss_typename_type_k buffer_type_::difference_type difference_type;
  160. /// @}
  161. /// \name Construction
  162. /// @{
  163. public:
  164. ss_explicit_k pod_vector(size_type cItems = 0);
  165. pod_vector(size_type cItems, value_type const& value);
  166. pod_vector(class_type const& rhs);
  167. pod_vector(const_iterator first, const_iterator last);
  168. pod_vector& operator =(class_type const& rhs);
  169. /// @}
  170. /// \name Iteration
  171. /// @{
  172. public:
  173. iterator begin();
  174. const_iterator begin() const;
  175. iterator end();
  176. const_iterator end() const;
  177. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  178. reverse_iterator rbegin();
  179. const_reverse_iterator rbegin() const;
  180. reverse_iterator rend();
  181. const_reverse_iterator rend() const;
  182. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  183. /// @}
  184. /// \name Attributes
  185. /// @{
  186. public:
  187. size_type size() const;
  188. size_type capacity() const;
  189. size_type max_size() const;
  190. ss_bool_t empty() const;
  191. allocator_type get_allocator() const;
  192. /// @}
  193. /// \name Accessors
  194. /// @{
  195. public:
  196. reference at(size_type index);
  197. const_reference at(size_type index) const;
  198. reference operator [](size_type index);
  199. const_reference operator [](size_type index) const;
  200. reference front();
  201. const_reference front() const;
  202. reference back();
  203. const_reference back() const;
  204. /// @}
  205. /// \name Operations
  206. /// @{
  207. public:
  208. void clear();
  209. void swap(class_type& rhs);
  210. void reserve(size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */;
  211. // Note: resize() is split into two, so the one-param version can be very quick
  212. void resize(size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */;
  213. void resize(size_type cItems, value_type const& value) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */;
  214. void push_back(value_type const& value);
  215. void pop_back();
  216. void assign(const_iterator first, const_iterator last);
  217. void assign(size_type cItems, value_type const& value = value_type());
  218. iterator insert(iterator it, value_type const& value = value_type());
  219. void insert(iterator it, size_type cItems, value_type const& value);
  220. void insert(iterator it, const_iterator first, const_iterator last);
  221. iterator erase(iterator it);
  222. iterator erase(iterator first, iterator last);
  223. /// @}
  224. /// \name Implementation
  225. /// @{
  226. private:
  227. pointer begin_();
  228. const_pointer begin_() const;
  229. void range_check_(size_type index) const /* stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) ) */;
  230. ss_bool_t resize_(size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */;
  231. ss_bool_t is_valid_() const;
  232. /// @}
  233. /// \name Members
  234. /// @{
  235. private:
  236. size_type m_cItems; // A size member is used, rather than m_end (iterator), because some of the state
  237. // is maintained in the parent class. Doing it this way makes swap() and other methods
  238. // very simple.
  239. buffer_type_ m_buffer; // The auto_buffer
  240. /// @}
  241. };
  242. /* /////////////////////////////////////////////////////////////////////////
  243. * Operators
  244. */
  245. template< ss_typename_param_k T
  246. , ss_typename_param_k A
  247. , ss_size_t SPACE
  248. >
  249. inline ss_bool_t operator ==(pod_vector<T, A, SPACE> const& lhs, pod_vector<T, A, SPACE> const& rhs)
  250. {
  251. if(lhs.size() != rhs.size())
  252. {
  253. return false;
  254. }
  255. else
  256. {
  257. #if 0
  258. for(ss_typename_type_k pod_vector<T, A, SPACE>::size_type i = 0, size = lhs.size(); i < size; ++i)
  259. {
  260. if(lhs[i] != rhs[i])
  261. {
  262. return false;
  263. }
  264. }
  265. return true;
  266. #else /* ? 0 */
  267. return 0 == memcmp(&lhs[0], &rhs[0], sizeof(ss_typename_type_k pod_vector<T, A, SPACE>::size_type) * lhs.size());
  268. #endif /* 0 */
  269. }
  270. }
  271. template< ss_typename_param_k T
  272. , ss_typename_param_k A
  273. , ss_size_t SPACE
  274. >
  275. inline ss_bool_t operator !=(pod_vector<T, A, SPACE> const& lhs, pod_vector<T, A, SPACE> const& rhs)
  276. {
  277. return !operator ==(lhs, rhs);
  278. }
  279. /* /////////////////////////////////////////////////////////////////////////
  280. * swapping
  281. */
  282. template< ss_typename_param_k T
  283. , ss_typename_param_k A
  284. , ss_size_t SPACE
  285. >
  286. inline void swap(pod_vector<T, A, SPACE>& lhs, pod_vector<T, A, SPACE>& rhs)
  287. {
  288. lhs.swap(rhs);
  289. }
  290. /* /////////////////////////////////////////////////////////////////////////
  291. * Unit-testing
  292. */
  293. #ifdef STLSOFT_UNITTEST
  294. # include "./unittest/pod_vector_unittest_.h"
  295. #endif /* STLSOFT_UNITTEST */
  296. /* /////////////////////////////////////////////////////////////////////////
  297. * Implementation
  298. */
  299. #if defined(STLSOFT_COMPILER_IS_MSVC) && \
  300. _MSC_VER >= 1310
  301. # define STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS
  302. #endif /* compiler */
  303. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  304. template< ss_typename_param_k T
  305. , ss_typename_param_k A
  306. , ss_size_t SPACE
  307. >
  308. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::pointer pod_vector<T, A, SPACE>::begin_()
  309. {
  310. return m_buffer.data();
  311. }
  312. template< ss_typename_param_k T
  313. , ss_typename_param_k A
  314. , ss_size_t SPACE
  315. >
  316. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_pointer pod_vector<T, A, SPACE>::begin_() const
  317. {
  318. return m_buffer.data();
  319. }
  320. template< ss_typename_param_k T
  321. , ss_typename_param_k A
  322. , ss_size_t SPACE
  323. >
  324. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
  325. inline void pod_vector<T, A, SPACE>::range_check_(size_type index) const /* stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) ) */
  326. #elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  327. inline void pod_vector<T, A, SPACE>::range_check_(ss_typename_type_k pod_vector<T, A, SPACE>::size_type index) const /* stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) ) */
  328. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  329. inline void pod_vector<T, A, SPACE>::range_check_(size_type index) const /* stlsoft_throw_1(stlsoft_ns_qual_std(out_of_range) ) */
  330. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  331. {
  332. # ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  333. if(!(index < size()))
  334. {
  335. STLSOFT_THROW_X(stlsoft_ns_qual_std(out_of_range)("pod vector index out of range"));
  336. }
  337. #else /* ? STLSOFT_CF_EXCEPTION_SUPPORT */
  338. STLSOFT_MESSAGE_ASSERT("w index out of range", index < size());
  339. #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */
  340. }
  341. template< ss_typename_param_k T
  342. , ss_typename_param_k A
  343. , ss_size_t SPACE
  344. >
  345. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
  346. inline ss_bool_t pod_vector<T, A, SPACE>::resize_(size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */
  347. #elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  348. inline ss_bool_t pod_vector<T, A, SPACE>::resize_(ss_typename_type_k pod_vector<T, A, SPACE>::size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */
  349. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  350. inline ss_bool_t pod_vector<T, A, SPACE>::resize_(size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */
  351. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  352. {
  353. // This method is only called for insertions, so we can make some assumptions.
  354. size_type curr_capacity = capacity();
  355. // We only resize the internal buffer if it is not large enough
  356. if(cItems > curr_capacity)
  357. {
  358. size_type capacity = m_buffer.internal_size() + cItems;
  359. capacity -= capacity % m_buffer.internal_size();
  360. if(!m_buffer.resize(capacity))
  361. {
  362. return false;
  363. }
  364. }
  365. m_cItems = cItems;
  366. return true;
  367. }
  368. template< ss_typename_param_k T
  369. , ss_typename_param_k A
  370. , ss_size_t SPACE
  371. >
  372. inline ss_bool_t pod_vector<T, A, SPACE>::is_valid_() const
  373. {
  374. if(m_buffer.size() < m_cItems)
  375. {
  376. return false;
  377. }
  378. return true;
  379. }
  380. // Construction
  381. template< ss_typename_param_k T
  382. , ss_typename_param_k A
  383. , ss_size_t SPACE
  384. >
  385. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
  386. inline /* ss_explicit_k */ pod_vector<T, A, SPACE>::pod_vector(size_type cItems /* = 0 */)
  387. #elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  388. inline /* ss_explicit_k */ pod_vector<T, A, SPACE>::pod_vector(ss_typename_type_k pod_vector<T, A, SPACE>::size_type cItems /* = 0 */)
  389. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  390. inline /* ss_explicit_k */ pod_vector<T, A, SPACE>::pod_vector(size_type cItems /* = 0 */)
  391. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  392. : m_buffer(cItems)
  393. {
  394. m_cItems = m_buffer.size(); // This is done here, since it comes before m_buffer in
  395. // the object layout for efficiency (caching) reasons
  396. STLSOFT_ASSERT(is_valid_());
  397. }
  398. template< ss_typename_param_k T
  399. , ss_typename_param_k A
  400. , ss_size_t SPACE
  401. >
  402. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
  403. inline pod_vector<T, A, SPACE>::pod_vector(size_type cItems, value_type const& value)
  404. #elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  405. inline pod_vector<T, A, SPACE>::pod_vector(ss_typename_type_k pod_vector<T, A, SPACE>::size_type cItems, ss_typename_type_k pod_vector<T, A, SPACE>::value_type const& value)
  406. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  407. inline pod_vector<T, A, SPACE>::pod_vector(size_type cItems, value_type const& value)
  408. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  409. : m_buffer(cItems)
  410. {
  411. m_cItems = m_buffer.size(); // This is done here, since it comes before m_buffer in
  412. // the object layout for efficiency (caching) reasons
  413. pod_fill_n(begin_(), size(), value);
  414. STLSOFT_ASSERT(is_valid_());
  415. }
  416. template< ss_typename_param_k T
  417. , ss_typename_param_k A
  418. , ss_size_t SPACE
  419. >
  420. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
  421. inline pod_vector<T, A, SPACE>::pod_vector(class_type const& rhs)
  422. #elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  423. inline pod_vector<T, A, SPACE>::pod_vector(ss_typename_type_k pod_vector<T, A, SPACE>::class_type const& rhs)
  424. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  425. inline pod_vector<T, A, SPACE>::pod_vector(class_type const& rhs)
  426. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  427. : m_buffer(rhs.size())
  428. {
  429. m_cItems = m_buffer.size(); // This is done here, since it comes before m_buffer in
  430. // the object layout for efficiency (caching) reasons
  431. pod_copy_n(begin_(), rhs.begin_(), size());
  432. STLSOFT_ASSERT(is_valid_());
  433. }
  434. template< ss_typename_param_k T
  435. , ss_typename_param_k A
  436. , ss_size_t SPACE
  437. >
  438. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
  439. inline pod_vector<T, A, SPACE>::pod_vector(const_iterator first, const_iterator last)
  440. #elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  441. inline pod_vector<T, A, SPACE>::pod_vector(ss_typename_type_k pod_vector<T, A, SPACE>::const_iterator first, ss_typename_type_k pod_vector<T, A, SPACE>::const_iterator last)
  442. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  443. inline pod_vector<T, A, SPACE>::pod_vector(const_iterator first, const_iterator last)
  444. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  445. : m_buffer(static_cast<ss_size_t>(last - first))
  446. {
  447. m_cItems = m_buffer.size(); // This is done here, since it comes before m_buffer in
  448. // the object layout for efficiency (caching) reasons
  449. if(0 != size()) // It will either be the full size requested, or 0
  450. {
  451. pod_copy(&*first, &*last, begin_());
  452. }
  453. STLSOFT_ASSERT(is_valid_());
  454. }
  455. template< ss_typename_param_k T
  456. , ss_typename_param_k A
  457. , ss_size_t SPACE
  458. >
  459. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
  460. inline pod_vector<T, A, SPACE> &pod_vector<T, A, SPACE>::operator =(class_type const& rhs)
  461. #elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  462. inline pod_vector<T, A, SPACE> &pod_vector<T, A, SPACE>::operator =(ss_typename_type_k pod_vector<T, A, SPACE>::class_type const& rhs)
  463. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  464. inline pod_vector<T, A, SPACE> &pod_vector<T, A, SPACE>::operator =(class_type const& rhs)
  465. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  466. {
  467. // NOTE: This will be optimised by testing the contents of this and the rhs
  468. STLSOFT_ASSERT(is_valid_());
  469. class_type temp(rhs);
  470. temp.swap(*this);
  471. STLSOFT_ASSERT(is_valid_());
  472. return *this;
  473. }
  474. // Iteration
  475. template< ss_typename_param_k T
  476. , ss_typename_param_k A
  477. , ss_size_t SPACE
  478. >
  479. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  480. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::iterator pod_vector<T, A, SPACE>::begin()
  481. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  482. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::iterator pod_vector<T, A, SPACE>::begin()
  483. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  484. {
  485. STLSOFT_ASSERT(is_valid_());
  486. return m_buffer.begin();
  487. }
  488. template< ss_typename_param_k T
  489. , ss_typename_param_k A
  490. , ss_size_t SPACE
  491. >
  492. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  493. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_iterator pod_vector<T, A, SPACE>::begin() const
  494. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  495. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_iterator pod_vector<T, A, SPACE>::begin() const
  496. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  497. {
  498. STLSOFT_ASSERT(is_valid_());
  499. return m_buffer.begin();
  500. }
  501. template< ss_typename_param_k T
  502. , ss_typename_param_k A
  503. , ss_size_t SPACE
  504. >
  505. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  506. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::iterator pod_vector<T, A, SPACE>::end()
  507. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  508. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::iterator pod_vector<T, A, SPACE>::end()
  509. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  510. {
  511. STLSOFT_ASSERT(is_valid_());
  512. return &begin_()[size()];
  513. }
  514. template< ss_typename_param_k T
  515. , ss_typename_param_k A
  516. , ss_size_t SPACE
  517. >
  518. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  519. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_iterator pod_vector<T, A, SPACE>::end() const
  520. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  521. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_iterator pod_vector<T, A, SPACE>::end() const
  522. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  523. {
  524. STLSOFT_ASSERT(is_valid_());
  525. return &begin_()[size()];
  526. }
  527. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  528. template< ss_typename_param_k T
  529. , ss_typename_param_k A
  530. , ss_size_t SPACE
  531. >
  532. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  533. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reverse_iterator pod_vector<T, A, SPACE>::rbegin()
  534. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  535. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reverse_iterator pod_vector<T, A, SPACE>::rbegin()
  536. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  537. {
  538. STLSOFT_ASSERT(is_valid_());
  539. return reverse_iterator(end());
  540. }
  541. template< ss_typename_param_k T
  542. , ss_typename_param_k A
  543. , ss_size_t SPACE
  544. >
  545. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  546. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reverse_iterator pod_vector<T, A, SPACE>::rbegin() const
  547. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  548. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reverse_iterator pod_vector<T, A, SPACE>::rbegin() const
  549. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  550. {
  551. STLSOFT_ASSERT(is_valid_());
  552. return const_reverse_iterator(end());
  553. }
  554. template< ss_typename_param_k T
  555. , ss_typename_param_k A
  556. , ss_size_t SPACE
  557. >
  558. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  559. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reverse_iterator pod_vector<T, A, SPACE>::rend()
  560. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  561. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reverse_iterator pod_vector<T, A, SPACE>::rend()
  562. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  563. {
  564. STLSOFT_ASSERT(is_valid_());
  565. return reverse_iterator(begin());
  566. }
  567. template< ss_typename_param_k T
  568. , ss_typename_param_k A
  569. , ss_size_t SPACE
  570. >
  571. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  572. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reverse_iterator pod_vector<T, A, SPACE>::rend() const
  573. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  574. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reverse_iterator pod_vector<T, A, SPACE>::rend() const
  575. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  576. {
  577. STLSOFT_ASSERT(is_valid_());
  578. return const_reverse_iterator(begin());
  579. }
  580. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  581. // Attributes
  582. template< ss_typename_param_k T
  583. , ss_typename_param_k A
  584. , ss_size_t SPACE
  585. >
  586. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  587. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::size_type pod_vector<T, A, SPACE>::size() const
  588. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  589. inline ss_size_t pod_vector<T, A, SPACE>::size() const
  590. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  591. {
  592. STLSOFT_ASSERT(is_valid_());
  593. return m_cItems;
  594. }
  595. template< ss_typename_param_k T
  596. , ss_typename_param_k A
  597. , ss_size_t SPACE
  598. >
  599. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  600. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::size_type pod_vector<T, A, SPACE>::capacity() const
  601. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  602. inline ss_size_t pod_vector<T, A, SPACE>::capacity() const
  603. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  604. {
  605. STLSOFT_ASSERT(is_valid_());
  606. return m_buffer.size();
  607. }
  608. template< ss_typename_param_k T
  609. , ss_typename_param_k A
  610. , ss_size_t SPACE
  611. >
  612. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  613. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::size_type pod_vector<T, A, SPACE>::max_size() const
  614. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  615. inline ss_size_t pod_vector<T, A, SPACE>::max_size() const
  616. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  617. {
  618. STLSOFT_ASSERT(is_valid_());
  619. return static_cast<size_type>(-1) / sizeof(value_type);
  620. }
  621. template< ss_typename_param_k T
  622. , ss_typename_param_k A
  623. , ss_size_t SPACE
  624. >
  625. inline ss_bool_t pod_vector<T, A, SPACE>::empty() const
  626. {
  627. STLSOFT_ASSERT(is_valid_());
  628. return 0 == size();
  629. }
  630. template< ss_typename_param_k T
  631. , ss_typename_param_k A
  632. , ss_size_t SPACE
  633. >
  634. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  635. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::allocator_type pod_vector<T, A, SPACE>::get_allocator() const
  636. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  637. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::allocator_type pod_vector<T, A, SPACE>::get_allocator() const
  638. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  639. {
  640. STLSOFT_ASSERT(is_valid_());
  641. return m_buffer.get_allocator();
  642. }
  643. // Accessors
  644. template< ss_typename_param_k T
  645. , ss_typename_param_k A
  646. , ss_size_t SPACE
  647. >
  648. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
  649. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reference pod_vector<T, A, SPACE>::at(size_type index)
  650. #elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  651. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reference pod_vector<T, A, SPACE>::at(ss_typename_type_k pod_vector<T, A, SPACE>::size_type index)
  652. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  653. inline T &pod_vector<T, A, SPACE>::at(size_type index)
  654. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  655. {
  656. STLSOFT_ASSERT(is_valid_());
  657. range_check_(index);
  658. STLSOFT_ASSERT(is_valid_());
  659. return begin_()[index];
  660. }
  661. template< ss_typename_param_k T
  662. , ss_typename_param_k A
  663. , ss_size_t SPACE
  664. >
  665. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
  666. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reference pod_vector<T, A, SPACE>::at(size_type index) const
  667. #elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  668. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reference pod_vector<T, A, SPACE>::at(ss_typename_type_k pod_vector<T, A, SPACE>::size_type index) const
  669. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  670. inline T const& pod_vector<T, A, SPACE>::at(size_type index) const
  671. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  672. {
  673. STLSOFT_ASSERT(is_valid_());
  674. range_check_(index);
  675. STLSOFT_ASSERT(is_valid_());
  676. return begin_()[index];
  677. }
  678. template< ss_typename_param_k T
  679. , ss_typename_param_k A
  680. , ss_size_t SPACE
  681. >
  682. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
  683. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reference pod_vector<T, A, SPACE>::operator [](size_type index)
  684. #elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  685. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reference pod_vector<T, A, SPACE>::operator [](ss_typename_type_k pod_vector<T, A, SPACE>::size_type index)
  686. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  687. inline T &pod_vector<T, A, SPACE>::operator [](size_type index)
  688. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  689. {
  690. STLSOFT_ASSERT(is_valid_());
  691. // The index must be <= the size(). It is allowed to be equal to the size because
  692. // we must facilitate the taking of the end() element in order to specify ranges.
  693. STLSOFT_MESSAGE_ASSERT("Requested index is out of range", !(size() < index));
  694. return begin_()[index];
  695. }
  696. template< ss_typename_param_k T
  697. , ss_typename_param_k A
  698. , ss_size_t SPACE
  699. >
  700. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
  701. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reference pod_vector<T, A, SPACE>::operator [](size_type index) const
  702. #elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  703. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reference pod_vector<T, A, SPACE>::operator [](ss_typename_type_k pod_vector<T, A, SPACE>::size_type index) const
  704. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  705. inline T const& pod_vector<T, A, SPACE>::operator [](size_type index) const
  706. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  707. {
  708. STLSOFT_ASSERT(is_valid_());
  709. STLSOFT_MESSAGE_ASSERT("Requested index is out of range", index < size());
  710. return begin_()[index];
  711. }
  712. template< ss_typename_param_k T
  713. , ss_typename_param_k A
  714. , ss_size_t SPACE
  715. >
  716. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
  717. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reference pod_vector<T, A, SPACE>::front()
  718. #elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  719. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reference pod_vector<T, A, SPACE>::front()
  720. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  721. inline T &pod_vector<T, A, SPACE>::front()
  722. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  723. {
  724. STLSOFT_ASSERT(is_valid_());
  725. STLSOFT_MESSAGE_ASSERT("Range is empty!", 0 != size());
  726. return begin_()[0];
  727. }
  728. template< ss_typename_param_k T
  729. , ss_typename_param_k A
  730. , ss_size_t SPACE
  731. >
  732. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
  733. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reference pod_vector<T, A, SPACE>::front() const
  734. #elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  735. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reference pod_vector<T, A, SPACE>::front() const
  736. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  737. inline T const& pod_vector<T, A, SPACE>::front() const
  738. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  739. {
  740. STLSOFT_ASSERT(is_valid_());
  741. STLSOFT_MESSAGE_ASSERT("Range is empty!", 0 != size());
  742. return begin_()[0];
  743. }
  744. template< ss_typename_param_k T
  745. , ss_typename_param_k A
  746. , ss_size_t SPACE
  747. >
  748. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
  749. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reference pod_vector<T, A, SPACE>::back()
  750. #elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  751. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::reference pod_vector<T, A, SPACE>::back()
  752. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  753. inline T &pod_vector<T, A, SPACE>::back()
  754. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  755. {
  756. STLSOFT_ASSERT(is_valid_());
  757. STLSOFT_MESSAGE_ASSERT("Range is empty!", 0 != size());
  758. return begin_()[size() - 1];
  759. }
  760. template< ss_typename_param_k T
  761. , ss_typename_param_k A
  762. , ss_size_t SPACE
  763. >
  764. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED_EXCEPT_ARGS)
  765. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reference pod_vector<T, A, SPACE>::back() const
  766. #elif defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  767. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::const_reference pod_vector<T, A, SPACE>::back() const
  768. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  769. inline T const& pod_vector<T, A, SPACE>::back() const
  770. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  771. {
  772. STLSOFT_ASSERT(is_valid_());
  773. STLSOFT_MESSAGE_ASSERT("Range is empty!", 0 != size());
  774. return begin_()[size() - 1];
  775. }
  776. // Operations
  777. template< ss_typename_param_k T
  778. , ss_typename_param_k A
  779. , ss_size_t SPACE
  780. >
  781. inline void pod_vector<T, A, SPACE>::clear()
  782. {
  783. STLSOFT_ASSERT(is_valid_());
  784. if(m_buffer.resize(0))
  785. {
  786. m_cItems = 0;
  787. }
  788. STLSOFT_ASSERT(is_valid_());
  789. }
  790. template< ss_typename_param_k T
  791. , ss_typename_param_k A
  792. , ss_size_t SPACE
  793. >
  794. inline void pod_vector<T, A, SPACE>::swap(pod_vector<T, A, SPACE>& rhs)
  795. {
  796. STLSOFT_ASSERT(is_valid_());
  797. m_buffer.swap(rhs.m_buffer);
  798. std_swap(m_cItems, rhs.m_cItems);
  799. STLSOFT_ASSERT(is_valid_());
  800. }
  801. template< ss_typename_param_k T
  802. , ss_typename_param_k A
  803. , ss_size_t SPACE
  804. >
  805. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  806. inline void pod_vector<T, A, SPACE>::reserve(ss_typename_type_k pod_vector<T, A, SPACE>::size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */
  807. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  808. inline void pod_vector<T, A, SPACE>::reserve(size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */
  809. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  810. {
  811. STLSOFT_ASSERT(is_valid_());
  812. // We do not follow vector's much maligned example and refuse to truncate, although
  813. // we only do so if the requested size is 0.
  814. if( 0 == cItems ||
  815. cItems > size())
  816. {
  817. m_buffer.resize(cItems);
  818. }
  819. STLSOFT_ASSERT(is_valid_());
  820. }
  821. template< ss_typename_param_k T
  822. , ss_typename_param_k A
  823. , ss_size_t SPACE
  824. >
  825. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  826. inline void pod_vector<T, A, SPACE>::resize(ss_typename_type_k pod_vector<T, A, SPACE>::size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */
  827. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  828. inline void pod_vector<T, A, SPACE>::resize(size_type cItems) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */
  829. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  830. {
  831. STLSOFT_ASSERT(is_valid_());
  832. resize(cItems, value_type());
  833. STLSOFT_ASSERT(is_valid_());
  834. }
  835. template< ss_typename_param_k T
  836. , ss_typename_param_k A
  837. , ss_size_t SPACE
  838. >
  839. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  840. inline void pod_vector<T, A, SPACE>::resize(ss_typename_type_k pod_vector<T, A, SPACE>::size_type cItems, ss_typename_type_k pod_vector<T, A, SPACE>::value_type const& value) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */
  841. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  842. inline void pod_vector<T, A, SPACE>::resize(size_type cItems, ss_typename_type_k pod_vector<T, A, SPACE>::value_type const& value) /* stlsoft_throw_1(stlsoft_ns_qual_std(bad_alloc) ) */
  843. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  844. {
  845. STLSOFT_ASSERT(is_valid_());
  846. if(m_buffer.resize(cItems))
  847. {
  848. if(m_cItems < cItems)
  849. {
  850. pod_fill_n(begin_() + m_cItems, cItems - m_cItems, value);
  851. }
  852. m_cItems = cItems;
  853. }
  854. STLSOFT_ASSERT(is_valid_());
  855. }
  856. template< ss_typename_param_k T
  857. , ss_typename_param_k A
  858. , ss_size_t SPACE
  859. >
  860. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  861. inline void pod_vector<T, A, SPACE>::push_back(ss_typename_type_k pod_vector<T, A, SPACE>::value_type const& value)
  862. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  863. inline void pod_vector<T, A, SPACE>::push_back(ss_typename_type_k pod_vector<T, A, SPACE>::value_type const& value)
  864. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  865. {
  866. STLSOFT_ASSERT(is_valid_());
  867. insert(end(), value);
  868. STLSOFT_ASSERT(is_valid_());
  869. }
  870. template< ss_typename_param_k T
  871. , ss_typename_param_k A
  872. , ss_size_t SPACE
  873. >
  874. inline void pod_vector<T, A, SPACE>::pop_back()
  875. {
  876. STLSOFT_ASSERT(is_valid_());
  877. STLSOFT_MESSAGE_ASSERT("No elements to pop", size() > 0);
  878. if(0 == --m_cItems)
  879. {
  880. m_buffer.resize(0);
  881. }
  882. STLSOFT_ASSERT(is_valid_());
  883. }
  884. template< ss_typename_param_k T
  885. , ss_typename_param_k A
  886. , ss_size_t SPACE
  887. >
  888. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  889. inline void pod_vector<T, A, SPACE>::assign(ss_typename_type_k pod_vector<T, A, SPACE>::const_iterator first, ss_typename_type_k pod_vector<T, A, SPACE>::const_iterator last)
  890. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  891. inline void pod_vector<T, A, SPACE>::assign(const_iterator first, const_iterator last)
  892. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  893. {
  894. STLSOFT_ASSERT(is_valid_());
  895. // NOTE: This will be optimised by testing the contents of this and the rhs
  896. class_type temp(first, last);
  897. temp.swap(*this);
  898. STLSOFT_ASSERT(is_valid_());
  899. }
  900. template< ss_typename_param_k T
  901. , ss_typename_param_k A
  902. , ss_size_t SPACE
  903. >
  904. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  905. inline void pod_vector<T, A, SPACE>::assign(ss_typename_type_k pod_vector<T, A, SPACE>::size_type cItems, ss_typename_type_k pod_vector<T, A, SPACE>::value_type const& value /* = value_type() */)
  906. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  907. inline void pod_vector<T, A, SPACE>::assign(size_type cItems, value_type const& value /* = value_type() */)
  908. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  909. {
  910. STLSOFT_ASSERT(is_valid_());
  911. // NOTE: This will be optimised by testing the contents of this and the rhs
  912. class_type temp(cItems, value);
  913. temp.swap(*this);
  914. STLSOFT_ASSERT(is_valid_());
  915. }
  916. template< ss_typename_param_k T
  917. , ss_typename_param_k A
  918. , ss_size_t SPACE
  919. >
  920. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  921. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::iterator pod_vector<T, A, SPACE>::insert(ss_typename_type_k pod_vector<T, A, SPACE>::iterator it, ss_typename_type_k pod_vector<T, A, SPACE>::value_type const& value /* = value_type() */)
  922. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  923. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::iterator pod_vector<T, A, SPACE>::insert(iterator it, value_type const& value /* = value_type() */)
  924. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  925. {
  926. STLSOFT_ASSERT(is_valid_());
  927. STLSOFT_ASSERT(!(end() < it));
  928. STLSOFT_ASSERT(!(it < begin()));
  929. size_type index = static_cast<size_type>(it - begin());
  930. insert(it, 1, value);
  931. STLSOFT_ASSERT(is_valid_());
  932. return begin() + index;
  933. }
  934. template< ss_typename_param_k T
  935. , ss_typename_param_k A
  936. , ss_size_t SPACE
  937. >
  938. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  939. inline void pod_vector<T, A, SPACE>::insert(ss_typename_type_k pod_vector<T, A, SPACE>::iterator it, ss_typename_type_k pod_vector<T, A, SPACE>::size_type cItems, ss_typename_type_k pod_vector<T, A, SPACE>::value_type const& value)
  940. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  941. inline void pod_vector<T, A, SPACE>::insert(iterator it, size_type cItems, value_type const& value)
  942. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  943. {
  944. STLSOFT_ASSERT(is_valid_());
  945. STLSOFT_ASSERT(!(end() < it));
  946. STLSOFT_ASSERT(!(it < begin()));
  947. size_type curr_size = size();
  948. size_type index = static_cast<size_type>(it - begin());
  949. if(resize_(size() + cItems))
  950. {
  951. size_type cMove = curr_size - index;
  952. // The resize_ may have invalidated the iterator(s)!!
  953. it = begin() + index;
  954. // Move the existing ones up out of the way
  955. pod_move_n(&it[cItems], &it[0], cMove);
  956. // And insert the new ones
  957. pod_fill_n(begin_() + index, cItems, value);
  958. }
  959. STLSOFT_ASSERT(is_valid_());
  960. }
  961. template< ss_typename_param_k T
  962. , ss_typename_param_k A
  963. , ss_size_t SPACE
  964. >
  965. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  966. inline void pod_vector<T, A, SPACE>::insert(ss_typename_type_k pod_vector<T, A, SPACE>::iterator it, ss_typename_type_k pod_vector<T, A, SPACE>::const_iterator first, ss_typename_type_k pod_vector<T, A, SPACE>::const_iterator last)
  967. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  968. inline void pod_vector<T, A, SPACE>::insert(iterator it, const_iterator first, const_iterator last)
  969. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  970. {
  971. STLSOFT_ASSERT(is_valid_());
  972. STLSOFT_ASSERT(!(end() < it));
  973. STLSOFT_ASSERT(!(it < begin()));
  974. size_type curr_size = size();
  975. size_type index = it - begin();
  976. size_type cItems = last - first;
  977. if(resize_(size() + cItems))
  978. {
  979. size_type cMove = curr_size - index;
  980. // The resize_ may have invalidated the iterator(s)!!
  981. it = begin() + index;
  982. // Move the existing ones up out of the way
  983. pod_move_n(&it[cItems], &it[0], cMove);
  984. // And insert the new ones
  985. pod_copy_n(it, first, cItems);
  986. }
  987. STLSOFT_ASSERT(is_valid_());
  988. }
  989. template< ss_typename_param_k T
  990. , ss_typename_param_k A
  991. , ss_size_t SPACE
  992. >
  993. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  994. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::iterator pod_vector<T, A, SPACE>::erase(ss_typename_type_k pod_vector<T, A, SPACE>::iterator it)
  995. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  996. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::iterator pod_vector<T, A, SPACE>::erase(iterator it)
  997. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  998. {
  999. STLSOFT_ASSERT(is_valid_());
  1000. STLSOFT_ASSERT(it < end());
  1001. STLSOFT_ASSERT(!(it < begin()));
  1002. size_type index = it - begin();
  1003. size_type cMove = size() - (index + 1);
  1004. pod_move_n(&it[0], &it[1], cMove);
  1005. if(0 == --m_cItems)
  1006. {
  1007. m_buffer.resize(0);
  1008. it = begin();
  1009. }
  1010. STLSOFT_ASSERT(is_valid_());
  1011. return it;
  1012. }
  1013. template< ss_typename_param_k T
  1014. , ss_typename_param_k A
  1015. , ss_size_t SPACE
  1016. >
  1017. #if defined(STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED)
  1018. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::iterator pod_vector<T, A, SPACE>::erase(ss_typename_type_k pod_vector<T, A, SPACE>::iterator first, ss_typename_type_k pod_vector<T, A, SPACE>::iterator last)
  1019. #else /* ? STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  1020. inline ss_typename_type_ret_k pod_vector<T, A, SPACE>::iterator pod_vector<T, A, SPACE>::erase(iterator first, iterator last)
  1021. #endif /* STLSOFT_CF_FUNCTION_SIGNATURE_FULL_ARG_QUALIFICATION_REQUIRED */
  1022. {
  1023. STLSOFT_ASSERT(is_valid_());
  1024. STLSOFT_ASSERT(first < end());
  1025. STLSOFT_ASSERT(!(first < begin()));
  1026. STLSOFT_ASSERT(!(end() < last));
  1027. STLSOFT_ASSERT(!(last < begin()));
  1028. size_type curr_size = size();
  1029. size_type index_first = first - begin();
  1030. size_type index_last = last - begin();
  1031. size_type cItems = last - first;
  1032. size_type cMove = curr_size - index_last;
  1033. // Move the remaining ones down
  1034. pod_move_n(&first[0], &last[0], cMove);
  1035. resize(curr_size - cItems);
  1036. STLSOFT_ASSERT(is_valid_());
  1037. return begin() + index_first;
  1038. }
  1039. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  1040. /* ////////////////////////////////////////////////////////////////////// */
  1041. #ifndef _STLSOFT_NO_NAMESPACE
  1042. } // namespace stlsoft
  1043. #endif /* _STLSOFT_NO_NAMESPACE */
  1044. /* In the special case of Intel behaving as VC++ 7.0 or earlier on Win32, we
  1045. * illegally insert into the std namespace.
  1046. */
  1047. #if defined(STLSOFT_CF_std_NAMESPACE)
  1048. # if ( ( defined(STLSOFT_COMPILER_IS_INTEL) && \
  1049. defined(_MSC_VER))) && \
  1050. _MSC_VER < 1310
  1051. namespace std
  1052. {
  1053. template< ss_typename_param_k T
  1054. , ss_typename_param_k A
  1055. , stlsoft_ns_qual(ss_size_t) SPACE
  1056. >
  1057. inline void swap(stlsoft_ns_qual(pod_vector)<T, A, SPACE>& lhs, stlsoft_ns_qual(pod_vector)<T, A, SPACE>& rhs)
  1058. {
  1059. lhs.swap(rhs);
  1060. }
  1061. } // namespace std
  1062. # endif /* INTEL && _MSC_VER < 1310 */
  1063. #endif /* STLSOFT_CF_std_NAMESPACE */
  1064. /* ////////////////////////////////////////////////////////////////////// */
  1065. #endif /* !STLSOFT_INCL_STLSOFT_CONTAINERS_HPP_POD_VECTOR */
  1066. /* ///////////////////////////// end of file //////////////////////////// */