Google OR-Tools v9.14
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
elements.h
Go to the documentation of this file.
1// Copyright 2010-2025 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#ifndef OR_TOOLS_MATH_OPT_ELEMENTAL_ELEMENTS_H_
15#define OR_TOOLS_MATH_OPT_ELEMENTAL_ELEMENTS_H_
16
17#include <cstddef>
18#include <cstdint>
19#include <iterator>
20#include <ostream>
21#include <string>
22#include <type_traits>
23#include <utility>
24#include <vector>
25
26#include "absl/base/attributes.h"
27#include "absl/log/check.h"
28#include "absl/strings/str_format.h"
29#include "absl/strings/string_view.h"
30#include "ortools/base/array.h"
31
33
41constexpr auto kElements = gtl::to_array(
45constexpr int kNumElements = static_cast<int>(kElements.size());
46constexpr absl::string_view kElementNames[kNumElements] = {
47 "variable", "linear_constraint", "auxiliary_objective",
48 "quadratic_constraint", "indicator_constraint"};
49// Short names, typically to fit more things on a screen when debugging. Not
50// part of the API, can be changed if needed.
51constexpr absl::string_view kShortElementNames[kNumElements] = {
52 "var", "lin_con", "aux_obj", "quad_con", "indic_con"};
53
54absl::string_view ToString(ElementType element_type);
55std::ostream& operator<<(std::ostream& ostr, ElementType element_type);
56
57template <typename Sink>
58void AbslStringify(Sink& sink, ElementType element_type) {
59 sink.Append(ToString(element_type));
60}
61
62// A strongly typed element id. Value type.
63template <ElementType element_type>
64class ElementId final {
65 public:
66 // Constructs an invalid element id.
67 constexpr ElementId() : id_(-1) {}
68
69 // Constructs a valid element id. `DCHECK`s that id is non-negative.
70 constexpr explicit ElementId(int64_t id) : id_(id) {
71 CHECK_GE(id, 0) << "negative " << element_type << " id: " << id;
72 }
73
74 constexpr bool IsValid() const { return id_ >= 0; }
75
76 // Returns the raw id value.
77 int64_t value() const { return id_; }
78
79 static constexpr ElementType type() { return element_type; }
80
81 friend bool operator==(const ElementId& lhs, const ElementId& rhs) {
82 return lhs.id_ == rhs.id_;
83 }
84
85 friend bool operator!=(const ElementId& lhs, const ElementId& rhs) {
86 return lhs.id_ != rhs.id_;
87 }
88
89 friend bool operator<(const ElementId& lhs, const ElementId& rhs) {
90 return lhs.id_ < rhs.id_;
91 }
92
93 friend bool operator<=(const ElementId& lhs, const ElementId& rhs) {
94 return lhs.id_ <= rhs.id_;
95 }
96
97 friend bool operator>(const ElementId& lhs, const ElementId& rhs) {
98 return lhs.id_ > rhs.id_;
99 }
100
101 friend bool operator>=(const ElementId& lhs, const ElementId& rhs) {
102 return lhs.id_ >= rhs.id_;
103 }
104
105 // We don't support addition between `ElementId`s: what does it mean to add
106 // indices ? We do support getting the next element id though.
107 ElementId Next() const {
108 DCHECK(IsValid());
109 return ElementId(id_ + 1);
110 }
111
112 // `MakeStrongIntRange()` relies on `operator++` being present. Prefer the
113 // more explicit `Next()` in general.
115 DCHECK(IsValid());
116 ++id_;
117 return *this;
118 }
119
120 template <typename H>
121 friend H AbslHashValue(H h, const ElementId& a) {
122 return H::combine(std::move(h), a.id_);
123 }
124
125 using ValueType = int64_t; // Support for `StrongVector<ElementId>`.
126
127 private:
128 int64_t id_;
129};
130
131template <ElementType element_type>
132std::string ToString(const ElementId<element_type>& id) {
133 if (id.IsValid()) {
134 return absl::StrFormat("%s{%i}", ToString(id.type()), id.value());
135 } else {
136 return absl::StrFormat("%s{invalid}", ToString(id.type()));
137 }
138}
139
140template <ElementType element_type>
141std::ostream& operator<<(std::ostream& ostr,
142 const ElementId<element_type>& id) {
143 ostr << ToString(id);
144 return ostr;
145}
146
147template <typename Sink, ElementType element_type>
148void AbslStringify(Sink& sink, const ElementId<element_type>& id) {
149 sink.Append(ToString(id));
150}
151
152// An adaptor to expose a sequential container of `int64_t` as strongly typed
153// element ids.
154// Does not own the container.
155template <ElementType element_type, typename Container>
157 public:
159
161 const Container* container ABSL_ATTRIBUTE_LIFETIME_BOUND)
162 : container_(*container) {}
163
164 size_t size() const { return container_.size(); }
165 bool empty() const { return container_.empty(); }
166
168 return ElementId<element_type>(container_[i]);
169 }
170
171 auto begin() const { return Iterator(container_.begin()); }
172 auto end() const { return Iterator(container_.end()); }
173
174 private:
175 class Iterator final {
176 public:
177 using difference_type = std::ptrdiff_t;
179
180 Iterator() = default;
181 explicit Iterator(typename Container::const_iterator it) : it_(it) {}
182
183 value_type operator*() const { return value_type(*it_); }
184
185 Iterator& operator++() {
186 ++it_;
187 return *this;
188 }
189
190 Iterator operator++(int) {
191 auto tmp = *this;
192 ++*this;
193 return tmp;
194 }
195
196 friend bool operator==(const Iterator& lhs, const Iterator& rhs) {
197 return lhs.it_ == rhs.it_;
198 }
199 friend bool operator!=(const Iterator& lhs, const Iterator& rhs) {
200 return lhs.it_ != rhs.it_;
201 }
202
203 private:
204 typename Container::const_iterator it_ = {};
205 };
206#if __cplusplus >= 202002L
207 static_assert(std::forward_iterator<Iterator>);
208#endif
209
210 const Container& container_;
211};
212
213// A container that exposes a container of `int64_t` as strongly typed element
214// ids.
215template <ElementType element_type>
216class ElementIdsVector final {
217 public:
218 using Container = std::vector<int64_t>;
220 using value_type = typename View::value_type;
221
223 : container_(std::move(container)) {}
224
225 // This is move-constructible only.
227
228 View view() const { return View(&container_); }
229
230 size_t size() const { return container_.size(); }
231 bool empty() const { return container_.empty(); }
232
234 return ElementId<element_type>(container_[i]);
235 }
236
237 auto begin() const { return view().begin(); }
238 auto end() const { return view().end(); }
239
243
244 // Provides access to the untyped container.
245 Container& container() { return container_; }
246
247 private:
248 Container container_;
249};
250
251template <ElementType element_type>
253
254// Traits to detect whether `T` is an `ElementId`.
255template <typename T>
256struct is_element_id : public std::false_type {};
257
258template <ElementType element_type>
259struct is_element_id<ElementId<element_type>> : public std::true_type {};
260
261template <typename T>
262static constexpr inline bool is_element_id_v = is_element_id<T>::value;
263
269
270} // namespace operations_research::math_opt
271
272#endif // OR_TOOLS_MATH_OPT_ELEMENTAL_ELEMENTS_H_
A strongly typed element id. Value type.
Definition elements.h:64
friend bool operator>(const ElementId &lhs, const ElementId &rhs)
Definition elements.h:97
friend H AbslHashValue(H h, const ElementId &a)
Definition elements.h:121
static constexpr ElementType type()
Definition elements.h:79
friend bool operator<(const ElementId &lhs, const ElementId &rhs)
Definition elements.h:89
friend bool operator<=(const ElementId &lhs, const ElementId &rhs)
Definition elements.h:93
constexpr ElementId()
Constructs an invalid element id.
Definition elements.h:67
int64_t value() const
Returns the raw id value.
Definition elements.h:77
friend bool operator==(const ElementId &lhs, const ElementId &rhs)
Definition elements.h:81
constexpr ElementId(int64_t id)
Constructs a valid element id. DCHECKs that id is non-negative.
Definition elements.h:70
friend bool operator>=(const ElementId &lhs, const ElementId &rhs)
Definition elements.h:101
friend bool operator!=(const ElementId &lhs, const ElementId &rhs)
Definition elements.h:85
ElementId< element_type > operator[](size_t i) const
Definition elements.h:167
ElementIdsConstView(const Container *container ABSL_ATTRIBUTE_LIFETIME_BOUND)
Definition elements.h:160
Container & container()
Provides access to the untyped container.
Definition elements.h:245
ElementIdsVector & operator=(const ElementIdsVector &container)=delete
ElementIdsVector(const ElementIdsVector &container)=delete
ElementId< element_type > operator[](size_t i) const
Definition elements.h:233
ElementIdsConstView< element_type, Container > View
Definition elements.h:219
ElementIdsVector & operator=(ElementIdsVector &&container)=delete
ElementIdsVector(ElementIdsVector &&) noexcept=default
This is move-constructible only.
constexpr std::array< std::remove_cv_t< T >, N > to_array(T(&ts)[N])
Definition array.h:40
An object oriented wrapper for quadratic constraints in ModelStorage.
Definition gurobi_isv.cc:28
When the underlying default is used When the feature cannot be turned kOff will return an error If the feature is enabled by default
Definition parameters.h:180
ElementId< ElementType::kAuxiliaryObjective > AuxiliaryObjectiveId
Definition elements.h:266
static constexpr bool is_element_id_v
Definition elements.h:262
constexpr absl::string_view kShortElementNames[kNumElements]
Definition elements.h:51
ElementId< ElementType::kVariable > VariableId
Definition elements.h:264
typename ElementIdsVector< element_type >::View ElementIdsSpan
Definition elements.h:252
ElementId< ElementType::kQuadraticConstraint > QuadraticConstraintId
Definition elements.h:267
void AbslStringify(Sink &sink, const AttrT attr_type)
Definition attributes.h:336
std::ostream & operator<<(std::ostream &ostr, const SecondOrderConeConstraint &constraint)
ElementId< ElementType::kLinearConstraint > LinearConstraintId
Definition elements.h:265
absl::string_view ToString(const AttrT attr)
Definition attributes.h:327
constexpr absl::string_view kElementNames[kNumElements]
Definition elements.h:46
ElementId< ElementType::kIndicatorConstraint > IndicatorConstraintId
Definition elements.h:268
LinearExpr operator*(LinearExpr lhs, double rhs)
STL namespace.
Traits to detect whether T is an ElementId.
Definition elements.h:256