UncopiableAndUnmovableClass.h
Go to the documentation of this file.
1 /**
2  * @file larcorealg/CoreUtils/UncopiableAndUnmovableClass.h
3  * @brief Defines classes that can't be copied nor moved.
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  *
6  * This library is currently a pure header.
7  *
8  */
9 
10 #ifndef LARCORE_COREUTILS_UNCOPIABLEANDUNMOVEABLECLASS_H
11 #define LARCORE_COREUTILS_UNCOPIABLEANDUNMOVEABLECLASS_H
12 
13 
14 namespace lar {
15 
16  // --- BEGIN -- Non-polymorphic classes --------------------------------------
17  /**
18  * @name Non-polymorphic classes
19  * @anchor LArSoftCoreUtils_NonPolymorphicUncopiableUnmovable
20  *
21  * These base classes can be used to explicitly control movability and
22  * copiability of the derived classes. It's a trade of a long class name
23  * (and a long header file include statement) against five or six boilerplate
24  * statements.
25  *
26  * The four classes in this group should be used only for classes with no
27  * run-time polymorphism, for example:
28  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
29  * struct UniqueData: protected lar::UncopiableClass {
30  *
31  * std::vector<float> fLotsOfData{ 100'000'000U };
32  *
33  * };
34  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
35  * The class `UniqueData` in the example can be moved, but not copied.
36  *
37  * See
38  * @ref LArSoftCoreUtils_PolymorphicUncopiableUnmovable "polymorphic classes"
39  * for use with classes presenting run-time polymorphism.
40  *
41  */
42  /// @{
43 
44  /** **************************************************************************
45  * @brief An empty class that can't be copied (moving is allowed).
46  * @see `UnmovableClass`, `UncopiableAndUnmovableClass`
47  *
48  * A class derived from this one can still be copied with an explicit effort.
49  * For example, to enable copy construction:
50  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
51  * struct CopiableClass: protected UncopiableAndUnmovableClass {
52  * CopiableClass(CopiableClass const& from)
53  * : UncopiableClass() // , ...
54  * {
55  * // ...
56  * }
57  * };
58  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
59  * the default constructor of the base class can be called explicitly instead
60  * of the copy constructor. To provide an assignment operation,
61  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
62  * struct CopyAssignableClass: protected UncopiableClass {
63  * CopyAssignableClass& operator= (CopyAssignableClass const& from)
64  * {
65  * // ...
66  * return *this;
67  * }
68  * };
69  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
70  *
71  */
72  struct UncopiableClass {
73 
74  /// Default constructor
75  UncopiableClass() = default;
76 
77  // @{
78  /// Deleted copy and move constructors and assignments
79  UncopiableClass(UncopiableClass const&) = delete;
80  UncopiableClass(UncopiableClass&&) = default;
81 
82  UncopiableClass& operator= (UncopiableClass const&) = delete;
84  // @}
85 
86  /// Default destructor
87  ~UncopiableClass() = default;
88 
89  }; // UncopiableClass
90 
91 
92  /** **************************************************************************
93  * @brief An empty class that can't be moved (copy is allowed).
94  * @see `UncopiableClass`, `UncopiableAndUnmovableClass`
95  *
96  * A class derived from this one can still be moved with an explicit effort.
97  * For example, to enable move construction:
98  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
99  * struct MoveableClass: protected UnmovableClass {
100  * MoveableClass(MoveableClass&& from)
101  * : UnmovableClass() // , ...
102  * {
103  * // ...
104  * }
105  * };
106  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
107  * the default constructor of the base class can be called explicitly instead
108  * of the move constructor. To provide a move assignment operation,
109  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
110  * struct MoveAssignableClass: protected UnmovableClass {
111  * MoveAssignableClass& operator= (MoveAssignableClass&& from)
112  * {
113  * // ...
114  * return *this;
115  * }
116  * };
117  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
118  *
119  */
120  struct UnmovableClass {
121 
122  /// Default constructor.
123  UnmovableClass() = default;
124 
125  //@{
126  /// Default copy constructor and assignment.
127  UnmovableClass(UnmovableClass const&) = default;
128  UnmovableClass& operator= (UnmovableClass const&) = default;
129  //@}
130 
131  //@{
132  /// Deleted move constructor and assignment.
133  UnmovableClass(UnmovableClass&&) = delete;
135  //@}
136 
137  /// Default destructor.
138  ~UnmovableClass() = default;
139 
140  }; // UnmovableClass
141 
142 
143  /** **************************************************************************
144  * @brief An empty class that can't be copied nor moved.
145  * @see `UncopiableClass`, `UnmovableClass`
146  *
147  * A class derived from this one can still be copied and/or moved with an
148  * explicit effort. See `UncopiableClass` and `UnmovableClass` for examples.
149  */
151  : public UncopiableClass, public UnmovableClass
152  {};
153 
154  /// @}
155  // --- END -- Non-polymorphic classes ----------------------------------------
156 
157 
158 
159  // --- BEGIN -- Run-time-polymorphic classes ---------------------------------
160  /**
161  * @name Run-time polymorphic classes
162  * @anchor LArSoftCoreUtils_PolymorphicUncopiableUnmovable
163  *
164  * These base classes can be used to explicitly control movability and
165  * copiability of the derived classes which feature run-time polymorphism.
166  * It's a trade of a long class name (and a long header file include
167  * statement) against five or six boilerplate statements.
168  *
169  * The four relevant classes in this group should be used only for classes
170  * with run-time polymorphism, for example:
171  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
172  * struct UniqueAlgorithmBase
173  * : protected lar::PolymorphicUncopiableAndUnmovableClass
174  * {
175  *
176  * virtual int compute() const = 0;
177  *
178  * };
179  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
180  * All the classes derived from `UniqueAlgorithmBase` in the example can't be
181  * copied nor moved (as `UniqueAlgorithmBase` as well, but that's moot
182  * since it's pure virtual).
183  * In general this may be a good thing to avoid slicing, that is an incomplete
184  * copy produced by the copy or move constructor of a base class being used
185  * instead of the actual underlying class.
186  *
187  * If run-time polymorphism is not needed, stick to
188  * @ref LArSoftCoreUtils_NonPolymorphicUncopiableUnmovable "non-polymorphic classes"
189  * instead.
190  *
191  */
192  /// @{
193 
194  /**
195  * @brief A simple polymorphic class, providing a virtual table.
196  *
197  * This class (and its derived ones) are going to be copiable and movable.
198  */
200 
201  PolymorphicClass() = default;
202 
203  virtual ~PolymorphicClass() = default;
204 
205  }; // PolymorphicClass
206 
207 
208  /**
209  * @brief A polymorphic empty class that can't be copied (moving is allowed).
210  * @see `PolymorphicClass`, `PolymorphicUnmovableClass`,
211  * `PolymorphicUncopiableAndUnmovableClass`
212  *
213  * A class derived from this one can still be copied with an explicit effort.
214  * For example, to enable copy construction:
215  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
216  * struct CopiableClass: protected PolymorphicUncopiableClass {
217  * CopiableClass(CopiableClass const& from)
218  * : PolymorphicUncopiableClass() // , ...
219  * {
220  * // ...
221  * }
222  * };
223  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
224  * the default constructor of the base class can be called explicitly instead
225  * of the copy constructor. To provide an assignment operation,
226  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
227  * struct CopyAssignableClass: protected PolymorphicUncopiableClass {
228  * CopyAssignableClass& operator= (CopyAssignableClass const& from)
229  * {
230  * // ...
231  * return *this;
232  * }
233  * };
234  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
235  *
236  */
238 
239  PolymorphicUncopiableClass() = default;
240 
243 
245  = delete;
247  = default;
248 
249  }; // PolymorphicUncopiableClass
250 
251 
252  /**
253  * @brief An empty polymorphic class that can't be moved (copy is allowed).
254  * @see `PolymorphicClass`, `PolymorphicUncopiableClass`,
255  * `PolymorphicUncopiableAndUnmovableClass`
256  *
257  * A class derived from this one can still be moved with an explicit effort.
258  * For example, to enable move construction:
259  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
260  * struct MoveableClass: protected PolymorphicUnmovableClass {
261  * MoveableClass(MoveableClass&& from)
262  * : PolymorphicUnmovableClass() // , ...
263  * {
264  * // ...
265  * }
266  * };
267  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
268  * the default constructor of the base class can be called explicitly instead
269  * of the move constructor. To provide a move assignment operation,
270  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
271  * struct MoveAssignableClass: protected PolymorphicUnmovableClass {
272  * MoveAssignableClass& operator= (MoveAssignableClass&& from)
273  * {
274  * // ...
275  * return *this;
276  * }
277  * };
278  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
279  *
280  */
282 
283  PolymorphicUnmovableClass() = default;
284 
287 
289  = default;
291  = delete;
292 
293  }; // PolymorphicUnmovableClass
294 
295 
296 
297 
298  /** **************************************************************************
299  * @brief An empty class that can't be copied nor moved.
300  * @see `PolymorphicClass`, `PolymorphicUncopiableClass`,
301  * `PolymorphicUnmovableClass`
302  *
303  * A class derived from this one can still be copied and/or moved with an
304  * explicit effort. See `PolymorphicUncopiableClass` and
305  * `PolymorphicUnmovableClass` documentation for examples.
306  */
309  {};
310 
311 
312  /// @}
313  // --- END -- Run-time-polymorphic classes -----------------------------------
314 
315 } // namespace lar
316 
317 #endif // LARCORE_COREUTILS_UNCOPIABLEANDUNMOVEABLECLASS_H
An empty class that can&#39;t be copied nor moved.
~UncopiableClass()=default
Default destructor.
UncopiableClass & operator=(UncopiableClass const &)=delete
A polymorphic empty class that can&#39;t be copied (moving is allowed).
UncopiableClass()=default
Default constructor.
A simple polymorphic class, providing a virtual table.
An empty class that can&#39;t be copied nor moved.
An empty polymorphic class that can&#39;t be moved (copy is allowed).
An empty class that can&#39;t be copied (moving is allowed).
LArSoft-specific namespace.
An empty class that can&#39;t be moved (copy is allowed).