15#ifndef OR_TOOLS_UTIL_REV_H_
16#define OR_TOOLS_UTIL_REV_H_
22#include "absl/container/flat_hash_map.h"
55 int Level()
const {
return end_of_level_.size(); }
63 if (end_of_level_.empty())
return;
64 stack_.push_back({object, *
object});
73 if (*
stamp == stamp_)
return;
80 std::vector<int> end_of_level_;
84 std::vector<std::pair<T*, T>> stack_;
88template <
class IndexType,
class T>
98 if (!end_of_level_.empty()) stack_.push_back({
index, vector_[
index]});
99 return vector_[
index];
102 int size()
const {
return vector_.size(); }
105 CHECK_GE(new_size, vector_.size());
111 int Level()
const {
return end_of_level_.size(); }
115 if (level ==
Level())
return;
116 if (level <
Level()) {
117 const int index = end_of_level_[level];
118 end_of_level_.resize(level);
119 for (
int i = stack_.size() - 1; i >=
index; --i) {
120 vector_[stack_[i].first] = stack_[i].second;
122 stack_.resize(
index);
124 end_of_level_.resize(level, stack_.size());
129 std::vector<int> end_of_level_;
130 std::vector<std::pair<IndexType, T>> stack_;
137 if (level == Level())
return;
139 if (level < Level()) {
140 const int index = end_of_level_[level];
141 end_of_level_.resize(level);
142 for (
int i = stack_.size() - 1; i >=
index; --i) {
143 *stack_[i].first = stack_[i].second;
145 stack_.resize(
index);
147 end_of_level_.resize(level, stack_.size());
170 int Level()
const {
return first_op_index_of_next_level_.size(); }
179 int size()
const {
return map_.size(); }
180 bool empty()
const {
return map_.empty(); }
191 struct UndoOperation {
200 std::vector<UndoOperation> operations_;
201 std::vector<int> first_op_index_of_next_level_;
207 if (level < Level()) {
208 const int backtrack_level = first_op_index_of_next_level_[level];
209 first_op_index_of_next_level_.resize(level);
210 while (operations_.size() > backtrack_level) {
211 const UndoOperation& to_undo = operations_.back();
212 if (to_undo.is_deletion) {
213 map_.erase(to_undo.key);
215 map_.insert({to_undo.key, to_undo.value}).first->second = to_undo.value;
217 operations_.pop_back();
223 first_op_index_of_next_level_.resize(level, operations_.size());
228 const auto iter = map_.find(key);
229 if (iter == map_.end()) LOG(FATAL) <<
"key not present: '" << key <<
"'.";
231 operations_.push_back({
false, key, iter->second});
238 auto insertion_result = map_.insert({key,
value});
240 if (insertion_result.second) {
242 operations_.push_back({
true, key});
245 operations_.push_back({
false, key, insertion_result.first->second});
248 insertion_result.first->second =
value;
252template <
class Key,
class Value>
261 const std::vector<Value>&
Values(Key key)
const;
264 std::vector<Value> empty_values_;
269 absl::flat_hash_map<Key, std::vector<Value>> map_;
272 std::vector<Key> added_keys_;
273 std::vector<int> first_added_key_of_next_level_;
276template <
class Key,
class Value>
279 if (level < first_added_key_of_next_level_.size()) {
280 const int backtrack_level = first_added_key_of_next_level_[level];
281 first_added_key_of_next_level_.resize(level);
282 while (added_keys_.size() > backtrack_level) {
283 auto it = map_.find(added_keys_.back());
284 if (it->second.size() > 1) {
285 it->second.pop_back();
289 added_keys_.pop_back();
295 first_added_key_of_next_level_.resize(level, added_keys_.size());
298template <
class Key,
class Value>
301 const auto it = map_.find(key);
302 if (it != map_.end())
return it->second;
303 return empty_values_;
306template <
class Key,
class Value>
308 if (!first_added_key_of_next_level_.empty()) {
309 added_keys_.push_back(key);
311 map_[key].push_back(
value);
A basic backtrackable multi map that can only grow (except on backtrack).
void SetLevel(int level) final
void Add(Key key, Value value)
Adds a new value at the given key.
const std::vector< Value > & Values(Key key) const
Returns the list of values for a given key (can be empty).
void EraseOrDie(key_type key)
Map::value_type value_type
bool contains(key_type key) const
const_iterator end() const
int size() const
Wrapper to the underlying const map functions.
const mapped_type & at(key_type key) const
const_iterator begin() const
const_iterator find(const key_type &k) const
Map::mapped_type mapped_type
void SetLevel(int level) final
Map::const_iterator const_iterator
void Set(key_type key, mapped_type value)
void SetLevel(int level) final
void SaveStateWithStamp(T *object, int64_t *stamp)
void SaveState(T *object)
A basic reversible vector implementation.
const T & operator[](IndexType index) const
T & MutableRef(IndexType index)
void SetLevel(int level) final
virtual ~ReversibleInterface()
virtual void SetLevel(int level)=0
void resize(size_type new_size)
In SWIG mode, we don't want anything besides these top-level includes.