Drake
reinit_after_move.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <utility>
4 
5 namespace drake {
6 
7 /// Type wrapper that performs value-initialization on the wrapped type, and
8 /// guarantees that when moving from this type that the donor object is reset
9 /// to its value-initialized value.
10 ///
11 /// Background:
12 ///
13 /// For performance reasons, we often like to provide overloaded move functions
14 /// on our types, instead of relying on the copy functions. When doing so, it
15 /// is more robust to rely on the compiler's `= default` implementation using
16 /// member-wise move, instead of writing out the operations manually. In
17 /// general, move functions should reset the donor object of the move to its
18 /// default-constructed (empty) resource state. Inductively, the member
19 /// fields' existing move implementations do this already, except in the case
20 /// of non-class (primitive) members, where the donor object's primitives will
21 /// not be zeroed. By wrapping primitive members fields with this type, they
22 /// are guaranteed to be zeroed on construction and after being moved from.
23 ///
24 /// Example:
25 ///
26 /// <pre>
27 /// class Foo {
28 /// public:
29 /// DRAKE_DEFAULT_COPY_AND_MOVE_AND_ASSIGN(Foo)
30 /// Foo() = default;
31 ///
32 /// private:
33 /// std::vector<int> items_;
34 /// reinit_after_move<int> sum_;
35 /// };
36 /// </pre>
37 ///
38 /// When moving from `Foo`, the donor object will reset to its default state:
39 /// `items_` will be empty and `sum_` will be zero. If `Foo` had not used the
40 /// `reinit_after_move` wrapper, the `sum_` would remain intact (be copied)
41 /// while moving, even though `items_` was cleared.
42 ///
43 /// @tparam T must support CopyConstructible, CopyAssignable, MoveConstructible,
44 /// and MoveAssignable and must not throw exceptions during construction or
45 /// assignment.
46 template <typename T>
48  public:
49  /// Constructs a reinit_after_move<T> with a value-initialized wrapped value.
50  /// See http://en.cppreference.com/w/cpp/language/value_initialization.
52 
53  /// Constructs a reinit_after_move<T> with the given wrapped value. This is
54  /// an implicit conversion, so that reinit_after_move<T> behaves more like
55  /// the unwrapped type.
56  // NOLINTNEXTLINE(runtime/explicit)
57  reinit_after_move(const T& value) : value_(value) {}
58 
59  /// @name Implements CopyConstructible, CopyAssignable, MoveConstructible,
60  /// MoveAssignable.
61  /** @{ */
62  reinit_after_move(const reinit_after_move&) = default;
65  value_ = std::move(other.value_);
66  other.value_ = T{};
67  }
69  if (this != &other) {
70  value_ = std::move(other.value_);
71  other.value_ = T{};
72  }
73  return *this;
74  }
75  /** @} */
76 
77  /// @name Implicit conversion operators to make reinit_after_move<T> to act
78  /// as the wrapped type.
79  /** @{ */
80  operator T&() { return value_; }
81  operator const T&() const { return value_; }
82  /** @} */
83 
84  private:
85  T value_{};
86 };
87 
88 } // namespace drake
Definition: automotive_demo.cc:88
Type wrapper that performs value-initialization on the wrapped type, and guarantees that when moving ...
Definition: reinit_after_move.h:47
int value
Definition: copyable_unique_ptr_test.cc:61
reinit_after_move & operator=(const reinit_after_move &)=default
reinit_after_move(reinit_after_move &&other)
Definition: reinit_after_move.h:64
reinit_after_move & operator=(reinit_after_move &&other)
Definition: reinit_after_move.h:68
reinit_after_move()
Constructs a reinit_after_move<T> with a value-initialized wrapped value.
Definition: reinit_after_move.h:51
reinit_after_move(const T &value)
Constructs a reinit_after_move<T> with the given wrapped value.
Definition: reinit_after_move.h:57