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
21namespace 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().
44template <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_; }
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...