PrevUpHomeNext

class result

primer::result is a small structure that is meant to be used by user code, in functions that are pushed to lua using adapt.

See adapt reference page for extended examples.

primer::result is supposed to be the return type in a user callback. It signals how to terminate the lua function call when we return to lua.

There are three possible signals:

return

End this function call, and return some values from the stack to the caller.

yield

Yield the current coroutine, which effectively "pauses" this function call, and transfers execution back to the caller. Yield is also permitted to pass some values back to the caller. (See documentation.)

error

Raise a lua error.

These are normally represented in lua C api by simply returning, or by calling lua_yield or lua_error respectively.

In primer,

Table 1.1. Example Usage

lua C API

primer

Function Prototype

int my_func(lua_State *);

primer::result my_func(lua_State *);

return zero values

return 0;
return 0;
return {0};
return primer::result{0};

yield two values

lua_yield(L, 2);
return primer::yield{2};

error

lua_pushstring(L, "no more foobar");
lua_error(L);
return primer:error{"no more foobar"};

return and yield both take an int, indicating how many return values went on the stack which should be returned to the caller.

error is indicated by a primer::error object.

The reasons why we do it slightly differently hopefully will become clear in the adapt section. One advantage is that even though lua_yield and lua_error work by executing longjmp, returning a primer::result doesn't, so local variables in your function get cleaned up whether lua is compiled as C or C++, and without relying on C++ exceptions.

Synopsis
// Tag used by the user to indicate a yield.
struct yield {
  int n_;
};

// Helper object: Represents a return or yield signal.
struct return_or_yield {
  int n_;
  bool is_return_;

  bool is_valid() const { return n_ >= 0; }
};

// Result object
class result {

  expected<return_or_yield> payload_;

public:
  // Ctors (implicit for ease of use)
  result(int i)
    : payload_(return_or_yield{i, true}) {}
  result(yield y)
    : payload_(return_or_yield{y.n_, false}) {}
  result(error e)
    : payload_(e) {}

  // Accessor
  const expected<return_or_yield> & get_payload() const & { return payload_; }
  expected<return_or_yield> & get_payload() & { return payload_; }
};

PrevUpHomeNext