00001 #ifndef TAGCOLL_DERIVEDTAGS_H
00002 #define TAGCOLL_DERIVEDTAGS_H
00003
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
00162 #endif