LCOV - lcov.info - /usr/include/tagcoll-2.0.11/tagcoll/coll/patched.h

LTP GCOV extension - code coverage report
Current view: | directory - usr/include/tagcoll-2.0.11/tagcoll/coll - patched.h
Test: | lcov.info
Date: | 2008-08-14 |  | Instrumented lines: | 57
Code covered: | 66.7 % |  | Executed lines: | 38

           1                 : #ifndef TAGCOLL_COLL_PATCHED_H
           2                 : #define TAGCOLL_COLL_PATCHED_H
           3                 :
           4                 : /** \file
           5                 :  * Wrap a Collection, preserving modifications as patches
           6                 :  */
           7                 :
           8                 : /*
           9                 :  * Copyright (C) 2005,2006  Enrico Zini <enrico@debian.org>
          10                 :  *
          11                 :  * This program is free software; you can redistribute it and/or modify
          12                 :  * it under the terms of the GNU General Public License as published by
          13                 :  * the Free Software Foundation; either version 2 of the License, or
          14                 :  * (at your option) any later version.
          15                 :  *
          16                 :  * This program is distributed in the hope that it will be useful,
          17                 :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
          18                 :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
          19                 :  * GNU General Public License for more details.
          20                 :  *
          21                 :  * You should have received a copy of the GNU General Public License
          22                 :  * along with this program; if not, write to the Free Software
          23                 :  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
          24                 :  */
          25                 :
          26                 : #include <tagcoll/coll/base.h>
          27                 : #include <tagcoll/patch.h>
          28                 :
          29                 : namespace tagcoll {
          30                 : template<typename T1, typename T2> class PatchList;
          31                 :
          32                 : namespace coll {
          33                 : template<typename ROCOLL>
          34                 : class Patched;
          35                 :
          36                 : template<typename ROCOLL>
          37                 : struct coll_traits< Patched<ROCOLL> >
          38                 : {
          39                 :         typedef typename coll_traits<ROCOLL>::item_type item_type;
          40                 :         typedef typename coll_traits<ROCOLL>::tag_type tag_type;
          41                 :         typedef typename coll_traits<ROCOLL>::tagset_type tagset_type;
          42                 :         typedef typename coll_traits<ROCOLL>::itemset_type itemset_type;
          43                 : };
          44                 :
          45                 : /**
          46                 :  * Wraps a collection by intercepting all changes to it and preserving them as
          47                 :  * a PatchList.
          48                 :  */
          49                 : template<typename ROCOLL>
          50                 : class Patched : public coll::Collection< Patched<ROCOLL> >
          51              10 : {
          52                 : public:
          53                 :         typedef tagcoll::Patch<
          54                 :                 typename coll_traits<ROCOLL>::item_type,
          55                 :                 typename coll_traits<ROCOLL>::tag_type> Patch;
          56                 :         typedef tagcoll::PatchList<
          57                 :                 typename coll_traits<ROCOLL>::item_type,
          58                 :                 typename coll_traits<ROCOLL>::tag_type> Patches;
          59                 :         typedef tagcoll::Patch<
          60                 :                 typename coll_traits<ROCOLL>::tag_type,
          61                 :                 typename coll_traits<ROCOLL>::item_type> RPatch;
          62                 :         typedef tagcoll::PatchList<
          63                 :                 typename coll_traits<ROCOLL>::tag_type,
          64                 :                 typename coll_traits<ROCOLL>::item_type> RPatches;
          65                 :
          66                 : protected:
          67                 :         typedef typename coll_traits<ROCOLL>::item_type Item;
          68                 :         typedef typename coll_traits<ROCOLL>::tag_type Tag;
          69                 :         typedef typename coll_traits<ROCOLL>::itemset_type ItemSet;
          70                 :         typedef typename coll_traits<ROCOLL>::tagset_type TagSet;
          71                 :
          72                 :         const ROCOLL& coll;
          73                 :         Patches m_changes;
          74                 :         RPatches m_rchanges;
          75                 :
          76                 : #if 0
          77                 :         virtual void consumeItem(const ITEM& item, const std::set<TAG>& tags);
          78                 :
          79                 :         virtual std::set<ITEM> getItemsHavingTag(const TAG& tag) const;
          80                 :         virtual std::set<TAG> getTagsOfItem(const ITEM& item) const;
          81                 : #endif
          82                 :
          83                 : public:
          84                 :         typedef std::pair<Item, TagSet> value_type;
          85                 :
          86                 :         class const_iterator
          87                 :         {
          88                 :                 const Patched<ROCOLL>& coll;
          89                 :                 typename ROCOLL::const_iterator ci;
          90                 :                 typename Patches::const_iterator pi;
          91                 :                 mutable typename Patched<ROCOLL>::value_type* cached_val;
          92                 :
          93                 :         protected:
          94                 :                 const_iterator(const Patched<ROCOLL>& coll,
          95                 :                                                 const typename ROCOLL::const_iterator& ci,
          96           84592 :                                                 const typename Patches::const_iterator& pi)
          97           84592 :                         : coll(coll), ci(ci), pi(pi), cached_val(0) {}
          98                 :
          99                 :         public:
         100          148035 :                 ~const_iterator()
         101                 :                 {
         102          148035 :                         if (cached_val)
         103               0 :                                 delete cached_val;
         104          148035 :                 }
         105           84580 :                 const typename Patched<ROCOLL>::value_type operator*() const
         106                 :                 {
         107           84580 :                         if (cached_val)
         108               0 :                                 return *cached_val;
         109                 :
         110           84580 :                         if (ci == coll.coll.end() && pi == coll.m_changes.end())
         111               0 :                                 return *(typename Patched<ROCOLL>::value_type*)0;
         112           84580 :                         else if (pi == coll.m_changes.end())
         113           84580 :                                 return *ci;
         114               0 :                         else if (ci == coll.coll.end())
         115               0 :                                 return make_pair(pi->first, pi->second.added);
         116               0 :                         else if (ci->first < pi->first)
         117               0 :                                 return *ci;
         118               0 :                         else if (ci->first > pi->first)
         119               0 :                                 return make_pair(pi->first, pi->second.added);
         120                 :                         else
         121               0 :                                 return make_pair(ci->first, pi->second.apply(ci->second));
         122                 :                 }
         123          211450 :                 const typename Patched<ROCOLL>::value_type* operator->() const
         124                 :                 {
         125          211450 :                         if (cached_val)
         126          126870 :                                 return cached_val;
         127           84580 :                         return cached_val = new typename Patched<ROCOLL>::value_type(*(*this));
         128                 :                 }
         129           84580 :                 const_iterator& operator++()
         130                 :                 {
         131           84580 :                         if (ci == coll.coll.end() && pi == coll.m_changes.end())
         132                 :                                 ;
         133           84580 :                         else if (pi == coll.m_changes.end())
         134           84580 :                                 ++ci;
         135               0 :                         else if (ci == coll.coll.end())
         136               0 :                                 ++pi;
         137               0 :                         else if (ci->first < pi->first)
         138               0 :                                 ++ci;
         139               0 :                         else if (ci->first > pi->first)
         140               0 :                                 ++pi;
         141                 :                         else
         142                 :                         {
         143               0 :                                 ++ci;
         144               0 :                                 ++pi;
         145                 :                         }
         146           84580 :                         if (cached_val)
         147                 :                         {
         148           84580 :                                 delete cached_val;
         149           84580 :                                 cached_val = 0;
         150                 :                         }
         151           84580 :                         return *this;
         152                 :                 }
         153               1 :                 bool operator==(const const_iterator& iter) const
         154                 :                 {
         155               1 :                         return ci == iter.ci && pi == iter.pi;
         156                 :                 }
         157           84585 :                 bool operator!=(const const_iterator& iter) const
         158                 :                 {
         159           84585 :                         return ci != iter.ci || pi != iter.pi;
         160                 :                 }
         161                 :
         162                 :                 friend class Patched<ROCOLL>;
         163                 :         };
         164               6 :         const_iterator begin() const { return const_iterator(*this, coll.begin(), m_changes.begin()); }
         165           84586 :         const_iterator end() const { return const_iterator(*this, coll.end(), m_changes.end()); }
         166                 :
         167              10 :         Patched(const ROCOLL& coll) : coll(coll) {}
         168                 :
         169                 :         template<typename ITEMS, typename TAGS>
         170                 :         void insert(const ITEMS& items, const TAGS& tags);
         171                 :
         172                 :         template<typename ITEMS>
         173                 :         void insert(const ITEMS& items, const wibble::Empty<Tag>& tags)
         174                 :         {
         175                 :                 // Nothing to do in this case
         176                 :         }
         177                 :
         178                 :         /**
         179                 :          * Removes all items from the collection
         180                 :          */
         181                 :         void clear();
         182                 :
         183                 :         /**
         184                 :          * Get the changes that have been applied to this collection
         185                 :          */
         186               4 :         const Patches& changes() const { return m_changes; }
         187                 :
         188                 :         /**
         189                 :          * Throw away all changes previously applied to this collection
         190                 :          */
         191                 :         void resetChanges() { m_changes.clear(); m_rchanges.clear(); }
         192                 :
         193                 :         /**
         194                 :          * Set the changes list to a specific patch list
         195                 :          */
         196               0 :         void setChanges(const Patches& changes);
         197                 :
         198                 :         /**
         199                 :          * Add a specific patch list to the changes list
         200                 :          */
         201               2 :         void addChanges(const Patches& changes);
         202                 :
         203                 :     bool hasTag(const Tag& tag) const;
         204                 :
         205               5 :         TagSet getTagsOfItem(const Item& item) const
         206                 :         {
         207               5 :                 return m_changes.patch(item, coll.getTagsOfItem(item));
         208                 :         }
         209               9 :         ItemSet getItemsHavingTag(const typename coll_traits<ROCOLL>::tag_type& tag) const
         210                 :         {
         211               9 :                 return m_rchanges.patch(tag, coll.getItemsHavingTag(tag));
         212                 :         }
         213                 :
         214                 :         ItemSet getTaggedItems() const;
         215               1 :         TagSet getAllTags() const;
         216                 :
         217                 :         unsigned int tagCount() const { return getAllTags().size(); }
         218                 :
         219                 :         unsigned int getCardinality(const Tag& tag) const;
         220                 :
         221               2 :         void applyChange(const Patches& change) { this->addChanges(change); }
         222                 :
         223                 : #if 0
         224                 :         template<typename OUT>
         225                 :         void output(OUT out) const
         226                 :         {
         227                 :                 for (const_iterator i = begin(); i != end(); ++i)
         228                 :                 {
         229                 :                         *out = *i;
         230                 :                         ++out;
         231                 :                 }
         232                 :         }
         233                 : #endif
         234                 : };
         235                 :
         236                 : }
         237                 : }
         238                 :
         239                 : // vim:set ts=4 sw=4:
         240                 : #endif

Generated by: LTP GCOV extension version 1.6