[pan2] Replace RulesInfo.deque<RulesInfo> with deque<RulesInfo *>.



commit f9e0a50ca1cf6304d3babde0b9473d7e02cc15e0
Author: Olaf Seibert <rhialto falu nl>
Date:   Wed Mar 9 00:00:37 2016 +0100

    Replace RulesInfo.deque<RulesInfo> with deque<RulesInfo *>.
    
    An object cannot be contained in itself (and the library doesn't like
    incomplete types in deques).
    Add memory management for the now pointed-to aggregates.
    
    Some remarks while I'm looking at it:
    - _negate seems unused in evaluating the rules in rules-filter.cc:test_article().
    - but fortunately also set_type_le()
    - AGGREGATE__AND seems to be handled incorrectly in test_article(): pass is always true.

 pan/data-impl/rules-filter.cc  |    8 +++---
 pan/gui/header-pane.cc         |   16 ++++++++-----
 pan/usenet-utils/rules-info.cc |   47 ++++++++++++++++++++++++++++++++++++++++
 pan/usenet-utils/rules-info.h  |   19 +++++++++++++--
 4 files changed, 77 insertions(+), 13 deletions(-)
---
diff --git a/pan/data-impl/rules-filter.cc b/pan/data-impl/rules-filter.cc
index 197e564..86116e5 100644
--- a/pan/data-impl/rules-filter.cc
+++ b/pan/data-impl/rules-filter.cc
@@ -61,8 +61,8 @@ RulesFilter :: test_article ( Data        & data,
   {
     case RulesInfo::AGGREGATE__AND:
       pass = true;
-      foreach (RulesInfo::aggregates_t, rules._aggregates, it)
-        test_article (data, *it, group, article);
+      foreach (RulesInfo::aggregatesp_t, rules._aggregates, it)
+        test_article (data, **it, group, article);
       break;
 
     case RulesInfo::AGGREGATE__OR:
@@ -70,8 +70,8 @@ RulesFilter :: test_article ( Data        & data,
         pass = true;
       else {
         pass = false;
-        foreach (RulesInfo::aggregates_t, rules._aggregates, it) {
-          if (test_article (data, *it, group, article)) {
+        foreach (RulesInfo::aggregatesp_t, rules._aggregates, it) {
+          if (test_article (data, **it, group, article)) {
             pass = true;
             break;
           }
diff --git a/pan/gui/header-pane.cc b/pan/gui/header-pane.cc
index 3b4c3fa..c63177b 100644
--- a/pan/gui/header-pane.cc
+++ b/pan/gui/header-pane.cc
@@ -1353,25 +1353,29 @@ HeaderPane :: rebuild_rules (bool enable)
 
   RulesInfo &r (_rules);
   r.set_type_aggregate_and ();
-  RulesInfo tmp;
+  RulesInfo *tmp;
 
   std::pair<int,int> res;
 
   res = get_int_from_rules_str(_prefs.get_string("rules-delete-value", "never"));
-  tmp.set_type_delete_b (res.first, res.second);
+  tmp = new RulesInfo;
+  tmp->set_type_delete_b (res.first, res.second);
   r._aggregates.push_back (tmp);
 
   res = get_int_from_rules_str(_prefs.get_string("rules-mark-read-value", "never"));
-  tmp.set_type_mark_read_b (res.first, res.second);
+  tmp = new RulesInfo;
+  tmp->set_type_mark_read_b (res.first, res.second);
   r._aggregates.push_back (tmp);
 
   res = get_int_from_rules_str(_prefs.get_string("rules-autocache-value", "never"));
-  tmp.set_type_autocache_b (res.first, res.second);
+  tmp = new RulesInfo;
+  tmp->set_type_autocache_b (res.first, res.second);
   r._aggregates.push_back (tmp);
 
   res = get_int_from_rules_str(_prefs.get_string("rules-auto-dl-value", "never"));
-  tmp.set_type_dl_b (res.first, res.second);
-   r._aggregates.push_back (tmp);
+  tmp = new RulesInfo;
+  tmp->set_type_dl_b (res.first, res.second);
+  r._aggregates.push_back (tmp);
 
 }
 
diff --git a/pan/usenet-utils/rules-info.cc b/pan/usenet-utils/rules-info.cc
index 68b7319..5a7be25 100644
--- a/pan/usenet-utils/rules-info.cc
+++ b/pan/usenet-utils/rules-info.cc
@@ -35,10 +35,57 @@ using namespace pan;
 ****
 ***/
 
+/*
+ * Copy-and-swap idiom according to
+ * http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom
+ */
+
+RulesInfo :: RulesInfo (const RulesInfo &that)
+  : _type(that._type)
+  , _negate(that._negate)
+  , _ge(that._ge)
+  , _lb(that._lb)
+  , _hb(that._hb)
+{
+  foreach_const (aggregatesp_t, that._aggregates, it) {
+    _aggregates.push_back (new RulesInfo(**it));
+  }
+}
+
+void
+swap (RulesInfo &first, RulesInfo &second)
+{
+  using std::swap;
+
+  swap (first._type,       second._type);
+  swap (first._aggregates, second._aggregates);
+  swap (first._negate,     second._negate);
+  swap (first._ge,         second._ge);
+  swap (first._lb,         second._lb);
+  swap (first._hb,         second._hb);
+}
+
+RulesInfo &RulesInfo::operator = (RulesInfo other)
+{
+  swap (*this, other);
+
+  return *this;
+}
+
+RulesInfo :: ~RulesInfo ()
+{
+  foreach (aggregatesp_t, _aggregates, it) {
+    delete *it;
+  }
+}
+
 void
 RulesInfo :: clear ()
 {
   _type = RulesInfo::TYPE__ERR;
+  foreach (aggregatesp_t, _aggregates, it) {
+    delete *it;
+  }
   _aggregates.clear ();
   _lb = _hb = 0;
   _ge = 0;
diff --git a/pan/usenet-utils/rules-info.h b/pan/usenet-utils/rules-info.h
index 54cd15d..35a8a1f 100644
--- a/pan/usenet-utils/rules-info.h
+++ b/pan/usenet-utils/rules-info.h
@@ -25,6 +25,16 @@
 #include <pan/general/string-view.h>
 #include <pan/general/text-match.h>
 
+/**
+ * Pre-declaring swap(...) is a bit involved, given the use
+ * of the namespace pan and it needs to be outside.
+ */
+namespace pan {
+  class RulesInfo;
+};
+
+void swap(pan::RulesInfo &first, pan::RulesInfo &second);
+
 namespace pan
 {
   /**
@@ -51,14 +61,17 @@ namespace pan
 
       bool empty() const { return _type == TYPE__ERR; }
       RulesInfo () { clear(); }
-      virtual ~RulesInfo () { }
+      RulesInfo (const RulesInfo &that);
+      friend void ::swap (RulesInfo &first, RulesInfo &second);
+      RulesInfo &operator = (RulesInfo other);
+      virtual ~RulesInfo ();
 
       /** Convenience typedef. */
-      typedef std::deque<RulesInfo> aggregates_t;
+      typedef std::deque<RulesInfo *> aggregatesp_t;
 
       /** When `_type' is AGGREGATE_OR or AGGREGATE_AND,
           these are the filters being or'ed or and'ed together. */
-      aggregates_t _aggregates;
+      aggregatesp_t _aggregates;
 
       /** When this is true, the results of the test should be negated. */
       bool _negate;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]