diff mbox

libstdc++ - Add xmethods for associative containers (ordered and unordered)

Message ID CAGyQ6gwF9eh0Jg=JH0MUKsw0pY1-JcBBPnvAxGMEmOHMnJ2b+Q@mail.gmail.com
State New
Headers show

Commit Message

Siva Chandra Nov. 10, 2014, midnight UTC
Hello,

Attached is a patch which adds xmethods for the associative containers
(set, map, multiset and multimap) and their unordered versions. I
think the GDB Python API is not rich enough to implement xmethods for
the more interesting methods like find, count etc. The attached patch
only implements xmethods for size and empty. That way, it is a fairly
straightforward patch.

libstdc++-v3/ChangeLog:

2014-11-09  Siva Chandra Reddy  <sivachandra@google.com>

        * python/libstdcxx/v6/xmethods.py: Add xmethods for associative
        containers.
        * testsuite/libstdc++-xmethods/associative-containers.cc: New
        file.

Comments

Jonathan Wakely Nov. 10, 2014, 9:49 p.m. UTC | #1
On 09/11/14 16:00 -0800, Siva Chandra wrote:
>Hello,
>
>Attached is a patch which adds xmethods for the associative containers
>(set, map, multiset and multimap) and their unordered versions. I
>think the GDB Python API is not rich enough to implement xmethods for
>the more interesting methods like find, count etc. The attached patch
>only implements xmethods for size and empty. That way, it is a fairly
>straightforward patch.

This looks fine, I'll commit it soon. Thanks.
Jonathan Wakely Nov. 11, 2014, 11:38 a.m. UTC | #2
On 10/11/14 21:49 +0000, Jonathan Wakely wrote:
>On 09/11/14 16:00 -0800, Siva Chandra wrote:
>>Hello,
>>
>>Attached is a patch which adds xmethods for the associative containers
>>(set, map, multiset and multimap) and their unordered versions. I
>>think the GDB Python API is not rich enough to implement xmethods for
>>the more interesting methods like find, count etc. The attached patch
>>only implements xmethods for size and empty. That way, it is a fairly
>>straightforward patch.
>
>This looks fine, I'll commit it soon. Thanks.

Committed to trunk.
Siva Chandra Nov. 11, 2014, 1:03 p.m. UTC | #3
On Tue, Nov 11, 2014 at 3:38 AM, Jonathan Wakely <jwakely@redhat.com> wrote:
> On 10/11/14 21:49 +0000, Jonathan Wakely wrote:
>>
>> On 09/11/14 16:00 -0800, Siva Chandra wrote:
>>>
>>> Hello,
>>>
>>> Attached is a patch which adds xmethods for the associative containers
>>> (set, map, multiset and multimap) and their unordered versions. I
>>> think the GDB Python API is not rich enough to implement xmethods for
>>> the more interesting methods like find, count etc. The attached patch
>>> only implements xmethods for size and empty. That way, it is a fairly
>>> straightforward patch.
>>
>>
>> This looks fine, I'll commit it soon. Thanks.
>
>
> Committed to trunk.
>
Siva Chandra Nov. 11, 2014, 1:04 p.m. UTC | #4
On Tue, Nov 11, 2014 at 5:03 AM, Siva Chandra <sivachandra@google.com> wrote:
> On Tue, Nov 11, 2014 at 3:38 AM, Jonathan Wakely <jwakely@redhat.com> wrote:
>> On 10/11/14 21:49 +0000, Jonathan Wakely wrote:
>>>
>>> On 09/11/14 16:00 -0800, Siva Chandra wrote:
>>>>
>>>> Hello,
>>>>
>>>> Attached is a patch which adds xmethods for the associative containers
>>>> (set, map, multiset and multimap) and their unordered versions. I
>>>> think the GDB Python API is not rich enough to implement xmethods for
>>>> the more interesting methods like find, count etc. The attached patch
>>>> only implements xmethods for size and empty. That way, it is a fairly
>>>> straightforward patch.
>>>
>>>
>>> This looks fine, I'll commit it soon. Thanks.
>>
>>
>> Committed to trunk.

Thanks for the quick review and commit.

(Sorry for the premature "Send" earlier.)
Jonathan Wakely Nov. 11, 2014, 10:10 p.m. UTC | #5
On 11/11/14 11:38 +0000, Jonathan Wakely wrote:
>On 10/11/14 21:49 +0000, Jonathan Wakely wrote:
>>On 09/11/14 16:00 -0800, Siva Chandra wrote:
>>>Hello,
>>>
>>>Attached is a patch which adds xmethods for the associative containers
>>>(set, map, multiset and multimap) and their unordered versions. I
>>>think the GDB Python API is not rich enough to implement xmethods for
>>>the more interesting methods like find, count etc. The attached patch
>>>only implements xmethods for size and empty. That way, it is a fairly
>>>straightforward patch.
>>
>>This looks fine, I'll commit it soon. Thanks.
>
>Committed to trunk.

I forgot to 'git add' the new test before committing, done now.
diff mbox

Patch

diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
index 6af1c95..2198411 100644
--- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py
+++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
@@ -422,6 +422,50 @@  class VectorMethodsMatcher(gdb.xmethod.XMethodMatcher):
             return None
         return method.worker_class(class_type.template_argument(0))
 
+# Xmethods for associative containers
+
+class AssociativeContainerWorkerBase(gdb.xmethod.XMethodWorker):
+    def __init__(self, unordered):
+        self._unordered = unordered
+
+    def node_count(self, obj):
+        if self._unordered:
+            return obj['_M_h']['_M_element_count']
+        else:
+            return obj['_M_t']['_M_impl']['_M_node_count']
+
+    def get_arg_types(self):
+        return None
+
+class AssociativeContainerEmptyWorker(AssociativeContainerWorkerBase):
+    def __call__(self, obj):
+        return int(self.node_count(obj)) == 0
+
+class AssociativeContainerSizeWorker(AssociativeContainerWorkerBase):
+    def __call__(self, obj):
+        return self.node_count(obj)
+
+class AssociativeContainerMethodsMatcher(gdb.xmethod.XMethodMatcher):
+    def __init__(self, name):
+        gdb.xmethod.XMethodMatcher.__init__(self,
+                                            matcher_name_prefix + name)
+        self._name = name
+        self._method_dict = {
+            'size': LibStdCxxXMethod('size', AssociativeContainerSizeWorker),
+            'empty': LibStdCxxXMethod('empty',
+                                      AssociativeContainerEmptyWorker),
+        }
+        self.methods = [self._method_dict[m] for m in self._method_dict]
+
+    def match(self, class_type, method_name):
+        if not re.match('^std::%s<.*>$' % self._name, class_type.tag):
+            return None
+        method = self._method_dict.get(method_name)
+        if method is None or not method.enabled:
+            return None
+        unordered = 'unordered' in self._name
+        return method.worker_class(unordered)
+
 # Xmethods for std::unique_ptr
 
 class UniquePtrGetWorker(gdb.xmethod.XMethodWorker):
@@ -465,4 +509,20 @@  def register_libstdcxx_xmethods(locus):
     gdb.xmethod.register_xmethod_matcher(locus, DequeMethodsMatcher())
     gdb.xmethod.register_xmethod_matcher(locus, ListMethodsMatcher())
     gdb.xmethod.register_xmethod_matcher(locus, VectorMethodsMatcher())
+    gdb.xmethod.register_xmethod_matcher(
+        locus, AssociativeContainerMethodsMatcher('set'))
+    gdb.xmethod.register_xmethod_matcher(
+        locus, AssociativeContainerMethodsMatcher('map'))
+    gdb.xmethod.register_xmethod_matcher(
+        locus, AssociativeContainerMethodsMatcher('multiset'))
+    gdb.xmethod.register_xmethod_matcher(
+        locus, AssociativeContainerMethodsMatcher('multimap'))
+    gdb.xmethod.register_xmethod_matcher(
+        locus, AssociativeContainerMethodsMatcher('unordered_set'))
+    gdb.xmethod.register_xmethod_matcher(
+        locus, AssociativeContainerMethodsMatcher('unordered_map'))
+    gdb.xmethod.register_xmethod_matcher(
+        locus, AssociativeContainerMethodsMatcher('unordered_multiset'))
+    gdb.xmethod.register_xmethod_matcher(
+        locus, AssociativeContainerMethodsMatcher('unordered_multimap'))
     gdb.xmethod.register_xmethod_matcher(locus, UniquePtrMethodsMatcher())
diff --git a/libstdc++-v3/testsuite/libstdc++-xmethods/associative-containers.cc b/libstdc++-v3/testsuite/libstdc++-xmethods/associative-containers.cc
new file mode 100644
index 0000000..7949f22
--- /dev/null
+++ b/libstdc++-v3/testsuite/libstdc++-xmethods/associative-containers.cc
@@ -0,0 +1,79 @@ 
+// { dg-do run }
+// { dg-options "-std=gnu++11 -g -O0" }
+
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <set>
+#include <map>
+#include <unordered_set>
+#include <unordered_map>
+
+int
+main ()
+{
+  std::set<int> s, s1;
+  std::multiset<int> ms, ms1;
+  std::unordered_set<int> us, us1;
+  std::unordered_multiset<int> ums, ums1;
+  std::map<char, int> m, m1;
+  std::multimap<char, int> mm, mm1;
+  std::unordered_map<char, int> um, um1;
+  std::unordered_multimap<char, int> umm, umm1;
+
+  for (int i = 0; i < 100; i++)
+    {
+      s.insert (i % 5);
+      ms.insert (i % 5);
+      us.insert (i % 7);
+      ums.insert (i % 7);
+
+      m.insert(std::pair<char, int> ('a' + i % 5, i));
+      mm.insert(std::pair<char, int> ('a' + i % 5, i));
+      um.insert(std::pair<char, int> ('a' + i % 7, i));
+      umm.insert(std::pair<char, int> ('a' + i % 7, i));
+    }
+
+// { dg-final { note-test s.size() 5 } }
+// { dg-final { note-test s.empty() false } }
+// { dg-final { note-test s1.empty() true } }
+// { dg-final { note-test ms.size() 100 } }
+// { dg-final { note-test ms.empty() false } }
+// { dg-final { note-test ms1.empty() true } }
+// { dg-final { note-test us.size() 7 } }
+// { dg-final { note-test us.empty() false } }
+// { dg-final { note-test us1.empty() true } }
+// { dg-final { note-test ums.size() 100 } }
+// { dg-final { note-test ums.empty() false } }
+// { dg-final { note-test ums1.empty() true } }
+// { dg-final { note-test m.size() 5 } }
+// { dg-final { note-test m.empty() false } }
+// { dg-final { note-test m1.empty() true } }
+// { dg-final { note-test mm.size() 100 } }
+// { dg-final { note-test mm.empty() false } }
+// { dg-final { note-test mm1.empty() true } }
+// { dg-final { note-test um.size() 7 } }
+// { dg-final { note-test um.empty() false } }
+// { dg-final { note-test um1.empty() true } }
+// { dg-final { note-test umm.size() 100 } }
+// { dg-final { note-test umm.empty() false } }
+// { dg-final { note-test umm1.empty() true } }
+
+  return 0;  // Mark SPOT
+}
+
+// { dg-final { gdb-test SPOT {} 1 } }