expression.h

Go to the documentation of this file.
00001 #ifndef TAGCOLL_EXPRESSION_H
00002 #define TAGCOLL_EXPRESSION_H
00003 
00004 /*
00005  * Expression that can match tagsets
00006  * 
00007  * Copyright (C) 2003,2004,2005,2006  Enrico Zini <enrico@debian.org>
00008  *
00009  * This library is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2.1 of the License, or (at your option) any later version.
00013  *
00014  * This library is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Lesser General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public
00020  * License along with this library; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00022  */
00023 
00024 #include <string>
00025 #include <set>
00026 #include <map>
00027 #include <wibble/singleton.h>
00028 #include <wibble/mixin.h>
00029 
00030 namespace tagcoll
00031 {
00032 
00033 class TagexprContext;
00034 
00038 class ExpressionImpl
00039 {
00040 protected:
00041     int _ref;
00042 
00043 public:
00044     ExpressionImpl() : _ref(0) {}
00045     virtual ~ExpressionImpl() {}
00046 
00048     void ref() throw () { ++_ref; }
00049 
00052     bool unref() throw () { return --_ref == 0; }
00053 
00057     virtual std::string format() const = 0;
00058 
00064     virtual bool eval(const TagexprContext& context) const = 0;
00065 
00072     virtual bool eval(const std::set<std::string>& tags) const = 0;
00073 
00077     //virtual Tagexpr* clone() const = 0;
00078 };
00079 
00080 class Expression
00081 {
00082 protected:
00083     ExpressionImpl* m_impl;
00084 
00085     Expression(ExpressionImpl* impl) : m_impl(impl) { m_impl->ref(); }
00086 
00087     const ExpressionImpl* impl() const { return m_impl; }
00088     ExpressionImpl* impl() { return m_impl; }
00089 
00090 public:
00091     Expression();
00092     Expression(const std::string& expr);
00093 
00094     Expression(const Expression& e)
00095     {
00096         if (e.m_impl)
00097             e.m_impl->ref();
00098         m_impl = e.m_impl;
00099     }
00100     ~Expression() { if (m_impl->unref()) delete m_impl; }
00101 
00102     Expression& operator=(const Expression& e)
00103     {
00104         if (e.m_impl)
00105             e.m_impl->ref();  // Do it early to correctly handle the case of x = x;
00106         if (m_impl && m_impl->unref())
00107             delete m_impl;
00108         m_impl = e.m_impl;
00109         return *this;
00110     }
00111 
00112     Expression operator and (const Expression& e);
00113     Expression operator or (const Expression& e);
00114     Expression operator not ();
00115 
00116     template<typename Tags>
00117     bool operator()(const Tags& tags) const
00118     {
00119         std::set<std::string> stags;
00120         for (typename Tags::const_iterator i = tags.begin();
00121                 i != tags.end(); ++i)
00122             stags.insert(*i);
00123         return m_impl->eval(stags);
00124     }
00125     bool operator()(const std::set<std::string>& tags) const { return m_impl->eval(tags); }
00126 
00127     bool operator()(const TagexprContext& context) const { return m_impl->eval(context); }
00128 
00129     std::string format() const { return m_impl->format(); }
00130 
00131     static Expression matchTag(const std::string& pattern);
00132 };
00133 
00146 class TagexprContext
00147 {
00148 protected:
00149     const std::set<std::string>& tags;
00150     const std::map<std::string, Expression>& derivedTags;
00151     // Tags "visited" during tag evaluation: used to break circular loops
00152     mutable std::set<std::string> seen;
00153 
00154 public:
00168     TagexprContext(const std::set<std::string>& tags, const std::map<std::string, Expression>& derivedTags)
00169         : tags(tags), derivedTags(derivedTags) {}
00170 
00176     bool eval(const std::string& tag) const;
00177 };
00178 
00179 };
00180 
00181 // vim:set ts=4 sw=4:
00182 #endif

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