| Index: webrtc/base/optional.h
 | 
| diff --git a/webrtc/base/optional.h b/webrtc/base/optional.h
 | 
| index f5354ee0f25fdb6eabcf6fa367e3db64152681ee..c8ed069d55570b1f6bf5e7191bcf121626dd0a0b 100644
 | 
| --- a/webrtc/base/optional.h
 | 
| +++ b/webrtc/base/optional.h
 | 
| @@ -15,6 +15,11 @@
 | 
|  #include <memory>
 | 
|  #include <utility>
 | 
|  
 | 
| +#ifdef UNIT_TEST
 | 
| +#include <iomanip>
 | 
| +#include <ostream>
 | 
| +#endif  // UNIT_TEST
 | 
| +
 | 
|  #include "webrtc/base/array_view.h"
 | 
|  #include "webrtc/base/checks.h"
 | 
|  #include "webrtc/base/sanitizer.h"
 | 
| @@ -25,7 +30,9 @@ namespace optional_internal {
 | 
|  
 | 
|  #if RTC_HAS_ASAN
 | 
|  
 | 
| -// This is a non-inlined function. The optimizer can't see inside it.
 | 
| +// This is a non-inlined function. The optimizer can't see inside it.  It
 | 
| +// prevents the compiler from generating optimized code that reads value_ even
 | 
| +// if it is unset. Although safe, this causes memory sanitizers to complain.
 | 
|  void* FunctionThatDoesNothingImpl(void*);
 | 
|  
 | 
|  template <typename T>
 | 
| @@ -296,6 +303,98 @@ class Optional final {
 | 
|    };
 | 
|  };
 | 
|  
 | 
| +#ifdef UNIT_TEST
 | 
| +namespace optional_internal {
 | 
| +
 | 
| +// Checks if there's a valid PrintTo(const T&, std::ostream*) call for T.
 | 
| +template <typename T>
 | 
| +struct HasPrintTo {
 | 
| + private:
 | 
| +  struct No {};
 | 
| +
 | 
| +  template <typename T2>
 | 
| +  static auto Test(const T2& obj)
 | 
| +      -> decltype(PrintTo(obj, std::declval<std::ostream*>()));
 | 
| +
 | 
| +  template <typename>
 | 
| +  static No Test(...);
 | 
| +
 | 
| + public:
 | 
| +  static constexpr bool value =
 | 
| +      !std::is_same<decltype(Test<T>(std::declval<const T&>())), No>::value;
 | 
| +};
 | 
| +
 | 
| +// Checks if there's a valid operator<<(std::ostream&, const T&) call for T.
 | 
| +template <typename T>
 | 
| +struct HasOstreamOperator {
 | 
| + private:
 | 
| +  struct No {};
 | 
| +
 | 
| +  template <typename T2>
 | 
| +  static auto Test(const T2& obj)
 | 
| +      -> decltype(std::declval<std::ostream&>() << obj);
 | 
| +
 | 
| +  template <typename>
 | 
| +  static No Test(...);
 | 
| +
 | 
| + public:
 | 
| +  static constexpr bool value =
 | 
| +      !std::is_same<decltype(Test<T>(std::declval<const T&>())), No>::value;
 | 
| +};
 | 
| +
 | 
| +// Prefer using PrintTo to print the object.
 | 
| +template <typename T>
 | 
| +typename std::enable_if<HasPrintTo<T>::value, void>::type OptionalPrintToHelper(
 | 
| +    const T& value,
 | 
| +    std::ostream* os) {
 | 
| +  PrintTo(value, os);
 | 
| +}
 | 
| +
 | 
| +// Fall back to operator<<(std::ostream&, ...) if it exists.
 | 
| +template <typename T>
 | 
| +typename std::enable_if<HasOstreamOperator<T>::value && !HasPrintTo<T>::value,
 | 
| +                        void>::type
 | 
| +OptionalPrintToHelper(const T& value, std::ostream* os) {
 | 
| +  *os << value;
 | 
| +}
 | 
| +
 | 
| +inline void OptionalPrintObjectBytes(const unsigned char* bytes,
 | 
| +                                     size_t size,
 | 
| +                                     std::ostream* os) {
 | 
| +  *os << "<optional with " << size << "-byte object [";
 | 
| +  for (size_t i = 0; i != size; ++i) {
 | 
| +    *os << (i == 0 ? "" : ((i & 1) ? "-" : " "));
 | 
| +    *os << std::hex << std::setw(2) << std::setfill('0')
 | 
| +        << static_cast<int>(bytes[i]);
 | 
| +  }
 | 
| +  *os << "]>";
 | 
| +}
 | 
| +
 | 
| +// As a final back-up, just print the contents of the objcets byte-wise.
 | 
| +template <typename T>
 | 
| +typename std::enable_if<!HasOstreamOperator<T>::value && !HasPrintTo<T>::value,
 | 
| +                        void>::type
 | 
| +OptionalPrintToHelper(const T& value, std::ostream* os) {
 | 
| +  OptionalPrintObjectBytes(reinterpret_cast<const unsigned char*>(&value),
 | 
| +                           sizeof(value), os);
 | 
| +}
 | 
| +
 | 
| +}  // namespace optional_internal
 | 
| +
 | 
| +// PrintTo is used by gtest to print out the results of tests. We want to ensure
 | 
| +// the object contained in an Optional can be printed out if it's set, while
 | 
| +// avoiding touching the object's storage if it is undefined.
 | 
| +template <typename T>
 | 
| +void PrintTo(const rtc::Optional<T>& opt, std::ostream* os) {
 | 
| +  if (opt) {
 | 
| +    optional_internal::OptionalPrintToHelper(*opt, os);
 | 
| +  } else {
 | 
| +    *os << "<empty optional>";
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +#endif  // UNIT_TEST
 | 
| +
 | 
|  }  // namespace rtc
 | 
|  
 | 
|  #endif  // WEBRTC_BASE_OPTIONAL_H_
 | 
| 
 |