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

           1                 : #ifndef TAGCOLL_COLL_BASE_H
           2                 : #define TAGCOLL_COLL_BASE_H
           3                 :
           4                 : /** \file
           5                 :  * Base mixins for tagged collections
           6                 :  */
           7                 :
           8                 : /*
           9                 :  * Copyright (C) 2003,2004,2005,2006  Enrico Zini <enrico@debian.org>
          10                 :  *
          11                 :  * This library is free software; you can redistribute it and/or
          12                 :  * modify it under the terms of the GNU Lesser General Public
          13                 :  * License as published by the Free Software Foundation; either
          14                 :  * version 2.1 of the License, or (at your option) any later version.
          15                 :  *
          16                 :  * This library 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 GNU
          19                 :  * Lesser General Public License for more details.
          20                 :  *
          21                 :  * You should have received a copy of the GNU Lesser General Public
          22                 :  * License along with this library; if not, write to the Free Software
          23                 :  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
          24                 :  */
          25                 :
          26                 : #include <wibble/mixin.h>
          27                 : #include <vector>
          28                 :
          29                 : namespace std {
          30                 : template<typename A, typename B> class pair;
          31                 : }
          32                 :
          33                 : namespace tagcoll {
          34                 : namespace coll {
          35                 :
          36                 : template<typename T>
          37                 : class coll_traits;
          38                 :
          39                 : /**
          40                 :  * Interface for all collections of tagged items.
          41                 :  *
          42                 :  * \note The point of a collection is to track the tags attached to items, and
          43                 :  * not to store the items themselves.  This means that collections are not
          44                 :  * required to keep track of items with no tags.
          45                 :  */
          46                 : template<typename Self>
          47                 : class ReadonlyCollection
          48              37 : {
          49           84611 :         const Self& self() const { return *static_cast<const Self*>(this); }
          50                 :
          51                 :         class CardinalityOrder
          52                 :         {
          53                 :                 const Self& coll;
          54                 :         public:
          55                 :                 CardinalityOrder(const Self& coll) : coll(coll) {}
          56                 :                 bool operator()(const typename coll_traits<Self>::tag_type& t1, const typename coll_traits<Self>::tag_type& t2)
          57                 :                 {
          58                 :                         // Returns true if t1 precedes t2, and false otherwise
          59                 :                         return coll.getCardinality(t1) < coll.getCardinality(t2);
          60                 :                 }
          61                 :         };
          62                 :
          63                 :         class DiscriminanceOrder
          64                 :         {
          65                 :                 const Self& coll;
          66                 :         public:
          67                 :                 DiscriminanceOrder(const Self& coll) : coll(coll) {}
          68                 :                 bool operator()(const typename coll_traits<Self>::tag_type& t1, const typename coll_traits<Self>::tag_type& t2)
          69                 :                 {
          70                 :                         // Returns true if t1 precedes t2, and false otherwise
          71                 :                         return coll.getDiscriminance(t1) < coll.getDiscriminance(t2);
          72                 :                 }
          73                 :         };
          74                 :
          75                 :         template<typename COLL>
          76                 :         class RelevanceOrder
          77                 :         {
          78                 :                 const COLL& first;
          79                 :                 const Self& second;
          80                 :         public:
          81                 :                 RelevanceOrder(const COLL& first, const Self& second)
          82                 :                         : first(first), second(second) {}
          83                 :                 bool operator()(const typename coll_traits<Self>::tag_type& t1, const typename coll_traits<Self>::tag_type& t2);
          84                 :         };
          85                 :
          86                 :         /**
          87                 :          * Get the items which are tagged with at least the tag `tag'
          88                 :          *
          89                 :          * \return
          90                 :          *   The items found, or an empty set if no items have that tag
          91                 :          */
          92                 :         //virtual std::set<ITEM> getItemsHavingTag(const TAG& tag) const = 0;
          93                 :
          94                 :         /**
          95                 :          * Get the tags attached to an item.
          96                 :          *
          97                 :          * \param item
          98                 :          *   The item to query
          99                 :          * \return
         100                 :          *   The set of tags, or an empty set if the item has no tags or it does
         101                 :          *   not exist.
         102                 :          */
         103                 :         //virtual std::set<TAG> getTagsOfItem(const ITEM& item) const = 0;
         104                 :
         105                 : public:
         106                 :         /**
         107                 :          * Check if the collection contains a tag
         108                 :          *
         109                 :          * \param tag
         110                 :          *   The tag to look for
         111                 :          * \return
         112                 :          *   true if the collection contains tag, false otherwise
         113                 :          */
         114                 :         bool hasTag(const typename coll_traits<Self>::tag_type& tag) const;
         115                 :
         116                 :         /**
         117                 :          * Get the tags of item `item'.  Return an empty set if `item' does not exist
         118                 :          */
         119                 :         //std::set<Self::tag_type> getTags(const typename Self::item_type& item) const = 0;
         120                 :
         121                 :         /**
         122                 :          * Get all the tags attached to the items in a set.
         123                 :          *
         124                 :          * \param items
         125                 :          *   The items to query
         126                 :          * \return
         127                 :          *   The set of tags, or an empty set if the items have no tags or do not
         128                 :          *   exist.
         129                 :          */
         130                 :         template<typename ITEMS>
         131                 :         typename coll_traits<Self>::tagset_type getTagsOfItems(const ITEMS& items) const;
         132                 :
         133                 :         /**
         134                 :          * Get the items with tag `tag'.  Return an empty set if `tag' does not exist
         135                 :          */
         136                 :         //std::set<typename Self::item_type> getItems(const TAG& tag) const { return getItemsHavingTag(tag); }
         137                 :
         138                 :         /**
         139                 :          * Get the items which are tagged with at least the tags `tags'
         140                 :          *
         141                 :          * \return
         142                 :          *   The items found, or an empty set if no items have that tag
         143                 :          */
         144                 :         template<typename TAGS>
         145               2 :         typename coll_traits<Self>::itemset_type getItemsHavingTags(const TAGS& tags) const;
         146                 :
         147                 :         /**
         148                 :          * Get the set of all the items that have tags according to this collection
         149                 :          */
         150                 :         //virtual std::set<Self::item_type> getTaggedItems() const = 0;
         151                 :
         152                 :         /**
         153                 :          * Get the set of all the tags in this collection
         154                 :          */
         155                 :         //virtual std::set<Self::tag_type> getAllTags() const = 0;
         156                 :
         157                 :         /**
         158                 :          * Get all the tags in the collectin, as a vector
         159                 :          */
         160                 :         std::vector<typename coll_traits<Self>::tag_type> getAllTagsAsVector() const;
         161                 :
         162                 :         /**
         163                 :          * Get the cardinality of tag `tag' (that is, the number of items who have it)
         164                 :          */
         165                 :         unsigned int getCardinality(const typename coll_traits<Self>::tag_type& tag) const;
         166                 :
         167                 :         /**
         168                 :          * Return the discriminance value for this tag, that is, the minimum number
         169                 :          * of packages that would be eliminated by selecting only those tagged with
         170                 :          * this tag or only those not tagged with this tag.
         171                 :          */
         172                 :         unsigned int getDiscriminance(const typename coll_traits<Self>::tag_type& tag) const
         173                 :         {
         174                 :                 return self().getCardinality(tag) < self().tagCount() - self().getCardinality(tag) ?
         175                 :                                 self().getCardinality(tag) :
         176                 :                                 self().tagCount() - self().getCardinality(tag);
         177                 :         }
         178                 :
         179                 :         /**
         180                 :          * Get the set of all tags in this collection that appear in tagsets
         181                 :          * containing `tags'
         182                 :          *
         183                 :          * Example:
         184                 :          * \code
         185                 :          * void refineSelection(const std::set<Tag>& selection)
         186                 :          * {
         187                 :          *    std::set<Tag> extraTags = collection.getCompanionTags(selection);
         188                 :          *    tagMenu.setAvailableOptions(extraTags);
         189                 :          * }
         190                 :          * \endcode
         191                 :          */
         192                 :         template<typename TAGS>
         193                 :         typename coll_traits<Self>::tagset_type getCompanionTags(const TAGS& tags) const;
         194                 :
         195                 :         /**
         196                 :          * Get the related items at the given maximum distance
         197                 :          *
         198                 :          * Examples:
         199                 :          * \code
         200                 :          * // Get the items related to a given one, at the given distance
         201                 :          * std::set<Item> getRelated(const Item& item, int distance)
         202                 :          * {
         203                 :          *    std::set<Item> res = collection.getRelatedItems(collection.getTags(item), distance);
         204                 :          *    return res - item;
         205                 :          * }
         206                 :          *
         207                 :          * // Get the items related to the given ones, at the given distance
         208                 :          * std::set<Item> getRelated(const std::set<Item>& items, int distance)
         209                 :          * {
         210                 :          *    std::set<Item> res = collection.getRelatedItems(collection.getTags(items), distance);
         211                 :          *    return res - items;
         212                 :          * }
         213                 :          *
         214                 :          * // Get the related items, increasing the distance until it finds at
         215                 :          * // least 'minimum' items
         216                 :          * std::set<Item> getRelated(const Item& item, int minimum)
         217                 :          * {
         218                 :          *    std::set<Tag> tags = collection.getTags(item);
         219                 :          *    std::set<Item> res;
         220                 :          *    for (int i = 0; i < tags.size() && res.size() < minimum; i++)
         221                 :          *       res += collection.getRelatedItems(tags, i);
         222                 :          *        return res - item;
         223                 :          * }
         224                 :          * \endcode
         225                 :          */
         226                 :         template<typename TAGS>
         227                 :         typename coll_traits<Self>::itemset_type getRelatedItems(const TAGS& tags, int maxdistance = 1) const;
         228                 :
         229                 :         /**
         230                 :          * Output all the contents of the collection to an output iterator
         231                 :          */
         232                 :         template<typename OUT>
         233               5 :         void output(OUT out) const;
         234                 :
         235                 :         /**
         236                 :          * Send to a consumer all the items which are tagged with at least the
         237                 :          * given tags
         238                 :          */
         239                 :         template<typename TAGS, typename OUT>
         240                 :         void outputHavingTags(const TAGS& tags, OUT out) const;
         241                 :
         242                 :         /**
         243                 :          * Get a vector containing all tags in this collection, sorted by
         244                 :          * increasing cardinality
         245                 :          */
         246                 :         std::vector<typename coll_traits<Self>::tag_type> tagsInCardinalityOrder() const;
         247                 :
         248                 :         /**
         249                 :          * Get a vector containing all tags in this collection, sorted by
         250                 :          * increasing discriminance value (@see getDiscriminance)
         251                 :          */
         252                 :         std::vector<typename coll_traits<Self>::tag_type> tagsInDiscriminanceOrder() const;
         253                 :
         254                 :         /**
         255                 :          * Get a vector containing all tags in this collection, sorted by
         256                 :          * increasing relevance to the filtering applied between coll and this
         257                 :          * collection
         258                 :          */
         259                 :         template<typename COLL>
         260                 :         std::vector<typename coll_traits<Self>::tag_type> tagsInRelevanceOrder(const COLL& coll) const;
         261                 : };
         262                 :
         263                 :
         264                 : /**
         265                 :  * Interface for all collections of tagged items.
         266                 :  *
         267                 :  * \note The point of a collection is to track the tags attached to items, and
         268                 :  * not to store the items themselves.  This means that collections are not
         269                 :  * required to keep track of items with no tags.
         270                 :  */
         271                 : template<typename Self>
         272                 : class Collection : public ReadonlyCollection<Self>
         273              27 : {
         274                 : //protected:
         275                 :         /*
         276                 :          * Implementation note: to avoid problems with classes implementing only
         277                 :          * some of the virtual methods, they are given different names.  The common
         278                 :          * 'comsume' methods are just inlined calls to the right virtual functions,
         279                 :          * and are a way of keeping the unoverridden methods from being hidden.
         280                 :          */
         281                 :
         282                 :         //void consumeItemUntagged(const ITEM&) {}
         283                 :         //void consumeItemsUntagged(const std::set<ITEM>&) {}
         284                 :
         285                 : public:
         286                 :         //virtual ~Collection() {}
         287                 :
         288                 :         /**
         289                 :          * Apply a patch to the collection
         290                 :          *
         291                 :          * Example:
         292                 :          * \code
         293                 :          * void perform(const PatchList<ITEM, TAG>& change)
         294                 :          * {
         295                 :          *    collection.applyChange(change);
         296                 :          *    undo.push_back(change.getReverse());
         297                 :          * }
         298                 :          * \endcode
         299                 :          */
         300                 : //      void applyChange(
         301                 : //                      const PatchList<
         302                 : //                              typename coll_traits<Self>::item_type,
         303                 : //                              typename coll_traits<Self>::tag_type>& change);
         304                 : };
         305                 :
         306                 :
         307                 : template<typename COLL>
         308                 : class Inserter : public wibble::mixin::OutputIterator< Inserter<COLL> >
         309                 : {
         310                 :         COLL& coll;
         311                 :
         312                 : public:
         313              10 :         Inserter(COLL& coll) : coll(coll) {}
         314                 :
         315                 :         template<typename Items, typename Tags>
         316           63426 :         Inserter<COLL>& operator=(const std::pair<Items, Tags>& data)
         317                 :         {
         318           63426 :                 coll.insert(data.first, data.second);
         319           63426 :                 return *this;
         320                 :         }
         321                 : };
         322                 :
         323                 : template<typename COLL>
         324              10 : Inserter<COLL> inserter(COLL& target)
         325                 : {
         326              10 :         return Inserter<COLL>(target);
         327                 : }
         328                 :
         329                 : }
         330                 : }
         331                 :
         332                 : // vim:set ts=4 sw=4:
         333                 : #endif

Generated by: LTP GCOV extension version 1.6