Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
key_types.h
Go to the documentation of this file.
1// Copyright 2010-2024 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14// IWYU pragma: private, include "ortools/math_opt/cpp/math_opt.h"
15// IWYU pragma: friend "ortools/math_opt/cpp/.*"
16
17// This header defines the common properties of "key types" and some related
18// constants.
19//
20// Key types are types that are used as identifiers in the C++ interface where
21// the ModelStorage is using typed integers. They are pairs of (storage,
22// typed_index) where `storage` is a pointer on an ModelStorage and
23// `typed_index` is the typed integer type used in ModelStorage (or a pair of
24// typed integers for QuadraticTermKey).
25//
26// A key type K must match the following requirements:
27// - K::IdType is a value type used for indices.
28// - K has a constructor K(const ModelStorage*, K::IdType).
29// - K is a value-semantic type.
30// - K has a function with signature `K::IdType K::typed_id() const`.
31// - K has a function with signature `const ModelStorage* K::storage() const`.
32// It must return a non-null pointer.
33// - K::IdType is a valid key for absl::flat_hash_map or absl::flat_hash_set
34// (supports hash and ==).
35// - the is_key_type_v<> below should include them.
36#ifndef OR_TOOLS_MATH_OPT_CPP_KEY_TYPES_H_
37#define OR_TOOLS_MATH_OPT_CPP_KEY_TYPES_H_
38
39#include <type_traits>
40#include <vector>
41
42#include "absl/algorithm/container.h"
43#include "absl/container/flat_hash_map.h"
44#include "absl/status/status.h"
45#include "absl/strings/string_view.h"
46#include "absl/types/span.h"
48
50
51// Forward declarations of types implementing the keys interface defined at the
52// top of this file.
53class Variable;
54class LinearConstraint;
55class QuadraticConstraint;
56class SecondOrderConeConstraint;
57class Sos1Constraint;
58class Sos2Constraint;
59class IndicatorConstraint;
60class QuadraticTermKey;
61class Objective;
62
63// True for types in MathOpt that implements the keys interface defined at the
64// top of this file.
65//
66// This is used in conjunction with std::enable_if_t<> to prevent Argument
67// Dependent Lookup (ADL) from selecting some overload defined in MathOpt
68// because one of the template type is in MathOpt. For example the SortedKeys()
69// function below could be selected as a valid overload in another namespace if
70// the values in the hash map are in the math_opt namespace.
71template <typename T>
72constexpr inline bool is_key_type_v =
73 (std::is_same_v<T, Variable> || std::is_same_v<T, LinearConstraint> ||
74 std::is_same_v<T, QuadraticConstraint> ||
75 std::is_same_v<T, SecondOrderConeConstraint> ||
76 std::is_same_v<T, Sos1Constraint> || std::is_same_v<T, Sos2Constraint> ||
77 std::is_same_v<T, IndicatorConstraint> ||
78 std::is_same_v<T, QuadraticTermKey> || std::is_same_v<T, Objective>);
79
80// Returns the keys of the map sorted by their (storage(), type_id()).
81//
82// Implementation note: here we must use std::enable_if to prevent Argument
83// Dependent Lookup (ADL) from selecting this overload for maps which values are
84// in MathOpt but keys are not.
85template <typename Map,
86 typename = std::enable_if_t<is_key_type_v<typename Map::key_type>>>
87std::vector<typename Map::key_type> SortedKeys(const Map& map) {
88 using K = typename Map::key_type;
89 std::vector<K> result;
90 result.reserve(map.size());
91 for (const typename Map::const_reference item : map) {
92 result.push_back(item.first);
93 }
94 absl::c_sort(result, [](const K& lhs, const K& rhs) {
95 if (lhs.storage() != rhs.storage()) {
96 return lhs.storage() < rhs.storage();
97 }
98 return lhs.typed_id() < rhs.typed_id();
99 });
100 return result;
101}
102
103// Returns the elements of the set sorted by their (storage(), type_id()).
104//
105// Implementation note: here we must use std::enable_if to prevent Argument
106// Dependent Lookup (ADL) from selecting this overload for maps which values are
107// in MathOpt but keys are not.
108template <typename Set,
109 typename = std::enable_if_t<is_key_type_v<typename Set::key_type>>>
110std::vector<typename Set::key_type> SortedElements(const Set& set) {
111 using K = typename Set::key_type;
112 std::vector<K> result;
113 result.reserve(set.size());
114 for (const typename Set::const_reference item : set) {
115 result.push_back(item);
116 }
117 absl::c_sort(result, [](const K& lhs, const K& rhs) {
118 if (lhs.storage() != rhs.storage()) {
119 return lhs.storage() < rhs.storage();
120 }
121 return lhs.typed_id() < rhs.typed_id();
122 });
123 return result;
124}
125
126// Returns the values corresponding to the keys. Keys must be present in the
127// input map.
128//
129// The keys must be in a type convertible to absl::Span<const K>.
130//
131// Implementation note: here we must use std::enable_if to prevent Argument
132// Dependent Lookup (ADL) from selecting this overload for maps which values are
133// in MathOpt but keys are not.
134template <typename Map, typename Keys,
135 typename = std::enable_if_t<is_key_type_v<typename Map::key_type>>>
136std::vector<typename Map::mapped_type> Values(const Map& map,
137 const Keys& keys) {
138 using K = typename Map::key_type;
139 const absl::Span<const K> keys_span = keys;
140 std::vector<typename Map::mapped_type> result;
141 result.reserve(keys_span.size());
142 for (const K& key : keys_span) {
143 result.push_back(map.at(key));
144 }
145 return result;
146}
147
148namespace internal {
149
150// The CHECK message to use when a KeyType::storage() is nullptr.
151inline constexpr absl::string_view kKeyHasNullModelStorage =
152 "The input key has null .storage().";
153
154// The CHECK message to use when two KeyType with different storage() are used
155// in the same collection.
156inline constexpr absl::string_view kObjectsFromOtherModelStorage =
157 "The input objects belongs to another model.";
158
159// The Status message to use when an input KeyType is from an unexpected
160// storage().
161inline constexpr absl::string_view kInputFromInvalidModelStorage =
162 "the input does not belong to the same model";
163
164// Returns a failure when the input pointer is not nullptr and points to a
165// different model storage than expected_storage (which must not be nullptr).
166//
167// Failure message is kInputFromInvalidModelStorage.
168inline absl::Status CheckModelStorage(
169 const ModelStorage* const storage,
170 const ModelStorage* const expected_storage) {
171 if (expected_storage == nullptr) {
172 return absl::InternalError("expected_storage is nullptr");
173 }
174 if (storage != nullptr && storage != expected_storage) {
175 return absl::InvalidArgumentError(internal::kInputFromInvalidModelStorage);
176 }
177 return absl::OkStatus();
178}
179
180} // namespace internal
181} // namespace operations_research::math_opt
182
183#endif // OR_TOOLS_MATH_OPT_CPP_KEY_TYPES_H_
constexpr absl::string_view kKeyHasNullModelStorage
The CHECK message to use when a KeyType::storage() is nullptr.
Definition key_types.h:151
constexpr absl::string_view kInputFromInvalidModelStorage
Definition key_types.h:161
constexpr absl::string_view kObjectsFromOtherModelStorage
Definition key_types.h:156
absl::Status CheckModelStorage(const ModelStorage *const storage, const ModelStorage *const expected_storage)
Definition key_types.h:168
An object oriented wrapper for quadratic constraints in ModelStorage.
Definition gurobi_isv.cc:28
std::vector< typename Set::key_type > SortedElements(const Set &set)
Definition key_types.h:110
std::vector< typename Map::mapped_type > Values(const Map &map, const Keys &keys)
Definition key_types.h:136
constexpr bool is_key_type_v
Definition key_types.h:72
std::vector< typename Map::key_type > SortedKeys(const Map &map)
Definition key_types.h:87