LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/context - cdlist.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 52 54 96.3 %
Date: 2024-10-20 11:38:31 Functions: 284 329 86.3 %
Branches: 15 30 50.0 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * Top contributors (to current version):
       3                 :            :  *   Andres Noetzli, Morgan Deters, Tim King
       4                 :            :  *
       5                 :            :  * This file is part of the cvc5 project.
       6                 :            :  *
       7                 :            :  * Copyright (c) 2009-2024 by the authors listed in the file AUTHORS
       8                 :            :  * in the top-level source directory and their institutional affiliations.
       9                 :            :  * All rights reserved.  See the file COPYING in the top-level source
      10                 :            :  * directory for licensing information.
      11                 :            :  * ****************************************************************************
      12                 :            :  * Context-dependent list class (only supports append).
      13                 :            :  *
      14                 :            :  * This list only supports appending to the list; on backtrack, the list is
      15                 :            :  * simply shortened.
      16                 :            :  */
      17                 :            : 
      18                 :            : #include "cvc5parser_public.h"
      19                 :            : 
      20                 :            : #ifndef CVC5__CONTEXT__CDLIST_H
      21                 :            : #define CVC5__CONTEXT__CDLIST_H
      22                 :            : 
      23                 :            : #include <cstring>
      24                 :            : #include <iterator>
      25                 :            : #include <memory>
      26                 :            : #include <string>
      27                 :            : #include <vector>
      28                 :            : 
      29                 :            : #include "base/check.h"
      30                 :            : #include "context/cdlist_forward.h"
      31                 :            : #include "context/context.h"
      32                 :            : #include "context/context_mm.h"
      33                 :            : #include "context/default_clean_up.h"
      34                 :            : 
      35                 :            : namespace cvc5::context {
      36                 :            : 
      37                 :            : /**
      38                 :            :  * Generic context-dependent dynamic array.  Note that for efficiency, this
      39                 :            :  * implementation makes the following assumption: Over time, objects are only
      40                 :            :  * added to the list.  Objects are only removed when a pop restores the list to
      41                 :            :  * a previous state.
      42                 :            :  */
      43                 :            : template <class T, class CleanUpT, class Allocator>
      44                 :            : class CDList : public ContextObj
      45                 :            : {
      46                 :            :  public:
      47                 :            :   /** The value type with which this CDList<> was instantiated. */
      48                 :            :   using value_type = T;
      49                 :            : 
      50                 :            :   /** The cleanup type with which this CDList<> was instantiated. */
      51                 :            :   using CleanUp = CleanUpT;
      52                 :            : 
      53                 :            :   /**
      54                 :            :    * `std::vector<T>::operator[] const` returns an
      55                 :            :    * std::vector<T>::const_reference, which does not necessarily have to be a
      56                 :            :    * `const T&`. Specifically, in the case of `std::vector<bool>`, the type is
      57                 :            :    * specialized to be just a simple `bool`. For our `operator[] const`, we use
      58                 :            :    * the same type.
      59                 :            :    */
      60                 :            :   using ConstReference = typename std::vector<T>::const_reference;
      61                 :            : 
      62                 :            :   /**
      63                 :            :    * Instead of implementing our own iterators, we just use the iterators of
      64                 :            :    * the underlying `std::vector<T>`.
      65                 :            :    */
      66                 :            :   using const_iterator = typename std::vector<T>::const_iterator;
      67                 :            :   using iterator = typename std::vector<T>::const_iterator;
      68                 :            : 
      69                 :            :   /**
      70                 :            :    * Main constructor: d_list starts with size 0
      71                 :            :    *
      72                 :            :    * Optionally, a cleanup callback can be specified, which is called on every
      73                 :            :    * element that gets removed during a pop. The callback is only used when
      74                 :            :    * callCleanup is true. Note: the destructor of the elements in the list is
      75                 :            :    * called regardless of whether callCleanup is true or false.
      76                 :            :    */
      77                 :   15304008 :   CDList(Context* context,
      78                 :            :          bool callCleanup = true,
      79                 :            :          const CleanUp& cleanup = CleanUp())
      80                 :            :       : ContextObj(context),
      81                 :            :         d_list(),
      82                 :            :         d_size(0),
      83                 :            :         d_callCleanup(callCleanup),
      84                 :   15304008 :         d_cleanUp(cleanup)
      85                 :            :   {
      86                 :   15304008 :   }
      87                 :            : 
      88                 :            :   /**
      89                 :            :    * Destructor: delete the list
      90                 :            :    */
      91                 :   15250642 :   ~CDList() {
      92                 :   15250642 :     this->destroy();
      93                 :            : 
      94         [ +  + ]:   15250642 :     if (this->d_callCleanup)
      95                 :            :     {
      96                 :   15152603 :       truncateList(0);
      97                 :            :     }
      98                 :   30501284 :   }
      99                 :            : 
     100                 :            :   /**
     101                 :            :    * Return the current size of (i.e. valid number of objects in) the
     102                 :            :    * list.
     103                 :            :    */
     104                 :  492378868 :   size_t size() const { return d_list.size(); }
     105                 :            : 
     106                 :            :   /**
     107                 :            :    * Return true iff there are no valid objects in the list.
     108                 :            :    */
     109                 :   21499863 :   bool empty() const { return d_list.empty(); }
     110                 :            : 
     111                 :            :   /**
     112                 :            :    * Add an item to the end of the list. This method uses the copy constructor
     113                 :            :    * of T, so the type has to support it. As a result, this method cannot be
     114                 :            :    * used with types that do not have a copy constructor such as
     115                 :            :    * std::unique_ptr. Use CDList::emplace_back() instead of CDList::push_back()
     116                 :            :    * to avoid this issue.
     117                 :            :    */
     118                 :  232896745 :   void push_back(const T& data) {
     119         [ +  - ]:  232896745 :     Trace("cdlist") << "push_back " << this << " " << getContext()->getLevel()
     120                 :          0 :                     << ": make-current" << std::endl;
     121                 :  232896745 :     makeCurrent();
     122                 :  232896745 :     d_list.push_back(data);
     123                 :  232896745 :     ++d_size;
     124                 :  232896745 :   }
     125                 :            : 
     126                 :            :   /**
     127                 :            :    * Construct an item to the end of the list. This method constructs the item
     128                 :            :    * in-place (similar to std::vector::emplace_back()), so it can be used for
     129                 :            :    * types that do not have a copy constructor such as std::unique_ptr.
     130                 :            :    */
     131                 :            :   template <typename... Args>
     132                 :      27254 :   void emplace_back(Args&&... args)
     133                 :            :   {
     134         [ +  - ]:      54508 :     Trace("cdlist") << "emplace_back " << this << " "
     135                 :      27254 :                     << getContext()->getLevel() << ": make-current" << std::endl;
     136                 :      27254 :     makeCurrent();
     137                 :      27254 :     d_list.emplace_back(std::forward<Args>(args)...);
     138                 :      27254 :     ++d_size;
     139                 :      27254 :   }
     140                 :            : 
     141                 :            :   /**
     142                 :            :    * Access to the ith item in the list.
     143                 :            :    */
     144                 :  304124240 :   ConstReference operator[](size_t i) const
     145                 :            :   {
     146 [ -  + ][ -  + ]:  304124240 :     Assert(i < d_size) << "index out of bounds in CDList::operator[]";
                 [ -  - ]
     147                 :  304124240 :     return d_list[i];
     148                 :            :   }
     149                 :            : 
     150                 :            :   /**
     151                 :            :    * Returns the most recent item added to the list.
     152                 :            :    */
     153                 :      20786 :   ConstReference back() const
     154                 :            :   {
     155 [ -  + ][ -  + ]:      20786 :     Assert(d_size > 0) << "CDList::back() called on empty list";
                 [ -  - ]
     156                 :      20786 :     return d_list[d_size - 1];
     157                 :            :   }
     158                 :            : 
     159                 :            :   /**
     160                 :            :    * Returns an iterator pointing to the first item in the list.
     161                 :            :    */
     162                 :   26255338 :   const_iterator begin() const { return d_list.begin(); }
     163                 :            : 
     164                 :            :   /**
     165                 :            :    * Returns an iterator pointing one past the last item in the list.
     166                 :            :    */
     167                 :   30003353 :   const_iterator end() const { return d_list.end(); }
     168                 :            : 
     169                 :            :  protected:
     170                 :            :   /**
     171                 :            :    * Private copy constructor used only by save(). d_list is not copied: only
     172                 :            :    * the base class information and d_size are needed in restore.
     173                 :            :    */
     174                 :   42427445 :   CDList(const CDList& l)
     175                 :            :       : ContextObj(l),
     176                 :   42427445 :         d_size(l.d_size),
     177                 :            :         d_callCleanup(false),
     178                 :   42427445 :         d_cleanUp(l.d_cleanUp)
     179                 :            :   {
     180         [ +  - ]:   42427445 :     Trace("cdlist") << "copy ctor: " << this << " from " << &l << " size "
     181                 :          0 :                     << d_size << std::endl;
     182                 :   42427445 :   }
     183                 :            :   CDList& operator=(const CDList& l) = delete;
     184                 :            :   /**
     185                 :            :    * Implementation of mandatory ContextObj method restore: simply
     186                 :            :    * restores the previous size.  Note that the list pointer and the
     187                 :            :    * allocated size are not changed.
     188                 :            :    */
     189                 :            : 
     190                 :   42425391 :   void restore(ContextObj* data) override
     191                 :            :   {
     192                 :   42425391 :     truncateList(((CDList<T, CleanUp, Allocator>*)data)->d_size);
     193                 :   42425391 :   }
     194                 :            : 
     195                 :            :   /**
     196                 :            :    * Given a size parameter smaller than d_size, truncateList()
     197                 :            :    * removes the elements from the end of the list until d_size equals size.
     198                 :            :    *
     199                 :            :    * WARNING! You should only use this function when you know what you are
     200                 :            :    * doing. This is a primitive operation with strange context dependent
     201                 :            :    * behavior! It is up to the user of the function to ensure that the saved
     202                 :            :    * d_size values at lower context levels are less than or equal to size.
     203                 :            :    */
     204                 :   70778512 :   void truncateList(const size_t size)
     205                 :            :   {
     206 [ -  + ][ -  + ]:   70778512 :     Assert(size <= d_size);
                 [ -  - ]
     207         [ +  + ]:   70778512 :     if (d_callCleanup)
     208                 :            :     {
     209         [ +  + ]:  282196593 :       while (d_size != size)
     210                 :            :       {
     211                 :  213206637 :         --d_size;
     212                 :  213206637 :         typename std::vector<T>::reference elem = d_list[d_size];
     213                 :  213206637 :         d_cleanUp(elem);
     214                 :            :       }
     215                 :            :     }
     216                 :            :     else
     217                 :            :     {
     218                 :    1788633 :       d_size = size;
     219                 :            :     }
     220                 :            :     // Note that std::vector::resize() would require a default constructor for
     221                 :            :     // the elements in std::vector
     222                 :   70778512 :     d_list.erase(d_list.begin() + d_size, d_list.end());
     223                 :   70778512 :   }
     224                 :            : 
     225                 :            :   /**
     226                 :            :    * d_list is a vector of objects of type T.
     227                 :            :    */
     228                 :            :   std::vector<T> d_list;
     229                 :            : 
     230                 :            :   /**
     231                 :            :    * Number of objects in d_list
     232                 :            :    */
     233                 :            :   size_t d_size;
     234                 :            : 
     235                 :            :  private:
     236                 :            :   /**
     237                 :            :    * Whether to call the destructor when items are popped from the
     238                 :            :    * list.  True by default, but can be set to false by setting the
     239                 :            :    * second argument in the constructor to false.
     240                 :            :    */
     241                 :            :   bool d_callCleanup;
     242                 :            : 
     243                 :            :   /**
     244                 :            :    * The CleanUp functor.
     245                 :            :    */
     246                 :            :   CleanUp d_cleanUp;
     247                 :            : 
     248                 :            :   /**
     249                 :            :    * Implementation of mandatory ContextObj method save: simply copies
     250                 :            :    * the current size to a copy using the copy constructor (the
     251                 :            :    * pointer and the allocated size are *not* copied as they are not
     252                 :            :    * restored on a pop).  The saved information is allocated using the
     253                 :            :    * ContextMemoryManager.
     254                 :            :    */
     255                 :   28481525 :   ContextObj* save(ContextMemoryManager* pCMM) override
     256                 :            :   {
     257                 :   28481525 :     ContextObj* data = new(pCMM) CDList<T, CleanUp, Allocator>(*this);
     258                 :   28481525 :     return data;
     259                 :            :   }
     260                 :            : 
     261                 :            : }; /* class CDList<> */
     262                 :            : 
     263                 :            : }  // namespace cvc5::context
     264                 :            : 
     265                 :            : #endif /* CVC5__CONTEXT__CDLIST_H */

Generated by: LCOV version 1.14