Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
model.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#ifndef OR_TOOLS_SAT_MODEL_H_
15#define OR_TOOLS_SAT_MODEL_H_
16
17#include <cstddef>
18#include <cstdio>
19#include <ctime>
20#include <functional>
21#include <map>
22#include <memory>
23#include <new>
24#include <string>
25#include <vector>
26
27#include "absl/container/flat_hash_map.h"
28#include "absl/log/check.h"
29#include "absl/meta/type_traits.h"
31#include "ortools/base/typeid.h"
32
33namespace operations_research {
34namespace sat {
35
42class Model {
43 public:
44 Model() = default;
45
47 // The order of deletion seems to be platform dependent.
48 // We force a reverse order on the cleanup vector.
49 for (int i = cleanup_list_.size() - 1; i >= 0; --i) {
50 cleanup_list_[i].reset();
51 }
52 }
53
58 explicit Model(std::string name) : name_(name) {}
59
60 // This type is neither copyable nor movable.
61 Model(const Model&) = delete;
62 Model& operator=(const Model&) = delete;
63
88 template <typename T>
89 T Add(std::function<T(Model*)> f) {
90 return f(this);
91 }
92
94 template <typename T>
95 T Get(std::function<T(const Model&)> f) const {
96 return f(*this);
97 }
98
113 template <typename T>
115 const size_t type_id = gtl::FastTypeId<T>();
116 auto find = singletons_.find(type_id);
117 if (find != singletons_.end()) {
118 return static_cast<T*>(find->second);
119 }
120
121 // New element.
122 // TODO(user): directly store std::unique_ptr<> in singletons_?
123 T* new_t = MyNew<T>(0);
124 singletons_[type_id] = new_t;
125 TakeOwnership(new_t);
126 return new_t;
127 }
128
134 template <typename T>
135 const T* Get() const {
136 const auto& it = singletons_.find(gtl::FastTypeId<T>());
137 return it != singletons_.end() ? static_cast<const T*>(it->second)
138 : nullptr;
139 }
140
144 template <typename T>
145 T* Mutable() const {
146 const auto& it = singletons_.find(gtl::FastTypeId<T>());
147 return it != singletons_.end() ? static_cast<T*>(it->second) : nullptr;
148 }
149
155 template <typename T>
156 T* TakeOwnership(T* t) {
157 cleanup_list_.emplace_back(new Delete<T>(t));
158 return t;
159 }
160
166 template <typename T>
167 T* Create() {
168 T* new_t = MyNew<T>(0);
169 TakeOwnership(new_t);
170 return new_t;
171 }
172
178 template <typename T>
179 void Register(T* non_owned_class) {
180 const size_t type_id = gtl::FastTypeId<T>();
181 CHECK(!singletons_.contains(type_id));
182 singletons_[type_id] = non_owned_class;
183 }
184
185 const std::string& Name() const { return name_; }
186
187 private:
188 // We want to call the constructor T(model*) if it exists or just T() if
189 // it doesn't. For this we use some template "magic":
190 // - The first MyNew() will only be defined if the type in decltype() exist.
191 // - The second MyNew() will always be defined, but because of the ellipsis
192 // it has lower priority that the first one.
193 template <typename T>
194 decltype(T(static_cast<Model*>(nullptr)))* MyNew(int) {
195 return new T(this);
196 }
197 template <typename T>
198 T* MyNew(...) {
199 return new T();
200 }
201
202 const std::string name_;
203
204 // Map of FastTypeId<T> to a "singleton" of type T.
205 absl::flat_hash_map</*typeid*/ size_t, void*> singletons_;
206
207 struct DeleteInterface {
208 virtual ~DeleteInterface() = default;
209 };
210 template <typename T>
211 class Delete : public DeleteInterface {
212 public:
213 explicit Delete(T* t) : to_delete_(t) {}
214 ~Delete() override = default;
215
216 private:
217 std::unique_ptr<T> to_delete_;
218 };
219
220 // The list of items to delete.
221 //
222 // TODO(user): I don't think we need the two layers of unique_ptr, but we
223 // don't care too much about efficiency here and this was easier to get
224 // working.
225 std::vector<std::unique_ptr<DeleteInterface>> cleanup_list_;
226};
227
228} // namespace sat
229} // namespace operations_research
230
231#endif // OR_TOOLS_SAT_MODEL_H_
T Add(std::function< T(Model *)> f)
Definition model.h:89
T Get(std::function< T(const Model &)> f) const
Similar to Add() but this is const.
Definition model.h:95
Model(std::string name)
Definition model.h:58
const std::string & Name() const
Definition model.h:185
Model(const Model &)=delete
This type is neither copyable nor movable.
void Register(T *non_owned_class)
Definition model.h:179
Model & operator=(const Model &)=delete
const T * Get() const
Definition model.h:135
const std::string name
A name for logging purposes.
absl::Status Delete(absl::string_view path, Options options)
Definition file.cc:371
size_t FastTypeId()
Definition typeid.h:19
In SWIG mode, we don't want anything besides these top-level includes.