Make gmock-matchers.h auto-detect the value_type of ranges that don't have a typedef for it based on the ranges' iterators
This is needed for ranges such as [`std::ranges::subrange`](https://en.cppreference.com/w/cpp/ranges/subrange.html) that don't expose the typical typedefs. PiperOrigin-RevId: 879124865 Change-Id: Ie89e6ff249ee861d1b2d880079dc162bb9801679
This commit is contained in:
committed by
Copybara-Service
parent
73a63ea05d
commit
a35bc7693c
@@ -2602,9 +2602,9 @@ class [[nodiscard]] WhenSortedByMatcher {
|
|||||||
typedef typename LhsView::const_reference LhsStlContainerReference;
|
typedef typename LhsView::const_reference LhsStlContainerReference;
|
||||||
// Transforms std::pair<const Key, Value> into std::pair<Key, Value>
|
// Transforms std::pair<const Key, Value> into std::pair<Key, Value>
|
||||||
// so that we can match associative containers.
|
// so that we can match associative containers.
|
||||||
typedef
|
typedef typename RemoveConstFromKey<
|
||||||
typename RemoveConstFromKey<typename LhsStlContainer::value_type>::type
|
typename internal::RangeTraits<LhsStlContainer>::value_type>::type
|
||||||
LhsValue;
|
LhsValue;
|
||||||
|
|
||||||
Impl(const Comparator& comparator, const ContainerMatcher& matcher)
|
Impl(const Comparator& comparator, const ContainerMatcher& matcher)
|
||||||
: comparator_(comparator), matcher_(matcher) {}
|
: comparator_(comparator), matcher_(matcher) {}
|
||||||
@@ -2670,7 +2670,7 @@ class [[nodiscard]] PointwiseMatcher {
|
|||||||
public:
|
public:
|
||||||
typedef internal::StlContainerView<RhsContainer> RhsView;
|
typedef internal::StlContainerView<RhsContainer> RhsView;
|
||||||
typedef typename RhsView::type RhsStlContainer;
|
typedef typename RhsView::type RhsStlContainer;
|
||||||
typedef typename RhsStlContainer::value_type RhsValue;
|
typedef typename internal::RangeTraits<RhsStlContainer>::value_type RhsValue;
|
||||||
|
|
||||||
static_assert(!std::is_const<RhsContainer>::value,
|
static_assert(!std::is_const<RhsContainer>::value,
|
||||||
"RhsContainer type must not be const");
|
"RhsContainer type must not be const");
|
||||||
@@ -2700,7 +2700,8 @@ class [[nodiscard]] PointwiseMatcher {
|
|||||||
LhsView;
|
LhsView;
|
||||||
typedef typename LhsView::type LhsStlContainer;
|
typedef typename LhsView::type LhsStlContainer;
|
||||||
typedef typename LhsView::const_reference LhsStlContainerReference;
|
typedef typename LhsView::const_reference LhsStlContainerReference;
|
||||||
typedef typename LhsStlContainer::value_type LhsValue;
|
typedef
|
||||||
|
typename internal::RangeTraits<LhsStlContainer>::value_type LhsValue;
|
||||||
// We pass the LHS value and the RHS value to the inner matcher by
|
// 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
|
// reference, as they may be expensive to copy. We must use tuple
|
||||||
// instead of pair here, as a pair cannot hold references (C++ 98,
|
// instead of pair here, as a pair cannot hold references (C++ 98,
|
||||||
@@ -2786,7 +2787,7 @@ class [[nodiscard]] QuantifierMatcherImpl : public MatcherInterface<Container> {
|
|||||||
typedef StlContainerView<RawContainer> View;
|
typedef StlContainerView<RawContainer> View;
|
||||||
typedef typename View::type StlContainer;
|
typedef typename View::type StlContainer;
|
||||||
typedef typename View::const_reference StlContainerReference;
|
typedef typename View::const_reference StlContainerReference;
|
||||||
typedef typename StlContainer::value_type Element;
|
typedef typename internal::RangeTraits<StlContainer>::value_type Element;
|
||||||
|
|
||||||
template <typename InnerMatcher>
|
template <typename InnerMatcher>
|
||||||
explicit QuantifierMatcherImpl(InnerMatcher inner_matcher)
|
explicit QuantifierMatcherImpl(InnerMatcher inner_matcher)
|
||||||
@@ -3600,7 +3601,7 @@ class [[nodiscard]] ElementsAreMatcherImpl
|
|||||||
typedef internal::StlContainerView<RawContainer> View;
|
typedef internal::StlContainerView<RawContainer> View;
|
||||||
typedef typename View::type StlContainer;
|
typedef typename View::type StlContainer;
|
||||||
typedef typename View::const_reference StlContainerReference;
|
typedef typename View::const_reference StlContainerReference;
|
||||||
typedef typename StlContainer::value_type Element;
|
typedef typename internal::RangeTraits<StlContainer>::value_type Element;
|
||||||
|
|
||||||
// Constructs the matcher from a sequence of element values or
|
// Constructs the matcher from a sequence of element values or
|
||||||
// element matchers.
|
// element matchers.
|
||||||
@@ -3875,7 +3876,7 @@ class [[nodiscard]] UnorderedElementsAreMatcherImpl
|
|||||||
typedef internal::StlContainerView<RawContainer> View;
|
typedef internal::StlContainerView<RawContainer> View;
|
||||||
typedef typename View::type StlContainer;
|
typedef typename View::type StlContainer;
|
||||||
typedef typename View::const_reference StlContainerReference;
|
typedef typename View::const_reference StlContainerReference;
|
||||||
typedef typename StlContainer::value_type Element;
|
typedef typename internal::RangeTraits<StlContainer>::value_type Element;
|
||||||
|
|
||||||
template <typename InputIter>
|
template <typename InputIter>
|
||||||
UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags,
|
UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags,
|
||||||
@@ -3963,8 +3964,7 @@ class [[nodiscard]] UnorderedElementsAreMatcher {
|
|||||||
template <typename Container>
|
template <typename Container>
|
||||||
operator Matcher<Container>() const {
|
operator Matcher<Container>() const {
|
||||||
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
|
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
|
||||||
typedef typename internal::StlContainerView<RawContainer>::type View;
|
typedef typename internal::RangeTraits<RawContainer>::value_type Element;
|
||||||
typedef typename View::value_type Element;
|
|
||||||
typedef ::std::vector<Matcher<const Element&>> MatcherVec;
|
typedef ::std::vector<Matcher<const Element&>> MatcherVec;
|
||||||
MatcherVec matchers;
|
MatcherVec matchers;
|
||||||
matchers.reserve(::std::tuple_size<MatcherTuple>::value);
|
matchers.reserve(::std::tuple_size<MatcherTuple>::value);
|
||||||
@@ -3995,7 +3995,7 @@ class [[nodiscard]] ElementsAreMatcher {
|
|||||||
|
|
||||||
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
|
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
|
||||||
typedef typename internal::StlContainerView<RawContainer>::type View;
|
typedef typename internal::StlContainerView<RawContainer>::type View;
|
||||||
typedef typename View::value_type Element;
|
typedef typename internal::RangeTraits<View>::value_type Element;
|
||||||
typedef ::std::vector<Matcher<const Element&>> MatcherVec;
|
typedef ::std::vector<Matcher<const Element&>> MatcherVec;
|
||||||
MatcherVec matchers;
|
MatcherVec matchers;
|
||||||
matchers.reserve(::std::tuple_size<MatcherTuple>::value);
|
matchers.reserve(::std::tuple_size<MatcherTuple>::value);
|
||||||
@@ -5081,7 +5081,7 @@ UnorderedPointwise(const Tuple2Matcher& tuple2_matcher,
|
|||||||
// STL-style container and it being a native C-style array.
|
// STL-style container and it being a native C-style array.
|
||||||
typedef typename internal::StlContainerView<RhsContainer> RhsView;
|
typedef typename internal::StlContainerView<RhsContainer> RhsView;
|
||||||
typedef typename RhsView::type RhsStlContainer;
|
typedef typename RhsView::type RhsStlContainer;
|
||||||
typedef typename RhsStlContainer::value_type Second;
|
typedef typename internal::RangeTraits<RhsStlContainer>::value_type Second;
|
||||||
const RhsStlContainer& rhs_stl_container =
|
const RhsStlContainer& rhs_stl_container =
|
||||||
RhsView::ConstReference(rhs_container);
|
RhsView::ConstReference(rhs_container);
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
#include <ostream> // NOLINT
|
#include <ostream> // NOLINT
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
@@ -322,6 +323,24 @@ inline T Invalid() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GetValueType(const void*);
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
typename std::iterator_traits<
|
||||||
|
decltype(std::begin(std::declval<T&>()))>::value_type
|
||||||
|
GetValueType(T*);
|
||||||
|
|
||||||
|
template <class T, class = void>
|
||||||
|
struct RangeTraits {
|
||||||
|
typedef decltype(internal::GetValueType(
|
||||||
|
static_cast<std::remove_reference_t<T>*>(nullptr))) value_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct RangeTraits<T, std::conditional_t<true, void, typename T::value_type>> {
|
||||||
|
typedef typename T::value_type value_type;
|
||||||
|
};
|
||||||
|
|
||||||
// Given a raw type (i.e. having no top-level reference or const
|
// Given a raw type (i.e. having no top-level reference or const
|
||||||
// modifier) RawContainer that's either an STL-style container or a
|
// modifier) RawContainer that's either an STL-style container or a
|
||||||
// native array, class StlContainerView<RawContainer> has the
|
// native array, class StlContainerView<RawContainer> has the
|
||||||
|
|||||||
Reference in New Issue
Block a user