]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdbsupport: add gdb::make_array_view overload to create from an array
authorSimon Marchi <simon.marchi@polymtl.ca>
Sun, 9 Feb 2025 05:51:00 +0000 (00:51 -0500)
committerSimon Marchi <simon.marchi@efficios.com>
Mon, 10 Feb 2025 16:17:23 +0000 (11:17 -0500)
I think this overload will be useful for the following reasons.
Consider a templated function like this:

    template <typename T>
    void func(gdb::array_view<T> view) {}

Trying to pass an array to this function doesn't work, as template
argument deduction fails:

    test.c:698:8: error: no matching function for call to ‘func(int [12])’
      698 |   func (array);
          |   ~~~~~^~~~~~~
    test.c:686:6: note: candidate: ‘template<class T> void func(gdb::array_view<U>)’
      686 | void func(gdb::array_view<T> view) {}
          |      ^~~~
    test.c:686:6: note:   template argument deduction/substitution failed:
    test.c:698:8: note:   mismatched types ‘gdb::array_view<U>’ and ‘int*’
      698 |   func (array);
          |   ~~~~~^~~~~~~

Similarly, trying to compare a view with an array doesn't work.  This:

  int array[12];
  gdb::array_view<int> view;

  if (view == array) {}

... fails with:

    test.c:698:8: error: no matching function for call to ‘func(int [12])’
      698 |   func (array);
          |   ~~~~~^~~~~~~
    test.c:686:6: note: candidate: ‘template<class T> void func(gdb::array_view<U>)’
      686 | void func(gdb::array_view<T> view) {}
          |      ^~~~
    test.c:686:6: note:   template argument deduction/substitution failed:
    test.c:698:8: note:   mismatched types ‘gdb::array_view<U>’ and ‘int*’
      698 |   func (array);
          |   ~~~~~^~~~~~~

With this new overload, we can do:

    func (gdb::make_array_view (array));

and

    if (view == gdb::make_array_view (array)) {}

This is not ideal, I wish that omitting `gdb::make_array_view` would
just work, but at least it allows creating an array view and have the
element type automatically deduced from the array type.

If someone knows how to make these cases "just work", I would be happy
to know how.

Change-Id: I6a71919d2d5a385e6826801d53f5071b470fef5f
Approved-By: Tom Tromey <tom@tromey.com>
gdb/unittests/array-view-selftests.c
gdbsupport/array-view.h

index c07b5720ef0abe5bbe5c01c503d407394b135665..cc3fcfd8173d9aae46e80c60f04e08b9567390ad 100644 (file)
@@ -554,6 +554,19 @@ run_tests ()
       SELF_CHECK (view[i] == data[i]);
   }
 
+  /* gdb::make_array_view with an array.  */
+  {
+    const gdb_byte data[] = {0x55, 0x66, 0x77, 0x88};
+    const auto len = sizeof (data) / sizeof (data[0]);
+    const auto view = gdb::make_array_view (data);
+
+    SELF_CHECK (view.data () == data);
+    SELF_CHECK (view.size () == len);
+
+    for (std::size_t i = 0; i < len; ++i)
+      SELF_CHECK (view[i] == data[i]);
+  }
+
   /* Test slicing.  */
   {
     gdb_byte data[] = {0x55, 0x66, 0x77, 0x88, 0x99};
index 5054d7013fac2d7e73904de6b9ea8fcb20348921..5dcf8d83990dcf3ecae610ed944e706642e86911 100644 (file)
@@ -294,6 +294,15 @@ make_array_view (U *array, size_t size) noexcept
   return {array, size};
 }
 
+/* Create an array view from an array.  */
+
+template <typename U, std::size_t Size>
+constexpr inline array_view<U>
+make_array_view (U (&array)[Size])
+{
+  return {array};
+}
+
 } /* namespace gdb */
 
 #endif /* GDBSUPPORT_ARRAY_VIEW_H */