Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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.  
  12. #include "llvm/ADT/StringMapEntry.h"
  13. #include "gmock/gmock.h"
  14. #include <ostream>
  15. #include <type_traits>
  16.  
  17. namespace llvm {
  18. namespace detail {
  19.  
  20. template <typename T, typename = std::void_t<>>
  21. struct CanOutputToOStream : std::false_type {};
  22.  
  23. template <typename T>
  24. struct 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.
  32. template <typename T>
  33. std::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.  
  43. namespace detail {
  44.  
  45. template <typename StringMapEntryT>
  46. class StringMapEntryMatcherImpl
  47.     : public testing::MatcherInterface<StringMapEntryT> {
  48. public:
  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.  
  94. private:
  95.   const testing::Matcher<const std::string &> KeyMatcher;
  96.   const testing::Matcher<const ValueT &> ValueMatcher;
  97. };
  98.  
  99. template <typename KeyMatcherT, typename ValueMatcherT>
  100. class StringMapEntryMatcher {
  101. public:
  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.  
  111. private:
  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`.
  120. template <typename KeyMatcherT, typename ValueMatcherT>
  121. detail::StringMapEntryMatcher<KeyMatcherT, ValueMatcherT>
  122. IsStringMapEntry(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
  130.