LLVM 19.0.0git
StringMapEntry.h
Go to the documentation of this file.
1//===- llvm/Testing/ADT/StringMapEntry.h ----------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_TESTING_ADT_STRINGMAPENTRY_H_
10#define LLVM_TESTING_ADT_STRINGMAPENTRY_H_
11
13#include "gmock/gmock.h"
14#include <ostream>
15#include <type_traits>
16
17namespace llvm {
18namespace detail {
19
20template <typename T, typename = std::void_t<>>
21struct CanOutputToOStream : std::false_type {};
22
23template <typename T>
24struct CanOutputToOStream<T, std::void_t<decltype(std::declval<std::ostream &>()
25 << std::declval<T>())>>
26 : std::true_type {};
27
28} // namespace detail
29
30/// Support for printing to std::ostream, for use with e.g. producing more
31/// useful error messages with Google Test.
32template <typename T>
33std::ostream &operator<<(std::ostream &OS, const StringMapEntry<T> &E) {
34 OS << "{\"" << E.getKey().data() << "\": ";
35 if constexpr (detail::CanOutputToOStream<decltype(E.getValue())>::value) {
36 OS << E.getValue();
37 } else {
38 OS << "non-printable value";
39 }
40 return OS << "}";
41}
42
43namespace detail {
44
45template <typename StringMapEntryT>
46class StringMapEntryMatcherImpl
47 : public testing::MatcherInterface<StringMapEntryT> {
48public:
49 using ValueT = typename std::remove_reference_t<StringMapEntryT>::ValueType;
50
51 template <typename KeyMatcherT, typename ValueMatcherT>
52 StringMapEntryMatcherImpl(KeyMatcherT KeyMatcherArg,
53 ValueMatcherT ValueMatcherArg)
54 : KeyMatcher(
55 testing::SafeMatcherCast<const std::string &>(KeyMatcherArg)),
56 ValueMatcher(
57 testing::SafeMatcherCast<const ValueT &>(ValueMatcherArg)) {}
58
59 void DescribeTo(std::ostream *OS) const override {
60 *OS << "has a string key that ";
61 KeyMatcher.DescribeTo(OS);
62 *OS << ", and has a value that ";
63 ValueMatcher.DescribeTo(OS);
64 }
65
66 void DescribeNegationTo(std::ostream *OS) const override {
67 *OS << "has a string key that ";
68 KeyMatcher.DescribeNegationTo(OS);
69 *OS << ", or has a value that ";
70 ValueMatcher.DescribeNegationTo(OS);
71 }
72
73 bool
74 MatchAndExplain(StringMapEntryT Entry,
75 testing::MatchResultListener *ResultListener) const override {
76 testing::StringMatchResultListener KeyListener;
77 if (!KeyMatcher.MatchAndExplain(Entry.getKey().data(), &KeyListener)) {
78 *ResultListener << ("which has a string key " +
79 (KeyListener.str().empty() ? "that doesn't match"
80 : KeyListener.str()));
81 return false;
82 }
83 testing::StringMatchResultListener ValueListener;
84 if (!ValueMatcher.MatchAndExplain(Entry.getValue(), &ValueListener)) {
85 *ResultListener << ("which has a value " + (ValueListener.str().empty()
86 ? "that doesn't match"
87 : ValueListener.str()));
88 return false;
89 }
90 *ResultListener << "which is a match";
91 return true;
92 }
93
94private:
95 const testing::Matcher<const std::string &> KeyMatcher;
96 const testing::Matcher<const ValueT &> ValueMatcher;
97};
98
99template <typename KeyMatcherT, typename ValueMatcherT>
100class StringMapEntryMatcher {
101public:
102 StringMapEntryMatcher(KeyMatcherT KMArg, ValueMatcherT VMArg)
103 : KM(std::move(KMArg)), VM(std::move(VMArg)) {}
104
105 template <typename StringMapEntryT>
106 operator testing::Matcher<StringMapEntryT>() const { // NOLINT
107 return testing::Matcher<StringMapEntryT>(
108 new StringMapEntryMatcherImpl<const StringMapEntryT &>(KM, VM));
109 }
110
111private:
112 const KeyMatcherT KM;
113 const ValueMatcherT VM;
114};
115
116} // namespace detail
117
118/// Returns a gMock matcher that matches a `StringMapEntry` whose string key
119/// matches `KeyMatcher`, and whose value matches `ValueMatcher`.
120template <typename KeyMatcherT, typename ValueMatcherT>
121detail::StringMapEntryMatcher<KeyMatcherT, ValueMatcherT>
122IsStringMapEntry(KeyMatcherT KM, ValueMatcherT VM) {
123 return detail::StringMapEntryMatcher<KeyMatcherT, ValueMatcherT>(
124 std::move(KM), std::move(VM));
125}
126
127} // namespace llvm
128
129#endif
This file defines the StringMapEntry class - it is intended to be a low dependency implementation det...
Definition: ClauseT.h:79
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858