summaryrefslogtreecommitdiffstats
path: root/src/corelib/global/qglobal.cpp
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2022-09-30 13:12:42 +0200
committerIvan Solovev <ivan.solovev@qt.io>2022-10-06 14:26:24 +0200
commitdff985140a9f31632ba6630ec3391be55051a7ac (patch)
tree380babdac720c2cec4d10f493edf95581c4791d3 /src/corelib/global/qglobal.cpp
parent394e9a8d06e475a46d6e14cc96dfd12d431cb412 (diff)
Move qAsConst() and qExchange() to QtTypeTraits
It's the least worst place we could think of. Add the qttypetraits.h include to qforeach, because otherwise the tests fail to build. Task-number: QTBUG-106154 Task-number: QTBUG-99313 Change-Id: I841f22e887f351146589377ec2376957e2adfd5e Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/global/qglobal.cpp')
-rw-r--r--src/corelib/global/qglobal.cpp96
1 files changed, 0 insertions, 96 deletions
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 7077efb662..e444755f1b 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -228,102 +228,6 @@ void qAbort()
// strftime() -- not used (except in tests)
/*!
- \fn template <typename T> typename std::add_const<T>::type &qAsConst(T &t)
- \relates <QtGlobal>
- \since 5.7
-
- Returns \a t cast to \c{const T}.
-
- This function is a Qt implementation of C++17's std::as_const(),
- a cast function like std::move(). But while std::move() turns
- lvalues into rvalues, this function turns non-const lvalues into
- const lvalues. Like std::as_const(), it doesn't work on rvalues,
- because it cannot be efficiently implemented for rvalues without
- leaving dangling references.
-
- Its main use in Qt is to prevent implicitly-shared Qt containers
- from detaching:
- \snippet code/src_corelib_global_qglobal.cpp as-const-0
-
- Of course, in this case, you could (and probably should) have declared
- \c s as \c const in the first place:
- \snippet code/src_corelib_global_qglobal.cpp as-const-1
- but often that is not easily possible.
-
- It is important to note that qAsConst() does not copy its argument,
- it just performs a \c{const_cast<const T&>(t)}. This is also the reason
- why it is designed to fail for rvalues: The returned reference would go
- stale too soon. So while this works (but detaches the returned object):
- \snippet code/src_corelib_global_qglobal.cpp as-const-2
-
- this would not:
- \snippet code/src_corelib_global_qglobal.cpp as-const-3
-
- To prevent this construct from compiling (and failing at runtime), qAsConst() has
- a second, deleted, overload which binds to rvalues.
-*/
-
-/*!
- \fn template <typename T> void qAsConst(const T &&t)
- \relates <QtGlobal>
- \since 5.7
- \overload
-
- This overload is deleted to prevent a dangling reference in code like
- \snippet code/src_corelib_global_qglobal.cpp as-const-4
-*/
-
-/*!
- \fn template <typename T, typename U = T> T qExchange(T &obj, U &&newValue)
- \relates <QtGlobal>
- \since 5.14
-
- Replaces the value of \a obj with \a newValue and returns the old value of \a obj.
-
- This is Qt's implementation of std::exchange(). It differs from std::exchange()
- only in that it is \c constexpr already in C++14, and available on all supported
- compilers.
-
- Here is how to use qExchange() to implement move constructors:
- \code
- MyClass(MyClass &&other)
- : m_pointer{qExchange(other.m_pointer, nullptr)},
- m_int{qExchange(other.m_int, 0)},
- m_vector{std::move(other.m_vector)},
- ...
- \endcode
-
- For members of class type, we can use std::move(), as their move-constructor will
- do the right thing. But for scalar types such as raw pointers or integer type, move
- is the same as copy, which, particularly for pointers, is not what we expect. So, we
- cannot use std::move() for such types, but we can use std::exchange()/qExchange() to
- make sure the source object's member is already reset by the time we get to the
- initialization of our next data member, which might come in handy if the constructor
- exits with an exception.
-
- Here is how to use qExchange() to write a loop that consumes the collection it
- iterates over:
- \code
- for (auto &e : qExchange(collection, {})
- doSomethingWith(e);
- \endcode
-
- Which is equivalent to the following, much more verbose code:
- \code
- {
- auto tmp = std::move(collection);
- collection = {}; // or collection.clear()
- for (auto &e : tmp)
- doSomethingWith(e);
- } // destroys 'tmp'
- \endcode
-
- This is perfectly safe, as the for-loop keeps the result of qExchange() alive for as
- long as the loop runs, saving the declaration of a temporary variable. Be aware, though,
- that qExchange() returns a non-const object, so Qt containers may detach.
-*/
-
-/*!
\macro Q_UNUSED(name)
\relates <QtGlobal>