Google OR-Tools v9.14
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
derived_data.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_DERIVED_DATA_H_
15#define OR_TOOLS_MATH_OPT_ELEMENTAL_DERIVED_DATA_H_
16
17#include <array>
18#include <string>
19#include <tuple>
20#include <type_traits>
21
22#include "absl/log/log.h"
23#include "absl/strings/str_cat.h"
29
31
32// A helper to manipulate the list of attributes.
33struct AllAttrs {
34 // The number of available attribute types.
35 static constexpr int kNumAttrTypes =
36 std::tuple_size_v<AllAttrTypeDescriptors>;
37
38 // Returns the descriptor of the `i-th` attribute type in the list.
39 template <int i>
40 using TypeDescriptor = std::tuple_element_t<i, AllAttrTypeDescriptors>;
41
42 // Returns the `i-th` attribute type in the list.
43 template <int i>
45
46 // Returns the index of attribute type `AttrT`.
47 // Fails to compile if `AttrT` is not an attribute.
48 template <typename AttrT>
49 static constexpr int GetIndex() {
50 constexpr int index = GetIndexIfAttr<AttrT>();
51 // This weird construct is to show `AttrT` explicitly instead of letting
52 // the user fish it out of the stack trace when the static_assert fails.
53 static_assert(
54 std::is_const_v<std::conditional_t<(index >= 0), const AttrT, AttrT>>,
55 "no such attribute");
56 return index;
57 }
58
59 // Applies `fn` on each value for each attribute type. `fn` must have a
60 // overload set of `operator(AttrType)` that accepts a `AttrType` for
61 // each attribute type.
62 template <typename Fn>
63 static void ForEachAttr(Fn&& fn) {
64 ForEach(
65 [&fn](const auto& descriptor) {
66 for (auto attr : descriptor.Enumerate()) {
67 fn(attr);
68 }
69 },
71 }
72};
73
74// Returns the descriptor for attribute `AttrT`.
75template <typename AttrT>
78
79// Returns the default value for the attribute type `attr`.
80//
81// For example GetAttrDefaultValue<DoubleAttr2::kLinConCoef>() returns 0.0.
82template <auto attr>
83constexpr typename AttrTypeDescriptorT<decltype(attr)>::ValueType
85 return AttrTypeDescriptorT<decltype(attr)>::kAttrDescriptors[static_cast<int>(
86 attr)]
87 .default_value;
88}
89
90// Returns the number of elements in a key for the attribute type `AttrType`.
91//
92// For example `GetAttrKeySize<DoubleAttr2>()` returns 2.
93template <typename AttrType>
97template <auto attr>
98constexpr int GetAttrKeySize() {
100}
101
102// The type of the `AttrKey` for attribute type `AttrType`.
103template <typename AttrType>
106
107// The value type for attribute type `AttrType`.
108template <typename AttrType>
110
111// Returns the array of elements for the key for the attribute type `attr`.
112//
113// For example, GetElementTypes<DoubleAttr2>() returns the array
114// {ElementType::kLinearConstraint, ElementType::kVariable}.
115template <typename AttrType>
116constexpr std::array<ElementType, GetAttrKeySize<AttrType>()> GetElementTypes(
117 const AttrType attr) {
118 return AttrTypeDescriptorT<AttrType>::kAttrDescriptors[static_cast<int>(attr)]
119 .key_types;
120}
121template <auto attr>
122constexpr std::array<ElementType, GetAttrKeySize<attr>()> GetElementTypes() {
123 return GetElementTypes(attr);
124}
125
126// After C++20, this can be replaced by a lambda. C++17 does not allow lambdas
127// in unevaluated contexts.
128template <template <int i> typename ValueType>
130 template <int... i>
131 auto operator()() const {
132 return std::make_tuple(ValueType<i>()...);
133 }
134};
135
136// A tuple of `ValueType<i>` for `i` in `0..n`.
137template <int n, template <int i> typename ValueType>
140
141// A map of attribute to `ValueType<i>`, where `i` is the index of the attribute
142// type.
143// See `AttrMapTest` for example usage.
144// NOTE: this is formally a map (it maps attributes to values), but internally
145// uses dense storage.
146template <template <int i> typename ValueType>
147class AttrMap {
148 public:
149 template <typename AttrT>
150 ValueType<AllAttrs::GetIndex<AttrT>()>& operator[](AttrT a) {
151 // TODO(b/365997645): post C++ 23, prefer `std::to_underlying(a)`.
152 return std::get<AllAttrs::GetIndex<AttrT>()>(
153 array_tuple_)[static_cast<int>(a)];
154 }
155
156 template <typename AttrT>
157 const ValueType<AllAttrs::GetIndex<AttrT>()>& operator[](AttrT a) const {
158 // The `const_cast` is fine because non-const `operator[]` does not mutate
159 // anything and we're casting the return type back to const.
160 return (*const_cast<AttrMap*>(this))[a];
161 }
162
163 // Applies `fn` on each value for each attribute type. `fn` must have a
164 // overload set of `operator()` that accepts a `ValueType<i>` for `i` in
165 // `0..AllAttrs::kSize`.
166 // This cannot be an iterator because value types are not homogeneous.
167 template <typename Fn>
168 void ForEachAttrValue(Fn&& fn) {
169 ForEach(
170 [&fn](auto& array) {
171 for (auto& value : array) {
172 fn(value);
173 }
174 },
175 array_tuple_);
176 }
177
178 private:
179 template <int i>
180 using ArrayType =
181 std::array<ValueType<i>, AllAttrs::TypeDescriptor<i>::NumAttrs()>;
183};
184
185// Calls `fn<attr>()`.
186template <typename AttrType, typename Fn, int n = 0>
187decltype(auto) CallForAttr(AttrType attr, Fn&& fn) {
188 using Descriptor = AttrTypeDescriptorT<AttrType>;
189 if constexpr (n < Descriptor::NumAttrs()) {
190 constexpr AttrType a = static_cast<AttrType>(n);
191 if (a == attr) {
192 return fn.template operator()<a>();
193 }
194 return CallForAttr<AttrType, Fn, n + 1>(attr, std::forward<Fn>(fn));
195 } else {
196 LOG(FATAL) << "impossible";
197 return decltype(fn.template operator()<AttrType{}>()) {};
198 }
199}
200
201template <typename ValueType>
202std::string FormatAttrValue(const ValueType v) {
203 return absl::StrCat(v);
204}
205
206template <>
207inline std::string FormatAttrValue(const double v) {
209}
210
211template <>
212inline std::string FormatAttrValue(const bool v) {
213 return v ? "true" : "false";
214}
215
216} // namespace operations_research::math_opt
217
218#endif // OR_TOOLS_MATH_OPT_ELEMENTAL_DERIVED_DATA_H_
static std::string ToString(double value)
ValueType< AllAttrs::GetIndex< AttrT >()> & operator[](AttrT a)
const ValueType< AllAttrs::GetIndex< AttrT >()> & operator[](AttrT a) const
An object oriented wrapper for quadratic constraints in ModelStorage.
Definition gurobi_isv.cc:28
constexpr decltype(auto) ApplyOnIndexRange(Fn &&fn)
Definition arrays.h:38
AttrKey< AttrTypeDescriptorT< AttrType >::kNumKeyElements, typename AttrTypeDescriptorT< AttrType >::Symmetry > AttrKeyFor
The type of the AttrKey for attribute type AttrType.
decltype(auto) CallForAttr(AttrType attr, Fn &&fn)
Calls fn<attr>().
constexpr std::array< ElementType, GetAttrKeySize< attr >()> GetElementTypes()
std::tuple< BoolAttr0TypeDescriptor, BoolAttr1TypeDescriptor, IntAttr0TypeDescriptor, IntAttr1TypeDescriptor, DoubleAttr0TypeDescriptor, DoubleAttr1TypeDescriptor, DoubleAttr2TypeDescriptor, SymmetricDoubleAttr2TypeDescriptor, SymmetricDoubleAttr3TypeDescriptor, VariableAttr1TypeDescriptor > AllAttrTypeDescriptors
Definition attributes.h:291
constexpr decltype(auto) ForEach(Fn &&fn, Tuple &&tuple)
Definition arrays.h:65
constexpr AttrTypeDescriptorT< decltype(attr)>::ValueType GetAttrDefaultValue()
AllAttrs::TypeDescriptor< AllAttrs::GetIndex< AttrT >()> AttrTypeDescriptorT
Returns the descriptor for attribute AttrT.
typename AttrTypeDescriptorT< AttrType >::ValueType ValueTypeFor
The value type for attribute type AttrType.
static constexpr int GetIndexIfAttr()
Definition attributes.h:313
std::string FormatAttrValue(const ValueType v)
decltype(ApplyOnIndexRange< n >(EnumeratedTupleCpp17Helper< ValueType >{})) EnumeratedTuple
A tuple of ValueType<i> for i in 0..n.
A helper to manipulate the list of attributes.
std::tuple_element_t< i, AllAttrTypeDescriptors > TypeDescriptor
Returns the descriptor of the i-th attribute type in the list.
static constexpr int kNumAttrTypes
The number of available attribute types.
typename TypeDescriptor< i >::AttrType Type
Returns the i-th attribute type in the list.