Simbody 3.7
ReinitOnCopy.h
Go to the documentation of this file.
1#ifndef SimTK_SimTKCOMMON_REINIT_ON_COPY_H_
2#define SimTK_SimTKCOMMON_REINIT_ON_COPY_H_
3
4/* -------------------------------------------------------------------------- *
5 * Simbody(tm): SimTKcommon *
6 * -------------------------------------------------------------------------- *
7 * This is part of the SimTK biosimulation toolkit originating from *
8 * Simbios, the NIH National Center for Physics-Based Simulation of *
9 * Biological Structures at Stanford, funded under the NIH Roadmap for *
10 * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11 * *
12 * Portions copyright (c) 2015 Stanford University and the Authors. *
13 * Authors: Michael Sherman *
14 * Contributors: *
15 * *
16 * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17 * not use this file except in compliance with the License. You may obtain a *
18 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19 * *
20 * Unless required by applicable law or agreed to in writing, software *
21 * distributed under the License is distributed on an "AS IS" BASIS, *
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23 * See the License for the specific language governing permissions and *
24 * limitations under the License. *
25 * -------------------------------------------------------------------------- */
26
28#include <cassert>
29#include <utility>
30#include <memory>
31#include <cstddef>
32#include <type_traits>
33
34namespace SimTK {
35
36//==============================================================================
37// REINIT ON COPY
38//==============================================================================
39
40// Only show the unspecialized helper class in Doxygen.
41
44template <class T, bool IsScalarType>
46
93template <class T>
94class ReinitOnCopy : public ReinitOnCopyHelper<T, std::is_scalar<T>::value> {
96 // These confuse doxygen.
98 // TODO: should be possible to specialize this for arrays.
99 static_assert(!std::is_array<T>::value,
100 "ReinitOnCopy<T> does not allow T to be an array. Use an array "
101 "of ReinitOnCopy<E> instead, where E is the element type.");
102
103 static_assert( std::is_copy_constructible<T>::value
104 && std::is_copy_assignable<T>::value,
105 "ReinitOnCopy<T> requires type T to have an accessible copy "
106 "constructor and copy assignment operator. Use ResetOnCopy<T> instead "
107 "to reinitialize using only default construction.");
108
109 static_assert(std::is_destructible<T>::value,
110 "ReinitOnCopy<T> requires type T to have an accessible destructor.");
113public:
114 using Super::Super;
115 using Super::operator=;
116
118 ReinitOnCopy() = delete;
119
122 ReinitOnCopy(const T& value) : Super(value) {}
123
127 ReinitOnCopy(T&& value) : Super(std::move(value)) {}
128
133 : Super(static_cast<const Super&>(source)) {}
134
138 : Super(static_cast<Super&&>(source)) {} // default
139
143 { Super::operator=(static_cast<const Super&>(ignored)); return *this; }
144
148 { Super::operator=(static_cast<Super&&>(source)); return *this; }
149
153 ReinitOnCopy& operator=(const T& value)
154 { Super::operator=(value); return *this; }
155
160 { Super::operator=(std::move(value)); return *this; }
161
163 const T& getT() const {return Super::getT();}
164
166 T& updT() {return Super::updT();}
167
169 const T& getReinitT() const {return Super::getReinitT();}
170
173 T& updReinitT() {return Super::updReinitT();}
174};
175
176//==============================================================================
177// REINIT ON COPY HELPERS
178//==============================================================================
179
180 // hide helpers from doxygen
182/* ReinitOnCopy helper class for built-in types (integral or floating point).
183These types are value initialized, so will be reset to zero. */
184template <class T>
185class ReinitOnCopyHelper<T,true> {
186public:
187 // These three are just the defaults but for debugging it is helpful to
188 // have them explicitly present to step into.
189
190 // Default construction (note that members are "value initialized").
191 ReinitOnCopyHelper() {}
192
193 // Copy constructor sets the value and remembered initial value to the
194 // initial value in the source, using type `T`'s copy constructor. The
195 // current value of the source is ignored.
196 ReinitOnCopyHelper(const ReinitOnCopyHelper& source)
197 : ReinitOnCopyHelper(source.m_reinitValue) {}
198
199 // Default move construction.
200 ReinitOnCopyHelper(ReinitOnCopyHelper&& source)
201 : m_value(std::move(source.m_value)),
202 m_reinitValue(std::move(source.m_reinitValue)) {}
203
204 // Constructor from lvalue or rvalue `T` sets the value and remembered
205 // initial value to the given value, using type `T`'s copy constructor.
206 explicit ReinitOnCopyHelper(const T& value)
207 : m_value(value), m_reinitValue(value) {}
208
209 // Move assignment moves the *value* from source to `this` but does not
210 // move the recorded initial value which may differ.
211 ReinitOnCopyHelper& operator=(ReinitOnCopyHelper&& source)
212 { m_value = std::move(source.m_value); return *this; }
213
214 // Copy assignment resets the current value to the remembered initial value
215 // using type `T`'s copy assignment operator. The source is ignored.
216 ReinitOnCopyHelper& operator=(const ReinitOnCopyHelper&)
217 { m_value = m_reinitValue; return *this; }
218
219 // Allow assignment from an lvalue or rvalue object of type T; affects only
220 // the current value. Uses built-in type `T`'s copy assignment operator.
221 ReinitOnCopyHelper& operator=(const T& value)
222 { m_value = value; return *this; }
223
224 // Implicit conversion to a const reference to the contained object of
225 // type `T`.
226 operator const T&() const {return getT();}
227
228 // Implicit conversion to a writable reference to the contained object of
229 // type `T`.
230 operator T&() {return updT();}
231
232 const T& getT() const {return m_value;}
233 T& updT() {return m_value;}
234
235 // Return a const reference to the stored initial value.
236 const T& getReinitT() const {return m_reinitValue;}
237
238 // Return a writable reference to the stored initial value. Use of this
239 // should be restricted to constructors.
240 T& updReinitT() {return m_reinitValue;}
241
242private:
243 T m_value{}; // note "value initialization"; i.e. zero
244 const T m_reinitValue{};
245};
246
247
248/* ReinitOnCopy helper class specialization for any type `T` that is not a
249built-in ("scalar") type and that is `CopyConstructible` and `CopyAssignable`.
250Those operators are used to reinitialize the object to a stored initial value
251when copy constructor or copy assignment is performed. */
252template <class T>
253class ReinitOnCopyHelper<T,false> : public T {
254public:
255 using T::T;
256 using T::operator=;
257
258 // Default construction (T and the stored initial value are default
259 // constructed).
260 ReinitOnCopyHelper() : T(), m_reinitValue() {}
261
262 // Move construction moves both the value and initial value from the
263 // source object. This is the same as default move construction.
264 ReinitOnCopyHelper(ReinitOnCopyHelper&& source)
265 : T(std::move(source)), m_reinitValue(std::move(source.m_reinitValue)) {}
266
267 // Constructor from lvalue `T` sets the value and remembered initial value
268 // to the given value, using type `T`'s copy constructor.
269 explicit ReinitOnCopyHelper(const T& value)
270 : T(value), m_reinitValue(value) {}
271
272 // Constructor from rvalue `T` sets the value and remembered initial value
273 // to the given value, using type `T`'s move and copy constructors.
274 explicit ReinitOnCopyHelper(T&& value)
275 : T(value), m_reinitValue(static_cast<const T&>(*this)) {} // careful!
276
277 // Copy constructor sets the value and remembered initial value to the
278 // initial value in the source, using type `T`'s copy constructor. The
279 // current value of the source is ignored.
280 ReinitOnCopyHelper(const ReinitOnCopyHelper& source)
281 : ReinitOnCopyHelper(source.m_reinitValue) {}
282
283 // Move assignment moves the *value* from source to `this` but does not
284 // move the recorded initial value which may differ.
285 ReinitOnCopyHelper& operator=(ReinitOnCopyHelper&& source)
286 { T::operator=(std::move(source)); return *this; }
287
288 // Copy assignment resets the current value to the remembered initial value
289 // using type `T`'s copy assignment operator. The source is ignored.
290 ReinitOnCopyHelper& operator=(const ReinitOnCopyHelper&)
291 { T::operator=(m_reinitValue); return *this; }
292
293 // Allow assignment from an lvalue object of type T; affects only the
294 // current value. Uses type `T`'s copy assignment operator.
295 ReinitOnCopyHelper& operator=(const T& value)
296 { T::operator=(value); return *this; }
297
298 // Allow assignment from an rvalue object of type T; affects only the
299 // current value. Uses type `T`'s move assignment operator.
300 ReinitOnCopyHelper& operator=(T&& value)
301 { T::operator=(std::move(value)); return *this; }
302
303 const T& getT() const {return static_cast<const T&>(*this);}
304 T& updT() {return static_cast<T&>(*this);}
305
306 // Return a const reference to the stored initial value.
307 const T& getReinitT() const {return m_reinitValue;}
308
309 // Return a writable reference to the stored initial value. Use of this
310 // should be restricted to constructors.
311 T& updReinitT() {return m_reinitValue;}
312
313private:
314 // The remembered initial value is set to the already-constructed
315 // base value in case we used one of the base constructors. This uses
316 // the base class copy constructor.
317 const T m_reinitValue {static_cast<const T&>(*this)};
318};
319
322} // namespace SimTK
323
324#endif // SimTK_SimTKCOMMON_REINIT_ON_COPY_H_
325
Mandatory first inclusion for any Simbody source or header file.
This helper class is used only by ReinitOnCopy and is specialized as necessary to support a variety o...
Definition: ReinitOnCopy.h:45
Ensures that a data member of type T is automatically reinitialized to a given initial value upon cop...
Definition: ReinitOnCopy.h:94
ReinitOnCopy & operator=(const ReinitOnCopy &ignored)
Copy assignment reinitializes this object to its original condition; the source argument is ignored.
Definition: ReinitOnCopy.h:142
ReinitOnCopy()=delete
Default constructor is deleted; use ResetOnCopy instead.
T & updReinitT()
(Advanced) Return a writable reference to the stored initial value. Use of this should be rare and re...
Definition: ReinitOnCopy.h:173
ReinitOnCopy(const ReinitOnCopy &source)
Copy constructor sets the value and remembered initial value to the initial value in the source,...
Definition: ReinitOnCopy.h:132
ReinitOnCopy & operator=(ReinitOnCopy &&source)
Move assignment uses type T's move assignment for the current value but does not change the remembere...
Definition: ReinitOnCopy.h:147
ReinitOnCopy(const T &value)
Construct or implicitly convert from an object of type T. This sets both the current and remembered i...
Definition: ReinitOnCopy.h:122
const T & getT() const
Return a const reference to the contained object of type T.
Definition: ReinitOnCopy.h:163
ReinitOnCopy(ReinitOnCopy &&source)
Move constructor is simply a pass-through to the move constructor of the contained object for both th...
Definition: ReinitOnCopy.h:137
ReinitOnCopy(T &&value)
Construct or implicitly convert from an rvalue object of type T. This sets both the current and remem...
Definition: ReinitOnCopy.h:127
ReinitOnCopy & operator=(T &&value)
Assignment from an rvalue object of type T uses T's move or copy assignment operator; affects only th...
Definition: ReinitOnCopy.h:159
ReinitOnCopy & operator=(const T &value)
Assignment from an object of type T uses T's copy assignment operator; affects only the current value...
Definition: ReinitOnCopy.h:153
T & updT()
Return a writable reference to the contained object of type T.
Definition: ReinitOnCopy.h:166
const T & getReinitT() const
(Advanced) Return a const reference to the stored initial value.
Definition: ReinitOnCopy.h:169
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37