DerivedTags.h

Go to the documentation of this file.
00001 #ifndef TAGCOLL_DERIVEDTAGS_H
00002 #define TAGCOLL_DERIVEDTAGS_H
00003 
00009 /*
00010  * Copyright (C) 2003  Enrico Zini <enrico@debian.org>
00011  *
00012  * This library is free software; you can redistribute it and/or
00013  * modify it under the terms of the GNU Lesser General Public
00014  * License as published by the Free Software Foundation; either
00015  * version 2.1 of the License, or (at your option) any later version.
00016  *
00017  * This library is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020  * Lesser General Public License for more details.
00021  *
00022  * You should have received a copy of the GNU Lesser General Public
00023  * License along with this library; if not, write to the Free Software
00024  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00025  */
00026 
00027 #include <tagcoll/expression.h>
00028 
00029 #include <wibble/operators.h>
00030 #include <wibble/mixin.h>
00031 #include <map>
00032 #include <string>
00033 
00034 #include <stdio.h>
00035 
00036 namespace tagcoll
00037 {
00038 
00043 class DerivedTags : public std::map<std::string, Expression>
00044 {
00045 public:
00046     virtual ~DerivedTags() {}
00047 
00051     void add(const std::string& tag, const Expression& expr)
00052     {
00053         insert(make_pair(tag, expr));
00054     }
00055 
00059     std::set<std::string> derivedTags(const std::set<std::string>& tags) const
00060     {
00061         std::set<std::string> res;
00062         for (const_iterator i = begin(); i != end(); i++)
00063         {
00064             TagexprContext context(tags, *this);
00065             if (i->second(context))
00066                 res.insert(i->first);
00067         }
00068         return res;
00069     }
00070 
00071     template<typename TAGS>
00072     std::set<std::string> derivedTags(const TAGS& tags) const
00073     {
00074         std::set<std::string> tagset;
00075         for (typename TAGS::const_iterator i = tags.begin();
00076                 i != tags.end(); ++i)
00077             tagset.insert(*i);
00078 
00079         std::set<std::string> res;
00080         for (const_iterator i = begin(); i != end(); i++)
00081         {
00082             TagexprContext context(tagset, *this);
00083             if (i->second(context))
00084                 res.insert(i->first);
00085         }
00086         return res;
00087     }
00088 };
00089 
00093 template <typename OUT>
00094 class AddDerived : public wibble::mixin::OutputIterator< AddDerived<OUT> >
00095 {
00096 protected:
00097     const DerivedTags& dtags;
00098     OUT out;
00099 
00100 public:
00101     AddDerived(const DerivedTags& dtags, const OUT& out)
00102         : dtags(dtags), out(out) {}
00103 
00104     template<typename ITEMS, typename TAGS>
00105     AddDerived<OUT>& operator=(const std::pair<ITEMS, TAGS>& data)
00106     {
00107         using namespace wibble::operators;
00108         std::set<typename TAGS::value_type> newts;
00109         for (typename TAGS::const_iterator i = data.second.begin();
00110                 i != data.second.end(); ++i)
00111             newts.insert(*i);
00112         newts |= dtags.derivedTags(data.second);
00113         *out = make_pair(data.first, newts);
00114         ++out;
00115         return *this;
00116     }
00117 };
00118 
00119 template<class OUT>
00120 AddDerived<OUT> addDerived(const DerivedTags& dtags, const OUT& out)
00121 {
00122     return AddDerived<OUT>(dtags, out);
00123 }
00124 
00128 template <typename OUT>
00129 class RemoveDerived : public wibble::mixin::OutputIterator< RemoveDerived<OUT> >
00130 {
00131 protected:
00132     DerivedTags dtags;
00133     OUT out;
00134 
00135 public:
00136     RemoveDerived(const DerivedTags& dtags, const OUT& out)
00137         : dtags(dtags), out(out) {}
00138 
00139     template<typename ITEM, typename TAGS>
00140     RemoveDerived<OUT>& operator=(const std::pair<ITEM, TAGS>& data)
00141     {
00142         using namespace wibble::operators;
00143         std::set<typename TAGS::value_type> newts;
00144         for (typename TAGS::const_iterator i = data.second.begin();
00145                 i != data.second.end(); ++i)
00146             newts.insert(*i);
00147         *out = make_pair(data.first, newts - dtags.derivedTags(data.second));
00148         ++out;
00149         return *this;
00150     }
00151 };
00152 
00153 template<class OUT>
00154 RemoveDerived<OUT> removeDerived(const DerivedTags& dtags, const OUT& out)
00155 {
00156     return RemoveDerived<OUT>(dtags, out);
00157 }
00158 
00159 };
00160 
00161 // vim:set ts=4 sw=4:
00162 #endif

Generated on Fri Feb 8 10:50:41 2008 for libtagcoll by  doxygen 1.5.4