Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add method to check if an EventSet is a config
[simgrid.git] / src / mc / explo / udpor / History.hpp
index 554b1c3371b2a06cc359e8ef04a2a6fdac93898b..4815496e9a1debbbea237840d44da1daa312d9db 100644 (file)
@@ -6,9 +6,13 @@
 #ifndef SIMGRID_MC_UDPOR_HISTORY_HPP
 #define SIMGRID_MC_UDPOR_HISTORY_HPP
 
+#include "src/mc/explo/udpor/Configuration.hpp"
 #include "src/mc/explo/udpor/EventSet.hpp"
 #include "src/mc/explo/udpor/udpor_forward.hpp"
 
+#include <functional>
+#include <optional>
+
 namespace simgrid::mc::udpor {
 
 /**
@@ -45,13 +49,15 @@ private:
   EventSet events_;
 
 public:
-  History()                          = default;
   History(const History&)            = default;
   History& operator=(History const&) = default;
   History(History&&)                 = default;
 
   explicit History(UnfoldingEvent* e) : events_({e}) {}
-  explicit History(EventSet event_set) : events_(std::move(event_set)) {}
+  explicit History(EventSet event_set = EventSet()) : events_(std::move(event_set)) {}
+
+  auto begin() const { return Iterator(events_); }
+  auto end() const { return Iterator(EventSet()); }
 
   /**
    * @brief Whether or not the given event is contained in the history
@@ -80,6 +86,38 @@ public:
    */
   EventSet get_all_events() const;
   EventSet get_event_diff_with(const Configuration& config) const;
+
+private:
+  /**
+   * @brief An iterator which traverses the history of a set of events
+   */
+  struct Iterator {
+  public:
+    Iterator& operator++();
+    auto operator->() { 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) { return this->frontier == other.frontier; }
+    bool operator!=(const Iterator& other) { 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:
+    EventSet frontier;
+    EventSet current_history = EventSet();
+    optional_configuration configuration;
+    friend History;
+  };
 };
 
 } // namespace simgrid::mc::udpor