Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Use boost::iterator_facade for History::Iterator
authorMaxwell Pirtle <maxwellpirtle@gmail.com>
Wed, 1 Mar 2023 08:22:43 +0000 (09:22 +0100)
committerMaxwell Pirtle <maxwellpirtle@gmail.com>
Wed, 1 Mar 2023 08:22:43 +0000 (09:22 +0100)
The iterator that is used in the `History` class
was adjusted to use boost::iterator_facade, as it
simplifies life considerably, makes the code more
readable, and provides better conformance to being
a forward iterator (i.e. it probably handles some
subtleties with forward iterators etc. and implements
many methods automatically)

src/mc/explo/udpor/EventSet.cpp
src/mc/explo/udpor/History.cpp
src/mc/explo/udpor/History.hpp

index b03bef5..c0f0195 100644 (file)
@@ -114,11 +114,12 @@ bool EventSet::is_valid_configuration() const
 {
   /// @invariant: A collection of events `E` is a configuration
   /// if and only if following while following the history of
-  /// each event `e` of `E`you remain in `E`. In other words, you
+  /// each event `e` of `E` you remain in `E`. In other words, you
   /// only see events from set `E`
   ///
-  /// The proof is based on the definition of a configuration
-  /// which requires that all
+  /// The simple proof is based on the definition of a configuration
+  /// which requires that all events have their history contained
+  /// in the set
   const History history(*this);
   return this->contains(history);
 }
index e6a6405..313b464 100644 (file)
@@ -20,7 +20,7 @@ History::Iterator::Iterator(const EventSet& initial_events, optional_configurati
   // and all subsequent events that are added by the iterator
 }
 
-History::Iterator& History::Iterator::operator++()
+void History::Iterator::increment()
 {
   if (not frontier.empty()) {
     // "Pop" the event at the "front"
@@ -33,7 +33,7 @@ History::Iterator& History::Iterator::operator++()
     // be searched since the configuration contains
     // them (configuration invariant)
     if (configuration.has_value() && configuration->get().contains(e)) {
-      return *this;
+      return;
     }
 
     // Mark this event as seen
@@ -47,7 +47,19 @@ History::Iterator& History::Iterator::operator++()
     candidates.subtract(current_history);
     frontier.form_union(candidates);
   }
-  return *this;
+}
+
+UnfoldingEvent* const& History::Iterator::dereference() const
+{
+  return *frontier.begin();
+}
+
+bool History::Iterator::equal(const Iterator& other) const
+{
+  // If what the iterator sees next is the same, we consider them
+  // to be the same iterator. This way, once the iterator has completed
+  // its search, it will be "equal" to an iterator searching nothing
+  return this->frontier == other.frontier;
 }
 
 EventSet History::get_all_events() const
index 7087927..2deb655 100644 (file)
@@ -10,6 +10,7 @@
 #include "src/mc/explo/udpor/EventSet.hpp"
 #include "src/mc/explo/udpor/udpor_forward.hpp"
 
+#include <boost/iterator/iterator_facade.hpp>
 #include <functional>
 #include <optional>
 
@@ -99,25 +100,9 @@ private:
   /**
    * @brief An iterator which traverses the history of a set of events
    */
-  struct Iterator {
+  struct Iterator : boost::iterator_facade<Iterator, UnfoldingEvent* const, boost::forward_traversal_tag> {
   public:
-    Iterator& operator++();
-    auto operator->() const { return frontier.begin().operator->(); }
-    auto operator*() const { return *frontier.begin(); }
-
-    // If what the iterator sees next is the same, we consider them
-    // to be the same iterator. This way, once the iterator has completed
-    // its search, it will be "equal" to an iterator searching nothing
-    bool operator==(const Iterator& other) const { return this->frontier == other.frontier; }
-    bool operator!=(const Iterator& other) const { return not(this->operator==(other)); }
-
-    using iterator_category      = std::forward_iterator_tag;
-    using difference_type        = int; // # of steps between
-    using value_type             = UnfoldingEvent*;
-    using pointer                = value_type*;
-    using reference              = value_type&;
     using optional_configuration = std::optional<std::reference_wrapper<const Configuration>>;
-
     Iterator(const EventSet& initial_events, optional_configuration config = std::nullopt);
 
   private:
@@ -129,8 +114,21 @@ private:
     EventSet current_history = EventSet();
 
     /// @brief What the iterator currently believes
+    // to be the set of maximal events
     EventSet maximal_events;
     optional_configuration configuration;
+
+    // boost::iterator_facade<...> interface to implement
+    void increment();
+    bool equal(const Iterator& other) const;
+
+    UnfoldingEvent* const& dereference() const;
+
+    // Allows boost::iterator_facade<...> to function properly
+    friend class boost::iterator_core_access;
+
+    // Allow the `History` class to use some of the
+    // computation of the iterator
     friend History;
   };
 };