OR-Tools  8.1
sat/model.h
Go to the documentation of this file.
1 // Copyright 2010-2018 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 <functional>
19 #include <map>
20 #include <memory>
21 #include <vector>
22 
23 #include "absl/container/flat_hash_map.h"
24 #include "ortools/base/logging.h"
25 #include "ortools/base/macros.h"
26 #include "ortools/base/map_util.h"
27 #include "ortools/base/typeid.h"
28 
29 namespace operations_research {
30 namespace sat {
31 
38 class Model {
39  public:
40  Model() {}
41 
42  ~Model() {
43  // The order of deletion seems to be platform dependent.
44  // We force a reverse order on the cleanup vector.
45  for (int i = cleanup_list_.size() - 1; i >= 0; --i) {
46  cleanup_list_[i].reset();
47  }
48  }
49 
54  explicit Model(std::string name) : name_(name) {}
55 
80  template <typename T>
81  T Add(std::function<T(Model*)> f) {
82  return f(this);
83  }
84 
86  template <typename T>
87  T Get(std::function<T(const Model&)> f) const {
88  return f(*this);
89  }
90 
105  template <typename T>
106  T* GetOrCreate() {
107  const size_t type_id = gtl::FastTypeId<T>();
108  auto find = singletons_.find(type_id);
109  if (find != singletons_.end()) {
110  return static_cast<T*>(find->second);
111  }
112 
113  // New element.
114  // TODO(user): directly store std::unique_ptr<> in singletons_?
115  T* new_t = MyNew<T>(0);
116  singletons_[type_id] = new_t;
117  TakeOwnership(new_t);
118  return new_t;
119  }
120 
126  template <typename T>
127  const T* Get() const {
128  return static_cast<const T*>(
129  gtl::FindWithDefault(singletons_, gtl::FastTypeId<T>(), nullptr));
130  }
131 
135  template <typename T>
136  T* Mutable() const {
137  return static_cast<T*>(
138  gtl::FindWithDefault(singletons_, gtl::FastTypeId<T>(), nullptr));
139  }
140 
146  template <typename T>
147  void TakeOwnership(T* t) {
148  cleanup_list_.emplace_back(new Delete<T>(t));
149  }
150 
156  template <typename T>
157  T* Create() {
158  T* new_t = MyNew<T>(0);
159  TakeOwnership(new_t);
160  return new_t;
161  }
162 
168  template <typename T>
169  void Register(T* non_owned_class) {
170  const size_t type_id = gtl::FastTypeId<T>();
171  CHECK(!gtl::ContainsKey(singletons_, type_id));
172  singletons_[type_id] = non_owned_class;
173  }
174 
175  const std::string& Name() const { return name_; }
176 
177  private:
178  // We want to call the constructor T(model*) if it exists or just T() if
179  // it doesn't. For this we use some template "magic":
180  // - The first MyNew() will only be defined if the type in decltype() exist.
181  // - The second MyNew() will always be defined, but because of the ellipsis
182  // it has lower priority that the first one.
183  template <typename T>
184  decltype(T(static_cast<Model*>(nullptr)))* MyNew(int) {
185  return new T(this);
186  }
187  template <typename T>
188  T* MyNew(...) {
189  return new T();
190  }
191 
192  const std::string name_;
193 
194  // Map of FastTypeId<T> to a "singleton" of type T.
195  absl::flat_hash_map</*typeid*/ size_t, void*> singletons_;
196 
197  struct DeleteInterface {
198  virtual ~DeleteInterface() = default;
199  };
200  template <typename T>
201  class Delete : public DeleteInterface {
202  public:
203  explicit Delete(T* t) : to_delete_(t) {}
204  ~Delete() override = default;
205 
206  private:
207  std::unique_ptr<T> to_delete_;
208  };
209 
210  // The list of items to delete.
211  //
212  // TODO(user): I don't think we need the two layers of unique_ptr, but we
213  // don't care too much about efficiency here and this was easier to get
214  // working.
215  std::vector<std::unique_ptr<DeleteInterface>> cleanup_list_;
216 
217  DISALLOW_COPY_AND_ASSIGN(Model);
218 };
219 
220 } // namespace sat
221 } // namespace operations_research
222 
223 #endif // OR_TOOLS_SAT_MODEL_H_
map_util.h
operations_research::sat::Model::Get
const T * Get() const
Likes GetOrCreate() but do not create the object if it is non-existing.
Definition: sat/model.h:127
operations_research::sat::Model::Model
Model(std::string name)
When there is more than one model in an application, it makes sense to name them for debugging or log...
Definition: sat/model.h:54
logging.h
macros.h
gtl::FindWithDefault
const Collection::value_type::second_type & FindWithDefault(const Collection &collection, const typename Collection::value_type::first_type &key, const typename Collection::value_type::second_type &value)
Definition: map_util.h:26
operations_research
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
Definition: dense_doubly_linked_list.h:21
operations_research::sat::Model::~Model
~Model()
Definition: sat/model.h:42
typeid.h
operations_research::sat::Model
Class that owns everything related to a particular optimization model.
Definition: sat/model.h:38
operations_research::sat::Model::GetOrCreate
T * GetOrCreate()
Returns an object of type T that is unique to this model (like a "local" singleton).
Definition: sat/model.h:106
operations_research::sat::Model::Create
T * Create()
This returns a non-singleton object owned by the model and created with the T(Model* model) construct...
Definition: sat/model.h:157
operations_research::sat::Model::Mutable
T * Mutable() const
Same as Get(), but returns a mutable version of the object.
Definition: sat/model.h:136
file::Delete
absl::Status Delete(const absl::string_view &path, int flags)
Definition: file.cc:297
operations_research::sat::Model::Model
Model()
Definition: sat/model.h:40
operations_research::sat::Model::TakeOwnership
void TakeOwnership(T *t)
Gives ownership of a pointer to this model.
Definition: sat/model.h:147
operations_research::sat::Model::Name
const std::string & Name() const
Definition: sat/model.h:175
operations_research::sat::Model::Add
T Add(std::function< T(Model *)> f)
This makes it possible to have a nicer API on the client side, and it allows both of these forms:
Definition: sat/model.h:81
CHECK
#define CHECK(condition)
Definition: base/logging.h:495
name
const std::string name
Definition: default_search.cc:808
operations_research::sat::Model::Get
T Get(std::function< T(const Model &)> f) const
Similar to Add() but this is const.
Definition: sat/model.h:87
operations_research::sat::Model::Register
void Register(T *non_owned_class)
Register a non-owned class that will be "singleton" in the model.
Definition: sat/model.h:169
gtl::ContainsKey
bool ContainsKey(const Collection &collection, const Key &key)
Definition: map_util.h:170