15#ifndef OR_TOOLS_MATH_OPT_CPP_ID_MAP_H_
16#define OR_TOOLS_MATH_OPT_CPP_ID_MAP_H_
19#include <initializer_list>
25#include "absl/container/flat_hash_map.h"
26#include "absl/container/flat_hash_set.h"
27#include "absl/types/span.h"
53template <
typename K,
typename V>
84 return lhs.storage_iterator_ == rhs.storage_iterator_;
87 return lhs.storage_iterator_ != rhs.storage_iterator_;
94 typename StorageType::iterator storage_iterator);
96 const IdMap* map_ =
nullptr;
97 typename StorageType::iterator storage_iterator_;
118 return lhs.storage_iterator_ == rhs.storage_iterator_;
122 return lhs.storage_iterator_ != rhs.storage_iterator_;
130 typename StorageType::const_iterator storage_iterator);
132 const IdMap* map_ =
nullptr;
133 typename StorageType::const_iterator storage_iterator_;
137 template <
typename InputIt>
138 inline IdMap(InputIt first, InputIt last);
139 inline IdMap(std::initializer_list<value_type> ilist);
152 bool empty()
const {
return map_.empty(); }
157 inline std::pair<iterator, bool>
insert(std::pair<K, V> k_v);
158 template <
typename InputIt>
159 inline void insert(InputIt first, InputIt last);
160 inline void insert(std::initializer_list<value_type> ilist);
162 inline std::pair<iterator, bool>
emplace(
const K& k, V v);
163 template <
typename... Args>
164 inline std::pair<iterator, bool>
try_emplace(
const K& k, Args&&... args);
167 inline int erase(
const K& k);
181 inline const V&
at(
const K& k)
const;
182 inline V&
at(
const K& k);
185 inline bool contains(
const K& k)
const;
188 inline std::pair<iterator, iterator>
equal_range(
const K& k);
189 inline std::pair<const_iterator, const_iterator>
equal_range(
203 inline void Add(
const IdMap& other);
219 inline std::vector<V>
Values(absl::Span<const K> keys)
const;
220 inline absl::flat_hash_map<K, V>
Values(
221 const absl::flat_hash_set<K>& keys)
const;
232 return lhs.model_ == rhs.model_ && lhs.map_ == rhs.map_;
235 return !(lhs == rhs);
239 inline std::vector<IdType> SortedIds()
const;
243 inline void CheckModel(
const K& k)
const;
247 inline void CheckOrSetModel(
const K& k);
251 inline void CheckOrSetModel(
const IdMap& other);
262template <
typename K,
typename V>
275template <
typename K,
typename V>
277 return reference(K(map_->model_, storage_iterator_->first),
278 storage_iterator_->second);
281template <
typename K,
typename V>
287template <
typename K,
typename V>
293template <
typename K,
typename V>
300template <
typename K,
typename V>
302 typename StorageType::iterator storage_iterator)
303 : map_(map), storage_iterator_(
std::move(storage_iterator)) {}
309template <
typename K,
typename V>
311 : map_(non_const_iterator.map_),
312 storage_iterator_(non_const_iterator.storage_iterator_) {}
314template <
typename K,
typename V>
317 return reference(K(map_->model_, storage_iterator_->first),
318 storage_iterator_->second);
321template <
typename K,
typename V>
327template <
typename K,
typename V>
334template <
typename K,
typename V>
342template <
typename K,
typename V>
344 const IdMap* map,
typename StorageType::const_iterator storage_iterator)
345 : map_(map), storage_iterator_(
std::move(storage_iterator)) {}
351template <
typename K,
typename V>
353 : model_(
model), map_(
std::move(values)) {
355 CHECK(model_ !=
nullptr);
359template <
typename K,
typename V>
360template <
typename InputIt>
365template <
typename K,
typename V>
370template <
typename K,
typename V>
375template <
typename K,
typename V>
380template <
typename K,
typename V>
382 return iterator(
this, map_.begin());
385template <
typename K,
typename V>
390template <
typename K,
typename V>
395template <
typename K,
typename V>
400template <
typename K,
typename V>
406template <
typename K,
typename V>
408 std::pair<K, V> k_v) {
409 return emplace(k_v.first, std::move(k_v.second));
412template <
typename K,
typename V>
413template <
typename InputIt>
415 for (InputIt it = first; it != last; ++it) {
420template <
typename K,
typename V>
422 insert(ilist.begin(), ilist.end());
425template <
typename K,
typename V>
429 auto initial_ret = map_.emplace(k.typed_id(), std::move(v));
430 return std::make_pair(
iterator(
this, std::move(initial_ret.first)),
434template <
typename K,
typename V>
435template <
typename... Args>
437 const K& k, Args&&... args) {
440 map_.try_emplace(k.typed_id(), std::forward<Args>(args)...);
441 return std::make_pair(
iterator(
this, std::move(initial_ret.first)),
445template <
typename K,
typename V>
448 const int ret = map_.erase(k.typed_id());
455template <
typename K,
typename V>
457 map_.erase(pos.storage_iterator_);
463template <
typename K,
typename V>
466 auto ret = map_.erase(first.storage_iterator_, last.storage_iterator_);
470 return iterator(
this, std::move(ret));
473template <
typename K,
typename V>
476 swap(model_, other.model_);
477 swap(map_, other.map_);
480template <
typename K,
typename V>
483 return map_.at(k.typed_id());
486template <
typename K,
typename V>
489 return map_.at(k.typed_id());
492template <
typename K,
typename V>
495 return map_[k.typed_id()];
498template <
typename K,
typename V>
501 return map_.count(k.typed_id());
504template <
typename K,
typename V>
507 return map_.contains(k.typed_id());
510template <
typename K,
typename V>
513 return iterator(
this, map_.find(k.typed_id()));
516template <
typename K,
typename V>
522template <
typename K,
typename V>
525 const auto it = find(k);
532template <
typename K,
typename V>
533std::pair<typename IdMap<K, V>::const_iterator,
536 const auto it = find(k);
543template <
typename K,
typename V>
545 CheckOrSetModel(other);
546 for (
const auto& pair : other.map_) {
547 map_[pair.first] += pair.second;
551template <
typename K,
typename V>
553 CheckOrSetModel(other);
554 for (
const auto& pair : other.map_) {
555 map_[pair.first] -= pair.second;
559template <
typename K,
typename V>
561 std::vector<V> result;
562 result.reserve(keys.size());
563 for (
const K key : keys) {
564 result.push_back(at(key));
569template <
typename K,
typename V>
571 const absl::flat_hash_set<K>& keys)
const {
572 absl::flat_hash_map<K, V> result;
573 for (
const K key : keys) {
574 result[key] = at(key);
579template <
typename K,
typename V>
581 std::vector<K> result;
582 result.reserve(map_.size());
583 for (
const IdType id : SortedIds()) {
584 result.push_back(K(model_,
id));
589template <
typename K,
typename V>
591 std::vector<V> result;
592 result.reserve(map_.size());
593 for (
const IdType id : SortedIds()) {
594 result.push_back(map_.at(
id));
599template <
typename K,
typename V>
601 std::vector<IdType> result;
603 for (
const auto& [
id, _] : map_) {
604 result.push_back(
id);
606 std::sort(result.begin(), result.end());
610template <
typename K,
typename V>
611void IdMap<K, V>::CheckModel(
const K& k)
const {
613 CHECK(model_ ==
nullptr || model_ == k.model())
617template <
typename K,
typename V>
618void IdMap<K, V>::CheckOrSetModel(
const K& k) {
620 if (model_ ==
nullptr) {
627template <
typename K,
typename V>
628void IdMap<K, V>::CheckOrSetModel(
const IdMap& other) {
629 if (model_ ==
nullptr) {
630 model_ = other.model_;
631 }
else if (other.model_ !=
nullptr) {
#define CHECK_EQ(val1, val2)
#define DCHECK(condition)
friend bool operator!=(const const_iterator &lhs, const const_iterator &rhs)
IdMap::const_pointer pointer
IdMap::difference_type difference_type
internal::ArrowOperatorProxy< reference > operator->() const
std::forward_iterator_tag iterator_category
friend bool operator==(const const_iterator &lhs, const const_iterator &rhs)
const_iterator & operator++()
IdMap::const_reference reference
IdMap::value_type value_type
reference operator*() const
friend bool operator==(const iterator &lhs, const iterator &rhs)
IdMap::difference_type difference_type
std::forward_iterator_tag iterator_category
IdMap::value_type value_type
friend bool operator!=(const iterator &lhs, const iterator &rhs)
internal::ArrowOperatorProxy< reference > operator->() const
reference operator*() const
IdMap::reference reference
void Subtract(const IdMap &other)
std::pair< iterator, bool > try_emplace(const K &k, Args &&... args)
void reserve(size_type count)
const_iterator begin() const
std::pair< const K, V > value_type
V & operator[](const K &k)
std::vector< K > SortedKeys() const
std::vector< V > SortedValues() const
absl::flat_hash_map< IdType, V > StorageType
std::pair< iterator, bool > emplace(const K &k, V v)
std::pair< const K, const V & > const_reference
IndexedModel * model() const
std::vector< V > Values(absl::Span< const K > keys) const
friend bool operator==(const IdMap &lhs, const IdMap &rhs)
bool contains(const K &k) const
typename StorageType::size_type size_type
const_iterator end() const
std::pair< iterator, bool > insert(std::pair< K, V > k_v)
typename K::IdType IdType
const StorageType & raw_map() const
const_iterator cend() const
size_type count(const K &k) const
const V & at(const K &k) const
const_iterator cbegin() const
friend bool operator!=(const IdMap &lhs, const IdMap &rhs)
typename StorageType::difference_type difference_type
std::pair< iterator, iterator > equal_range(const K &k)
void Add(const IdMap &other)
iterator find(const K &k)
std::pair< const K, V & > reference
constexpr absl::string_view kObjectsFromOtherIndexedModel
constexpr absl::string_view kKeyHasNullIndexedModel
void swap(IdMap< K, V > &a, IdMap< K, V > &b)
Collection of objects used to extend the Constraint Solver library.