Add template functions assign_set/return_if_changed
Commit Message
Add template function assign_set_if_changed in gdb/utils.h:
...
template<typename T>
void
assign_set_if_changed (T &lval, T val, bool &changed)
{
if (lval == val)
return;
lval = val;
changed = true;
}
...
This allows us to rewrite code like this:
...
if (tui_border_attrs != entry->value)
{
tui_border_attrs = entry->value;
need_redraw = true;
}
...
into this:
...
assign_set_if_changed<int> (tui_border_attrs, entry->value, need_redraw);
...
The name is a composition of its functionality:
- it assigns val to lval, and
- is sets changed to true if the assignment changed lval.
I've initially considered using assign_return_if_changed for the rewrite:
...
template<typename T>
bool
assign_return_if_changed (T &lval, T val)
{
if (lval == val)
return false;
lval = val;
changed = true;
}
...
but liked the resulting bitwise operator on the boolean a bit less:
...
need_redraw |= assign_return_if_changed<int> (tui_border_attrs, entry->value);
...
I've included it anyway, it may be the preferred choice in other cases.
Tested on x86_64-linux.
---
gdb/utils.c | 39 +++++++++++++++++++++++++++++++++++++++
gdb/utils.h | 27 +++++++++++++++++++++++++++
2 files changed, 66 insertions(+)
base-commit: e1eecd81cc6a40b3547a7c5d456919275a0b4a27
Comments
Hi Tom,
> I've initially considered using assign_return_if_changed for the rewrite:
> ...
> template<typename T>
> bool
> assign_return_if_changed (T &lval, T val)
> {
> if (lval == val)
> return false;
>
> lval = val;
> changed = true;
This line should be "return true" (only the commit comment is affected,
the actual implementation is OK).
> }
> ...
> but liked the resulting bitwise operator on the boolean a bit less:
> ...
> need_redraw |= assign_return_if_changed<int> (tui_border_attrs, entry->value);
> ...
I think I like it a bit more (not by far though), but I guess that is
just a personal preference ^_^.
>
> I've included it anyway, it may be the preferred choice in other cases.
>
Best,
Lancelot.
On 5/23/23 11:57, Lancelot SIX wrote:
> Hi Tom,
>
>> I've initially considered using assign_return_if_changed for the rewrite:
>> ...
>> template<typename T>
>> bool
>> assign_return_if_changed (T &lval, T val)
>> {
>> if (lval == val)
>> return false;
>>
>> lval = val;
>> changed = true;
>
> This line should be "return true" (only the commit comment is affected,
> the actual implementation is OK).
>
Thanks for spotting that, I've updated my patch.
>> }
>> ...
>> but liked the resulting bitwise operator on the boolean a bit less:
>> ...
>> need_redraw |= assign_return_if_changed<int> (tui_border_attrs, entry->value);
>> ...
>
> I think I like it a bit more (not by far though), but I guess that is
> just a personal preference ^_^.
>
Thanks for that feedback, that's good to know, and I'm curious about
opinions of other as well.
- Tom
>>
>> I've included it anyway, it may be the preferred choice in other cases.
>>
>
> Best,
> Lancelot.
On 5/23/23 18:20, Tom de Vries via Gdb-patches wrote:
> On 5/23/23 11:57, Lancelot SIX wrote:
>> Hi Tom,
>>
>>> I've initially considered using assign_return_if_changed for the
>>> rewrite:
>>> ...
>>> template<typename T>
>>> bool
>>> assign_return_if_changed (T &lval, T val)
>>> {
>>> if (lval == val)
>>> return false;
>>>
>>> lval = val;
>>> changed = true;
>>
>> This line should be "return true" (only the commit comment is affected,
>> the actual implementation is OK).
>>
>
> Thanks for spotting that, I've updated my patch.
>
>>> }
>>> ...
>>> but liked the resulting bitwise operator on the boolean a bit less:
>>> ...
>>> need_redraw |= assign_return_if_changed<int> (tui_border_attrs,
>>> entry->value);
>>> ...
>>
>> I think I like it a bit more (not by far though), but I guess that is
>> just a personal preference ^_^.
>>
>
> Thanks for that feedback, that's good to know, and I'm curious about
> opinions of other as well.
>
I've submitted a v2 (
https://sourceware.org/pipermail/gdb-patches/2023-June/200148.html ):
- now as patch series, also including a patch implementing the proposed
rewrite in tui_update_variables
- it uses assign_return_if_changed, I've changed my mind about
preferring assign_set_if_changed
- the commit message of the first patch has been updated to be more
neutral
- I've dropped the actual implementation from the commit message.
Thanks,
- Tom
@@ -3631,6 +3631,43 @@ copy_bitwise (gdb_byte *dest, ULONGEST dest_offset,
}
}
+#if GDB_SELF_TEST
+static void
+test_assign_set_return_if_changed ()
+{
+ bool changed;
+ int a;
+
+ for (bool initial : { false, true })
+ {
+ changed = initial;
+ a = 1;
+ assign_set_if_changed (a, 1, changed);
+ SELF_CHECK (a == 1);
+ SELF_CHECK (changed == initial);
+ }
+
+ for (bool initial : { false, true })
+ {
+ changed = initial;
+ a = 1;
+ assign_set_if_changed (a, 2, changed);
+ SELF_CHECK (a == 2);
+ SELF_CHECK (changed == true);
+ }
+
+ a = 1;
+ changed = assign_return_if_changed (a, 1);
+ SELF_CHECK (a == 1);
+ SELF_CHECK (changed == false);
+
+ a = 1;
+ assign_set_if_changed (a, 2, changed);
+ SELF_CHECK (a == 2);
+ SELF_CHECK (changed == true);
+}
+#endif
+
void _initialize_utils ();
void
_initialize_utils ()
@@ -3695,5 +3732,7 @@ When set, debugging messages will be marked with seconds and microseconds."),
selftests::register_test ("strncmp_iw_with_mode",
strncmp_iw_with_mode_tests);
selftests::register_test ("pager", test_pager);
+ selftests::register_test ("assign_set_return_if_changed",
+ test_assign_set_return_if_changed);
#endif
}
@@ -337,4 +337,31 @@ extern void copy_bitwise (gdb_byte *dest, ULONGEST dest_offset,
extern int readline_hidden_cols;
+/* Assign VAL to LVAL, and set CHANGED to true if the assignment changed
+ LVAL. */
+
+template<typename T>
+void
+assign_set_if_changed (T &lval, T val, bool &changed)
+{
+ if (lval == val)
+ return;
+
+ lval = val;
+ changed = true;
+}
+
+/* Assign VAL to LVAL, and return true if the assignment changed LVAL. */
+
+template<typename T>
+bool
+assign_return_if_changed (T &lval, T val)
+{
+ if (lval == val)
+ return false;
+
+ lval = val;
+ return true;
+}
+
#endif /* UTILS_H */