diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index 2532d597..2f49371a 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -2602,9 +2602,9 @@ class [[nodiscard]] WhenSortedByMatcher { typedef typename LhsView::const_reference LhsStlContainerReference; // Transforms std::pair into std::pair // so that we can match associative containers. - typedef - typename RemoveConstFromKey::type - LhsValue; + typedef typename RemoveConstFromKey< + typename internal::RangeTraits::value_type>::type + LhsValue; Impl(const Comparator& comparator, const ContainerMatcher& matcher) : comparator_(comparator), matcher_(matcher) {} @@ -2670,7 +2670,7 @@ class [[nodiscard]] PointwiseMatcher { public: typedef internal::StlContainerView RhsView; typedef typename RhsView::type RhsStlContainer; - typedef typename RhsStlContainer::value_type RhsValue; + typedef typename internal::RangeTraits::value_type RhsValue; static_assert(!std::is_const::value, "RhsContainer type must not be const"); @@ -2700,7 +2700,8 @@ class [[nodiscard]] PointwiseMatcher { LhsView; typedef typename LhsView::type LhsStlContainer; typedef typename LhsView::const_reference LhsStlContainerReference; - typedef typename LhsStlContainer::value_type LhsValue; + typedef + typename internal::RangeTraits::value_type LhsValue; // We pass the LHS value and the RHS value to the inner matcher by // reference, as they may be expensive to copy. We must use tuple // instead of pair here, as a pair cannot hold references (C++ 98, @@ -2786,7 +2787,7 @@ class [[nodiscard]] QuantifierMatcherImpl : public MatcherInterface { typedef StlContainerView View; typedef typename View::type StlContainer; typedef typename View::const_reference StlContainerReference; - typedef typename StlContainer::value_type Element; + typedef typename internal::RangeTraits::value_type Element; template explicit QuantifierMatcherImpl(InnerMatcher inner_matcher) @@ -3600,7 +3601,7 @@ class [[nodiscard]] ElementsAreMatcherImpl typedef internal::StlContainerView View; typedef typename View::type StlContainer; typedef typename View::const_reference StlContainerReference; - typedef typename StlContainer::value_type Element; + typedef typename internal::RangeTraits::value_type Element; // Constructs the matcher from a sequence of element values or // element matchers. @@ -3875,7 +3876,7 @@ class [[nodiscard]] UnorderedElementsAreMatcherImpl typedef internal::StlContainerView View; typedef typename View::type StlContainer; typedef typename View::const_reference StlContainerReference; - typedef typename StlContainer::value_type Element; + typedef typename internal::RangeTraits::value_type Element; template UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags, @@ -3963,8 +3964,7 @@ class [[nodiscard]] UnorderedElementsAreMatcher { template operator Matcher() const { typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; - typedef typename internal::StlContainerView::type View; - typedef typename View::value_type Element; + typedef typename internal::RangeTraits::value_type Element; typedef ::std::vector> MatcherVec; MatcherVec matchers; matchers.reserve(::std::tuple_size::value); @@ -3995,7 +3995,7 @@ class [[nodiscard]] ElementsAreMatcher { typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; typedef typename internal::StlContainerView::type View; - typedef typename View::value_type Element; + typedef typename internal::RangeTraits::value_type Element; typedef ::std::vector> MatcherVec; MatcherVec matchers; matchers.reserve(::std::tuple_size::value); @@ -5081,7 +5081,7 @@ UnorderedPointwise(const Tuple2Matcher& tuple2_matcher, // STL-style container and it being a native C-style array. typedef typename internal::StlContainerView RhsView; typedef typename RhsView::type RhsStlContainer; - typedef typename RhsStlContainer::value_type Second; + typedef typename internal::RangeTraits::value_type Second; const RhsStlContainer& rhs_stl_container = RhsView::ConstReference(rhs_container); diff --git a/googlemock/include/gmock/internal/gmock-internal-utils.h b/googlemock/include/gmock/internal/gmock-internal-utils.h index 2e746f82..258397a4 100644 --- a/googlemock/include/gmock/internal/gmock-internal-utils.h +++ b/googlemock/include/gmock/internal/gmock-internal-utils.h @@ -41,6 +41,7 @@ #include +#include #include // NOLINT #include #include @@ -322,6 +323,24 @@ inline T Invalid() { #endif } +void GetValueType(const void*); + +template +typename std::iterator_traits< + decltype(std::begin(std::declval()))>::value_type +GetValueType(T*); + +template +struct RangeTraits { + typedef decltype(internal::GetValueType( + static_cast*>(nullptr))) value_type; +}; + +template +struct RangeTraits> { + typedef typename T::value_type value_type; +}; + // Given a raw type (i.e. having no top-level reference or const // modifier) RawContainer that's either an STL-style container or a // native array, class StlContainerView has the