Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:37

0001 //===- llvm/Testing/ADT/StringMapEntry.h ----------------------------------===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_TESTING_ADT_STRINGMAPENTRY_H_
0010 #define LLVM_TESTING_ADT_STRINGMAPENTRY_H_
0011 
0012 #include "llvm/ADT/StringMapEntry.h"
0013 #include "gmock/gmock.h"
0014 #include <ostream>
0015 #include <type_traits>
0016 
0017 namespace llvm {
0018 namespace detail {
0019 
0020 template <typename T, typename = std::void_t<>>
0021 struct CanOutputToOStream : std::false_type {};
0022 
0023 template <typename T>
0024 struct CanOutputToOStream<T, std::void_t<decltype(std::declval<std::ostream &>()
0025                                                   << std::declval<T>())>>
0026     : std::true_type {};
0027 
0028 } // namespace detail
0029 
0030 /// Support for printing to std::ostream, for use with e.g. producing more
0031 /// useful error messages with Google Test.
0032 template <typename T>
0033 std::ostream &operator<<(std::ostream &OS, const StringMapEntry<T> &E) {
0034   OS << "{\"" << E.getKey().data() << "\": ";
0035   if constexpr (detail::CanOutputToOStream<decltype(E.getValue())>::value) {
0036     OS << E.getValue();
0037   } else {
0038     OS << "non-printable value";
0039   }
0040   return OS << "}";
0041 }
0042 
0043 namespace detail {
0044 
0045 template <typename StringMapEntryT>
0046 class StringMapEntryMatcherImpl
0047     : public testing::MatcherInterface<StringMapEntryT> {
0048 public:
0049   using ValueT = typename std::remove_reference_t<StringMapEntryT>::ValueType;
0050 
0051   template <typename KeyMatcherT, typename ValueMatcherT>
0052   StringMapEntryMatcherImpl(KeyMatcherT KeyMatcherArg,
0053                             ValueMatcherT ValueMatcherArg)
0054       : KeyMatcher(
0055             testing::SafeMatcherCast<const std::string &>(KeyMatcherArg)),
0056         ValueMatcher(
0057             testing::SafeMatcherCast<const ValueT &>(ValueMatcherArg)) {}
0058 
0059   void DescribeTo(std::ostream *OS) const override {
0060     *OS << "has a string key that ";
0061     KeyMatcher.DescribeTo(OS);
0062     *OS << ", and has a value that ";
0063     ValueMatcher.DescribeTo(OS);
0064   }
0065 
0066   void DescribeNegationTo(std::ostream *OS) const override {
0067     *OS << "has a string key that ";
0068     KeyMatcher.DescribeNegationTo(OS);
0069     *OS << ", or has a value that ";
0070     ValueMatcher.DescribeNegationTo(OS);
0071   }
0072 
0073   bool
0074   MatchAndExplain(StringMapEntryT Entry,
0075                   testing::MatchResultListener *ResultListener) const override {
0076     testing::StringMatchResultListener KeyListener;
0077     if (!KeyMatcher.MatchAndExplain(Entry.getKey().data(), &KeyListener)) {
0078       *ResultListener << ("which has a string key " +
0079                           (KeyListener.str().empty() ? "that doesn't match"
0080                                                      : KeyListener.str()));
0081       return false;
0082     }
0083     testing::StringMatchResultListener ValueListener;
0084     if (!ValueMatcher.MatchAndExplain(Entry.getValue(), &ValueListener)) {
0085       *ResultListener << ("which has a value " + (ValueListener.str().empty()
0086                                                       ? "that doesn't match"
0087                                                       : ValueListener.str()));
0088       return false;
0089     }
0090     *ResultListener << "which is a match";
0091     return true;
0092   }
0093 
0094 private:
0095   const testing::Matcher<const std::string &> KeyMatcher;
0096   const testing::Matcher<const ValueT &> ValueMatcher;
0097 };
0098 
0099 template <typename KeyMatcherT, typename ValueMatcherT>
0100 class StringMapEntryMatcher {
0101 public:
0102   StringMapEntryMatcher(KeyMatcherT KMArg, ValueMatcherT VMArg)
0103       : KM(std::move(KMArg)), VM(std::move(VMArg)) {}
0104 
0105   template <typename StringMapEntryT>
0106   operator testing::Matcher<StringMapEntryT>() const { // NOLINT
0107     return testing::Matcher<StringMapEntryT>(
0108         new StringMapEntryMatcherImpl<const StringMapEntryT &>(KM, VM));
0109   }
0110 
0111 private:
0112   const KeyMatcherT KM;
0113   const ValueMatcherT VM;
0114 };
0115 
0116 } // namespace detail
0117 
0118 /// Returns a gMock matcher that matches a `StringMapEntry` whose string key
0119 /// matches `KeyMatcher`, and whose value matches `ValueMatcher`.
0120 template <typename KeyMatcherT, typename ValueMatcherT>
0121 detail::StringMapEntryMatcher<KeyMatcherT, ValueMatcherT>
0122 IsStringMapEntry(KeyMatcherT KM, ValueMatcherT VM) {
0123   return detail::StringMapEntryMatcher<KeyMatcherT, ValueMatcherT>(
0124       std::move(KM), std::move(VM));
0125 }
0126 
0127 } // namespace llvm
0128 
0129 #endif