BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bsltf_copymovetracker.h
Go to the documentation of this file.
1/// @file bsltf_copymovetracker.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsltf_copymovetracker.h -*-C++-*-
8#ifndef INCLUDED_BSLTF_COPYMOVETRACKER
9#define INCLUDED_BSLTF_COPYMOVETRACKER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsltf_copymovetracker bsltf_copymovetracker
15/// @brief Provide a type that tracks if it's been copied or moved
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsltf
19/// @{
20/// @addtogroup bsltf_copymovetracker
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsltf_copymovetracker-purpose"> Purpose</a>
25/// * <a href="#bsltf_copymovetracker-classes"> Classes </a>
26/// * <a href="#bsltf_copymovetracker-description"> Description </a>
27/// * <a href="#bsltf_copymovetracker-use-via-composition-vs-inheritance"> Use via composition vs. inheritance </a>
28/// * <a href="#bsltf_copymovetracker-usage"> Usage </a>
29/// * <a href="#bsltf_copymovetracker-example-1-a-tracked-value-class"> Example 1: A tracked value class </a>
30/// * <a href="#bsltf_copymovetracker-example-2-testing-a-wrapper-template"> Example 2: Testing a wrapper template </a>
31///
32/// # Purpose {#bsltf_copymovetracker-purpose}
33/// Provide a type that tracks if it's been copied or moved
34///
35/// # Classes {#bsltf_copymovetracker-classes}
36///
37/// - bsltf::CopyMoveTracker
38///
39/// @see bsltf_copymovestate, bsltf_argumenttype
40///
41/// # Description {#bsltf_copymovetracker-description}
42/// This component provides a class, `bsltf::CopyMoveTracker`, that
43/// keeps track of whether it has been copied to, moved to, or moved from. It
44/// is useful for test drivers to ensure that copy and move operations are
45/// invoked when expected and not invoked when not expected.
46///
47/// Each object of type `CopyMoveTracker` contains a bit mask of type
48/// `bsltf::CopyMoveState::Enum`. The constructors and manipulators clear all
49/// of the bits, then set them as follows:
50/// @code
51/// e_MOVED_FROM ----------------------.
52/// e_MOVED_INTO ------------------. |
53/// Bits set: e_COPIED_NONCONST_INTO ----. | |
54/// e_COPIED_CONST_INTO ---. | | |
55/// e_COPIED_INTO -----. | | | |
56/// Operation: V V V V V
57/// +------------------------------------------+---+---+---+---+---+
58/// | CopyMoveState() | | | | | |
59/// | resetCopyMoveState() | | | | | |
60/// +------------------------------------------+---+---+---+---+---+
61/// | CopyMoveState(const CopyMoveState&) | X | X | | | |
62/// | operator=(const CopyMoveState&) | X | X | | | |
63/// +------------------------------------------+---+---+---+---+---+
64/// | CopyMoveState(CopyMoveState&) | X | | X | | |
65/// | operator=(CopyMoveState&) | X | | X | | |
66/// +------------------------------------------+---+---+---+---+---+
67/// | CopyMoveState(MovableRef<CopyMoveState>) | | | | X | |
68/// | operator=(MovableRef<CopyMoveState>) | | | | X | |
69/// +------------------------------------------+---+---+---+---+---+
70/// @endcode
71/// In addition, the move constructor and move assignment operator modify the
72/// *moved-from* object by setting the `e_MOVED_FROM` bit *in addition* to any
73/// other bits that might already be set. Thus, if the `e_MOVED_FROM` bit is
74/// set, then the *most recent* change was caused by a move-from operation.
75/// Conversely, if a moved-from object is the target of an (copy or move)
76/// assignment, the `e_MOVED_FROM` bit is cleared.
77///
78/// The `CopyMoveTracker` class is an in-core value-semantic type having no
79/// salient attributes, and therefore only one value. The state of a
80/// `CopyMoveTracker` object is irrelevant to its value, so all
81/// `CopyMoveTracker` objects compare equal. A `CopyMoveTracker` subobject of a
82/// larger *client* class does not contribute to that class's value (see Usage
83/// Example 1, below), but the subobject provides all of the necessary
84/// value-semantic operations, allowing the client class to default the copy and
85/// move constructors, the copy and move assignment operators, and/or (in C++20)
86/// the equality comparison operators.
87///
88/// ## Use via composition vs. inheritance {#bsltf_copymovetracker-use-via-composition-vs-inheritance}
89///
90///
91/// When building a new type that tracks copy and move operations, it is
92/// tempting to include `CopyMoveTracker` via inheritance. Indeed, this class
93/// provides features to make inheritance convenient, including providing
94/// numerous fine-grained accessors named so as to avoid conflicts with
95/// derived-class members. By inheriting from `CopyMoveTracker`, these
96/// accessors become available in the derived class without manually defining
97/// forwarding functions.
98///
99/// The convenience of using inheritance should be balanced against contravening
100/// factors. The simultaneous use of interface and implementation inheritance
101/// is rarely a good design decision and is generally discouraged in our
102/// production code base. Inheriting from this class subjects the user to the
103/// potential dangers of slicing, e.g., assigning to, or moving from, a
104/// derived-class object through a base-class reference. Such issues can
105/// arguably be avoided fairly easily in relatively small,
106/// single-translation-unit programs such as test drivers, but users should be
107/// aware of the peril. Inheriting from `CopyMoveTracker` should be avoided in
108/// public header files.
109///
110/// To simplify the use of composition, which is preferred over inheritence, the
111/// `CopyMoveState` component on which this one is built provides a set of
112/// *psuedo* *accessors* that mirror the ones provided by `CopyMoveTracker`. A
113/// client class `MyType` enables these psuedo accessors by defining an ADL
114/// customization point named `copyMoveState(const MyType&)` in the namespace in
115/// which `MyType` is defined. With this customization point in place, a client
116/// program can call `bsltf::CopyMoveState::isMovedInto(obj)` instead of
117/// `obj.isMovedInto()`. Using a short alias for `bsltf::CopyMoveState`, a call
118/// to a psuedo accessor for an object of `MyType` is scarcely more verbose than
119/// a call to a real accessor within `MyType`, without using inheritance and
120/// without writing a large number of forwarding functions within `MyType`. The
121/// usage examples below show the use of composition applying this technique.
122///
123/// ## Usage {#bsltf_copymovetracker-usage}
124///
125///
126/// This section illustrates intended use of this component.
127///
128/// ### Example 1: A tracked value class {#bsltf_copymovetracker-example-1-a-tracked-value-class}
129///
130///
131/// In this example, we create a class that holds an integer value and tracks
132/// moves and copies.
133///
134/// First, we define the class and it's data members, including a
135/// `CopyMoveTracker` to keep track of the moves and copies:
136/// @code
137/// class TrackedValue {
138/// bsltf::CopyMoveTracker d_tracker;
139/// int d_value;
140/// @endcode
141/// Next, we define the constructors for `TrackedValue` such that they forward
142/// appropriately the `CopyMoveTracker` member appropriately:
143/// @code
144/// public:
145/// explicit TrackedValue(int v = 0) : d_tracker(), d_value(v) { }
146/// TrackedValue(const TrackedValue& original)
147/// : d_tracker(original.d_tracker), d_value(original.d_value) { }
148/// TrackedValue(TrackedValue& original)
149/// : d_tracker(original.d_tracker), d_value(original.d_value) { }
150/// TrackedValue(bslmf::MovableRef<TrackedValue> original)
151/// : d_tracker(bslmf::MovableRefUtil::move(
152/// bslmf::MovableRefUtil::access(original).d_tracker))
153/// {
154/// TrackedValue& originalLvalue = original;
155/// d_value = originalLvalue.d_value;
156/// originalLvalue.d_value = -1;
157/// }
158/// @endcode
159/// For this example, we don't need to define the assignment operators, but
160/// their implemenation would be similar to the corresponding constructors.
161///
162/// Next, we define an accessor to return the value of our tracked value.
163/// @code
164/// int value() const { return d_value; }
165/// @endcode
166/// Then, we define a hidden friend function, `copyMoveState`, that returns the
167/// copy/move state. This friend function is an ADL customization point that
168/// allows `CopyMoveState::get(obj)` to return the copy/move state when `obj` is
169/// a tracked value and allows boolean psuedo-accessors such as
170/// `CopyMoveState::isMovedFrom(obj)` to query the copy/move state:
171/// @code
172/// friend bsltf::CopyMoveState::Enum copyMoveState(const TrackedValue& v)
173/// { return v.d_tracker.copyMoveState(); }
174/// };
175/// @endcode
176/// Next, we define equality-comparison operators for `TrackedValue`. Note that
177/// only the value attribute is compared; the copy/move state is not a salient
178/// attribute of the class and is thus not part of its value:
179/// @code
180/// bool operator==(const TrackedValue &a, const TrackedValue &b)
181/// {
182/// return a.value() == b.value();
183/// }
184///
185/// BSLS_ANNOTATION_UNUSED
186/// bool operator!=(const TrackedValue &a, const TrackedValue &b)
187/// {
188/// return a.value() != b.value();
189/// }
190/// @endcode
191/// Now we use `TrackedValue` in a program, beginning by constructing a
192/// variable. The variable is in the not-copied-or-moved state:
193/// @code
194/// int main()
195/// {
196/// TrackedValue tv1(99);
197/// assert(99 == tv1.value());
198/// assert(bsltf::CopyMoveState::isOriginal(tv1));
199/// @endcode
200/// Finally, we make a copy of our `TrackedValue` variable. The copy is in a
201/// copied-into state, but it still has the same *value* as `tv1`:
202/// @code
203/// TrackedValue tv2(tv1);
204/// assert(99 == tv2.value());
205/// assert(bsltf::CopyMoveState::isCopiedInto(tv2));
206/// assert(bsltf::CopyMoveState::isCopiedNonconstInto(tv2));
207/// assert(tv2 == tv1);
208/// }
209/// @endcode
210///
211/// ### Example 2: Testing a wrapper template {#bsltf_copymovetracker-example-2-testing-a-wrapper-template}
212///
213///
214/// In this example, we test a simple wrapper template, `CountedWrapper<T>`,
215/// that holds an object of type `T` and counts the number of such wrapper
216/// object currently live in the program. We begin by sketching the wrapper
217/// template being tested (with unnecessary details left out):
218/// @code
219/// #include <bslmf_util.h>
220///
221/// template <class TYPE>
222/// class CountedWrapper {
223/// // Hold an object of 'TYPE' and count the number of objects.
224///
225/// // CLASS DATA
226/// static int s_count;
227///
228/// // DATA
229/// TYPE d_object;
230///
231/// public:
232/// // CLASS METHODS
233/// static int count() { return s_count; }
234///
235/// // CREATORS
236/// CountedWrapper() { ++s_count; }
237///
238/// template <class ARG>
239/// explicit
240/// CountedWrapper(BSLS_COMPILERFEATURES_FORWARD_REF(ARG) ctorArg)
241/// // Construct the wrapped object by forwarding the specified
242/// // 'ctorArg' to the constructor for 'TYPE'.
243/// : d_object(BSLS_COMPILERFEATURES_FORWARD(ARG, ctorArg))
244/// { ++s_count; }
245///
246/// ~CountedWrapper() { --s_count; }
247///
248/// // ...
249///
250/// // ACCESSORS
251/// const TYPE& object() const { return d_object; }
252/// };
253///
254/// template <class TYPE>
255/// int CountedWrapper<TYPE>::s_count = 0;
256/// @endcode
257/// Next, we instantiat our wrapper with the `TrackedValue` class from Example 1
258/// so that we can track whether the argument passed to the wrapper constructor
259/// is correctly passed to the wrapped object, including preserving its value
260/// category:
261/// @code
262/// typedef CountedWrapper<TrackedValue> WrappedValue;
263/// @endcode
264/// Next, we check that a value-constructed wrapper results in a tracked value
265/// that has not be copied or moved; i.e., no temporaries were created and then
266/// copied. Checking the copy/move state requires calling static methods of
267/// `bsltf::CopyMoveState`; we make such calls terser by defining `Cms` as an
268/// abbreviation for `bsltf::CopyMoveState`:
269/// @code
270/// int main()
271/// {
272/// typedef bsltf::CopyMoveState Cms;
273///
274/// WrappedValue wv1(99); // Default constructor
275/// assert(1 == WrappedValue::count());
276/// assert(99 == wv1.object().value());
277/// assert(Cms::isOriginal(wv1.object()));
278/// @endcode
279/// Next, we check that a wrapper constructed from a `TrackedValue` variable
280/// forwards the variable as an lvalue, resulting in a call to the copy
281/// constructor. We also check that, in C++11, the lvalue is perfectly
282/// forwarded as a non-const lvalue:
283/// @code
284/// TrackedValue t2(44);
285/// assert(Cms::isOriginal(t2));
286///
287/// WrappedValue wv2(t2);
288/// assert(44 == t2.value()); // Unchanged
289/// assert(Cms::isOriginal(t2)); // Unchanged
290/// assert(2 == WrappedValue::count());
291/// assert(44 == wv2.object().value());
292/// assert(Cms::isCopiedInto(wv2.object())); // Copy constructed
293/// #ifdef BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES
294/// // Copy constructed from non-const original
295/// assert(Cms::isCopiedNonconstInto(wv2.object()));
296/// #endif
297/// @endcode
298/// Finally, we check that a wrapper constructed from a moved `TrackedValue`
299/// forwards the variable as an rvalue, resulting in a call to the move
300/// constructor. Note that original variable is also modified by this
301/// operation:
302/// @code
303/// TrackedValue t3(t2);
304/// assert(44 == t3.value());
305/// assert(Cms::isCopiedNonconstInto(t3));
306///
307/// WrappedValue wv3(bslmf::MovableRefUtil::move(t3));
308/// assert(-1 == t3.value());
309/// assert(Cms::isCopiedNonconstInto(t3));
310/// assert(Cms::isMovedFrom(t3));
311/// assert(3 == WrappedValue::count());
312/// assert(44 == wv3.object().value());
313/// assert(Cms::isMovedInto(wv3.object()));
314/// }
315/// @endcode
316/// @}
317/** @} */
318/** @} */
319
320/** @addtogroup bsl
321 * @{
322 */
323/** @addtogroup bsltf
324 * @{
325 */
326/** @addtogroup bsltf_copymovetracker
327 * @{
328 */
329
330#include <bslscm_version.h>
331
332#include <bslmf_enableif.h>
333#include <bslmf_isconvertible.h>
334#include <bslmf_movableref.h>
335#include <bslmf_issame.h>
336
337#include <bsls_assert.h>
338#include <bsls_keyword.h>
339
340#include <bsltf_copymovestate.h>
341
342
343namespace bsltf {
344
345 // ===================
346 // class CopyMoveTracker
347 // ===================
348
349/// Type that tracks whether it has been copied into, moved into, or moved
350/// from.
351///
352/// See @ref bsltf_copymovetracker
354
355 // DATA
356 CopyMoveState::Enum d_state;
357
358 public:
359 // CREATORS
360
361 /// Create object an object in the `e_NOT_COPIED_OR_MOVE` state.
363
364 /// Create object an object in the `e_COPIED_CONST_INTO` state.
365 CopyMoveTracker(const CopyMoveTracker& original);
366
367 /// Create object an object in the `e_COPIED_NONCONST_INTO` state.
369
370 /// Create object an object in the `e_MOVED_INTO` state and set the
371 /// state of `original` to the bitwise OR of its inititial state and
372 /// `e_MOVED_FROM`.
374
375 /// Create object an object in the `e_MOVED_INTO` state and set the
376 /// state of `original` to the bitwise OR of its initial state and
377 /// `e_MOVED_FROM`. This constructor will not participate in overload
378 /// resolution unless a `DERIVED` is derived from `CopyMoveTracker`; in
379 /// C++03, therefore, this constructor will simulate automatic
380 /// derived-to-base conversion of rvalue references.
381 template <class DERIVED>
383 typename bsl::enable_if<bsl::is_convertible<DERIVED*,
384 CopyMoveTracker*>::value>::type * = 0);
385
386 ~CopyMoveTracker() = default;
387
388 // MANIPULATORS
389
390 /// Set this object to the `e_COPIED_CONST_INTO` state and return a
391 /// modifiable reference to this object.
393
394 /// Set this object to the `e_COPIED_NONCONST_INTO` state and return a
395 /// modifiable reference to this object.
397
398 /// Set this object to the `e_MOVED_INTO` state and return a modifiable
399 /// reference to this object. Set the state of `rhs` to the bitwise OR
400 /// of its initial state and `e_MOVED_FROM`.
402
403 /// Set this object to the `e_MOVED_INTO` state and return a modifiable
404 /// reference to this object. Set the state of `rhs` to the bitwise OR
405 /// of its initial state and `e_MOVED_FROM`. This operator will not
406 /// participate in overload resolution unless a `DERIVED` is derived
407 /// from `CopyMoveTracker`; in C++03, therefore, this operator will
408 /// simulate automatic derived-to-base conversion of rvalue references.
409 template <class DERIVED>
410 typename bsl::enable_if<
413 >::type
415
416 /// Set this object to the `e_NOT_COPIED_OR_MOVE` state.
417 void resetCopyMoveState();
418
419 /// Set this object to the specified `state`, which might be the bitwise
420 /// OR of `e_MOVED_FROM` and one of the other enumerator values. The
421 /// behavior is undefined unless `CopyMoveState::isValid(state)` is
422 /// `true`.
424
425 /// Set the state of both the specified `this` and `b` objects to the
426 /// bitwise OR of `e_MOVED_INTO` and `e_MOVED_FROM`.
428
429 // ACCESSORS
430
431 /// Return this object's state.
433
434 /// Return `true` if this object's state includes the `e_UNKNOWN`
435 /// bit. This attribute can be `true` only if `setCopyMoveState` was
436 /// called with an enumerator value that includes the `e_UNKNOWN` bit.
437 bool hasUnknownCopyMoveState() const;
438
439 /// Return `true` if this object's state includes the
440 /// `e_COPIED_CONST_INTO` bits but not `e_UNKNOWN`. This attribute is
441 /// `true` if this object was copy constructed or copy assigned from a
442 /// `const` lvalue (or, in C++03, from a prvalue).
443 bool isCopiedConstInto() const;
444
445 /// Return `true` if this object's state includes the `e_COPIED_INTO`
446 /// bit but not `e_UNKNOWN`. This attribute is `true` if either
447 /// `isCopiedConstInto()` or `isCopiedNonconstInto()` is true.
448 bool isCopiedInto() const;
449
450 /// Return `true` if this object's state includes the
451 /// `e_COPIED_NONCONST_INTO` bits but not `e_UNKNOWN`. This attribute
452 /// is `true` if this object was copy constructed or copy assigned from
453 /// a non-`const` lvalue.
454 bool isCopiedNonconstInto() const;
455
456 /// Return `true` if this object's state includes the `e_MOVED_INTO` bit
457 /// but not `e_UNKNOWN`. This attribute is `true` if this object was
458 /// move constructed or was the lhs the of move assignment operator.
459 bool isMovedInto() const;
460
461 /// Return `true` if this object's state includes the `e_MOVED_FROM` bit
462 /// but not `e_UNKNOWN`. This attribute is `true` if this object was
463 /// the argument of the move constructor or the rhs of the move
464 /// assignment operator and was not subsequently modified.
465 bool isMovedFrom() const;
466
467 /// Return `true` if this object is not in a copied-into, moved-into, or
468 /// unknown state. This attribute is `true` if this object was
469 /// default constructed or reset and not subsequently assigned to.
470 bool isOriginal() const;
471
472 // HIDDEN FRIENDS
473
474 /// Return `true`; the copy/move state is *not* a salient attribute, so
475 /// all `CopyMoveTracker` objects compare equal. Note that this
476 /// operator is called implicitly if a client class defines a defaulted
477 /// comparison operator (C++20), but will not be selected by overload
478 /// resolution for a derived class having no comparison operator.
479 template <class OTHER>
480 friend BSLS_KEYWORD_CONSTEXPR typename
482 operator==(const CopyMoveTracker&, const OTHER&)
483 { return true; }
484
485 /// Return `false`; the copy/move state is *not* a salient attribute, so
486 /// all `CopyMoveTracker` objects compare equal. Note that this
487 /// operator is called implicitly if a client class defines a defaulted
488 /// comparison operator (C++20), but will not be selected by overload
489 /// resolution for a derived class having no comparison operator.
490 template <class OTHER>
491 friend BSLS_KEYWORD_CONSTEXPR typename
493 operator!=(const CopyMoveTracker&, const OTHER&)
494 { return false; }
495
496 /// Return the state of the specified `tracker`. This function is an
497 /// ADL customization point used by `CopyMoveState::get(obj)`.
498 friend
500 { return tracker.copyMoveState(); }
501
502 /// Set the object at the specified `tracker` address to the specified
503 /// `state`. This function is an ADL customization point used by
504 /// `CopyMoveState::set(obj, state)`. The behavior is undefined unless
505 /// `CopyMoveState::isValid(state)` is `true`.
506 friend
508 { tracker->setCopyMoveState(state); }
509};
510
511// ============================================================================
512// TEMPLATE AND INLINE FUNCTION IMPLEMENTATIONS
513// ============================================================================
514
515// CREATORS
517 : d_state(CopyMoveState::e_ORIGINAL)
518{
519}
520
522 : d_state(CopyMoveState::e_COPIED_NONCONST_INTO)
523{
524}
525
527 : d_state(CopyMoveState::e_COPIED_CONST_INTO)
528{
529}
530
531inline
533 : d_state(CopyMoveState::e_MOVED_INTO)
534{
535 CopyMoveTracker& originalLvalue = original;
536 originalLvalue.d_state = CopyMoveState::Enum(originalLvalue.d_state |
538}
539
540template <class DERIVED>
543 typename bsl::enable_if<bsl::is_convertible<DERIVED*,
544 CopyMoveTracker*>::value>::type *)
545 : d_state(CopyMoveState::e_MOVED_INTO)
546{
547 // Upcast to base class
548 CopyMoveTracker& originalLvalue = bslmf::MovableRefUtil::access(original);
549 originalLvalue.d_state = CopyMoveState::Enum(originalLvalue.d_state |
551}
552
553// MANIPULATORS
555{
556 if (&rhs != this) {
558 }
559 return *this;
560}
561
563{
564 if (&rhs != this) {
566 }
567 return *this;
568}
569
570inline
573{
574 CopyMoveTracker& rhsLvalue = rhs;
575 if (&rhsLvalue != this) {
577 rhsLvalue.d_state = CopyMoveState::Enum(rhsLvalue.d_state |
579 }
580 return *this;
581}
582
583template <class DERIVED>
584inline
585typename bsl::enable_if<
588>::type
590{
591 // Upcast to base class
593 if (&rhsLvalue != this) {
595 rhsLvalue.d_state = CopyMoveState::Enum(rhsLvalue.d_state |
597 }
598 return *this;
599}
600
605
607{
609 d_state = state;
610}
611
617
618// ACCESSORS
620{
621 return d_state;
622}
623
625{
626 return bool(d_state & CopyMoveState::e_UNKNOWN);
627}
628
635
641
648
654
660
662{
663 return 0 == (d_state & (CopyMoveState::e_COPIED_INTO |
666}
667
668} // close package namespace
669
670
671
672#endif // ! defined(INCLUDED_BSLTF_COPYMOVETRACKER)
673
674// ----------------------------------------------------------------------------
675// Copyright 2023 Bloomberg Finance L.P.
676//
677// Licensed under the Apache License, Version 2.0 (the "License");
678// you may not use this file except in compliance with the License.
679// You may obtain a copy of the License at
680//
681// http://www.apache.org/licenses/LICENSE-2.0
682//
683// Unless required by applicable law or agreed to in writing, software
684// distributed under the License is distributed on an "AS IS" BASIS,
685// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
686// See the License for the specific language governing permissions and
687// limitations under the License.
688// ----------------------------- END-OF-FILE ----------------------------------
689
690/** @} */
691/** @} */
692/** @} */
Definition bslmf_movableref.h:751
Definition bsltf_copymovetracker.h:353
bool isCopiedConstInto() const
Definition bsltf_copymovetracker.h:629
CopyMoveState::Enum copyMoveState() const
Return this object's state.
Definition bsltf_copymovetracker.h:619
CopyMoveTracker()
Create object an object in the e_NOT_COPIED_OR_MOVE state.
Definition bsltf_copymovetracker.h:516
friend BSLS_KEYWORD_CONSTEXPR bsl::enable_if< bsl::is_same< CopyMoveTracker, OTHER >::value, bool >::type operator!=(const CopyMoveTracker &, const OTHER &)
Definition bsltf_copymovetracker.h:493
bool isMovedFrom() const
Definition bsltf_copymovetracker.h:649
void setCopyMoveState(CopyMoveState::Enum state)
Definition bsltf_copymovetracker.h:606
void swapCopyMoveStates(CopyMoveTracker &b)
Definition bsltf_copymovetracker.h:612
bool isCopiedNonconstInto() const
Definition bsltf_copymovetracker.h:642
bool isCopiedInto() const
Definition bsltf_copymovetracker.h:636
friend BSLS_KEYWORD_CONSTEXPR bsl::enable_if< bsl::is_same< CopyMoveTracker, OTHER >::value, bool >::type operator==(const CopyMoveTracker &, const OTHER &)
Definition bsltf_copymovetracker.h:482
void resetCopyMoveState()
Set this object to the e_NOT_COPIED_OR_MOVE state.
Definition bsltf_copymovetracker.h:601
friend CopyMoveState::Enum copyMoveState(const CopyMoveTracker &tracker)
Definition bsltf_copymovetracker.h:499
bool isMovedInto() const
Definition bsltf_copymovetracker.h:655
bool isOriginal() const
Definition bsltf_copymovetracker.h:661
CopyMoveTracker & operator=(const CopyMoveTracker &rhs)
Definition bsltf_copymovetracker.h:562
friend void setCopyMoveState(CopyMoveTracker *tracker, CopyMoveState::Enum state)
Definition bsltf_copymovetracker.h:507
bool hasUnknownCopyMoveState() const
Definition bsltf_copymovetracker.h:624
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_CONSTEXPR
Definition bsls_keyword.h:588
Definition bsltf_allocargumenttype.h:92
Definition bslmf_enableif.h:525
Definition bslmf_isconvertible.h:867
static t_TYPE & access(t_TYPE &ref) BSLS_KEYWORD_NOEXCEPT
Definition bslmf_movableref.h:1032
Definition bsltf_copymovestate.h:219
Enum
Definition bsltf_copymovestate.h:222
@ e_COPIED_NONCONST_INTO
Definition bsltf_copymovestate.h:228
@ e_COPIED_INTO
Definition bsltf_copymovestate.h:226
@ e_UNKNOWN
Definition bsltf_copymovestate.h:231
@ e_COPIED_CONST_INTO
Definition bsltf_copymovestate.h:227
@ e_MOVED_INTO
Definition bsltf_copymovestate.h:229
@ e_ORIGINAL
Definition bsltf_copymovestate.h:225
@ e_MOVED_FROM
Definition bsltf_copymovestate.h:230
static bool isValid(Enum val)
Definition bsltf_copymovestate.h:418