tool return then / map ....

This commit is contained in:
Kelvin Sherlock 2016-08-05 20:37:21 -04:00
parent 059cc09308
commit c509148aec
2 changed files with 93 additions and 33 deletions

View File

@ -6,6 +6,22 @@
namespace MacOS { namespace MacOS {
template<class T>
class tool_return;
template<class T>
struct tool_return_type { typedef tool_return<T> type; };
template<class T>
struct tool_return_type<tool_return<T>> { typedef tool_return<T> type; };
namespace internal { namespace internal {
class tool_return_base class tool_return_base
@ -13,18 +29,16 @@ namespace MacOS {
protected: protected:
macos_error _error = noErr; macos_error _error = noErr;
tool_return_base() = default; constexpr tool_return_base() = default;
tool_return_base(macos_error error) : _error(error) constexpr tool_return_base(macos_error error) : _error(error)
{} {}
public: public:
macos_error error() const constexpr macos_error error() const { return _error; }
{
return _error;
}
constexpr explicit operator bool() const { return !_error; }
template<class... Args> template<class... Args>
void throw_macos_error(Args&&... args) const void throw_macos_error(Args&&... args) const
@ -36,10 +50,12 @@ namespace MacOS {
}; };
} // namespace } // namespace
template<class T> template<class T>
class tool_return : public internal::tool_return_base class tool_return : public internal::tool_return_base
{ {
private: private:
T _value = T(); T _value = T();
tool_return() = delete; tool_return() = delete;
@ -50,22 +66,35 @@ namespace MacOS {
} }
public: public:
typedef T value_type; typedef T value_type;
tool_return(T value) : _value(value) tool_return(const T &value) : _value(value)
{} {}
tool_return(T &&value) : _value(std::forward<T>(value))
{}
tool_return(macos_error error) : tool_return_base(error) tool_return(macos_error error) : tool_return_base(error)
{} {}
tool_return &operator=(T value) tool_return &operator=(const T &value)
{ {
_value = value; _value = value;
_error = 0; _error = 0;
return *this; return *this;
} }
tool_return &operator=(T &&value)
{
_value = std::forward<T>(value);
_error = 0;
return *this;
}
tool_return &operator=(macos_error error) tool_return &operator=(macos_error error)
{ {
_value = T(); _value = T();
@ -94,10 +123,17 @@ namespace MacOS {
template<class U> template<class U>
T value_or(U&& u) const T value_or(U&& u) const
{ {
if (_error) return u; if (_error) return std::forward<U>(u);
return _value; return _value;
} }
template<class U>
T &&value_or(U&& u) &&
{
if (_error) return std::forward<U>(u);
return std::move(_value);
}
template<class... Args> template<class... Args>
T value_or_throw(Args&&... args) const T value_or_throw(Args&&... args) const
{ {
@ -106,9 +142,31 @@ namespace MacOS {
return _value; return _value;
} }
template<class F, typename RT = typename std::result_of<F(tool_return<T>)>::type>
void then(F &&f, typename std::enable_if<std::is_void<RT>::value>::type* = 0) {
f(std::move(*this));
}
template<class F, typename RT = typename std::result_of<F(tool_return<T>)>::type>
RT then(F &&f, typename std::enable_if<!std::is_void<RT>::value>::type* = 0) {
return f(std::move(*this));
}
template<class F, typename RT = typename std::result_of<F(value_type)>::type>
typename tool_return_type<RT>::type
map(F &&f, typename std::enable_if<std::is_void<RT>::value>::type* = 0) {
if (_error) return _error;
f(std::move(_value));
//return tool_return<void>();
return noErr;
}
template<class F, typename RT = typename std::result_of<F(value_type)>::type>
typename tool_return_type<RT>::type
map(F &&f, typename std::enable_if<!std::is_void<RT>::value>::type* = 0) {
if (_error) return _error;
return f(std::move(_value));
}
}; };
@ -129,10 +187,30 @@ namespace MacOS {
_error = error; _error = error;
return *this; return *this;
} }
}; };
template<>
class tool_return<macos_error> : public internal::tool_return_base
{
public:
typedef void value_type;
tool_return() = default;
tool_return(macos_error error) : tool_return_base(error)
{}
tool_return &operator=(macos_error error)
{
_error = error;
return *this;
}
};
} // namespace } // namespace
#endif #endif

View File

@ -107,20 +107,6 @@ namespace MM
{ {
template<class T>
struct tool_return_base { typedef T type; };
// not quite right.... gets turned to tool_return<void>();
/*
template<>
struct tool_return_base<macos_error> { typedef void type ; };
*/
template<class T>
struct tool_return_base<tool_return<T>> { typedef T type; };
template<class T> template<class T>
struct tool_return_type { typedef tool_return<T> type; }; struct tool_return_type { typedef tool_return<T> type; };
@ -1136,13 +1122,8 @@ namespace MM
Log("%04x GetHandleSize(%08x)\n", trap, hh); Log("%04x GetHandleSize(%08x)\n", trap, hh);
if (hh == 0) return SetMemError(MacOS::nilHandleErr); // ???? auto rv = Native::GetHandleSize(hh);
return rv ? rv.value() : rv.error();
auto iter = HandleMap.find(hh);
if (iter == HandleMap.end()) return SetMemError(MacOS::memWZErr);
return iter->second.size;
} }
uint16_t SetHandleSize(uint16_t trap) uint16_t SetHandleSize(uint16_t trap)
@ -1232,7 +1213,8 @@ namespace MM
Log("%04x HGetState(%08x)\n", trap, hh); Log("%04x HGetState(%08x)\n", trap, hh);
auto rv = Native::HGetState(hh); auto rv = Native::HGetState(hh);
return rv.error() ? rv.error() : rv.value(); return rv ? rv.value() : rv.error();
//return Native::HGetState(hh).then([](const tool_return<uint16_t> &rv){ return rv ? *rv : rv.error(); });
} }
uint16_t HSetState(uint16_t trap) uint16_t HSetState(uint16_t trap)