//////////////////////////////////////////////////////////////////////////////// //// Copyright 2017 Google LLC //// //// This software is licensed under the terms defined in the Widevine Master //// License Agreement. For a copy of this agreement, please contact //// widevine-licensing@google.com. //////////////////////////////////////////////////////////////////////////////// #ifndef VIDEO_WIDEVINE_EXPORT_EXPORTED_ROOT_UTIL_ERROR_SPACE_H_ #define VIDEO_WIDEVINE_EXPORT_EXPORTED_ROOT_UTIL_ERROR_SPACE_H_ #include #include "absl/strings/string_view.h" namespace video_widevine { namespace util { class ErrorSpace { public: absl::string_view SpaceName() const { return space_name_func_(this); } std::string String(int code) const { return code_to_string_func_(this, code); } protected: // typedef instead of using statements for SWIG compatibility. typedef absl::string_view (*SpaceNameFunc)(const ErrorSpace* space); typedef std::string (*CodeToStringFunc)(const ErrorSpace* space, int code); constexpr ErrorSpace(SpaceNameFunc space_name_func, CodeToStringFunc code_to_string_func) : space_name_func_(space_name_func), code_to_string_func_(code_to_string_func) {} private: const SpaceNameFunc space_name_func_; const CodeToStringFunc code_to_string_func_; }; // Manages creation of error space subclasses. template class ErrorSpaceImpl : public ErrorSpace { public: constexpr ErrorSpaceImpl() : ErrorSpace(&ErrorSpaceImpl::SpaceNameImpl, &ErrorSpaceImpl::CodeToStringImpl) {} // Returns the canonical instance of the `T` error space. static constexpr const T* Get(); private: // These functions adapt the stateful implementation that takes a space // pointer to stateless static methods, so that clients of ErrorSpaceImpl are // safe to have constexpr global instances. static absl::string_view SpaceNameImpl(const ErrorSpace* /*space*/) { return T::space_name(); } static std::string CodeToStringImpl(const ErrorSpace* /*space*/, int code) { return T::code_to_string(code); } }; namespace internal { // Provides a global constexpr instance of the error space `T`. // We need the indirection because ErrorSpaceImpl can't declare constexpr // instances of T since it is not yet fully declared. template struct ErrorSpaceInstance { static constexpr T value = {}; }; template constexpr T ErrorSpaceInstance::value; } // namespace internal template constexpr const T* ErrorSpaceImpl::Get() { return &internal::ErrorSpaceInstance::value; } } // namespace util } // namespace video_widevine #endif // VIDEO_WIDEVINE_EXPORT_EXPORTED_ROOT_UTIL_ERROR_SPACE_H_