LCOV - code coverage report
Current view: top level - atermpp/include/mcrl2/atermpp/standard_containers - vector.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 34 34 100.0 %
Date: 2024-05-01 03:37:31 Functions: 15 16 93.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Author(s): Jan Friso Groote, Maurice Laveaux
       2             : // Copyright: see the accompanying file COPYING or copy at
       3             : // https://github.com/mCRL2org/mCRL2/blob/master/COPYING
       4             : //
       5             : // Distributed under the Boost Software License, Version 1.0.
       6             : // (See accompanying file LICENSE_1_0.txt or copy at
       7             : // http://www.boost.org/LICENSE_1_0.txt)
       8             : //
       9             : //
      10             : /// \file mcrl2/data/standard_containers/vector.h
      11             : /// \brief This file contains a vector class that behaves 
      12             : ///        exactly as a standard vector. It can only be used
      13             : ///        to store class instances that derive from aterms.
      14             : ///        The stored aterms are protected as a whole, i.e.,
      15             : ///        time and memory is saved as individual protection
      16             : ///        per element is unnecessary. 
      17             : 
      18             : #ifndef MCRL2_ATERMPP_STANDARD_CONTAINER_VECTOR_H
      19             : #define MCRL2_ATERMPP_STANDARD_CONTAINER_VECTOR_H
      20             : 
      21             : #include <vector>
      22             : 
      23             : #include "mcrl2/atermpp/detail/aterm_container.h"
      24             : #include "mcrl2/atermpp/detail/thread_aterm_pool.h"
      25             : #include "mcrl2/utilities/shared_mutex.h"
      26             : 
      27             : /// \brief The main namespace for the aterm++ library.
      28             : namespace atermpp
      29             : {
      30             : 
      31             : /// \brief A vector class in which aterms can be stored. 
      32             : template < class T, class Alloc = std::allocator<detail::reference_aterm<T> >, bool ThreadSafe = false > 
      33             : class vector : public std::vector< detail::reference_aterm<T>, Alloc >
      34             : {
      35             : protected:
      36             :   typedef std::vector< detail::reference_aterm<T>, Alloc > super;
      37             : 
      38             :   detail::generic_aterm_container<std::vector<detail::reference_aterm<T>, Alloc>> container_wrapper;
      39             : 
      40             : public: 
      41             :   /// Standard typedefs.
      42             :   typedef typename super::allocator_type allocator_type;
      43             :   typedef typename super::value_type value_type;
      44             :   typedef typename super::size_type size_type;
      45             :   typedef typename super::reference reference;
      46             :   typedef typename super::iterator iterator;
      47             :   typedef typename super::const_iterator const_iterator;
      48             :   
      49             :   /// \brief Default constructor.
      50       15613 :   vector()
      51             :    : super(),
      52       15613 :      container_wrapper(*this)
      53       15613 :   {}
      54             : 
      55             :   /// \brief Constructor.
      56             :   explicit vector (const allocator_type& alloc)
      57             :    : super::vector(alloc),
      58             :      container_wrapper(*this)     
      59             :   {}
      60             : 
      61             :   /// \brief Constructor.
      62             :   explicit vector (size_type n, const allocator_type& alloc = allocator_type())
      63             :    : super::vector(n, alloc),
      64             :      container_wrapper(*this)     
      65             :   {}
      66             : 
      67             :   vector (size_type n, const value_type& val, const allocator_type& alloc = allocator_type())
      68             :    : super::vector(n, detail::reference_aterm(val), alloc),
      69             :      container_wrapper(*this)
      70             :   {}
      71             : 
      72             :   /// \brief Constructor.
      73             :   template <class InputIterator>
      74             :   vector (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type())
      75             :    : super::vector(first, last, alloc),
      76             :      container_wrapper(*this)     
      77             :   {}
      78             : 
      79             :   /// \brief Constructor.
      80           8 :   vector (const vector& x)
      81             :    : super::vector(x),
      82           8 :      container_wrapper(*this)     
      83           8 :   {}
      84             : 
      85             :   /// \brief Constructor.
      86             :   vector (const vector& x, const allocator_type& alloc)
      87             :    : super::vector(x, alloc),
      88             :      container_wrapper(*this)     
      89             :   {}
      90             :   
      91             :   /// \brief Constructor.
      92           4 :   vector (vector&& x)
      93           4 :    : super::vector(std::move(x)),
      94           4 :      container_wrapper(*this)     
      95           4 :   {}
      96             : 
      97             :   /// \brief Constructor.
      98             :   vector (vector&& x, const allocator_type& alloc)
      99             :    : super::vector(std::move(x), alloc),
     100             :      container_wrapper(*this)
     101             :   {}
     102             : 
     103             :   /// \brief Constructor. To be done later....
     104             :   vector (std::initializer_list<value_type> il, const allocator_type& alloc = allocator_type())
     105             :     : super::vector(il, alloc),
     106             :       container_wrapper(*this)      
     107             :   {}
     108             : 
     109             :   /// \brief Assignment operator.
     110             :   vector& operator=(const vector& x) = default;
     111             :   
     112             :   /// \brief Move assignment operator
     113             :   vector& operator=(vector&& x) = default;
     114             : 
     115             :   /// \brief Standard destructor.
     116       15625 :   ~vector() {}
     117             :   
     118             :   void shrink_to_fit()
     119             :   {
     120             :     if constexpr (ThreadSafe) {
     121             :       mcrl2::utilities::lock_guard guard = detail::g_thread_term_pool().lock();
     122             :       super::shrink_to_fit();
     123             :     } else {
     124             :       mcrl2::utilities::shared_guard guard = detail::g_thread_term_pool().lock_shared();
     125             :       super::shrink_to_fit();
     126             :     }
     127             :   }
     128             : 
     129             :   void clear() noexcept
     130             :   {
     131             :     if constexpr (ThreadSafe) {
     132             :       mcrl2::utilities::lock_guard guard = detail::g_thread_term_pool().lock();
     133             :       super::clear();
     134             :     } else {
     135             :       mcrl2::utilities::shared_guard guard = detail::g_thread_term_pool().lock_shared();
     136             :       super::clear();
     137             :     }
     138             :   }
     139             : 
     140             :   iterator insert( const_iterator pos, const T& value )
     141             :   {
     142             :     if constexpr (ThreadSafe) {
     143             :       mcrl2::utilities::lock_guard guard = detail::g_thread_term_pool().lock();
     144             : 
     145             :       // This is not thread safe otherwise since the length or end iterator is updated during this producedure.
     146             :       return super::insert(pos, value);
     147             :     }
     148             : 
     149             :     mcrl2::utilities::shared_guard guard = detail::g_thread_term_pool().lock_shared();
     150             :     return super::insert(pos, value);
     151             :   }
     152             : 
     153             :   iterator insert( const_iterator pos, T&& value )
     154             :   {
     155             :     if constexpr (ThreadSafe) {
     156             :       mcrl2::utilities::lock_guard guard = detail::g_thread_term_pool().lock();
     157             :       return super::insert(pos, value);
     158             :     }
     159             : 
     160             :     mcrl2::utilities::shared_guard guard = detail::g_thread_term_pool().lock_shared();
     161             :     return super::insert(pos, value);
     162             :   }
     163             :   
     164             :   iterator insert( const_iterator pos, size_type count, const T& value )
     165             :   {
     166             :     if constexpr (ThreadSafe) {
     167             :       mcrl2::utilities::lock_guard guard = detail::g_thread_term_pool().lock();
     168             :       return super::insert(pos, count, value);
     169             :     }
     170             : 
     171             :     mcrl2::utilities::shared_guard guard = detail::g_thread_term_pool().lock_shared();
     172             :     return super::insert(pos, count, value);
     173             :   }
     174             :     
     175             :   template< class InputIt >
     176             :   iterator insert( const_iterator pos,
     177             :                   InputIt first, InputIt last )
     178             :   {
     179             :     if constexpr (ThreadSafe) {
     180             :       mcrl2::utilities::lock_guard guard = detail::g_thread_term_pool().lock();
     181             :       return super::insert(pos, first, last); 
     182             :     }
     183             : 
     184             :     mcrl2::utilities::shared_guard guard = detail::g_thread_term_pool().lock_shared();
     185             :     return super::insert(pos, first, last);  
     186             :   }
     187             :     
     188             :   iterator insert( const_iterator pos, std::initializer_list<T> ilist )
     189             :   {
     190             :     if constexpr (ThreadSafe) {
     191             :       mcrl2::utilities::lock_guard guard = detail::g_thread_term_pool().lock();
     192             :       return super::insert(pos, ilist);
     193             :     }
     194             : 
     195             :     mcrl2::utilities::shared_guard guard = detail::g_thread_term_pool().lock_shared();
     196             :     return super::insert(pos, ilist);
     197             :   }
     198             :   
     199             :   template< class... Args >
     200             :   iterator emplace( const_iterator pos, Args&&... args )
     201             :   {
     202             :     if constexpr (ThreadSafe) {
     203             :       mcrl2::utilities::lock_guard guard = detail::g_thread_term_pool().lock();
     204             :       return super::emplace(pos, args...);   
     205             :     }
     206             : 
     207             :     mcrl2::utilities::shared_guard guard = detail::g_thread_term_pool().lock_shared();
     208             :     return super::emplace(pos, args...);   
     209             :   }
     210             : 
     211             :   iterator erase( const_iterator pos )
     212             :   {
     213             :     if constexpr (ThreadSafe) {
     214             :       mcrl2::utilities::lock_guard guard = detail::g_thread_term_pool().lock();
     215             :       return super::erase(pos);
     216             :     }
     217             : 
     218             :     mcrl2::utilities::shared_guard guard = detail::g_thread_term_pool().lock_shared();
     219             :     return super::erase(pos);
     220             :   }
     221             : 
     222             :   iterator erase( const_iterator first, const_iterator last )
     223             :   {
     224             :     if constexpr (ThreadSafe) {
     225             :       mcrl2::utilities::lock_guard guard = detail::g_thread_term_pool().lock();
     226             :       return super::erase(first, last);
     227             :     }
     228             : 
     229             :     mcrl2::utilities::shared_guard guard = detail::g_thread_term_pool().lock_shared();
     230             :     return super::erase(first, last);
     231             :   }
     232             : 
     233   100003681 :   void push_back( const T& value )
     234             :   {
     235             :     if constexpr (ThreadSafe) {
     236             :       mcrl2::utilities::lock_guard guard = detail::g_thread_term_pool().lock();
     237             :       super::push_back(value);
     238             :     } else {
     239   100003681 :       mcrl2::utilities::shared_guard guard = detail::g_thread_term_pool().lock_shared();
     240   100003681 :       super::push_back(value);
     241   100003681 :     }
     242   100003681 :   }
     243             : 
     244           1 :   void push_back( T&& value )
     245             :   {
     246             :     if constexpr (ThreadSafe) {
     247             :       mcrl2::utilities::lock_guard guard = detail::g_thread_term_pool().lock();
     248             :       super::push_back(value);
     249             :     } else {
     250           1 :       mcrl2::utilities::shared_guard guard = detail::g_thread_term_pool().lock_shared();
     251           1 :       super::push_back(value);
     252           1 :     }
     253           1 :   }
     254             : 
     255             :   template< class... Args >
     256        3892 :   reference emplace_back( Args&&... args )
     257             :   {
     258             :     if constexpr (ThreadSafe) {
     259        3892 :       mcrl2::utilities::lock_guard guard = detail::g_thread_term_pool().lock();
     260        3892 :       return super::emplace_back(args...);  
     261        3892 :     }
     262             : 
     263             :     mcrl2::utilities::shared_guard guard = detail::g_thread_term_pool().lock_shared();
     264             :     return super::emplace_back(args...);  
     265             :   }
     266             : 
     267             :   void pop_back()
     268             :   {
     269             :     if constexpr (ThreadSafe) {
     270             :       mcrl2::utilities::lock_guard guard = detail::g_thread_term_pool().lock();
     271             :       super::pop_back();
     272             :     } else {
     273             :       mcrl2::utilities::shared_guard guard = detail::g_thread_term_pool().lock_shared();
     274             :       super::pop_back();
     275             :     }
     276             :   }
     277             : 
     278        1807 :   void resize( size_type count )
     279             :   {
     280             :     if constexpr (ThreadSafe) {
     281             :       mcrl2::utilities::lock_guard guard = detail::g_thread_term_pool().lock();
     282             :       super::resize(count);
     283             :     } else {
     284        1807 :       mcrl2::utilities::shared_guard guard = detail::g_thread_term_pool().lock_shared();
     285        1807 :       super::resize(count);
     286        1807 :     }
     287        1807 :   }
     288             : 
     289             :   void resize( size_type count, const value_type& value )
     290             :   {
     291             :     if constexpr (ThreadSafe) {
     292             :       mcrl2::utilities::lock_guard guard = detail::g_thread_term_pool().lock();
     293             :       super::resize(count, value);
     294             :     } else {
     295             :       mcrl2::utilities::shared_guard guard = detail::g_thread_term_pool().lock_shared();
     296             :       super::resize(count, value);
     297             :     }
     298             :   }
     299             : 
     300             :   void swap( vector& other ) noexcept
     301             :   {
     302             :     if constexpr (ThreadSafe) {
     303             :       mcrl2::utilities::lock_guard guard = detail::g_thread_term_pool().lock();
     304             :       super::swap(other); // Invalidates end() so must be protected.
     305             :     } else {
     306             :       mcrl2::utilities::shared_guard guard = detail::g_thread_term_pool().lock_shared();
     307             :       super::swap(other); // Invalidates end() so must be protected.
     308             :     }
     309             :   }
     310             : 
     311       12109 :   std::size_t size() const
     312             :   {
     313             :     // Concurrent read/write on the size.
     314       12109 :     mcrl2::utilities::shared_guard guard = detail::g_thread_term_pool().lock_shared();
     315       24218 :     return super::size();
     316       12109 :   }
     317             : };
     318             : 
     319             : } // namespace atermpp
     320             : #endif // MCRL2_ATERMPP_STANDARD_CONTAINER_VECTOR_H

Generated by: LCOV version 1.14