From ef436ac4d73edf6c9346894ebfad7fe1ae29e135 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 18 Jun 2021 13:49:08 +0200 Subject: [PATCH] [libcalamares] add a convenience optional-setter for use with pointers --- src/libcalamares/utils/RAII.h | 17 ++++++++++++ src/libcalamares/utils/Tests.cpp | 45 ++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/src/libcalamares/utils/RAII.h b/src/libcalamares/utils/RAII.h index 1cbead4a2..f3adb90f6 100644 --- a/src/libcalamares/utils/RAII.h +++ b/src/libcalamares/utils/RAII.h @@ -14,6 +14,7 @@ #include #include +#include #include /** @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 diff --git a/src/libcalamares/utils/Tests.cpp b/src/libcalamares/utils/Tests.cpp index cdb37f20d..7a6d52623 100644 --- a/src/libcalamares/utils/Tests.cpp +++ b/src/libcalamares/utils/Tests.cpp @@ -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 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