mirror of
https://github.com/google/googletest.git
synced 2026-04-30 19:09:20 +08:00
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:
parent
73a63ea05d
commit
a35bc7693c
@ -2602,9 +2602,9 @@ class [[nodiscard]] WhenSortedByMatcher {
|
||||
typedef typename LhsView::const_reference LhsStlContainerReference;
|
||||
// Transforms std::pair<const Key, Value> into std::pair<Key, Value>
|
||||
// so that we can match associative containers.
|
||||
typedef
|
||||
typename RemoveConstFromKey<typename LhsStlContainer::value_type>::type
|
||||
LhsValue;
|
||||
typedef typename RemoveConstFromKey<
|
||||
typename internal::RangeTraits<LhsStlContainer>::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<RhsContainer> RhsView;
|
||||
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,
|
||||
"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<LhsStlContainer>::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<Container> {
|
||||
typedef StlContainerView<RawContainer> View;
|
||||
typedef typename View::type StlContainer;
|
||||
typedef typename View::const_reference StlContainerReference;
|
||||
typedef typename StlContainer::value_type Element;
|
||||
typedef typename internal::RangeTraits<StlContainer>::value_type Element;
|
||||
|
||||
template <typename InnerMatcher>
|
||||
explicit QuantifierMatcherImpl(InnerMatcher inner_matcher)
|
||||
@ -3600,7 +3601,7 @@ class [[nodiscard]] ElementsAreMatcherImpl
|
||||
typedef internal::StlContainerView<RawContainer> View;
|
||||
typedef typename View::type StlContainer;
|
||||
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
|
||||
// element matchers.
|
||||
@ -3875,7 +3876,7 @@ class [[nodiscard]] UnorderedElementsAreMatcherImpl
|
||||
typedef internal::StlContainerView<RawContainer> View;
|
||||
typedef typename View::type StlContainer;
|
||||
typedef typename View::const_reference StlContainerReference;
|
||||
typedef typename StlContainer::value_type Element;
|
||||
typedef typename internal::RangeTraits<StlContainer>::value_type Element;
|
||||
|
||||
template <typename InputIter>
|
||||
UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags,
|
||||
@ -3963,8 +3964,7 @@ class [[nodiscard]] UnorderedElementsAreMatcher {
|
||||
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 typename internal::RangeTraits<RawContainer>::value_type Element;
|
||||
typedef ::std::vector<Matcher<const Element&>> MatcherVec;
|
||||
MatcherVec matchers;
|
||||
matchers.reserve(::std::tuple_size<MatcherTuple>::value);
|
||||
@ -3995,7 +3995,7 @@ class [[nodiscard]] ElementsAreMatcher {
|
||||
|
||||
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
|
||||
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;
|
||||
MatcherVec matchers;
|
||||
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.
|
||||
typedef typename internal::StlContainerView<RhsContainer> RhsView;
|
||||
typedef typename RhsView::type RhsStlContainer;
|
||||
typedef typename RhsStlContainer::value_type Second;
|
||||
typedef typename internal::RangeTraits<RhsStlContainer>::value_type Second;
|
||||
const RhsStlContainer& rhs_stl_container =
|
||||
RhsView::ConstReference(rhs_container);
|
||||
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <iterator>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
@ -322,6 +323,24 @@ inline T Invalid() {
|
||||
#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
|
||||
// modifier) RawContainer that's either an STL-style container or a
|
||||
// native array, class StlContainerView<RawContainer> has the
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user