[libcalamares] Rename cPointerSetter

This class doesn't really set a pointer -- it is a scoped assignment
through a pointer, which **can** set a value on destruction (when
it leaves scope). Rename it.

While here, extend the API so that it can do an assignment to the
underlying object **now**, while also doing a scoped assignment
later when it leaves scope. This makes some code a bit easier
to read ("in this scope, X is now <v> and then it becomes <v'>")
This commit is contained in:
Adriaan de Groot 2021-09-22 11:26:28 +02:00
parent bba5b21873
commit 8f65a644a9
6 changed files with 39 additions and 25 deletions

View File

@ -244,7 +244,7 @@ gettext_path()
{ {
// Going to log informatively just once // Going to log informatively just once
static bool first_time = true; static bool first_time = true;
cPointerSetter( &first_time, false ); cScopedAssignment( &first_time, false );
// TODO: distinguish between -d runs and normal runs // TODO: distinguish between -d runs and normal runs
// TODO: can we detect DESTDIR-installs? // TODO: can we detect DESTDIR-installs?

View File

@ -48,10 +48,11 @@ using cSignalBlocker = QSignalBlocker;
/** @brief Writes a value on destruction to a pointed-to location. /** @brief Writes a value on destruction to a pointed-to location.
* *
* If the pointer is non-null, write the last-given-value if there * If the pointer is non-null, write the last-given-value if there
* is one to the pointed-to object. * is one to the pointed-to object. This is called the "then-value".
*
*/ */
template < typename T > template < typename T >
struct cPointerSetter struct cScopedAssignment
{ {
std::optional< T > m_value; std::optional< T > m_value;
T* m_pointer; T* m_pointer;
@ -62,22 +63,36 @@ struct cPointerSetter
* will do nothing on destruction, leaving the pointed-to * will do nothing on destruction, leaving the pointed-to
* value unchanged. * value unchanged.
*/ */
cPointerSetter( T* p ) cScopedAssignment( T* p )
: m_pointer( p ) : m_pointer( p )
{ {
} }
/** @brief Create a setter with a value already set /** @brief Create a setter with a then-value already set
* *
* This ensures that on destruction, the value @p v will be written; * This ensures that on destruction, the value @p v will be written;
* it is equivalent to assigning @p v immediately. The pointed-to * it is equivalent to assigning @p v immediately. The pointed-to
* value is **not** changed (until destruction). * value is **not** changed (until destruction).
*/ */
cPointerSetter( T* p, T v ) cScopedAssignment( T* p, T then )
: m_value( v ) : m_value( then )
, m_pointer( p ) , m_pointer( p )
{ {
} }
~cPointerSetter() /** @brief Create a setter with a then-value and assign a new value now
*
* As above, but also assign @p now to the thing pointed-to.
*/
cScopedAssignment( T* p, T now, T then )
: m_value( then )
, m_pointer( p )
{
if ( p )
{
*p = now;
}
}
~cScopedAssignment()
{ {
if ( m_pointer && m_value.has_value() ) if ( m_pointer && m_value.has_value() )
{ {
@ -85,13 +100,13 @@ struct cPointerSetter
} }
} }
const T& operator=( const T& v ) const T& operator=( const T& then )
{ {
m_value = v; m_value = then;
return v; return then;
} }
}; };
template < typename T > template < typename T >
cPointerSetter( T p )->cPointerSetter< decltype( *p ) >; cScopedAssignment( T p )->cScopedAssignment< decltype( *p ) >;
#endif #endif

View File

@ -346,35 +346,35 @@ LibCalamaresTests::testPointerSetter()
QCOMPARE( special, 17 ); QCOMPARE( special, 17 );
{ {
cPointerSetter p( &special ); cScopedAssignment p( &special );
} }
QCOMPARE( special, 17 ); QCOMPARE( special, 17 );
{ {
cPointerSetter p( &special ); cScopedAssignment p( &special );
p = 18; p = 18;
} }
QCOMPARE( special, 18 ); QCOMPARE( special, 18 );
{ {
cPointerSetter p( &special ); cScopedAssignment p( &special );
p = 20; p = 20;
p = 3; p = 3;
} }
QCOMPARE( special, 3 ); QCOMPARE( special, 3 );
{ {
cPointerSetter< int > p( nullptr ); cScopedAssignment< int > p( nullptr );
} }
QCOMPARE( special, 3 ); QCOMPARE( special, 3 );
{ {
// "don't do this" .. order of destructors is important // "don't do this" .. order of destructors is important
cPointerSetter p( &special ); cScopedAssignment p( &special );
cPointerSetter q( &special ); cScopedAssignment q( &special );
p = 17; p = 17;
} }
QCOMPARE( special, 17 ); QCOMPARE( special, 17 );
{ {
// "don't do this" .. order of destructors is important // "don't do this" .. order of destructors is important
cPointerSetter p( &special ); cScopedAssignment p( &special );
cPointerSetter q( &special ); cScopedAssignment q( &special );
p = 34; p = 34;
q = 2; q = 2;
// q destroyed first, then p // q destroyed first, then p

View File

@ -275,7 +275,7 @@ Config::detectCurrentKeyboardLayout()
{ {
return; return;
} }
cPointerSetter returnToIntial( &m_state, State::Initial ); cScopedAssignment returnToIntial( &m_state, State::Initial );
m_state = State::Guessing; m_state = State::Guessing;
//### Detect current keyboard layout and variant //### Detect current keyboard layout and variant
@ -427,7 +427,7 @@ Config::guessLocaleKeyboardLayout()
{ {
return; return;
} }
cPointerSetter returnToIntial( &m_state, State::Initial ); cScopedAssignment returnToIntial( &m_state, State::Initial );
m_state = State::Guessing; m_state = State::Guessing;
/* Guessing a keyboard layout based on the locale means /* Guessing a keyboard layout based on the locale means

View File

@ -174,8 +174,7 @@ LocalePage::locationChanged( const CalamaresUtils::Locale::TimeZoneData* locatio
{ {
return; return;
} }
m_blockTzWidgetSet = true; // Blocked until we go out of scope cScopedAssignment b( &m_blockTzWidgetSet, true, false );
cPointerSetter b( &m_blockTzWidgetSet, false );
// Set region index // Set region index
int index = m_regionCombo->findData( location->region() ); int index = m_regionCombo->findData( location->region() );

View File

@ -529,7 +529,7 @@ efiFilesystemMinimumSize()
QString QString
canonicalFilesystemName( const QString& fsName, FileSystem::Type* fsType ) canonicalFilesystemName( const QString& fsName, FileSystem::Type* fsType )
{ {
cPointerSetter type( fsType ); cScopedAssignment type( fsType );
if ( fsName.isEmpty() ) if ( fsName.isEmpty() )
{ {
type = FileSystem::Ext4; type = FileSystem::Ext4;