LCOV - code coverage report
Current view: top level - core/core/memory - SPMemVector.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 78 88 88.6 %
Date: 2024-05-12 00:16:13 Functions: 876 1035 84.6 %

          Line data    Source code
       1             : /**
       2             : Copyright (c) 2017-2022 Roman Katuntsev <sbkarr@stappler.org>
       3             : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       4             : 
       5             : Permission is hereby granted, free of charge, to any person obtaining a copy
       6             : of this software and associated documentation files (the "Software"), to deal
       7             : in the Software without restriction, including without limitation the rights
       8             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       9             : copies of the Software, and to permit persons to whom the Software is
      10             : furnished to do so, subject to the following conditions:
      11             : 
      12             : The above copyright notice and this permission notice shall be included in
      13             : all copies or substantial portions of the Software.
      14             : 
      15             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      18             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      20             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      21             : THE SOFTWARE.
      22             : **/
      23             : 
      24             : #ifndef STAPPLER_CORE_MEMORY_SPMEMVECTOR_H_
      25             : #define STAPPLER_CORE_MEMORY_SPMEMVECTOR_H_
      26             : 
      27             : #include "SPMemStorageMem.h"
      28             : 
      29             : namespace STAPPLER_VERSIONIZED stappler::memory {
      30             : 
      31             : template <typename Type>
      32             : class vector : public AllocPool {
      33             : public:
      34             :         using allocator_type = Allocator<Type>;
      35             : 
      36             :         using pointer = Type *;
      37             :         using const_pointer = const Type *;
      38             :         using reference = Type &;
      39             :         using const_reference = const Type &;
      40             : 
      41             :         using size_type = size_t;
      42             :         using value_type = Type;
      43             :         using mem_type = storage_mem<Type, 0>;
      44             :         using self = vector<Type>;
      45             : 
      46             :         using iterator = typename mem_type::iterator;
      47             :         using const_iterator = typename mem_type::const_iterator;
      48             :         using reverse_iterator = typename mem_type::reverse_iterator;
      49             :         using const_reverse_iterator = typename mem_type::const_reverse_iterator;
      50             : 
      51             : public:
      52     2558628 :         vector() noexcept {}
      53      130103 :         explicit vector( const allocator_type& alloc ) noexcept : _mem(alloc) { }
      54             :         explicit vector( size_type count, const Type& value, const allocator_type& alloc = allocator_type()) noexcept : _mem(alloc) {
      55             :                 _mem.fill(count, value);
      56             :         }
      57             :         explicit vector( size_type count, const allocator_type& alloc = allocator_type() ) noexcept : _mem(alloc) {
      58             :                 _mem.fill(count);
      59             :         }
      60             : 
      61             :         template< class InputIt >
      62       10302 :         vector( InputIt first, InputIt last, const allocator_type& alloc = allocator_type() ) : _mem(alloc) {
      63       10302 :                 auto size = std::distance(first, last);
      64       10302 :                 _mem.reserve(size);
      65      193401 :                 for (auto it = first; it != last; it ++) {
      66      183099 :                         _mem.emplace_back_unsafe(*it);
      67             :                 }
      68       10302 :         }
      69             : 
      70      400855 :         vector( const vector& other ) noexcept : _mem(other._mem) { }
      71             :         vector( const vector& other, const allocator_type& alloc ) noexcept : _mem(other._mem, alloc) { }
      72      174563 :         vector( vector&& other ) noexcept : _mem(std::move(other._mem)) { }
      73             :         vector( vector&& other, const allocator_type& alloc ) noexcept : _mem(std::move(other._mem), alloc) { }
      74       25760 :         vector( InitializerList<Type> init, const allocator_type& alloc = allocator_type() ) noexcept : _mem(alloc) {
      75       25760 :                 _mem.reserve(init.size());
      76       54945 :                 for (auto & it : init) {
      77       29185 :                         _mem.emplace_back_unsafe(it);
      78             :                 }
      79       25760 :         }
      80             : 
      81         192 :         vector& operator=( const vector& other ) noexcept {
      82         192 :                 _mem = other._mem;
      83         192 :                 return *this;
      84             :         }
      85       30807 :         vector& operator=( vector&& other ) noexcept {
      86       30807 :                 _mem = std::move(other._mem);
      87       30807 :                 return *this;
      88             :         }
      89           0 :         vector& operator=( InitializerList<Type> init ) noexcept {
      90           0 :                 _mem.clear();
      91           0 :                 _mem.reserve(init.size());
      92           0 :                 for (auto & it : init) {
      93           0 :                         _mem.emplace_back_unsafe(it);
      94             :                 }
      95           0 :                 return *this;
      96             :         }
      97             : 
      98             :         void assign( size_type count, const Type& value ) {
      99             :                 _mem.fill(count, value);
     100             :         }
     101             : 
     102             :         template< class InputIt >
     103        2050 :         void assign( InputIt first, InputIt last ) { // @TODO: self-assign protection and modern assignment
     104        2050 :                 _mem.clear();
     105        2050 :                 auto size = std::distance(first, last);
     106        2050 :                 _mem.reserve(size);
     107   498997200 :                 for (auto it = first; it != last; it ++) {
     108   498995150 :                         _mem.emplace_back_unsafe(*it);
     109             :                 }
     110        2050 :         }
     111             : 
     112             :         void assign( InitializerList<Type> init ) {
     113             :                 _mem.clear();
     114             :                 _mem.reserve(init.size());
     115             :                 for (auto & it : init) {
     116             :                         _mem.emplace_back_unsafe(it);
     117             :                 }
     118             :         }
     119             : 
     120        9150 :         void assign_strong(Type *t, size_type s) {
     121        9150 :                 _mem.assign(t, s);
     122        9150 :         }
     123             : 
     124        4816 :         allocator_type get_allocator() const noexcept { return _mem.get_allocator(); }
     125             : 
     126       33675 :         reference at( size_type pos ) noexcept { return _mem.at(pos); }
     127      154256 :         const_reference at( size_type pos ) const noexcept { return _mem.at(pos); }
     128             : 
     129   221067427 :         reference operator[]( size_type pos ) noexcept { return _mem.at(pos); }
     130      627334 :         const_reference operator[]( size_type pos ) const noexcept { return _mem.at(pos); }
     131             : 
     132       10921 :         reference front() noexcept { return _mem.front(); }
     133      700989 :         const_reference front() const noexcept { return _mem.front(); }
     134             : 
     135     3336705 :         reference back() noexcept { return _mem.back(); }
     136     1061711 :         const_reference back() const noexcept { return _mem.back(); }
     137             : 
     138    11031986 :         pointer data() noexcept { return _mem.data(); }
     139     2394348 :         const_pointer data() const noexcept { return _mem.data(); }
     140             : 
     141    51061092 :         iterator begin() noexcept { return _mem.begin(); }
     142    55358439 :         iterator end() noexcept { return _mem.end(); }
     143             : 
     144     4567371 :         const_iterator begin() const noexcept { return _mem.begin(); }
     145     4838322 :         const_iterator end() const noexcept { return _mem.end(); }
     146             : 
     147             :         const_iterator cbegin() const noexcept { return _mem.cbegin(); }
     148             :         const_iterator cend() const noexcept { return _mem.cend(); }
     149             : 
     150      221862 :     reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
     151      260348 :     reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
     152             : 
     153             :     const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
     154             :     const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
     155             : 
     156             :     const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); }
     157             :     const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); }
     158             : 
     159    54597229 :         size_type size() const noexcept { return _mem.size(); }
     160             :         size_type capacity() const noexcept { return _mem.capacity(); }
     161     7978351 :         bool empty() const noexcept { return _mem.empty(); }
     162         625 :         void reserve_block_optimal() { _mem.reserve_block_optimal(); }
     163     1167684 :         void reserve( size_type new_cap ) { _mem.reserve(new_cap); }
     164      212400 :         void shrink_to_fit() { }
     165             : 
     166      986655 :         void clear() { _mem.clear(); }
     167             : 
     168             :         template< class... Args >
     169      118251 :         iterator emplace( const_iterator pos, Args&&... args ) {
     170      118251 :                 return _mem.emplace(pos, std::forward<Args>(args)...);
     171             :         }
     172             : 
     173             :         iterator insert( const_iterator pos, const Type& value ) {
     174             :                 return emplace(pos, value);
     175             :         }
     176             :         iterator insert( const_iterator pos, Type&& value ) {
     177             :                 return emplace(pos, std::move(value));
     178             :         }
     179             :         iterator insert( const_iterator pos, size_type count, const Type& value ) {
     180             :                 return _mem.insert(pos, count, value);
     181             :         }
     182             : 
     183             :         template< class InputIt >
     184           0 :         iterator insert( const_iterator pos, InputIt first, InputIt last ) {
     185           0 :                 return _mem.insert(pos, first, last);
     186             :         }
     187             : 
     188             :         iterator insert( const_iterator pos, InitializerList<Type> init ) {
     189             :                 return _mem.insert(pos, init.begin(), init.end());
     190             :         }
     191             : 
     192       34071 :         iterator erase( const_iterator pos ) {
     193       34071 :                 return _mem.erase(pos);
     194             :         }
     195             : 
     196             :         iterator erase( const_iterator first, const_iterator last ) {
     197             :                 return _mem.erase(first, last);
     198             :         }
     199             : 
     200             :         template< class... Args >
     201    44585270 :         reference emplace_back( Args&&... args ) {
     202    44585270 :                 return _mem.emplace_back(std::forward<Args>(args)...);
     203             :         }
     204             : 
     205     2450424 :         void push_back( const Type& value ) {
     206     2450424 :                 emplace_back(value);
     207     2450425 :         }
     208       74513 :         void push_back( Type&& value ) {
     209       74513 :                 emplace_back(std::move(value));
     210       74513 :         }
     211             : 
     212     3717210 :         void pop_back() {
     213     3717210 :                 _mem.pop_back();
     214     3717209 :         }
     215             : 
     216     7775680 :         void resize( size_type count ) {
     217     7775680 :                 _mem.resize(count);
     218     7775679 :         }
     219        3621 :         void resize( size_type count, const value_type& value ) {
     220        3621 :                 _mem.resize(count, value);
     221        3621 :         }
     222             : 
     223             : public:
     224             :         static const vector make_weak(const Type *str, size_type l, const allocator_type& alloc = allocator_type()) {
     225             :                 vector ret(alloc);
     226             :                 if (str) {
     227             :                         ret.assign_weak(str, l);
     228             :                 }
     229             :                 return ret;
     230             :         }
     231             : 
     232             :         vector& assign_weak(const Type *str, size_type l) {
     233             :                 _mem.assign_weak(str, l);
     234             :                 return *this;
     235             :         }
     236             : 
     237             :         bool is_weak() const noexcept {
     238             :                 return _mem.is_weak();
     239             :         }
     240             : 
     241        1350 :         void force_clear() {
     242        1350 :                 _mem.force_clear();
     243        1350 :         }
     244             : 
     245             : protected:
     246             :         mem_type _mem;
     247             : };
     248             : 
     249             : using bytes = vector<uint8_t>;
     250             : 
     251             : template<typename _Tp> inline bool
     252           0 : operator==(const vector<_Tp>& __x, const vector<_Tp>& __y) {
     253           0 :         return (__x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin()));
     254             : }
     255             : 
     256             : template<typename _Tp> inline bool
     257             : operator<(const vector<_Tp>& __x, const vector<_Tp>& __y) {
     258             :         return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
     259             : }
     260             : 
     261             : template<> inline bool
     262             : operator<(const vector<uint8_t>& x, const vector<uint8_t>& y) {
     263             :         auto len1 = x.size();
     264             :         auto len2 = y.size();
     265             :     int result = memcmp(x.data(), y.data(), min(len1, len2));
     266             :     if (result != 0)
     267             :         return result < 0;
     268             :     if (len1 < len2)
     269             :         return true;
     270             :     if (len1 > len2)
     271             :         return false;
     272             :     return false;
     273             : }
     274             : 
     275             : /// Based on operator==
     276             : template<typename _Tp> inline bool
     277             : operator!=(const vector<_Tp>& __x, const vector<_Tp>& __y) {
     278             :         return !(__x == __y);
     279             : }
     280             : 
     281             : /// Based on operator<
     282             : template<typename _Tp> inline bool
     283             : operator>(const vector<_Tp>& __x, const vector<_Tp>& __y) {
     284             :         return __y < __x;
     285             : }
     286             : 
     287             : /// Based on operator<
     288             : template<typename _Tp> inline bool
     289             : operator<=(const vector<_Tp>& __x, const vector<_Tp>& __y) {
     290             :         return !(__y < __x);
     291             : }
     292             : 
     293             : /// Based on operator<
     294             : template<typename _Tp> inline bool
     295             : operator>=(const vector<_Tp>& __x, const vector<_Tp>& __y) {
     296             :         return !(__x < __y);
     297             : }
     298             : 
     299             : }
     300             : 
     301             : #endif /* STAPPLER_CORE_MEMORY_SPMEMVECTOR_H_ */

Generated by: LCOV version 1.14