C++ Reference

C++ Reference: CP-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 
66  template <typename T>
67  T Add(std::function<T(Model*)> f) {
68  return f(this);
69  }
70 
72  template <typename T>
73  T Get(std::function<T(const Model&)> f) const {
74  return f(*this);
75  }
76 
91  template <typename T>
92  T* GetOrCreate() {
93  const size_t type_id = gtl::FastTypeId<T>();
94  auto find = singletons_.find(type_id);
95  if (find != singletons_.end()) {
96  return static_cast<T*>(find->second);
97  }
98 
99  // New element.
100  // TODO(user): directly store std::unique_ptr<> in singletons_?
101  T* new_t = MyNew<T>(0);
102  singletons_[type_id] = new_t;
103  TakeOwnership(new_t);
104  return new_t;
105  }
106 
112  template <typename T>
113  const T* Get() const {
114  return static_cast<const T*>(
115  gtl::FindWithDefault(singletons_, gtl::FastTypeId<T>(), nullptr));
116  }
117 
121  template <typename T>
122  T* Mutable() const {
123  return static_cast<T*>(
124  gtl::FindWithDefault(singletons_, gtl::FastTypeId<T>(), nullptr));
125  }
126 
132  template <typename T>
133  void TakeOwnership(T* t) {
134  cleanup_list_.emplace_back(new Delete<T>(t));
135  }
136 
142  template <typename T>
143  T* Create() {
144  T* new_t = MyNew<T>(0);
145  TakeOwnership(new_t);
146  return new_t;
147  }
148 
154  template <typename T>
155  void Register(T* non_owned_class) {
156  const size_t type_id = gtl::FastTypeId<T>();
157  CHECK(!gtl::ContainsKey(singletons_, type_id));
158  singletons_[type_id] = non_owned_class;
159  }
160 
161  private:
162  // We want to call the constructor T(model*) if it exists or just T() if
163  // it doesn't. For this we use some template "magic":
164  // - The first MyNew() will only be defined if the type in decltype() exist.
165  // - The second MyNew() will always be defined, but because of the ellipsis
166  // it has lower priority that the first one.
167  template <typename T>
168  decltype(T(static_cast<Model*>(nullptr)))* MyNew(int) {
169  return new T(this);
170  }
171  template <typename T>
172  T* MyNew(...) {
173  return new T();
174  }
175 
176  // Map of FastTypeId<T> to a "singleton" of type T.
177 #if defined(__APPLE__)
178  std::map</*typeid*/ size_t, void*> singletons_;
179 #else
180  absl::flat_hash_map</*typeid*/ size_t, void*> singletons_;
181 #endif
182 
183  struct DeleteInterface {
184  virtual ~DeleteInterface() = default;
185  };
186  template <typename T>
187  class Delete : public DeleteInterface {
188  public:
189  explicit Delete(T* t) : to_delete_(t) {}
190  ~Delete() override = default;
191 
192  private:
193  std::unique_ptr<T> to_delete_;
194  };
195 
196  // The list of items to delete.
197  //
198  // TODO(user): I don't think we need the two layers of unique_ptr, but we
199  // don't care too much about efficiency here and this was easier to get
200  // working.
201  std::vector<std::unique_ptr<DeleteInterface>> cleanup_list_;
202 
203  DISALLOW_COPY_AND_ASSIGN(Model);
204 };
205 
206 } // namespace sat
207 } // namespace operations_research
208 
209 #endif // OR_TOOLS_SAT_MODEL_H_
void TakeOwnership(T *t)
Gives ownership of a pointer to this model.
Definition: model.h:133
T * Create()
This returns a non-singleton object owned by the model and created with the T(Model* model) construct...
Definition: model.h:143
const T * Get() const
Likes GetOrCreate() but do not create the object if it is non-existing.
Definition: model.h:113
Definition: cp_model.h:52
Model()
Definition: model.h:40
Class that owns everything related to a particular optimization model.
Definition: model.h:38
T Get(std::function< T(const Model &)> f) const
Similar to Add() but this is const.
Definition: model.h:73
T * Mutable() const
Same as Get(), but returns a mutable version of the object.
Definition: model.h:122
void Register(T *non_owned_class)
Register a non-owned class that will be "singleton" in the model.
Definition: model.h:155
T * GetOrCreate()
Returns an object of type T that is unique to this model (like a "local" singleton).
Definition: model.h:92
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: model.h:67