[PATCH] D28288: [gmock] (WIP) Teach gmock ElementsAre and BeginEndDistanceIs matchers to handle generic ranges by using std::begin and std::end rather than requiring things to look exactly like an STL container.

Chandler Carruth via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 4 05:12:09 PST 2017


chandlerc created this revision.
chandlerc added a subscriber: llvm-commits.
chandlerc added a dependency: D28156: Add the 'googlemock' component of Google Test to LLVM's unittest libraries..
Herald added a subscriber: mcrosier.

Much of the credit for this goes to Dave Blaikie who helped me figure
out the right incantations.

This will probably be re-designed when I send this to the maintainers of
gmock, so I've instead structured it to change is little as possible
while it is a local patch. That makes it somewhat ugly, but I think a focused
change is better for getting this to work for LLVM today and letting the
upstream maintainers figure out the correct long-term pattern.

Note that I'm not looking to submit this, mostly to show all the patches
necessary in some examples of what using GoogleMock might look like in LLVM. So
just sending this out so folks can patch it in and play with it. There will be
an llvm-dev thread to discuss the larger issue of using gmock, and this will
only be seriously proposed for submission if the community decides to do that.

Depends on https://reviews.llvm.org/D28156.


https://reviews.llvm.org/D28288

Files:
  utils/unittest/googlemock/include/gmock/gmock-matchers.h


Index: utils/unittest/googlemock/include/gmock/gmock-matchers.h
===================================================================
--- utils/unittest/googlemock/include/gmock/gmock-matchers.h
+++ utils/unittest/googlemock/include/gmock/gmock-matchers.h
@@ -2462,11 +2462,14 @@
   template <typename Container>
   class Impl : public MatcherInterface<Container> {
    public:
-    typedef internal::StlContainerView<
-        GTEST_REMOVE_REFERENCE_AND_CONST_(Container)> ContainerView;
+    typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
+    typedef internal::StlContainerView<RawContainer> View;
+    typedef typename View::type StlContainer;
+    typedef typename View::const_reference StlContainerReference;
+    typedef decltype(std::begin(
+        std::declval<StlContainerReference>())) StlContainerConstIterator;
     typedef typename std::iterator_traits<
-        typename ContainerView::type::const_iterator>::difference_type
-        DistanceType;
+        StlContainerConstIterator>::difference_type DistanceType;
     explicit Impl(const DistanceMatcher& distance_matcher)
         : distance_matcher_(MatcherCast<DistanceType>(distance_matcher)) {}
 
@@ -3111,7 +3114,10 @@
   typedef internal::StlContainerView<RawContainer> View;
   typedef typename View::type StlContainer;
   typedef typename View::const_reference StlContainerReference;
-  typedef typename StlContainer::value_type Element;
+  typedef decltype(std::begin(
+      std::declval<StlContainerReference>())) StlContainerConstIterator;
+  typedef typename std::remove_reference<decltype(
+      *std::declval<StlContainerConstIterator &>())>::type Element;
 
   // Constructs the matcher from a sequence of element values or
   // element matchers.
@@ -3168,7 +3174,7 @@
     // explanations[i] is the explanation of the element at index i.
     ::std::vector<internal::string> explanations(count());
     StlContainerReference stl_container = View::ConstReference(container);
-    typename StlContainer::const_iterator it = stl_container.begin();
+    StlContainerConstIterator it = stl_container.begin();
     size_t exam_pos = 0;
     bool mismatch_found = false;  // Have we found a mismatched element yet?
 
@@ -3350,8 +3356,10 @@
   typedef internal::StlContainerView<RawContainer> View;
   typedef typename View::type StlContainer;
   typedef typename View::const_reference StlContainerReference;
-  typedef typename StlContainer::const_iterator StlContainerConstIterator;
-  typedef typename StlContainer::value_type Element;
+  typedef decltype(std::begin(
+      std::declval<StlContainerReference>())) StlContainerConstIterator;
+  typedef typename std::remove_reference<decltype(
+      *std::declval<StlContainerConstIterator &>())>::type Element;
 
   // Constructs the matcher from a sequence of element values or
   // element matchers.
@@ -3456,8 +3464,12 @@
   template <typename Container>
   operator Matcher<Container>() const {
     typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
-    typedef typename internal::StlContainerView<RawContainer>::type View;
-    typedef typename View::value_type Element;
+    typedef internal::StlContainerView<RawContainer> View;
+    typedef typename View::const_reference StlContainerReference;
+    typedef decltype(std::begin(
+        std::declval<StlContainerReference>())) StlContainerConstIterator;
+    typedef typename std::remove_reference<decltype(
+        *std::declval<StlContainerConstIterator &>())>::type Element;
     typedef ::std::vector<Matcher<const Element&> > MatcherVec;
     MatcherVec matchers;
     matchers.reserve(::testing::tuple_size<MatcherTuple>::value);
@@ -3481,8 +3493,12 @@
   template <typename Container>
   operator Matcher<Container>() const {
     typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
-    typedef typename internal::StlContainerView<RawContainer>::type View;
-    typedef typename View::value_type Element;
+    typedef internal::StlContainerView<RawContainer> View;
+    typedef typename View::const_reference StlContainerReference;
+    typedef decltype(std::begin(
+        std::declval<StlContainerReference>())) StlContainerConstIterator;
+    typedef typename std::remove_reference<decltype(
+        *std::declval<StlContainerConstIterator &>())>::type Element;
     typedef ::std::vector<Matcher<const Element&> > MatcherVec;
     MatcherVec matchers;
     matchers.reserve(::testing::tuple_size<MatcherTuple>::value);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D28288.83035.patch
Type: text/x-patch
Size: 4480 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170104/c9f33be0/attachment.bin>


More information about the llvm-commits mailing list