OR-Tools  8.2
lazy_mutable_copy.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_UTIL_LAZY_MUTABLE_COPY_H_
15 #define OR_TOOLS_UTIL_LAZY_MUTABLE_COPY_H_
16 
17 #include <memory>
18 
19 #include "absl/memory/memory.h"
20 
21 namespace operations_research {
22 
23 // LazyMutableCopy<T> is a helper class for making an on-demand copy of an
24 // object of arbitrary type T. Type T must have a copy constructor.
25 //
26 // Sample usage:
27 // const Proto& original_input = ...;
28 // LazyMutableCopy<Proto> input(original_input);
29 // if (input.get().foo() == BAD_VALUE) {
30 // input.get_mutable()->set_foo(GOOD_VALUE); // Copies the object.
31 // }
32 // // Process "input" here without worrying about BAD_VALUE.
33 // A good pattern is to have function taking LazyMutableCopy<> as argument:
34 // void ProcessProto(LazyMutableCopy<Proto> input) { // pass by copy
35 // ...
36 // }
37 // At the call site: ProcessProto({const_ref_to_my_proto});
38 //
39 // In basic usage, a LazyMutableCopy is in one of two states:
40 // - original: points to the const original. No memory allocated.
41 // - copy: points to a mutable copy of the original and owns it. Owning the
42 // copy means that the destructor will delete it, like std::unique_ptr<>.
43 // This is what you get by calling get_mutable().
44 template <class T>
46  public:
47  // You always construct a LazyMutableCopy with a const reference to an object,
48  // which must outlive this class (unless get_mutable() was called).
49  LazyMutableCopy(const T& obj) // NOLINT(google-explicit-constructor)
50  : original_(&obj) {}
51 
52  // You can move a LazyMutableCopy, much like a std::unique_ptr<> or a const*.
53  // We simply rely on the default move constructors being available.
54 
55  const T& get() const { return copy_ != nullptr ? *copy_ : *original_; }
56  T* get_mutable() {
57  if (copy_ == nullptr) {
58  copy_ = absl::make_unique<T>(*original_);
59  original_ = nullptr;
60  }
61  return copy_.get();
62  }
63 
64  // True iff get_mutable() was called at least once (in which case the object
65  // was copied).
66  bool was_copied() const { return copy_ != nullptr; }
67 
68  private:
69  const T* original_;
70  std::unique_ptr<T> copy_;
71 };
72 
73 } // namespace operations_research
74 
75 #endif // OR_TOOLS_UTIL_LAZY_MUTABLE_COPY_H_
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...