15#ifndef OR_TOOLS_MATH_OPT_CPP_ID_MAP_H_
16#define OR_TOOLS_MATH_OPT_CPP_ID_MAP_H_
19#include <initializer_list>
24#include "absl/container/flat_hash_map.h"
25#include "absl/container/flat_hash_set.h"
26#include "absl/types/span.h"
52template <
typename K,
typename V>
83 return lhs.storage_iterator_ == rhs.storage_iterator_;
86 return lhs.storage_iterator_ != rhs.storage_iterator_;
93 typename StorageType::iterator storage_iterator);
95 const IdMap* map_ =
nullptr;
96 typename StorageType::iterator storage_iterator_;
117 return lhs.storage_iterator_ == rhs.storage_iterator_;
121 return lhs.storage_iterator_ != rhs.storage_iterator_;
129 typename StorageType::const_iterator storage_iterator);
131 const IdMap* map_ =
nullptr;
132 typename StorageType::const_iterator storage_iterator_;
136 template <
typename InputIt>
137 inline IdMap(InputIt first, InputIt last);
138 inline IdMap(std::initializer_list<value_type> ilist);
144 inline const_iterator
begin()
const;
147 inline const_iterator
cend()
const;
148 inline const_iterator
end()
const;
151 bool empty()
const {
return map_.empty(); }
156 inline std::pair<iterator, bool>
insert(std::pair<K, V> k_v);
157 template <
typename InputIt>
158 inline void insert(InputIt first, InputIt last);
159 inline void insert(std::initializer_list<value_type> ilist);
161 inline std::pair<iterator, bool>
emplace(
const K& k, V v);
162 template <
typename... Args>
163 inline std::pair<iterator, bool>
try_emplace(
const K& k, Args&&... args);
175 inline void erase(const_iterator pos);
176 inline iterator
erase(const_iterator first, const_iterator last);
180 inline const V&
at(
const K& k)
const;
181 inline V&
at(
const K& k);
185 inline iterator
find(
const K& k);
186 inline const_iterator
find(
const K& k)
const;
218 inline std::vector<V>
Values(absl::Span<const K> keys)
const;
220 const absl::flat_hash_set<K>& keys)
const;
231 return lhs.storage_ == rhs.storage_ && lhs.map_ == rhs.map_;
234 return !(lhs == rhs);
238 inline std::vector<IdType> SortedIds()
const;
242 inline void CheckModel(
const K& k)
const;
246 inline void CheckOrSetModel(
const K& k);
250 inline void CheckOrSetModel(
const IdMap& other);
261template <
typename K,
typename V>
274template <
typename K,
typename V>
276 return reference(K(map_->storage_, storage_iterator_->first),
277 storage_iterator_->second);
280template <
typename K,
typename V>
286template <
typename K,
typename V>
292template <
typename K,
typename V>
299template <
typename K,
typename V>
301 typename StorageType::iterator storage_iterator)
302 : map_(map), storage_iterator_(
std::move(storage_iterator)) {}
308template <
typename K,
typename V>
310 : map_(non_const_iterator.map_),
311 storage_iterator_(non_const_iterator.storage_iterator_) {}
313template <
typename K,
typename V>
316 return reference(K(map_->storage_, storage_iterator_->first),
317 storage_iterator_->second);
320template <
typename K,
typename V>
326template <
typename K,
typename V>
333template <
typename K,
typename V>
341template <
typename K,
typename V>
343 const IdMap* map,
typename StorageType::const_iterator storage_iterator)
344 : map_(map), storage_iterator_(
std::move(storage_iterator)) {}
350template <
typename K,
typename V>
352 : storage_(
storage), map_(
std::move(values)) {
354 CHECK(storage_ !=
nullptr);
358template <
typename K,
typename V>
359template <
typename InputIt>
364template <
typename K,
typename V>
369template <
typename K,
typename V>
374template <
typename K,
typename V>
379template <
typename K,
typename V>
381 return iterator(
this, map_.begin());
384template <
typename K,
typename V>
389template <
typename K,
typename V>
394template <
typename K,
typename V>
399template <
typename K,
typename V>
405template <
typename K,
typename V>
407 std::pair<K, V> k_v) {
408 return emplace(k_v.first, std::move(k_v.second));
411template <
typename K,
typename V>
412template <
typename InputIt>
414 for (InputIt it = first; it != last; ++it) {
419template <
typename K,
typename V>
421 insert(ilist.begin(), ilist.end());
424template <
typename K,
typename V>
428 auto initial_ret = map_.emplace(k.typed_id(), std::move(v));
429 return std::make_pair(
iterator(
this, std::move(initial_ret.first)),
433template <
typename K,
typename V>
434template <
typename... Args>
436 const K& k, Args&&... args) {
439 map_.try_emplace(k.typed_id(), std::forward<Args>(args)...);
440 return std::make_pair(
iterator(
this, std::move(initial_ret.first)),
444template <
typename K,
typename V>
447 const int ret = map_.erase(k.typed_id());
454template <
typename K,
typename V>
456 map_.erase(pos.storage_iterator_);
462template <
typename K,
typename V>
465 auto ret = map_.erase(first.storage_iterator_, last.storage_iterator_);
469 return iterator(
this, std::move(ret));
472template <
typename K,
typename V>
475 swap(storage_, other.storage_);
476 swap(map_, other.map_);
479template <
typename K,
typename V>
482 return map_.at(k.typed_id());
485template <
typename K,
typename V>
488 return map_.at(k.typed_id());
491template <
typename K,
typename V>
494 return map_[k.typed_id()];
497template <
typename K,
typename V>
500 return map_.count(k.typed_id());
503template <
typename K,
typename V>
506 return map_.contains(k.typed_id());
509template <
typename K,
typename V>
512 return iterator(
this, map_.find(k.typed_id()));
515template <
typename K,
typename V>
521template <
typename K,
typename V>
524 const auto it = find(k);
531template <
typename K,
typename V>
532std::pair<typename IdMap<K, V>::const_iterator,
535 const auto it = find(k);
542template <
typename K,
typename V>
544 CheckOrSetModel(other);
545 for (
const auto& pair : other.map_) {
546 map_[pair.first] += pair.second;
550template <
typename K,
typename V>
552 CheckOrSetModel(other);
553 for (
const auto& pair : other.map_) {
554 map_[pair.first] -= pair.second;
558template <
typename K,
typename V>
560 std::vector<V> result;
561 result.reserve(keys.size());
562 for (
const K key : keys) {
563 result.push_back(at(key));
568template <
typename K,
typename V>
570 const absl::flat_hash_set<K>& keys)
const {
571 absl::flat_hash_map<K, V> result;
572 for (
const K key : keys) {
573 result[key] = at(key);
578template <
typename K,
typename V>
580 std::vector<K> result;
581 result.reserve(map_.size());
582 for (
const IdType id : SortedIds()) {
583 result.push_back(K(storage_,
id));
588template <
typename K,
typename V>
590 std::vector<V> result;
591 result.reserve(map_.size());
592 for (
const IdType id : SortedIds()) {
593 result.push_back(map_.at(
id));
598template <
typename K,
typename V>
600 std::vector<IdType> result;
602 for (
const auto& [
id, _] : map_) {
603 result.push_back(
id);
605 std::sort(result.begin(), result.end());
609template <
typename K,
typename V>
610void IdMap<K, V>::CheckModel(
const K& k)
const {
612 CHECK(storage_ ==
nullptr || storage_ == k.storage())
616template <
typename K,
typename V>
617void IdMap<K, V>::CheckOrSetModel(
const K& k) {
619 if (storage_ ==
nullptr) {
620 storage_ = k.storage();
626template <
typename K,
typename V>
627void IdMap<K, V>::CheckOrSetModel(
const IdMap& other) {
628 if (storage_ ==
nullptr) {
629 storage_ = other.storage_;
630 }
else if (other.storage_ !=
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)
IdMap(InputIt first, InputIt last)
void reserve(size_type count)
const_iterator begin() const
std::pair< const K, V > value_type
V & operator[](const K &k)
IdMap(const ModelStorage *storage, StorageType values)
void insert(InputIt first, InputIt last)
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
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
iterator erase(const_iterator first, const_iterator last)
typename StorageType::size_type size_type
const_iterator end() const
std::pair< iterator, bool > insert(std::pair< K, V > k_v)
IdMap(std::initializer_list< value_type > ilist)
std::pair< const_iterator, const_iterator > equal_range(const K &k) const
typename K::IdType IdType
const StorageType & raw_map() const
absl::flat_hash_map< K, V > Values(const absl::flat_hash_set< K > &keys) 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)
void insert(std::initializer_list< value_type > ilist)
const_iterator find(const K &k) const
typename StorageType::difference_type difference_type
void erase(const_iterator pos)
std::pair< iterator, iterator > equal_range(const K &k)
void Add(const IdMap &other)
iterator find(const K &k)
const ModelStorage * storage() const
std::pair< const K, V & > reference
constexpr absl::string_view kKeyHasNullModelStorage
constexpr absl::string_view kObjectsFromOtherModelStorage
void swap(IdMap< K, V > &a, IdMap< K, V > &b)
Collection of objects used to extend the Constraint Solver library.
std::optional< int64_t > end