#ifndef __tool_return__ #define __tool_return__ #include "errors.h" #include #include namespace MacOS { template class tool_return; template struct tool_return_type { typedef tool_return type; }; template struct tool_return_type> { typedef tool_return type; }; template<> struct tool_return_type { typedef tool_return type; }; namespace internal { class tool_return_base { protected: macos_error _error = noErr; constexpr tool_return_base() = default; constexpr tool_return_base(macos_error error) : _error(error) {} public: constexpr macos_error error() const { return _error; } constexpr explicit operator bool() const { return !_error; } template void throw_macos_error(Args&&... args) const { if (_error) MacOS::throw_macos_error(_error, std::forward(args)...); } }; class void_tool_return : public tool_return_base { public: typedef void value_type; void_tool_return() = default; void_tool_return(macos_error error) : tool_return_base(error) {} void_tool_return &operator=(macos_error error) { _error = error; return *this; } template::type> void then(F &&f, typename std::enable_if::value>::type* = 0) { f(std::move(*this)); } template::type> RT then(F &&f, typename std::enable_if::value>::type* = 0) { return f(std::move(*this)); } template::type> typename tool_return_type::type map(F &&f, typename std::enable_if::value>::type* = 0) { if (_error) return _error; f(); //return tool_return(); return noErr; } template::type> typename tool_return_type::type map(F &&f, typename std::enable_if::value>::type* = 0) { if (_error) return _error; return f(); } }; } // namespace template class tool_return : public internal::tool_return_base { private: T _value = T(); tool_return() = delete; operator T() const { return _value; } public: typedef T value_type; tool_return(const T &value) : _value(value) {} tool_return(T &&value) : _value(std::forward(value)) {} tool_return(macos_error error) : tool_return_base(error) {} tool_return &operator=(const T &value) { _value = value; _error = 0; return *this; } tool_return &operator=(T &&value) { _value = std::forward(value); _error = 0; return *this; } tool_return &operator=(macos_error error) { _value = T(); _error = error; return *this; } constexpr const T* operator->() const { return &_value; } constexpr const T& operator *() const { return _value; } T value() const { return _value; } template T value_or(U&& u) const { if (_error) return std::forward(u); return _value; } template T &&value_or(U&& u) && { if (_error) return std::forward(u); return std::move(_value); } template T value_or_throw(Args&&... args) const { if (_error) throw_macos_error(std::forward(args)...); return _value; } template::type> void then(F &&f, typename std::enable_if::value>::type* = 0) { f(std::move(*this)); } template::type> RT then(F &&f, typename std::enable_if::value>::type* = 0) { return f(std::move(*this)); } template::type> typename tool_return_type::type map(F &&f, typename std::enable_if::value>::type* = 0) { if (_error) return _error; f(std::move(_value)); //return tool_return(); return noErr; } template::type> typename tool_return_type::type map(F &&f, typename std::enable_if::value>::type* = 0) { if (_error) return _error; return f(std::move(_value)); } template TT value_or_error(typename std::enable_if::value>::type * = 0) const { return _error ? _error : _value; } }; template<> class tool_return : public internal::void_tool_return { public: using void_tool_return::void_tool_return; }; template<> class tool_return : public internal::void_tool_return { public: using void_tool_return::void_tool_return; }; } // namespace #endif