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 "ortools/base/logging.h"
24 #include "ortools/base/macros.h"
25 #include "ortools/base/map_util.h"
26 #include "ortools/base/typeid.h"
27 
28 namespace operations_research {
29 namespace sat {
30 
37 class Model {
38  public:
39  Model() {}
40 
65  template <typename T>
66  T Add(std::function<T(Model*)> f) {
67  return f(this);
68  }
69 
71  template <typename T>
72  T Get(std::function<T(const Model&)> f) const {
73  return f(*this);
74  }
75 
90  template <typename T>
91  T* GetOrCreate() {
92  const size_t type_id = gtl::FastTypeId<T>();
93  if (!gtl::ContainsKey(singletons_, type_id)) {
94  // TODO(user): directly store std::unique_ptr<> in singletons_?
95  T* new_t = MyNew<T>(0);
96  singletons_[type_id] = new_t;
97  TakeOwnership(new_t);
98  return new_t;
99  }
100  return static_cast<T*>(gtl::FindOrDie(singletons_, type_id));
101  }
102 
108  template <typename T>
109  const T* Get() const {
110  return static_cast<const T*>(
111  gtl::FindWithDefault(singletons_, gtl::FastTypeId<T>(), nullptr));
112  }
113 
117  template <typename T>
118  T* Mutable() const {
119  return static_cast<T*>(
120  gtl::FindWithDefault(singletons_, gtl::FastTypeId<T>(), nullptr));
121  }
122 
128  template <typename T>
129  void TakeOwnership(T* t) {
130  cleanup_list_.emplace_back(new Delete<T>(t));
131  }
132 
138  template <typename T>
139  T* Create() {
140  T* new_t = MyNew<T>(0);
141  TakeOwnership(new_t);
142  return new_t;
143  }
144 
150  template <typename T>
151  void Register(T* non_owned_class) {
152  const size_t type_id = gtl::FastTypeId<T>();
153  CHECK(!gtl::ContainsKey(singletons_, type_id));
154  singletons_[type_id] = non_owned_class;
155  }
156 
157  private:
158  // We want to call the constructor T(model*) if it exists or just T() if
159  // it doesn't. For this we use some template "magic":
160  // - The first MyNew() will only be defined if the type in decltype() exist.
161  // - The second MyNew() will always be defined, but because of the ellipsis
162  // it has lower priority that the first one.
163  template <typename T>
164  decltype(T(static_cast<Model*>(nullptr)))* MyNew(int) {
165  return new T(this);
166  }
167  template <typename T>
168  T* MyNew(...) {
169  return new T();
170  }
171 
172  // Map of FastTypeId<T> to a "singleton" of type T.
173  std::map</*typeid*/ size_t, void*> singletons_;
174 
175  struct DeleteInterface {
176  virtual ~DeleteInterface() = default;
177  };
178  template <typename T>
179  class Delete : public DeleteInterface {
180  public:
181  explicit Delete(T* t) : to_delete_(t) {}
182  ~Delete() override = default;
183 
184  private:
185  std::unique_ptr<T> to_delete_;
186  };
187 
188  // The list of items to delete.
189  //
190  // TODO(user): I don't think we need the two layers of unique_ptr, but we
191  // don't care too much about efficiency here and this was easier to get
192  // working.
193  std::vector<std::unique_ptr<DeleteInterface>> cleanup_list_;
194 
195  DISALLOW_COPY_AND_ASSIGN(Model);
196 };
197 
198 } // namespace sat
199 } // namespace operations_research
200 
201 #endif // OR_TOOLS_SAT_MODEL_H_
void TakeOwnership(T *t)
Gives ownership of a pointer to this model.
Definition: model.h:129
T * Create()
This returns a non-singleton object owned by the model and created with the T(Model* model) construct...
Definition: model.h:139
const T * Get() const
Likes GetOrCreate() but do not create the object if it is non-existing.
Definition: model.h:109
Definition: cp_model.h:52
Model()
Definition: model.h:39
Class that owns everything related to a particular optimization model.
Definition: model.h:37
T Get(std::function< T(const Model &)> f) const
Similar to Add() but this is const.
Definition: model.h:72
T * Mutable() const
Same as Get(), but returns a mutable version of the object.
Definition: model.h:118
void Register(T *non_owned_class)
Register a non-owned class that will be "singleton" in the model.
Definition: model.h:151
T * GetOrCreate()
Returns an object of type T that is unique to this model (like a "local" singleton).
Definition: model.h:91
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:66