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 
46  explicit Model(std::string name) : name_(name) {}
47 
72  template <typename T>
73  T Add(std::function<T(Model*)> f) {
74  return f(this);
75  }
76 
78  template <typename T>
79  T Get(std::function<T(const Model&)> f) const {
80  return f(*this);
81  }
82 
97  template <typename T>
98  T* GetOrCreate() {
99  const size_t type_id = gtl::FastTypeId<T>();
100  auto find = singletons_.find(type_id);
101  if (find != singletons_.end()) {
102  return static_cast<T*>(find->second);
103  }
104 
105  // New element.
106  // TODO(user): directly store std::unique_ptr<> in singletons_?
107  T* new_t = MyNew<T>(0);
108  singletons_[type_id] = new_t;
109  TakeOwnership(new_t);
110  return new_t;
111  }
112 
118  template <typename T>
119  const T* Get() const {
120  return static_cast<const T*>(
121  gtl::FindWithDefault(singletons_, gtl::FastTypeId<T>(), nullptr));
122  }
123 
127  template <typename T>
128  T* Mutable() const {
129  return static_cast<T*>(
130  gtl::FindWithDefault(singletons_, gtl::FastTypeId<T>(), nullptr));
131  }
132 
138  template <typename T>
139  void TakeOwnership(T* t) {
140  cleanup_list_.emplace_back(new Delete<T>(t));
141  }
142 
148  template <typename T>
149  T* Create() {
150  T* new_t = MyNew<T>(0);
151  TakeOwnership(new_t);
152  return new_t;
153  }
154 
160  template <typename T>
161  void Register(T* non_owned_class) {
162  const size_t type_id = gtl::FastTypeId<T>();
163  CHECK(!gtl::ContainsKey(singletons_, type_id));
164  singletons_[type_id] = non_owned_class;
165  }
166 
167  const std::string& Name() const { return name_; }
168 
169  private:
170  // We want to call the constructor T(model*) if it exists or just T() if
171  // it doesn't. For this we use some template "magic":
172  // - The first MyNew() will only be defined if the type in decltype() exist.
173  // - The second MyNew() will always be defined, but because of the ellipsis
174  // it has lower priority that the first one.
175  template <typename T>
176  decltype(T(static_cast<Model*>(nullptr)))* MyNew(int) {
177  return new T(this);
178  }
179  template <typename T>
180  T* MyNew(...) {
181  return new T();
182  }
183 
184  const std::string name_;
185 
186  // Map of FastTypeId<T> to a "singleton" of type T.
187 #if defined(__APPLE__)
188  std::map</*typeid*/ size_t, void*> singletons_;
189 #else
190  absl::flat_hash_map</*typeid*/ size_t, void*> singletons_;
191 #endif
192 
193  struct DeleteInterface {
194  virtual ~DeleteInterface() = default;
195  };
196  template <typename T>
197  class Delete : public DeleteInterface {
198  public:
199  explicit Delete(T* t) : to_delete_(t) {}
200  ~Delete() override = default;
201 
202  private:
203  std::unique_ptr<T> to_delete_;
204  };
205 
206  // The list of items to delete.
207  //
208  // TODO(user): I don't think we need the two layers of unique_ptr, but we
209  // don't care too much about efficiency here and this was easier to get
210  // working.
211  std::vector<std::unique_ptr<DeleteInterface>> cleanup_list_;
212 
213  DISALLOW_COPY_AND_ASSIGN(Model);
214 };
215 
216 } // namespace sat
217 } // namespace operations_research
218 
219 #endif // OR_TOOLS_SAT_MODEL_H_
void TakeOwnership(T *t)
Gives ownership of a pointer to this model.
Definition: model.h:139
T * Create()
This returns a non-singleton object owned by the model and created with the T(Model* model) construct...
Definition: model.h:149
const T * Get() const
Likes GetOrCreate() but do not create the object if it is non-existing.
Definition: model.h:119
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:79
T * Mutable() const
Same as Get(), but returns a mutable version of the object.
Definition: model.h:128
void Register(T *non_owned_class)
Register a non-owned class that will be "singleton" in the model.
Definition: model.h:161
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: model.h:46
T * GetOrCreate()
Returns an object of type T that is unique to this model (like a "local" singleton).
Definition: model.h:98
const std::string & Name() const
Definition: model.h:167
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:73