Add Result<Success, Error> type.

Result<Success, Error> is a tagged union that represents the success or
failure of an operation, along with either the success value or error
details.

Bug: 679313
Change-Id: Ic815cf1af0ad7f283460494db241b03957546f6b
Reviewed-on: https://chromium-review.googlesource.com/c/1393668
Commit-Queue: Erik Jensen <rkjnsn@chromium.org>
Reviewed-by: Lambros Lambrou <lambroslambrou@chromium.org>
Cr-Commit-Position: refs/heads/master@{#623778}
diff --git a/remoting/base/BUILD.gn b/remoting/base/BUILD.gn
index b43c596..e362c45 100644
--- a/remoting/base/BUILD.gn
+++ b/remoting/base/BUILD.gn
@@ -29,6 +29,7 @@
     "rate_counter.h",
     "remoting_bot.cc",
     "remoting_bot.h",
+    "result.h",
     "rsa_key_pair.cc",
     "rsa_key_pair.h",
     "running_samples.cc",
@@ -168,6 +169,7 @@
     "compound_buffer_unittest.cc",
     "oauth_helper_unittest.cc",
     "rate_counter_unittest.cc",
+    "result_unittest.cc",
     "rsa_key_pair_unittest.cc",
     "run_all_unittests.cc",
     "running_samples_unittest.cc",
diff --git a/remoting/base/result.h b/remoting/base/result.h
new file mode 100644
index 0000000..ee272eda
--- /dev/null
+++ b/remoting/base/result.h
@@ -0,0 +1,670 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef REMOTING_BASE_RESULT_H_
+#define REMOTING_BASE_RESULT_H_
+
+#include <type_traits>
+#include <utility>
+
+#include "base/logging.h"
+#include "base/optional.h"
+
+// Result<SuccessType, ErrorType> represents the success or failure of an
+// operation, along with either the success value or error details.
+//
+// It can be convenient to alias Result for specific error types. For example,
+// template <SuccessType>
+// using PosixResult<SuccessType, int>
+//
+// PosixResult<size_t> MyRead(int fd, void* buf, size_t count);
+
+// Synopsis:
+//
+// SuccessType
+// ErrorType
+//   The success and error types of the Result.
+//
+// Result()
+//   Only present when the success value is default constructible. Default
+//   constructs the success value. This is useful for situations like IPC
+//   deserialization where a default-costructed instance is created and the
+//   actual value is filled in later. In general, prefer using the
+//   Result(kSuccessTag) constructor to be explicit.
+//
+// Result(SuccessTag, Args&&... args)
+// Result(ErrorTag, Args&&... args)
+//   Direct constructs the success or error value, respectively, with the
+//   provided arguments.
+//
+// Result(T&& success_value)
+// Result(T&& error_value)
+//   Implicitly constructs either the success or error value. Only callable if
+//   T is implicitly convertible to SuccessType or ErrorType but not both.
+//
+// Result(const Result& other)
+// Result(Result&& other)
+//   Copy / move constructors. Only present if both SuccessType and ErrorType
+//   are copyable (for the first overload) / moveable (for the second).
+//
+// Result(const Result<S, E>& other)
+// Result(Result<S, E>&& other)
+//   Conversion constructors from a compatible Result. Only callable if S is
+//   copy (for the first overload) / move (for the second) convertible to
+//   SuccessType and E is convertible to ErrorType.
+//
+// Result& operator=(const Result& other)
+// Result& operator=(Result&& other)
+//   Copy / move assignment. If this!=*other, destroys the current value and
+//   copy / move constructs the current value from other. Only present if both
+//   SuccessType and ErrorType are copy (for the first overload) / move (for
+//   the second) constructible.
+//
+// Result& operator=(const Result<S, E>& other)
+// Result& operator=(Result<S, E>&& other)
+//   Conversion assignment. Only callable if S is copy (for the first overload)
+//   / move (for the second) convertible to SuccessType and E is copy / move
+//   convertible to ErrorType.
+//
+// EmplaceSuccess(Args&&... args)
+// EmplaceError(Args&&... args)
+//   Destroys the current value and direct constructs the success or error value
+//   with the provided arguments.
+//
+// Result<NewSuccessType, ErrorType> Map(F&& on_success) const&
+// Result<NewSuccessType, ErrorType> Map(F&& on_success) &&
+//   If is_success(), calls on_success passing the current value, and returns a
+//   new Result using the return value. If is_error(), the error value is passed
+//   through to the new result unchanged.
+//
+// Result<SuccessType, NewErrorType> MapError(F&& on_error) const&
+// Result<SuccessType, NewErrorType> MapError(F&& on_error) &&
+//   If is_error(), calls on_error passing the current value, and returns a new
+//   Result using the return value. If is_success(), the success value is passed
+//   through to the new result unchanged.
+//
+// Result<NewSuccessType, ErrorType> AndThen(F&& on_success) const&
+// Result<NewSuccessType, ErrorType> AndThen(F&& on_success) &&
+//   If is_success(), calls on_success passing the current value, which should
+//   itself return a Result. That Result is then returned, converting an error
+//   to ErrorType if necessary. If is_error(), the error value is passed through
+//   to the new result unchanged.
+//
+// Result<NewSuccessType, ErrorType> OrElse(F&& on_error) const&
+// Result<NewSuccessType, ErrorType> OrElse(F&& on_error) &&
+//   If is_error(), calls on_error passing the current value, which should
+//   itself return a Result. That Result is then returned, converting a success
+//   value to SuccessType if necessary. If is_success(), the success value is
+//   passed through to the new result unchanged.
+//
+// R Visit(F&& visitor) const&
+// R Visit(F&& visitor) &
+// R Visit(F&& visitor) &&
+//   Calls either success() or error() on the provided visitor depending on the
+//   state of the result, passing the value of the corresponding state and
+//   returning the value returned by the visitor. success() and error() must
+//   return the same type for the overload called. That is
+//   success(const SuccessType&) must have the same return type as
+//   error(const ErrorType&), but need not be the same as success(SuccessType&)
+//   and error(ErrorType&) (if present).
+//
+// bool is_success() const
+// bool is_error() const
+//   Check whether the Result currently holds a success value or an error.
+//
+// SuccessType& success()
+// const SuccessType& success() const
+//   Retrieve the success value. Undefined behavior if !is_success().
+//
+// ErrorType& error()
+// const ErrorType& error() const
+//   Retrieve the error value. Undefined behavior if !is_error().
+
+namespace remoting {
+
+// SuccessTag and ErrorTag are used for constructing a Result in the success
+// state or error state, respectively.
+class SuccessTag {};
+class ErrorTag {};
+// Monostate can be used for SuccessType or ErrorType to indicate that there is
+// no data for that state. Thus, Result<SomeType, Monostate> is somewhat
+// analogous to base::Optional<SomeType>, and Result<Monostate, Monostate> is
+// effectively a (2-byte) boolean. Result<Monostate, ErrorType> can be useful
+// for cases where an operation can fail, but there is no return value in the
+// success case.
+// TODO(rkjnsn): Replace with std::monostate once C++17 is allowed.
+class Monostate {};
+
+constexpr SuccessTag kSuccessTag = SuccessTag();
+constexpr ErrorTag kErrorTag = ErrorTag();
+constexpr Monostate kMonostate = Monostate();
+
+namespace internal {
+
+template <typename SuccessType, typename ErrorType>
+struct ResultStorage {
+  // Default constructor.
+  ResultStorage() : ResultStorage(kSuccessTag) {}
+
+  // Direct constructors.
+  template <typename... Args>
+  ResultStorage(SuccessTag, Args&&... args) : is_success(true) {
+    new (&success) SuccessType(std::forward<Args>(args)...);
+  }
+
+  template <typename... Args>
+  ResultStorage(ErrorTag, Args&&... args) : is_success(false) {
+    new (&error) ErrorType(std::forward<Args>(args)...);
+  }
+
+  // Copy/move constructors.
+  ResultStorage(const ResultStorage& other) : is_success(other.is_success) {
+    if (is_success) {
+      new (&success) SuccessType(other.success);
+    } else {
+      new (&error) ErrorType(other.error);
+    }
+  }
+
+  ResultStorage(ResultStorage&& other) : is_success(other.is_success) {
+    if (is_success) {
+      new (&success) SuccessType(std::move(other.success));
+    } else {
+      new (&error) ErrorType(std::move(other.error));
+    }
+  }
+
+  // Conversion constructors.
+  template <typename S, typename E>
+  ResultStorage(const ResultStorage<S, E>& other)
+      : is_success(other.is_success) {
+    if (is_success) {
+      new (&success) SuccessType(other.success);
+    } else {
+      new (&error) ErrorType(other.error);
+    }
+  }
+
+  template <typename S, typename E>
+  ResultStorage(ResultStorage<S, E>&& other) : is_success(other.is_success) {
+    if (is_success) {
+      new (&success) SuccessType(std::move(other.success));
+    } else {
+      new (&error) ErrorType(std::move(other.error));
+    }
+  }
+
+  ~ResultStorage() {
+    if (is_success) {
+      success.~SuccessType();
+    } else {
+      error.~ErrorType();
+    }
+  }
+
+  // Assignment.
+  ResultStorage& operator=(const ResultStorage& other) {
+    if (this == &other) {
+      return *this;
+    }
+    this->~ResultStorage();
+    new (this) ResultStorage(other);
+    return *this;
+  }
+
+  ResultStorage& operator=(ResultStorage&& other) {
+    if (this == &other) {
+      return *this;
+    }
+    this->~ResultStorage();
+    new (this) ResultStorage(std::move(other));
+    return *this;
+  }
+
+  union {
+    SuccessType success;
+    ErrorType error;
+  };
+
+  bool is_success;
+};
+
+// The following structs are helpers to implement constructor/assign-operator
+// overloading. Result defines all five as "default", and then inherits from
+// these base classes so the compiler will include or omit each constructor or
+// operator as appropriate.
+template <bool is_default_constructible>
+struct DefaultConstructible {
+  constexpr DefaultConstructible() = default;
+  constexpr DefaultConstructible(int) {}
+};
+
+template <>
+struct DefaultConstructible<false> {
+  constexpr DefaultConstructible() = delete;
+  constexpr DefaultConstructible(int) {}
+};
+
+template <bool is_copy_constructible>
+struct CopyConstructible {};
+
+template <>
+struct CopyConstructible<false> {
+  constexpr CopyConstructible() = default;
+  constexpr CopyConstructible(const CopyConstructible&) = delete;
+  constexpr CopyConstructible(CopyConstructible&&) = default;
+  CopyConstructible& operator=(const CopyConstructible&) = default;
+  CopyConstructible& operator=(CopyConstructible&&) = default;
+};
+
+template <bool is_move_constructible>
+struct MoveConstructible {};
+
+template <>
+struct MoveConstructible<false> {
+  constexpr MoveConstructible() = default;
+  constexpr MoveConstructible(const MoveConstructible&) = default;
+  constexpr MoveConstructible(MoveConstructible&&) = delete;
+  MoveConstructible& operator=(const MoveConstructible&) = default;
+  MoveConstructible& operator=(MoveConstructible&&) = default;
+};
+
+template <bool is_copy_assignable>
+struct CopyAssignable {};
+
+template <>
+struct CopyAssignable<false> {
+  constexpr CopyAssignable() = default;
+  constexpr CopyAssignable(const CopyAssignable&) = default;
+  constexpr CopyAssignable(CopyAssignable&&) = default;
+  CopyAssignable& operator=(const CopyAssignable&) = delete;
+  CopyAssignable& operator=(CopyAssignable&&) = default;
+};
+
+template <bool is_move_assignable>
+struct MoveAssignable {};
+
+template <>
+struct MoveAssignable<false> {
+  constexpr MoveAssignable() = default;
+  constexpr MoveAssignable(const MoveAssignable&) = default;
+  constexpr MoveAssignable(MoveAssignable&&) = default;
+  MoveAssignable& operator=(const MoveAssignable&) = default;
+  MoveAssignable& operator=(MoveAssignable&&) = delete;
+};
+
+}  // namespace internal
+
+// TODO(rkjnsn): Add [[nodiscard]] once C++17 is allowed.
+template <typename SuccessType_, typename ErrorType_>
+class Result : public internal::DefaultConstructible<
+                   std::is_default_constructible<SuccessType_>::value>,
+               public internal::CopyConstructible<
+                   std::is_copy_constructible<SuccessType_>::value &&
+                   std::is_copy_constructible<ErrorType_>::value>,
+               public internal::MoveConstructible<
+                   std::is_move_constructible<SuccessType_>::value &&
+                   std::is_move_constructible<ErrorType_>::value>,
+               public internal::CopyAssignable<
+                   std::is_copy_assignable<SuccessType_>::value &&
+                   std::is_copy_assignable<ErrorType_>::value>,
+               public internal::MoveAssignable<
+                   std::is_move_assignable<SuccessType_>::value &&
+                   std::is_move_assignable<ErrorType_>::value> {
+ public:
+  typedef SuccessType_ SuccessType;
+  typedef ErrorType_ ErrorType;
+
+ private:
+  template <typename T>
+  struct is_convertible_result : public std::false_type {};
+
+  template <typename OtherSuccessType, typename OtherErrorType>
+  struct is_convertible_result<Result<OtherSuccessType, OtherErrorType>>
+      : public std::integral_constant<
+            bool,
+            std::is_convertible<OtherSuccessType&&, SuccessType>::value &&
+                std::is_convertible<OtherErrorType&&, ErrorType>::value> {};
+
+  typedef internal::DefaultConstructible<
+      std::is_default_constructible<SuccessType_>::value>
+      DefaultConstructible;
+
+ public:
+  // Default constructor. Will default construct the success value. This is for
+  // situations like IPC deserialization where a default-constructed instance is
+  // created and the actual value is filled in later. In general, prefer using
+  // Result(kSuccessTag) constructor to be explicit.
+  Result() = default;
+
+  // Direct constructors allow constructing either the SuccessType or ErrorType
+  // in place. Usage: Result(kSuccessTag, success_type_constructor_args...) or
+  // Result(kErrorTag, error_type_constructor_args...)
+  template <typename... Args>
+  Result(typename std::enable_if<
+             std::is_constructible<SuccessType, Args...>::value,
+             SuccessTag>::type,
+         Args&&... args)
+      : DefaultConstructible(0),
+        storage_(kSuccessTag, std::forward<Args>(args)...) {}
+
+  template <typename... Args>
+  Result(
+      typename std::enable_if<std::is_constructible<ErrorType, Args...>::value,
+                              ErrorTag>::type,
+      Args&&... args)
+      : DefaultConstructible(0),
+        storage_(kErrorTag, std::forward<Args>(args)...) {}
+
+  // Allow implicit construction from objects implicitly convertible to
+  // SuccessType xor ErrorType.
+  template <typename T,
+            typename std::enable_if<
+                std::is_convertible<T&&, SuccessType>::value &&
+                    !std::is_convertible<T&&, ErrorType>::value &&
+                    // Prefer move/copy/conversion to member construction.
+                    !is_convertible_result<typename std::decay<T>::type>::value,
+                int>::type = 0>
+  Result(T&& success_value)
+      : Result(kSuccessTag, std::forward<T>(success_value)) {}
+
+  template <typename T,
+            typename std::enable_if<
+                !std::is_convertible<T&&, SuccessType>::value &&
+                    std::is_convertible<T&&, ErrorType>::value &&
+                    !is_convertible_result<typename std::decay<T>::type>::value,
+                int>::type = 0>
+  Result(T&& error_value) : Result(kErrorTag, std::forward<T>(error_value)) {}
+
+  // Copy / move constructors.
+  Result(const Result& other) = default;
+  Result(Result&& other) = default;
+
+  // Conversion constructors.
+  template <
+      typename OtherSuccessType,
+      typename OtherErrorType,
+      typename std::enable_if<
+          std::is_convertible<const OtherSuccessType&, SuccessType>::value &&
+              std::is_convertible<const OtherErrorType&, ErrorType>::value,
+          int>::type = 0>
+  Result(const Result<OtherSuccessType, OtherErrorType>& other)
+      : DefaultConstructible(0), storage_(other.storage_) {}
+
+  template <typename OtherSuccessType,
+            typename OtherErrorType,
+            typename std::enable_if<
+                std::is_convertible<OtherSuccessType&&, SuccessType>::value &&
+                    std::is_convertible<OtherErrorType&&, ErrorType>::value,
+                int>::type = 0>
+  Result(Result<OtherSuccessType, OtherErrorType>&& other)
+      : DefaultConstructible(0), storage_(std::move(other.storage_)) {}
+
+  // Assignment.
+  Result& operator=(const Result& other) = default;
+  Result& operator=(Result&& other) = default;
+
+  // Conversion assignment.
+  template <
+      typename OtherSuccessType,
+      typename OtherErrorType,
+      typename std::enable_if<
+          std::is_convertible<const OtherSuccessType&, SuccessType>::value &&
+              std::is_convertible<const OtherErrorType&, ErrorType>::value,
+          int>::type = 0>
+  Result& operator=(const Result<OtherSuccessType, OtherErrorType>& other) {
+    this->~Result();
+    new (this) Result(other);
+    return *this;
+  }
+
+  template <typename OtherSuccessType,
+            typename OtherErrorType,
+            typename std::enable_if<
+                std::is_convertible<OtherSuccessType&&, SuccessType>::value &&
+                    std::is_convertible<OtherErrorType&&, ErrorType>::value,
+                int>::type = 0>
+  Result& operator=(Result<OtherSuccessType, OtherErrorType>&& other) {
+    this->~Result();
+    new (this) Result(std::move(other));
+    return *this;
+  }
+
+  // Emplaces new success value in the result and returns a reference to it.
+  template <typename... Args>
+  typename std::enable_if<std::is_constructible<SuccessType, Args...>::value,
+                          SuccessType&>::type
+  EmplaceSuccess(Args&&... args) {
+    this->~Result();
+    new (this) Result(kSuccessTag, std::forward<Args>(args)...);
+    return storage_.success;
+  }
+
+  // Emplaces new error value in the result and returns a reference to it.
+  template <typename... Args>
+  typename std::enable_if<std::is_constructible<ErrorType, Args...>::value,
+                          ErrorType&>::type
+  EmplaceError(Args&&... args) {
+    this->~Result();
+    new (this) Result(kErrorTag, std::forward<Args>(args)...);
+    return storage_.error;
+  }
+
+  // Maps Result<Success, Error> to Result<NewSuccess, Error> by applying the
+  // provided Success->NewSuccess functor to the success value, if present. If
+  // this Result contains an error, it will be passed through unchanged and the
+  // functor will not be called.
+  template <typename SuccessFunctor>
+  Result<typename std::result_of<SuccessFunctor && (const SuccessType&)>::type,
+         ErrorType>
+  Map(SuccessFunctor&& on_success) const& {
+    if (storage_.is_success) {
+      return {kSuccessTag,
+              std::forward<SuccessFunctor>(on_success)(storage_.success)};
+    } else {
+      return {kErrorTag, storage_.error};
+    }
+  }
+
+  template <typename SuccessFunctor>
+  Result<typename std::result_of<SuccessFunctor && (SuccessType &&)>::type,
+         ErrorType>
+  Map(SuccessFunctor&& on_success) && {
+    if (storage_.is_success) {
+      return {kSuccessTag, std::forward<SuccessFunctor>(on_success)(
+                               std::move(storage_.success))};
+    } else {
+      return {kErrorTag, std::move(storage_.error)};
+    }
+  }
+
+  // Maps Result<Success, Error> to Result<Success, NewError> by applying the
+  // provided Error->NewError functor to the error value, if present. If this
+  // Result contains a success value, it will be passed through unchanged and
+  // the functor will not be called.
+  template <typename ErrorFunctor>
+  Result<SuccessType,
+         typename std::result_of<ErrorFunctor && (const ErrorType&)>::type>
+  MapError(ErrorFunctor&& on_error) const& {
+    if (storage_.is_success) {
+      return {kSuccessTag, storage_.success};
+    } else {
+      return {kErrorTag, std::forward<ErrorFunctor>(on_error)(storage_.error)};
+    }
+  }
+
+  template <typename ErrorFunctor>
+  Result<SuccessType,
+         typename std::result_of<ErrorFunctor && (ErrorType &&)>::type>
+  MapError(ErrorFunctor&& on_error) && {
+    if (storage_.is_success) {
+      return {kSuccessTag, std::move(storage_.success)};
+    } else {
+      return {kErrorTag,
+              std::forward<ErrorFunctor>(on_error)(std::move(storage_.error))};
+    }
+  }
+
+  // Maps Result<Success, Error> to Result<NewSuccess, Error> by calling the
+  // provided Success->Result<NewSuccess, Error> functor with the success value,
+  // if present. If this Result contains an error, it will be passed through
+  // unchanged and the functor will not be called.
+  template <
+      typename SuccessFunctor,
+      typename ReturnType =
+          typename std::result_of<SuccessFunctor && (const SuccessType&)>::type,
+      typename std::enable_if<
+          std::is_convertible<typename ReturnType::ErrorType, ErrorType>::value,
+          int>::type = 0>
+  Result<typename ReturnType::SuccessType, ErrorType> AndThen(
+      SuccessFunctor&& on_success) const& {
+    if (storage_.is_success) {
+      return std::forward<SuccessFunctor>(on_success)(storage_.success);
+    } else {
+      return {kErrorTag, storage_.error};
+    }
+  }
+
+  template <
+      typename SuccessFunctor,
+      typename ReturnType =
+          typename std::result_of<SuccessFunctor && (SuccessType &&)>::type,
+      typename std::enable_if<
+          std::is_convertible<typename ReturnType::ErrorType, ErrorType>::value,
+          int>::type = 0>
+  Result<typename ReturnType::SuccessType, ErrorType> AndThen(
+      SuccessFunctor&& on_success) && {
+    if (storage_.is_success) {
+      return std::forward<SuccessFunctor>(on_success)(
+          std::move(storage_.success));
+    } else {
+      return {kErrorTag, std::move(storage_.error)};
+    }
+  }
+
+  // Maps Result<Success, Error> to Result<Success, NewError> by calling the
+  // provided Error->Result<Success, NewError> functor with the error value, if
+  // present. If this Result contains a success value, it will be passed through
+  // unchanged and the functor will not be called.
+  template <typename ErrorFunctor,
+            typename ReturnType = typename std::result_of<
+                ErrorFunctor && (const ErrorType&)>::type,
+            typename std::enable_if<
+                std::is_convertible<typename ReturnType::SuccessType,
+                                    SuccessType>::value,
+                int>::type = 0>
+  Result<SuccessType, typename ReturnType::ErrorType> OrElse(
+      ErrorFunctor&& on_error) const& {
+    if (storage_.is_success) {
+      return {kSuccessTag, storage_.success};
+    } else {
+      return std::forward<ErrorFunctor>(on_error)(storage_.error);
+    }
+  }
+
+  template <typename ErrorFunctor,
+            typename ReturnType =
+                typename std::result_of<ErrorFunctor && (ErrorType &&)>::type,
+            typename std::enable_if<
+                std::is_convertible<typename ReturnType::SuccessType,
+                                    SuccessType>::value,
+                int>::type = 0>
+  Result<SuccessType, typename ReturnType::ErrorType> OrElse(
+      ErrorFunctor&& on_error) && {
+    if (storage_.is_success) {
+      return {kSuccessTag, std::move(storage_.success)};
+    } else {
+      return std::forward<ErrorFunctor>(on_error)(std::move(storage_.error));
+    }
+  }
+
+  // Calls either success() or error() on the provided visitor depending on the
+  // state of the result, passing the value of the corresponding state.
+  template <
+      typename Visitor,
+      typename SuccessReturn = decltype(
+          std::declval<Visitor>().success(std::declval<const SuccessType&>())),
+      typename ErrorReturn = decltype(
+          std::declval<Visitor>().error(std::declval<const ErrorType&>())),
+      typename std::enable_if<std::is_same<SuccessReturn, ErrorReturn>::value,
+                              int>::type = 0>
+  SuccessReturn Visit(Visitor&& visitor) const& {
+    if (storage_.is_success) {
+      return std::forward<Visitor>(visitor).success(storage_.success);
+    } else {
+      return std::forward<Visitor>(visitor).error(storage_.error);
+    }
+  }
+
+  template <
+      typename Visitor,
+      typename SuccessReturn = decltype(
+          std::declval<Visitor>().success(std::declval<SuccessType&>())),
+      typename ErrorReturn =
+          decltype(std::declval<Visitor>().error(std::declval<ErrorType&>())),
+      typename std::enable_if<std::is_same<SuccessReturn, ErrorReturn>::value,
+                              int>::type = 0>
+  SuccessReturn Visit(Visitor&& visitor) & {
+    if (storage_.is_success) {
+      return std::forward<Visitor>(visitor).success(storage_.success);
+    } else {
+      return std::forward<Visitor>(visitor).error(storage_.error);
+    }
+  }
+
+  template <
+      typename Visitor,
+      typename SuccessReturn = decltype(
+          std::declval<Visitor>().success(std::declval<SuccessType&&>())),
+      typename ErrorReturn =
+          decltype(std::declval<Visitor>().error(std::declval<ErrorType&&>())),
+      typename std::enable_if<std::is_same<SuccessReturn, ErrorReturn>::value,
+                              int>::type = 0>
+  SuccessReturn Visit(Visitor&& visitor) && {
+    if (storage_.is_success) {
+      return std::forward<Visitor>(visitor).success(
+          std::move(storage_.success));
+    } else {
+      return std::forward<Visitor>(visitor).error(std::move(storage_.error));
+    }
+  }
+
+  // Accessors
+
+  bool is_success() const { return storage_.is_success; }
+
+  bool is_error() const { return !storage_.is_success; }
+
+  explicit operator bool() const { return storage_.is_success; }
+
+  SuccessType& success() {
+    DCHECK(storage_.is_success);
+    return storage_.success;
+  }
+
+  const SuccessType& success() const {
+    DCHECK(storage_.is_success);
+    return storage_.success;
+  }
+
+  ErrorType& error() {
+    DCHECK(!storage_.is_success);
+    return storage_.error;
+  }
+
+  const ErrorType& error() const {
+    DCHECK(!storage_.is_success);
+    return storage_.error;
+  }
+
+ private:
+  internal::ResultStorage<SuccessType, ErrorType> storage_;
+
+  template <typename S, typename E>
+  friend class Result;
+};
+
+}  // namespace remoting
+
+#endif  // REMOTING_BASE_RESULT_H_
diff --git a/remoting/base/result_unittest.cc b/remoting/base/result_unittest.cc
new file mode 100644
index 0000000..b1bea5b5
--- /dev/null
+++ b/remoting/base/result_unittest.cc
@@ -0,0 +1,410 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+#include <string>
+
+#include "remoting/base/result.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace remoting {
+
+TEST(Result, DefaultConstruction) {
+  struct DefaultConstruct {
+    std::string value;
+    DefaultConstruct() : value("value1") {}
+  };
+
+  Result<DefaultConstruct, int> result;
+  ASSERT_TRUE(result.is_success());
+  EXPECT_EQ("value1", result.success().value);
+}
+
+namespace {
+struct NotDefaultConstructible {
+  NotDefaultConstructible(int);
+};
+}  // namespace
+
+static_assert(
+    !std::is_default_constructible<Result<NotDefaultConstructible, int>>::value,
+    "Should not be default constructible if success type isn't.");
+
+TEST(Result, TaggedSuccessConstruction) {
+  Result<std::string, int> result(kSuccessTag, 5, 'a');
+  ASSERT_TRUE(result.is_success());
+  ASSERT_FALSE(result.is_error());
+  EXPECT_EQ("aaaaa", result.success());
+}
+
+TEST(Result, TaggedErrorConstruction) {
+  Result<std::string, int> result(kErrorTag, 2);
+  ASSERT_FALSE(result.is_success());
+  ASSERT_TRUE(result.is_error());
+  EXPECT_EQ(2, result.error());
+}
+
+static_assert(
+    !std::is_constructible<Result<std::string, int>, SuccessTag, float>::value,
+    "Invalid constructor parameters should trigger SFINAE.");
+
+TEST(Result, ImplicitSuccessConstruction) {
+  Result<std::string, int> result = "value3";
+  ASSERT_TRUE(result.is_success());
+  EXPECT_EQ("value3", result.success());
+}
+
+TEST(Result, ImplicitErrorConstruction) {
+  Result<std::string, int> result = 3;
+  ASSERT_TRUE(result.is_error());
+  EXPECT_EQ(3, result.error());
+}
+
+static_assert(!std::is_constructible<Result<int, float>, int>::value,
+              "Should not allow ambiguous untagged construction.");
+
+TEST(Result, SuccessCopyConstruction) {
+  Result<std::string, int> result1 = "value4";
+  Result<std::string, int> result2 = result1;
+  ASSERT_TRUE(result2.is_success());
+  EXPECT_EQ("value4", result2.success());
+  // Ensure result1 wasn't modified.
+  EXPECT_EQ("value4", result1.success());
+}
+
+TEST(Result, ErrorCopyConstruction) {
+  Result<int, std::string> result1 = "value5";
+  Result<int, std::string> result2 = result1;
+  ASSERT_TRUE(result2.is_error());
+  EXPECT_EQ("value5", result2.error());
+  // Ensure result1 wasn't modified.
+  EXPECT_EQ("value5", result1.error());
+}
+
+static_assert(
+    !std::is_copy_constructible<Result<std::unique_ptr<int>, int>>::value &&
+        !std::is_copy_constructible<Result<int, std::unique_ptr<int>>>::value,
+    "Should not be copy constructible if either type isn't.");
+
+TEST(Result, SuccessMoveConstruction) {
+  Result<std::unique_ptr<std::string>, int> result1 =
+      std::make_unique<std::string>("value6");
+  Result<std::unique_ptr<std::string>, int> result2 = std::move(result1);
+  ASSERT_TRUE(result2.is_success());
+  EXPECT_EQ("value6", *result2.success());
+  EXPECT_TRUE(result1.is_success());
+  EXPECT_FALSE(result1.success());
+}
+
+TEST(Result, ErrorMoveConstruction) {
+  Result<int, std::unique_ptr<std::string>> result1 =
+      std::make_unique<std::string>("value7");
+  Result<int, std::unique_ptr<std::string>> result2 = std::move(result1);
+  ASSERT_TRUE(result2.is_error());
+  EXPECT_EQ("value7", *result2.error());
+  EXPECT_TRUE(result1.is_error());
+  EXPECT_FALSE(result1.error());
+}
+
+TEST(Result, SuccessCopyConversion) {
+  const char* value = "value8";
+  Result<const char*, int> result1 = value;
+  Result<std::string, int> result2 = result1;
+  ASSERT_TRUE(result2.is_success());
+  EXPECT_EQ("value8", result2.success());
+  EXPECT_EQ(value, result1.success());
+}
+
+TEST(Result, ErrorCopyConversion) {
+  const char* value = "value9";
+  Result<int, const char*> result1 = value;
+  Result<int, std::string> result2 = result1;
+  ASSERT_TRUE(result2.is_error());
+  EXPECT_EQ("value9", result2.error());
+  EXPECT_EQ(value, result1.error());
+}
+
+TEST(Result, SuccessMoveConversion) {
+  struct Deleter {
+    Deleter(const std::default_delete<std::string>&) {}
+    void operator()(void* ptr) { delete static_cast<std::string*>(ptr); }
+  };
+
+  Result<std::unique_ptr<std::string>, int> result1 =
+      std::make_unique<std::string>("value10");
+  Result<std::unique_ptr<void, Deleter>, int> result2 = std::move(result1);
+  ASSERT_TRUE(result2.is_success());
+  EXPECT_EQ("value10", *static_cast<std::string*>(result2.success().get()));
+}
+
+TEST(Result, ErrorMoveConversion) {
+  struct Deleter {
+    Deleter(const std::default_delete<std::string>&) {}
+    void operator()(void* ptr) { delete static_cast<std::string*>(ptr); }
+  };
+
+  Result<int, std::unique_ptr<std::string>> result1 =
+      std::make_unique<std::string>("value11");
+  Result<int, std::unique_ptr<void, Deleter>> result2 = std::move(result1);
+  ASSERT_TRUE(result2.is_error());
+  EXPECT_EQ("value11", *static_cast<std::string*>(result2.error().get()));
+}
+
+TEST(Result, Destruction) {
+  class DestructIncrement {
+   public:
+    explicit DestructIncrement(int* variable) : variable_(variable) {}
+    ~DestructIncrement() { ++(*variable_); }
+
+   private:
+    int* variable_;
+  };
+
+  int success_count = 0;
+  int error_count = 0;
+
+  Result<DestructIncrement, int>(kSuccessTag, &success_count);
+  EXPECT_EQ(1, success_count);
+  EXPECT_EQ(0, error_count);
+
+  Result<int, DestructIncrement>(kErrorTag, &error_count);
+  EXPECT_EQ(1, success_count);
+  EXPECT_EQ(1, error_count);
+}
+
+TEST(Result, CopyAssignment) {
+  Result<std::string, int> result1 = "value12";
+  Result<std::string, int> result2 = 0;
+  result2 = result1;
+  ASSERT_TRUE(result2.is_success());
+  EXPECT_EQ("value12", result2.success());
+
+  static_assert(
+      !std::is_copy_assignable<Result<std::unique_ptr<int>, int>>::value &&
+          !std::is_copy_assignable<Result<int, std::unique_ptr<int>>>::value,
+      "Should not be copy assignable if either type isn't.");
+}
+
+TEST(Result, MoveAssignment) {
+  Result<std::unique_ptr<std::string>, int> result1 =
+      std::make_unique<std::string>("value13");
+  Result<std::unique_ptr<std::string>, int> result2 = 0;
+  result2 = std::move(result1);
+  ASSERT_TRUE(result2.is_success());
+  EXPECT_EQ("value13", *result2.success());
+}
+
+TEST(Result, CopyConversionAssignment) {
+  const char* value1 = "value14";
+  Result<const char*, int> result1 = value1;
+  Result<std::string, int> result2 = 0;
+  result2 = result1;
+  ASSERT_TRUE(result2.is_success());
+  EXPECT_EQ("value14", result2.success());
+}
+
+TEST(Result, MoveConversionAssignment) {
+  struct Deleter {
+    Deleter(const std::default_delete<std::string>&) {}
+    void operator()(void* ptr) { delete static_cast<std::string*>(ptr); }
+  };
+
+  Result<std::unique_ptr<std::string>, int> result1 =
+      std::make_unique<std::string>("value15");
+  Result<std::unique_ptr<void, Deleter>, int> result2 = 0;
+  result2 = std::move(result1);
+  ASSERT_TRUE(result2.is_success());
+  EXPECT_EQ("value15", *static_cast<std::string*>(result2.success().get()));
+}
+
+TEST(Result, EmplaceSuccess) {
+  Result<std::string, int> result = 0;
+  result.EmplaceSuccess(5, 'p');
+  ASSERT_TRUE(result.is_success());
+  EXPECT_EQ("ppppp", result.success());
+}
+
+TEST(Result, EmplaceError) {
+  Result<std::string, int> result;
+  result.EmplaceError(17);
+  ASSERT_TRUE(result.is_error());
+  EXPECT_EQ(17, result.error());
+}
+
+TEST(Result, MapLvalue) {
+  Result<std::string, int> result1 = "value18";
+  Result<const char*, int> result2 =
+      result1.Map([](const std::string& value) { return value.c_str(); });
+  ASSERT_TRUE(result2.is_success());
+  EXPECT_TRUE(strcmp("value18", result2.success()) == 0);
+}
+
+TEST(Result, MapRvalue) {
+  Result<std::unique_ptr<std::string>, int> result1 =
+      std::make_unique<std::string>("value19");
+  auto result2 = std::move(result1).Map(
+      [](std::unique_ptr<std::string>&& value) { return std::move(*value); });
+  static_assert(
+      std::is_same<decltype(result2), Result<std::string, int>>::value,
+      "Incorrect type inferred.");
+  ASSERT_TRUE(result2.is_success());
+  EXPECT_EQ("value19", result2.success());
+}
+
+TEST(Result, MapPassesErrorThrough) {
+  Result<std::string, int> result1 = 20;
+  Result<const char*, int> result2 =
+      result1.Map([](const std::string& value) { return value.c_str(); });
+  ASSERT_TRUE(result2.is_error());
+  EXPECT_EQ(20, result2.error());
+}
+
+TEST(Result, MapErrorLvalue) {
+  Result<std::string, int> result1 = 21;
+  Result<std::string, int> result2 =
+      result1.MapError([](int value) { return value + 1; });
+  ASSERT_TRUE(result2.is_error());
+  EXPECT_EQ(22, result2.error());
+}
+
+TEST(Result, MapErrorRvalue) {
+  Result<int, std::unique_ptr<std::string>> result1 =
+      std::make_unique<std::string>("value23");
+  auto result2 =
+      std::move(result1).MapError([](std::unique_ptr<std::string>&& value) {
+        return std::make_unique<std::size_t>(value->size());
+      });
+  static_assert(std::is_same<decltype(result2),
+                             Result<int, std::unique_ptr<std::size_t>>>::value,
+                "Incorrect type inferred.");
+  ASSERT_TRUE(result2.is_error());
+  EXPECT_EQ(7UL, *result2.error());
+}
+
+TEST(Result, MapErrorPassesSuccessThrough) {
+  Result<std::string, int> result1 = "value24";
+  Result<std::string, float> result2 =
+      result1.MapError([](int value) { return value * 2.0; });
+  ASSERT_TRUE(result2.is_success());
+  EXPECT_EQ("value24", result2.success());
+}
+
+TEST(Result, AndThenLvalue) {
+  Result<std::string, int> result1 = "value25";
+  auto result2 = result1.AndThen(
+      [](const std::string&) { return Result<const char*, float>(26.0); });
+  static_assert(
+      std::is_same<decltype(result2), Result<const char*, int>>::value,
+      "Error type should stay the same.");
+  ASSERT_TRUE(result2.is_error());
+  EXPECT_EQ(26, result2.error());
+}
+
+TEST(Result, AndThenRvalue) {
+  Result<std::unique_ptr<std::string>, int> result1 =
+      std::make_unique<std::string>("value27");
+  auto result2 =
+      std::move(result1).AndThen([](std::unique_ptr<std::string>&& value) {
+        return Result<std::string, int>(std::move(*value));
+      });
+  static_assert(
+      std::is_same<decltype(result2), Result<std::string, int>>::value,
+      "Incorrect type inferred.");
+  ASSERT_TRUE(result2.is_success());
+  EXPECT_EQ("value27", result2.success());
+}
+
+TEST(Result, AndThenPassesErrorThrough) {
+  Result<std::string, int> result1 = 28;
+  Result<int, int> result2 = result1.AndThen(
+      [](const std::string&) { return Result<int, int>(kSuccessTag, 29); });
+  ASSERT_TRUE(result2.is_error());
+  EXPECT_EQ(28, result2.error());
+}
+
+TEST(Result, OrElseLvalue) {
+  Result<std::string, int> result1 = 30;
+  Result<std::string, int> result2 =
+      result1.OrElse([](int) -> Result<std::string, int> { return "value31"; });
+  ASSERT_TRUE(result2.is_success());
+  EXPECT_EQ("value31", result2.success());
+}
+
+TEST(Result, OrElseRvalue) {
+  Result<int, std::unique_ptr<std::string>> result1 =
+      std::make_unique<std::string>("value32");
+  Result<int, std::string> result2 =
+      std::move(result1).OrElse([](std::unique_ptr<std::string>&&) {
+        return Result<int, std::string>("value33");
+      });
+  ASSERT_TRUE(result2.is_error());
+  EXPECT_EQ("value33", result2.error());
+}
+
+TEST(Result, OrElsePassesSuccessThrough) {
+  Result<std::string, int> result1 = "value34";
+  Result<std::string, float> result2 = result1.OrElse(
+      [](int value) -> Result<std::string, float> { return value * 2.0; });
+  ASSERT_TRUE(result2.is_success());
+  EXPECT_EQ("value34", result2.success());
+}
+
+TEST(Result, Visit) {
+  struct Visitor {
+    char success(const std::string& value) {
+      EXPECT_EQ("value35", value);
+      return '\1';
+    }
+    bool success(std::string& value) {
+      EXPECT_EQ("value35", value);
+      return true;
+    }
+    int success(std::string&& value) {
+      EXPECT_EQ("value35", value);
+      return 1;
+    }
+    char error(const std::wstring& value) {
+      EXPECT_EQ(L"value36", value);
+      return '\0';
+    }
+    bool error(std::wstring& value) {
+      EXPECT_EQ(L"value36", value);
+      return false;
+    }
+    int error(std::wstring&& value) {
+      EXPECT_EQ(L"value36", value);
+      return 0;
+    }
+  };
+
+  Result<std::string, std::wstring> result;
+
+  result.EmplaceSuccess("value35");
+  auto success1 =
+      const_cast<const Result<std::string, std::wstring>&>(result).Visit(
+          Visitor());
+  static_assert(std::is_same<char, decltype(success1)>::value,
+                "Return type should be char.");
+  EXPECT_EQ('\1', success1);
+  auto success2 = result.Visit(Visitor());
+  static_assert(std::is_same<bool, decltype(success2)>::value,
+                "Return type should be bool.");
+  EXPECT_EQ(true, success2);
+  auto success3 = std::move(result).Visit(Visitor());
+  static_assert(std::is_same<int, decltype(success3)>::value,
+                "Return type should be int.");
+  EXPECT_EQ(1, success3);
+
+  result.EmplaceError(L"value36");
+  auto error1 =
+      const_cast<const Result<std::string, std::wstring>&>(result).Visit(
+          Visitor());
+  EXPECT_EQ('\0', error1);
+  auto error2 = result.Visit(Visitor());
+  EXPECT_EQ(false, error2);
+  auto error3 = std::move(result).Visit(Visitor());
+  EXPECT_EQ(0, error3);
+}
+
+}  // namespace remoting