[libcalamares] add a convenience optional-setter for use with pointers

This commit is contained in:
Adriaan de Groot 2021-06-18 13:49:08 +02:00
parent 2a0d4e5a23
commit ef436ac4d7
2 changed files with 62 additions and 0 deletions

View File

@ -14,6 +14,7 @@
#include <QObject>
#include <QSignalBlocker>
#include <optional>
#include <type_traits>
/** @brief Convenience to zero out and deleteLater of any QObject-derived-class
@ -58,4 +59,20 @@ struct cBoolSetter
/// @brief Blocks signals on a QObject until destruction
using cSignalBlocker = QSignalBlocker;
/** @brief Writes a value on destruction to a pointed-to location.
*
* If the pointer is non-null, write the last-given-value if there
* is one to the pointed-to object.
*/
template < typename T >
struct cPointerSetter
{
std::optional< T > m_value;
T* m_pointer;
cPointerSetter( T* p ) : m_pointer(p) {}
~cPointerSetter() { if ( m_pointer && m_value.has_value() ) { *m_pointer = m_value.value(); } }
const T& operator=(const T& v) { m_value = v; return v; }
};
#endif

View File

@ -56,6 +56,7 @@ private Q_SLOTS:
/** @brief Tests the RAII bits. */
void testBoolSetter();
void testPointerSetter();
/** @brief Tests the Traits bits. */
void testTraits();
@ -360,6 +361,50 @@ LibCalamaresTests::testBoolSetter()
QVERIFY( b );
}
void
LibCalamaresTests::testPointerSetter()
{
int special = 17;
QCOMPARE( special, 17 );
{
cPointerSetter p( &special );
}
QCOMPARE( special, 17 );
{
cPointerSetter p( &special );
p = 18;
}
QCOMPARE( special, 18 );
{
cPointerSetter p( &special );
p = 20;
p = 3;
}
QCOMPARE( special, 3 );
{
cPointerSetter<int> p( nullptr );
}
QCOMPARE( special, 3 );
{
// "don't do this" .. order of destructors is important
cPointerSetter p( &special );
cPointerSetter q( &special );
p = 17;
}
QCOMPARE( special, 17 );
{
// "don't do this" .. order of destructors is important
cPointerSetter p( &special );
cPointerSetter q( &special );
p = 34;
q = 2;
// q destroyed first, then p
}
QCOMPARE( special, 34 );
}
/* Demonstration of Traits support for has-a-method or not.
*
* We have two classes, c1 and c2; one has a method do_the_thing() and the