LTP GCOV extension - code coverage report
Current view: directory - usr/include/tagcoll-2.0.11/tagcoll/coll - patched.tcc
Test: lcov.info
Date: 2008-08-14 Instrumented lines: 22
Code covered: 59.1 % Executed lines: 13

       1                 : /*
       2                 :  * Wrap a Collection, preserving modifications as patches
       3                 :  *
       4                 :  * Copyright (C) 2005,2006  Enrico Zini <enrico@debian.org>
       5                 :  *
       6                 :  * This program is free software; you can redistribute it and/or modify
       7                 :  * it under the terms of the GNU General Public License as published by
       8                 :  * the Free Software Foundation; either version 2 of the License, or
       9                 :  * (at your option) any later version.
      10                 :  *
      11                 :  * This program is distributed in the hope that it will be useful,
      12                 :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13                 :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14                 :  * GNU General Public License for more details.
      15                 :  *
      16                 :  * You should have received a copy of the GNU General Public License
      17                 :  * along with this program; if not, write to the Free Software
      18                 :  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      19                 :  */
      20                 : 
      21                 : #ifndef TAGCOLL_COLL_PATCHED_TCC
      22                 : #define TAGCOLL_COLL_PATCHED_TCC
      23                 : 
      24                 : #include <tagcoll/coll/patched.h>
      25                 : #include <tagcoll/utils/set.h>
      26                 : 
      27                 : #include <wibble/operators.h>
      28                 : 
      29                 : using namespace std;
      30                 : using namespace wibble::operators;
      31                 : 
      32                 : namespace tagcoll {
      33                 : namespace coll {
      34                 : 
      35                 : template<typename ROCOLL> template<typename ITEMS, typename TAGS>
      36                 : void Patched<ROCOLL>::insert(const ITEMS& items, const TAGS& tags)
      37                 : {
      38                 :         Patches changes;
      39                 :         for (typename ITEMS::const_iterator i = items.begin();
      40                 :                         i != items.end(); ++i)
      41                 :                 changes.addPatch(Patch(*i, tags, TagSet()));
      42                 :         addChanges(changes);
      43                 : }
      44                 : 
      45                 : 
      46                 : template<typename ROCOLL>
      47                 : void Patched<ROCOLL>::clear()
      48                 : {
      49                 :         // Remove all patches
      50                 :         m_changes.clear();
      51                 :         m_rchanges.clear();
      52                 : 
      53                 :         // Add all tagsets of the underlying collection as removed tags in the patch
      54                 :         for (typename ROCOLL::const_iterator i = coll.begin();
      55                 :                         i != coll.end(); ++i)
      56                 :         {
      57                 :                 m_changes.addPatch(Patch(i->first, std::set<Tag>(), i->second));
      58                 : 
      59                 :                 for (typename TagSet::const_iterator j = i->second.begin();
      60                 :                                 j != i->second.end(); ++j)
      61                 :                         m_rchanges.addPatch(Patch(*j, wibble::Empty<Tag>(), wibble::singleton(i->first)));
      62                 :         }
      63                 : }
      64                 : 
      65                 : template<typename ROCOLL>
      66                 : void Patched<ROCOLL>::setChanges(const Patches& changes)
      67                 : {
      68               0 :         this->m_changes.clear();
      69               0 :         this->m_rchanges.clear();
      70                 :         
      71               0 :         addChanges(changes);
      72               0 : }
      73                 : 
      74                 : template<typename ROCOLL>
      75                 : void Patched<ROCOLL>::addChanges(const Patches& changes)
      76                 : {
      77                 :         // Simplify the patch against the contents of `coll' before adding it.
      78               4 :         for (typename Patches::const_iterator i = changes.begin(); i != changes.end(); ++i)
      79                 :                 // Consider only valid items
      80               2 :                 if (i->first != Item())
      81                 :                 {
      82                 :                         // Merge with existing patches
      83               2 :                         this->m_changes.addPatch(i->second);
      84                 :                         // Simplify the result
      85               2 :                         this->m_changes.removeRedundant(i->first, coll.getTagsOfItem(i->first));
      86                 :                 }
      87                 : 
      88               2 :         RPatches rchanges;
      89               2 :         rchanges.addPatchInverted(changes);
      90               4 :         for (typename RPatches::const_iterator i = rchanges.begin(); i != rchanges.end(); ++i)
      91                 :                 // Consider only valid tags
      92               2 :                 if (i->first != Tag())
      93                 :                 {
      94                 :                         // Merge with existing patches
      95               2 :                         this->m_rchanges.addPatch(i->second);
      96                 :                         // Simplify the result
      97               4 :                         this->m_rchanges.removeRedundant(i->first, coll.getItemsHavingTag(i->first));
      98                 :                 }
      99               2 : }
     100                 : 
     101                 : template<typename ROCOLL>
     102                 : bool Patched<ROCOLL>::hasTag(const Tag& tag) const
     103                 : {
     104                 :         typename RPatches::const_iterator i = m_rchanges.find(tag);
     105                 :         if (i == m_rchanges.end())
     106                 :                 return coll.hasTag(tag);
     107                 :         if (! i->second.added.empty())
     108                 :                 return true;
     109                 :         return !this->getItemsHavingTag(tag).empty();
     110                 : }
     111                 : 
     112                 : template<typename ROCOLL>
     113                 : typename coll_traits<ROCOLL>::itemset_type Patched<ROCOLL>::getTaggedItems() const
     114                 : {
     115                 :         ItemSet res(coll.getTaggedItems());
     116                 :         for (typename Patches::const_iterator i = m_changes.begin();
     117                 :                         i != m_changes.end(); ++i)
     118                 :                 if (!i->second.added.empty())
     119                 :                         // Add packages for which tags are added
     120                 :                         res |= i->first;
     121                 :                 else if (getTagsOfItem(i->first).empty())
     122                 :                         // Remove the packages to which the patch removes all tags
     123                 :                         res -= i->first;
     124                 :         return res;
     125                 : }
     126                 : 
     127                 : template<typename ROCOLL>
     128                 : typename coll_traits<ROCOLL>::tagset_type Patched<ROCOLL>::getAllTags() const
     129                 : {
     130               1 :         TagSet res(coll.getAllTags());
     131               1 :         for (typename RPatches::const_iterator i = m_rchanges.begin();
     132                 :                         i != m_rchanges.end(); ++i)
     133               0 :                 if (!i->second.added.empty())
     134                 :                         // Add tags for which packages are added
     135               0 :                         res |= i->first;
     136               0 :                 else if (coll.getCardinality(i->first) - i->second.removed.size() <= 0)
     137                 :                         // Remove the tags to which the patch removes all items
     138               0 :                         res -= i->first;
     139               0 :         return res;
     140                 : }
     141                 : 
     142                 : #if 0
     143                 : template<typename ITEM, typename TAG, typename OUT>
     144                 : class UnpatchedOnly : public wibble::mixin::OutputIterator< UnpatchedOnly<ITEM, TAG, OUT> >
     145                 : {
     146                 : protected:
     147                 :         OUT out;
     148                 :         const PatchList<ITEM, TAG>& changes;
     149                 : 
     150                 : public: 
     151                 :         UnpatchedOnly(const PatchList<ITEM, TAG>& changes, const OUT& out) : out(out), changes(changes) {}
     152                 : 
     153                 :         UnpatchedOnly<ITEM, TAG, OUT>& operator++() { return *this; }
     154                 :         
     155                 :         template<typename Items, typename Tags>
     156                 :         UnpatchedOnly<ITEM, TAG, OUT>& operator=(const std::pair<Items, Tags>& data)
     157                 :         {
     158                 :                 for (typename Items::const_iterator i = data.first.begin();
     159                 :                                 i != data.first.end(); ++i)
     160                 :                         if (changes.find(*i) == changes.end())
     161                 :                         {
     162                 :                                 *out = data;
     163                 :                                 ++out;
     164                 :                         }
     165                 :                 return *this;
     166                 :         }
     167                 : };
     168                 : 
     169                 : template<typename ITEM, typename TAG, typename OUT>
     170                 : UnpatchedOnly<ITEM, TAG, OUT> unpatchedOnly(const PatchList<ITEM, TAG>& changes, const OUT& out)
     171                 : {
     172                 :         return UnpatchedOnly<ITEM, TAG, OUT>(changes, out);
     173                 : }
     174                 : 
     175                 : template<class ITEM, class TAG>
     176                 : void Patched<ITEM, TAG>::output(Consumer<ITEM, TAG>& cons) const
     177                 : {
     178                 :         // First, only pass the unpatched items
     179                 :         coll.outputToIterator(unpatchedOnly(changes, consumer(cons)));
     180                 : 
     181                 :         // Then output the items in the patch
     182                 :         for (typename PatchList<ITEM, TAG>::const_iterator i = changes.begin();
     183                 :                         i != changes.end(); i++)
     184                 :                 cons.consume(i->first,
     185                 :                                 changes.patch(i->first, coll.getTags(i->first)));
     186                 : }
     187                 : #endif
     188                 : 
     189                 : template<typename ROCOLL>
     190                 : unsigned int Patched<ROCOLL>::getCardinality(const Tag& tag) const
     191                 : {
     192                 :         typename RPatches::const_iterator i = m_rchanges.find(tag);
     193                 :         if (i == m_rchanges.end())
     194                 :                 return coll.getCardinality(tag);
     195                 :         else
     196                 :                 return coll.getCardinality(tag) + i->second.added.size() - i->second.removed.size();
     197                 : }
     198                 : 
     199                 : }
     200                 : }
     201                 : 
     202                 : #include <tagcoll/coll/base.tcc>
     203                 : #include <tagcoll/patch.tcc>
     204                 : 
     205                 : #endif
     206                 : 
     207                 : // vim:set ts=4 sw=4:

Generated by: LTP GCOV extension version 1.6