//////////////////////////////////////////////////////////////////////////////// // 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 UTIL_ERROR_SPACE_H_ #define UTIL_ERROR_SPACE_H_ #include namespace widevine { namespace util { class ErrorSpace { public: std::string 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 std::string (*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 std::string SpaceNameImpl(const ErrorSpace* /*space*/) { return T::SpaceName(); } static std::string CodeToStringImpl(const ErrorSpace* /*space*/, int code) { return T::CodeToString(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 widevine #endif // UTIL_ERROR_SPACE_H_