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