[C++] Optionally enable throwing exceptions on errors

Nick prefers error handling based on exceptions in all cases, while I
prefer to save exception handling for truly exceptional situations -
function parameter validation and class constructor. However, there's no
need to not support both approaches, to be chosen at the discretion of
the developer.

NCPP follows RAII and all classes throw exceptions from their
constructors in case they cannot initialize properly. Likewise,
functions taking pointers that are required validate them and throw
exceptions whenever the requirement isn't met.

This commit goes one step further in that it enables optional validation
of notcurses function return values and throwing an
exception (`ncpp::call_error`) should the function signal an error. This
is disabled by default but it can be enabled by defining the
`NCPP_EXCEPTIONS_PLEASE` macro (preferably on the command line or
before *each* inclusion of any NCPP headers).

Out of necessity, this breaks the ABI (plus I found a handful of minor
issues in the code), but I think it's worth having this support in
place.
pull/490/head
Marek Habersack 4 years ago committed by Nick Black
parent a5a2b5646a
commit 64eeb95f1e

@ -24,49 +24,49 @@ namespace ncpp
ncdirect_stop (direct);
}
bool clear () const noexcept
bool clear () const NOEXCEPT_MAYBE
{
return ncdirect_clear (direct) >= 0;
return error_guard (ncdirect_clear (direct), -1);
}
bool set_fg_default () const noexcept
bool set_fg_default () const NOEXCEPT_MAYBE
{
return ncdirect_fg_default (direct) >= 0;
return error_guard (ncdirect_fg_default (direct), -1);
}
bool set_fg (unsigned rgb) const noexcept
bool set_fg (unsigned rgb) const NOEXCEPT_MAYBE
{
return ncdirect_fg (direct, rgb) >= 0;
return error_guard (ncdirect_fg (direct, rgb), -1);
}
bool set_fg (unsigned r, unsigned g, unsigned b) const noexcept
bool set_fg (unsigned r, unsigned g, unsigned b) const NOEXCEPT_MAYBE
{
return ncdirect_fg_rgb8 (direct, r, g, b) >= 0;
return error_guard (ncdirect_fg_rgb8 (direct, r, g, b), -1);
}
bool set_bg_default () const noexcept
bool set_bg_default () const NOEXCEPT_MAYBE
{
return ncdirect_bg_default (direct) >= 0;
return error_guard (ncdirect_bg_default (direct), -1);
}
bool set_bg (unsigned rgb) const noexcept
bool set_bg (unsigned rgb) const NOEXCEPT_MAYBE
{
return ncdirect_bg (direct, rgb) >= 0;
return error_guard (ncdirect_bg (direct, rgb), -1);
}
bool set_bg (unsigned r, unsigned g, unsigned b) const noexcept
bool set_bg (unsigned r, unsigned g, unsigned b) const NOEXCEPT_MAYBE
{
return ncdirect_bg_rgb8 (direct, r, g, b) >= 0;
return error_guard (ncdirect_bg_rgb8 (direct, r, g, b), -1);
}
int get_dim_x () const noexcept
int get_dim_x () const NOEXCEPT_MAYBE
{
return ncdirect_dim_x (direct);
return error_guard (ncdirect_dim_x (direct), -1);
}
int get_dim_y () const noexcept
int get_dim_y () const NOEXCEPT_MAYBE
{
return ncdirect_dim_y (direct);
return error_guard (ncdirect_dim_y (direct), -1);
}
void styles_set (CellStyle stylebits) const noexcept
@ -84,39 +84,39 @@ namespace ncpp
ncdirect_styles_off (direct, static_cast<unsigned>(stylebits));
}
int cursor_move_yx (int y, int x) const noexcept
bool cursor_move_yx (int y, int x) const NOEXCEPT_MAYBE
{
return ncdirect_cursor_move_yx (direct, y, x);
return error_guard (ncdirect_cursor_move_yx (direct, y, x), -1);
}
int cursor_up (int num) const noexcept
bool cursor_up (int num) const NOEXCEPT_MAYBE
{
return ncdirect_cursor_up (direct, num);
return error_guard (ncdirect_cursor_up (direct, num), -1);
}
int cursor_left (int num) const noexcept
bool cursor_left (int num) const NOEXCEPT_MAYBE
{
return ncdirect_cursor_left (direct, num);
return error_guard (ncdirect_cursor_left (direct, num), -1);
}
int cursor_right (int num) const noexcept
bool cursor_right (int num) const NOEXCEPT_MAYBE
{
return ncdirect_cursor_right (direct, num);
return error_guard (ncdirect_cursor_right (direct, num), -1);
}
int cursor_down (int num) const noexcept
bool cursor_down (int num) const NOEXCEPT_MAYBE
{
return ncdirect_cursor_down (direct, num);
return error_guard (ncdirect_cursor_down (direct, num), -1);
}
bool cursor_enable () const noexcept
bool cursor_enable () const NOEXCEPT_MAYBE
{
return ncdirect_cursor_enable (direct) != -1;
return error_guard (ncdirect_cursor_enable (direct), -1);
}
bool cursor_disable () const noexcept
bool cursor_disable () const NOEXCEPT_MAYBE
{
return ncdirect_cursor_disable (direct) != -1;
return error_guard (ncdirect_cursor_disable (direct), -1);
}
private:

@ -28,34 +28,34 @@ namespace ncpp
ncmenu_destroy (menu);
}
bool unroll (int sectionidx) const noexcept
bool unroll (int sectionidx) const NOEXCEPT_MAYBE
{
return ncmenu_unroll (menu, sectionidx) >= 0;
return error_guard (ncmenu_unroll (menu, sectionidx), -1);
}
bool rollup () const noexcept
bool rollup () const NOEXCEPT_MAYBE
{
return ncmenu_rollup (menu) >= 0;
return error_guard (ncmenu_rollup (menu), -1);
}
bool nextsection () const noexcept
bool nextsection () const NOEXCEPT_MAYBE
{
return ncmenu_nextsection (menu) >= 0;
return error_guard (ncmenu_nextsection (menu), -1);
}
bool prevsection () const noexcept
bool prevsection () const NOEXCEPT_MAYBE
{
return ncmenu_prevsection (menu) >= 0;
return error_guard (ncmenu_prevsection (menu), -1);
}
bool nextitem () const noexcept
bool nextitem () const NOEXCEPT_MAYBE
{
return ncmenu_nextitem (menu) >= 0;
return error_guard (ncmenu_nextitem (menu), -1);
}
bool previtem () const noexcept
bool previtem () const NOEXCEPT_MAYBE
{
return ncmenu_previtem (menu) >= 0;
return error_guard (ncmenu_previtem (menu), -1);
}
const char* get_selected (ncinput *ni = nullptr) const noexcept

@ -53,9 +53,9 @@ namespace ncpp
return ncmultiselector_offer_input (multiselector, nc);
}
const int get_selected (bool *selected, unsigned count) const noexcept
int get_selected (bool *selected, unsigned count) const NOEXCEPT_MAYBE
{
return ncmultiselector_selected (multiselector, selected, count);
return error_guard<int> (ncmultiselector_selected (multiselector, selected, count), -1);
}
Plane* get_plane () const noexcept;

@ -135,14 +135,14 @@ namespace ncpp
return use (*p);
}
bool use (const Palette256 &p) const noexcept
bool use (const Palette256 &p) const NOEXCEPT_MAYBE
{
return palette256_use (nc, reinterpret_cast<const palette256*>(&p)) != -1;
return error_guard (palette256_use (nc, reinterpret_cast<const palette256*>(&p)), -1);
}
bool render () const noexcept
int render () const NOEXCEPT_MAYBE
{
return notcurses_render (nc) == 0;
return error_guard<int> (notcurses_render (nc), -1);
}
void get_term_dim (int *rows, int *cols) const noexcept
@ -155,14 +155,14 @@ namespace ncpp
get_term_dim (&rows, &cols);
}
bool refresh (int* rows, int* cols) const noexcept
bool refresh (int* rows, int* cols) const NOEXCEPT_MAYBE
{
return notcurses_refresh (nc, rows, cols) == 0;
return error_guard (notcurses_refresh (nc, rows, cols), -1);
}
bool refresh (int& rows, int& cols) const noexcept
bool refresh (int& rows, int& cols) const NOEXCEPT_MAYBE
{
return refresh (&rows, &cols) == 0;
return refresh (&rows, &cols);
}
int get_palette_size () const noexcept
@ -170,14 +170,14 @@ namespace ncpp
return notcurses_palette_size (static_cast<const notcurses*> (nc));
}
bool mouse_enable () const noexcept
bool mouse_enable () const NOEXCEPT_MAYBE
{
return notcurses_mouse_enable (nc) != -1;
return error_guard (notcurses_mouse_enable (nc), -1);
}
bool mouse_disable () const noexcept
bool mouse_disable () const NOEXCEPT_MAYBE
{
return notcurses_mouse_disable (nc) != -1;
return error_guard (notcurses_mouse_disable (nc), -1);
}
CellStyle get_supported_styles () const noexcept

@ -31,14 +31,14 @@ namespace ncpp
return palette;
}
bool set (int idx, int r, int g, int b) const noexcept
bool set (int idx, int r, int g, int b) const NOEXCEPT_MAYBE
{
return palette256_set_rgb (palette, idx, r, g, b) != -1;
return error_guard (palette256_set_rgb (palette, idx, r, g, b), -1);
}
bool set (int idx, unsigned rgb) const noexcept
bool set (int idx, unsigned rgb) const NOEXCEPT_MAYBE
{
return palette256_set (palette, idx, rgb) != -1;
return error_guard (palette256_set (palette, idx, rgb), -1);
}
bool get (int idx, unsigned *r, unsigned *g, unsigned *b) const
@ -53,9 +53,9 @@ namespace ncpp
return get (idx, *r, *g, *b);
}
bool get (int idx, unsigned &r, unsigned &g, unsigned &b) const noexcept
bool get (int idx, unsigned &r, unsigned &g, unsigned &b) const NOEXCEPT_MAYBE
{
return palette256_get_rgb (palette, idx, &r, &g, &b) != -1;
return error_guard (palette256_get_rgb (palette, idx, &r, &g, &b), -1);
}
private:

@ -115,9 +115,9 @@ namespace ncpp
return plane;
}
bool resize (int keepy, int keepx, int keepleny, int keeplenx, int yoff, int xoff, int ylen, int xlen) const noexcept
bool resize (int keepy, int keepx, int keepleny, int keeplenx, int yoff, int xoff, int ylen, int xlen) const NOEXCEPT_MAYBE
{
return ncplane_resize (
int ret = ncplane_resize (
plane,
keepy,
keepx,
@ -127,40 +127,34 @@ namespace ncpp
xoff,
ylen,
xlen
) != -1;
}
bool pulse (const timespec* ts, fadecb fader, void* curry) const noexcept
{
return ncplane_pulse (plane, ts, fader, curry) != -1;
}
);
bool mergedown (Plane* dst = nullptr) {
return ncplane_mergedown(*this, dst ? dst->plane : nullptr);
return error_guard (ret, -1);
}
bool mergedown (Plane& dst) {
return mergedown(&dst);
bool pulse (const timespec* ts, fadecb fader, void* curry) const NOEXCEPT_MAYBE
{
return error_guard (ncplane_pulse (plane, ts, fader, curry), -1);
}
int gradient (const char* egc, uint32_t attrword, uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr, int ystop, int xstop) const noexcept
int gradient (const char* egc, uint32_t attrword, uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr, int ystop, int xstop) const NOEXCEPT_MAYBE
{
return ncplane_gradient (plane, egc, attrword, ul, ur, ll, lr, ystop, xstop);
return error_guard<int> (ncplane_gradient (plane, egc, attrword, ul, ur, ll, lr, ystop, xstop), -1);
}
int gradient_sized (const char* egc, uint32_t attrword, uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr, int ylen, int xlen) const noexcept
int gradient_sized (const char* egc, uint32_t attrword, uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr, int ylen, int xlen) const NOEXCEPT_MAYBE
{
return ncplane_gradient_sized (plane, egc, attrword, ul, ur, ll, lr, ylen, xlen);
return error_guard<int> (ncplane_gradient_sized (plane, egc, attrword, ul, ur, ll, lr, ylen, xlen), -1);
}
int high_gradient (uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr, int ylen, int xlen) const noexcept
int high_gradient (uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr, int ylen, int xlen) const NOEXCEPT_MAYBE
{
return ncplane_highgradient (plane, ul, ur, ll, lr, ylen, xlen);
return error_guard<int> (ncplane_highgradient (plane, ul, ur, ll, lr, ylen, xlen), -1);
}
int high_gradient_sized (uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr, int ylen, int xlen) const noexcept
int high_gradient_sized (uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr, int ylen, int xlen) const NOEXCEPT_MAYBE
{
return ncplane_highgradient_sized (plane, ul, ur, ll, lr, ylen, xlen);
return error_guard<int> (ncplane_highgradient_sized (plane, ul, ur, ll, lr, ylen, xlen), -1);
}
void greyscale () const noexcept
@ -168,49 +162,49 @@ namespace ncpp
ncplane_greyscale (plane);
}
bool resize (int ylen, int xlen) const noexcept
bool resize (int ylen, int xlen) const NOEXCEPT_MAYBE
{
return ncplane_resize_simple (plane, ylen, xlen) != -1;
return error_guard (ncplane_resize_simple (plane, ylen, xlen), -1);
}
bool fadeout (timespec *ts, fadecb fader = nullptr, void *curry = nullptr) const noexcept
bool fadeout (timespec *ts, fadecb fader = nullptr, void *curry = nullptr) const NOEXCEPT_MAYBE
{
return fadeout (static_cast<const timespec*>(ts), fader, curry);
}
bool fadeout (timespec &ts, fadecb fader = nullptr, void *curry = nullptr) const noexcept
bool fadeout (timespec &ts, fadecb fader = nullptr, void *curry = nullptr) const NOEXCEPT_MAYBE
{
return fadeout (&ts, fader, curry);
}
bool fadeout (timespec const& ts, fadecb fader = nullptr, void *curry = nullptr) const noexcept
bool fadeout (timespec const& ts, fadecb fader = nullptr, void *curry = nullptr) const NOEXCEPT_MAYBE
{
return fadeout (&ts, fader, curry);
}
bool fadeout (const timespec *ts, fadecb fader = nullptr, void *curry = nullptr) const noexcept
bool fadeout (const timespec *ts, fadecb fader = nullptr, void *curry = nullptr) const NOEXCEPT_MAYBE
{
return ncplane_fadeout (plane, ts, fader, curry) != -1;
return error_guard (ncplane_fadeout (plane, ts, fader, curry), -1);
}
bool fadein (timespec *ts, fadecb fader = nullptr) const noexcept
bool fadein (timespec *ts, fadecb fader = nullptr) const NOEXCEPT_MAYBE
{
return fadein (static_cast<const timespec*>(ts), fader);
}
bool fadein (timespec &ts, fadecb fader = nullptr) const noexcept
bool fadein (timespec &ts, fadecb fader = nullptr) const NOEXCEPT_MAYBE
{
return fadein (&ts, fader);
}
bool fadein (timespec const& ts, fadecb fader = nullptr) const noexcept
bool fadein (timespec const& ts, fadecb fader = nullptr) const NOEXCEPT_MAYBE
{
return fadein (&ts, fader);
}
bool fadein (const timespec *ts, fadecb fader = nullptr, void *curry = nullptr) const noexcept
bool fadein (const timespec *ts, fadecb fader = nullptr, void *curry = nullptr) const NOEXCEPT_MAYBE
{
return ncplane_fadein (plane, ts, fader, curry) != -1;
return error_guard (ncplane_fadein (plane, ts, fader, curry), -1);
}
void erase () const noexcept
@ -218,9 +212,9 @@ namespace ncpp
ncplane_erase (plane);
}
int get_align (NCAlign align, int c) const noexcept
int get_align (NCAlign align, int c) const NOEXCEPT_MAYBE
{
return ncplane_align (plane, static_cast<ncalign_e>(align), c);
return error_guard<int> (ncplane_align (plane, static_cast<ncalign_e>(align), c), INT_MAX);
}
void get_dim (int *rows, int *cols) const noexcept
@ -272,24 +266,24 @@ namespace ncpp
return reparent (const_cast<Plane*>(&newparent));
}
bool move (int y, int x) const noexcept
bool move (int y, int x) const NOEXCEPT_MAYBE
{
return ncplane_move_yx (plane, y, x) != -1;
return error_guard (ncplane_move_yx (plane, y, x), -1);
}
bool move_top () const noexcept
bool move_top () const NOEXCEPT_MAYBE
{
return ncplane_move_top (plane) != -1;
return error_guard (ncplane_move_top (plane), -1);
}
bool move_bottom () const noexcept
bool move_bottom () const NOEXCEPT_MAYBE
{
return ncplane_move_bottom (plane) != -1;
return error_guard (ncplane_move_bottom (plane), -1);
}
bool move_below (Plane &below) const noexcept
bool move_below (Plane &below) const NOEXCEPT_MAYBE
{
return ncplane_move_below (plane, below.plane) != -1;
return error_guard (ncplane_move_below (plane, below.plane), -1);
}
bool move_below (Plane *below) const
@ -300,9 +294,9 @@ namespace ncpp
return move_below (*below);
}
bool move_below_unsafe (Plane &below) const noexcept
bool move_below_unsafe (Plane &below) const NOEXCEPT_MAYBE
{
return ncplane_move_below_unsafe (plane, below.plane) != -1;
return error_guard (ncplane_move_below_unsafe (plane, below.plane), -1);
}
bool move_below_unsafe (Plane *below) const
@ -313,9 +307,9 @@ namespace ncpp
return move_below_unsafe (*below);
}
bool move_above (Plane &above) const noexcept
bool move_above (Plane &above) const NOEXCEPT_MAYBE
{
return ncplane_move_above (plane, above.plane) != -1;
return error_guard (ncplane_move_above (plane, above.plane), -1);
}
bool move_above (Plane *above) const
@ -326,9 +320,9 @@ namespace ncpp
return move_above (*above);
}
bool move_above_unsafe (Plane &above) const noexcept
bool move_above_unsafe (Plane &above) const NOEXCEPT_MAYBE
{
return ncplane_move_above_unsafe (plane, above.plane) != -1;
return error_guard (ncplane_move_above_unsafe (plane, above.plane), -1);
}
bool move_above_unsafe (Plane *above) const
@ -341,21 +335,20 @@ namespace ncpp
bool mergedown (Plane &dst) const
{
if (plane == dst.plane)
throw invalid_argument ("'dst' must refer to a differnt plane than the one this method is called on");
return ncplane_mergedown (plane, dst.plane) != -1;
return mergedown (&dst);
}
bool mergedown (Plane *dst) const
{
if (dst == nullptr)
throw invalid_argument ("'dst' must be a valid pointer");
return mergedown (*dst);
if (dst != nullptr && plane == dst->plane)
throw invalid_argument ("'dst' must refer to a differnt plane than the one this method is called on");
return error_guard (ncplane_mergedown (plane, dst != nullptr ? dst->plane : nullptr), -1);
}
bool cursor_move (int y, int x) const noexcept
bool cursor_move (int y, int x) const NOEXCEPT_MAYBE
{
return ncplane_cursor_move_yx (plane, y, x) != -1;
return error_guard (ncplane_cursor_move_yx (plane, y, x), -1);
}
void get_cursor_yx (int *y, int *x) const noexcept
@ -368,9 +361,9 @@ namespace ncpp
get_cursor_yx (&y, &x);
}
int putc (const Cell &c) const noexcept
int putc (const Cell &c) const NOEXCEPT_MAYBE
{
return ncplane_putc (plane, c);
return error_guard<int> (ncplane_putc (plane, c), -1);
}
int putc (const Cell *c) const
@ -381,12 +374,12 @@ namespace ncpp
return putc (*c);
}
int putc (int y, int x, Cell const& c) const noexcept
int putc (int y, int x, Cell const& c) const NOEXCEPT_MAYBE
{
return ncplane_putc_yx (plane, y, x, c);
return error_guard<int> (ncplane_putc_yx (plane, y, x, c), -1);
}
int putc (int y, int x, Cell const* c) const noexcept
int putc (int y, int x, Cell const* c) const NOEXCEPT_MAYBE
{
if (c == nullptr)
return -1;
@ -394,86 +387,103 @@ namespace ncpp
return putc (y, x, *c);
}
int putc (char c, bool retain_styling = false) const noexcept
int putc (char c, bool retain_styling = false) const NOEXCEPT_MAYBE
{
if (retain_styling)
return ncplane_putsimple_stainable (plane, c);
return ncplane_putsimple (plane, c);
int ret;
if (retain_styling) {
ret = ncplane_putsimple_stainable (plane, c);
} else {
ret = ncplane_putsimple (plane, c);
}
return error_guard<int> (ret, -1);
}
int putc (int y, int x, char c) const noexcept
int putc (int y, int x, char c) const NOEXCEPT_MAYBE
{
return ncplane_putsimple_yx (plane, y, x, c);
return error_guard<int> (ncplane_putsimple_yx (plane, y, x, c), -1);
}
int putc (const char *gclust, int *sbytes = nullptr, bool retain_styling = false) const noexcept
int putc (const char *gclust, int *sbytes = nullptr, bool retain_styling = false) const NOEXCEPT_MAYBE
{
if (retain_styling)
return ncplane_putegc_stainable (plane, gclust, sbytes);
return ncplane_putegc (plane, gclust, sbytes);
int ret;
if (retain_styling) {
ret = ncplane_putegc_stainable (plane, gclust, sbytes);
} else {
ret = ncplane_putegc (plane, gclust, sbytes);
}
return error_guard<int> (ret, -1);
}
int putc (int y, int x, const char *gclust, int *sbytes = nullptr) const noexcept
int putc (int y, int x, const char *gclust, int *sbytes = nullptr) const NOEXCEPT_MAYBE
{
return ncplane_putegc_yx (plane, y, x, gclust, sbytes);
return error_guard<int> (ncplane_putegc_yx (plane, y, x, gclust, sbytes), -1);
}
int putc (const wchar_t *gclust, int *sbytes = nullptr, bool retain_styling = false) const noexcept
int putc (const wchar_t *gclust, int *sbytes = nullptr, bool retain_styling = false) const NOEXCEPT_MAYBE
{
if (retain_styling)
return ncplane_putwegc_stainable (plane, gclust, sbytes);
return ncplane_putwegc (plane, gclust, sbytes);
int ret;
if (retain_styling) {
ret = ncplane_putwegc_stainable (plane, gclust, sbytes);
} else {
ret = ncplane_putwegc (plane, gclust, sbytes);
}
return error_guard<int> (ret, -1);
}
int putc (int y, int x, const wchar_t *gclust, int *sbytes = nullptr) const noexcept
int putc (int y, int x, const wchar_t *gclust, int *sbytes = nullptr) const NOEXCEPT_MAYBE
{
return ncplane_putwegc_yx (plane, y, x, gclust, sbytes);
return error_guard<int> (ncplane_putwegc_yx (plane, y, x, gclust, sbytes), -1);
}
// OK, this is ugly, but we need to rename this overload or calls similar to n->putc (0, 0, '0') will be
// considered ambiguous with the above `putc (int, int, char)` overload.
int putcw (int y, int x, wchar_t w) const noexcept
int putcw (int y, int x, wchar_t w) const NOEXCEPT_MAYBE
{
return ncplane_putwc_yx (plane, y, x, w);
return error_guard<int> (ncplane_putwc_yx (plane, y, x, w), -1);
}
// Ditto
int putcw (wchar_t w) const noexcept
int putcw (wchar_t w) const NOEXCEPT_MAYBE
{
return ncplane_putwc (plane, w);
return error_guard<int> (ncplane_putwc (plane, w), -1);
}
int putstr (const char *gclustarr) const noexcept
int putstr (const char *gclustarr) const NOEXCEPT_MAYBE
{
return ncplane_putstr (plane, gclustarr);
int ret = ncplane_putstr (plane, gclustarr);
return error_guard_cond<int> (ret, ret < 0);
}
int putstr (int y, int x, const char *gclustarr) const noexcept
int putstr (int y, int x, const char *gclustarr) const NOEXCEPT_MAYBE
{
return ncplane_putstr_yx (plane, y, x, gclustarr);
int ret = ncplane_putstr_yx (plane, y, x, gclustarr);
return error_guard_cond<int> (ret, ret < 0);
}
int putstr (int y, NCAlign atype, const char *s) const noexcept
int putstr (int y, NCAlign atype, const char *s) const NOEXCEPT_MAYBE
{
return ncplane_putstr_aligned (plane, y, static_cast<ncalign_e>(atype), s);
return error_guard<int> (ncplane_putstr_aligned (plane, y, static_cast<ncalign_e>(atype), s), -1);
}
int putstr (const wchar_t *gclustarr) const noexcept
int putstr (const wchar_t *gclustarr) const NOEXCEPT_MAYBE
{
return ncplane_putwstr (plane, gclustarr);
return error_guard<int> (ncplane_putwstr (plane, gclustarr), -1);
}
int putstr (int y, int x, const wchar_t *gclustarr) const noexcept
int putstr (int y, int x, const wchar_t *gclustarr) const NOEXCEPT_MAYBE
{
return ncplane_putwstr_yx (plane, y, x, gclustarr);
return error_guard<int> (ncplane_putwstr_yx (plane, y, x, gclustarr), -1);
}
int putstr (int y, NCAlign atype, const wchar_t *gclustattr) const noexcept
int putstr (int y, NCAlign atype, const wchar_t *gclustattr) const NOEXCEPT_MAYBE
{
return ncplane_putwstr_aligned (plane, y, static_cast<ncalign_e>(atype), gclustattr);
return error_guard<int> (ncplane_putwstr_aligned (plane, y, static_cast<ncalign_e>(atype), gclustattr), -1);
}
int printf (const char* format, ...) const noexcept
int printf (const char* format, ...) const NOEXCEPT_MAYBE
__attribute__ ((format (printf, 2, 3)))
{
va_list va;
@ -482,10 +492,10 @@ namespace ncpp
int ret = ncplane_vprintf (plane, format, va);
va_end (va);
return ret;
return error_guard<int> (ret, -1);
}
int printf (int y, int x, const char *format, ...) const noexcept
int printf (int y, int x, const char *format, ...) const NOEXCEPT_MAYBE
__attribute__ ((format (printf, 4, 5)))
{
va_list va;
@ -494,10 +504,10 @@ namespace ncpp
int ret = ncplane_vprintf_yx (plane, y, x, format, va);
va_end (va);
return ret;
return error_guard<int> (ret, -1);
}
int printf (int y, NCAlign align, const char *format, ...) const noexcept
int printf (int y, NCAlign align, const char *format, ...) const NOEXCEPT_MAYBE
__attribute__ ((format (printf, 4, 5)))
{
va_list va;
@ -506,116 +516,116 @@ namespace ncpp
int ret = vprintf (y, align, format, va);
va_end (va);
return ret;
return error_guard<int> (ret, -1);
}
int vprintf (const char* format, va_list ap) const noexcept
int vprintf (const char* format, va_list ap) const NOEXCEPT_MAYBE
{
return ncplane_vprintf (plane, format, ap);
return error_guard<int> (ncplane_vprintf (plane, format, ap), -1);
}
int vprintf (int y, int x, const char* format, va_list ap) const noexcept
int vprintf (int y, int x, const char* format, va_list ap) const NOEXCEPT_MAYBE
{
return ncplane_vprintf_yx (plane, y, x, format, ap);
return error_guard<int> (ncplane_vprintf_yx (plane, y, x, format, ap), -1);
}
int vprintf (int y, NCAlign align, const char *format, va_list ap) const noexcept
int vprintf (int y, NCAlign align, const char *format, va_list ap) const NOEXCEPT_MAYBE
{
return ncplane_vprintf_aligned (plane, y, static_cast<ncalign_e>(align), format, ap);
return error_guard<int> (ncplane_vprintf_aligned (plane, y, static_cast<ncalign_e>(align), format, ap), -1);
}
int hline (const Cell &c, int len) const noexcept
int hline (const Cell &c, int len) const NOEXCEPT_MAYBE
{
return ncplane_hline (plane, c, len);
return error_guard<int> (ncplane_hline (plane, c, len), -1);
}
int hline (const Cell &c, int len, uint64_t c1, uint64_t c2) const noexcept
int hline (const Cell &c, int len, uint64_t c1, uint64_t c2) const NOEXCEPT_MAYBE
{
return ncplane_hline_interp (plane, c, len, c1, c2);
return error_guard<int> (ncplane_hline_interp (plane, c, len, c1, c2), -1);
}
int vline (const Cell &c, int len) const noexcept
int vline (const Cell &c, int len) const NOEXCEPT_MAYBE
{
return ncplane_vline (plane, c, len);
return error_guard<int> (ncplane_vline (plane, c, len), -1);
}
int vline (const Cell &c, int len, uint64_t c1, uint64_t c2) const noexcept
int vline (const Cell &c, int len, uint64_t c1, uint64_t c2) const NOEXCEPT_MAYBE
{
return ncplane_vline_interp (plane, c, len, c1, c2);
return error_guard<int> (ncplane_vline_interp (plane, c, len, c1, c2), -1);
}
bool load_box (uint32_t attrs, uint64_t channels, Cell &ul, Cell &ur, Cell &ll, Cell &lr, Cell &hl, Cell &vl, const char *gclusters) const noexcept
bool load_box (uint32_t attrs, uint64_t channels, Cell &ul, Cell &ur, Cell &ll, Cell &lr, Cell &hl, Cell &vl, const char *gclusters) const NOEXCEPT_MAYBE
{
return cells_load_box (plane, attrs, channels, ul, ur, ll, lr, hl, vl, gclusters) != -1;
return error_guard (cells_load_box (plane, attrs, channels, ul, ur, ll, lr, hl, vl, gclusters), -1);
}
bool load_box (CellStyle style, uint64_t channels, Cell &ul, Cell &ur, Cell &ll, Cell &lr, Cell &hl, Cell &vl, const char *gclusters) const noexcept
bool load_box (CellStyle style, uint64_t channels, Cell &ul, Cell &ur, Cell &ll, Cell &lr, Cell &hl, Cell &vl, const char *gclusters) const NOEXCEPT_MAYBE
{
return load_box (static_cast<uint32_t>(style), channels, ul, ur, ll, lr, hl, vl, gclusters);
}
bool load_rounded_box (uint32_t attr, uint64_t channels, Cell &ul, Cell &ur, Cell &ll, Cell &lr, Cell &hl, Cell &vl) const noexcept
bool load_rounded_box (uint32_t attr, uint64_t channels, Cell &ul, Cell &ur, Cell &ll, Cell &lr, Cell &hl, Cell &vl) const NOEXCEPT_MAYBE
{
return cells_rounded_box (plane, attr, channels, ul, ur, ll, lr, hl, vl) != -1;
return error_guard (cells_rounded_box (plane, attr, channels, ul, ur, ll, lr, hl, vl), -1);
}
bool load_rounded_box (CellStyle style, uint64_t channels, Cell &ul, Cell &ur, Cell &ll, Cell &lr, Cell &hl, Cell &vl) const noexcept
bool load_rounded_box (CellStyle style, uint64_t channels, Cell &ul, Cell &ur, Cell &ll, Cell &lr, Cell &hl, Cell &vl) const NOEXCEPT_MAYBE
{
return load_rounded_box (static_cast<uint32_t>(style), channels, ul, ur, ll, lr, hl, vl);
}
bool load_double_box (uint32_t attr, uint64_t channels, Cell &ul, Cell &ur, Cell &ll, Cell &lr, Cell &hl, Cell &vl) const noexcept
bool load_double_box (uint32_t attr, uint64_t channels, Cell &ul, Cell &ur, Cell &ll, Cell &lr, Cell &hl, Cell &vl) const NOEXCEPT_MAYBE
{
return cells_double_box (plane, attr, channels, ul, ur, ll, lr, hl, vl) != -1;
return error_guard (cells_double_box (plane, attr, channels, ul, ur, ll, lr, hl, vl), -1);
}
bool load_double_box (CellStyle style, uint64_t channels, Cell &ul, Cell &ur, Cell &ll, Cell &lr, Cell &hl, Cell &vl) const noexcept
bool load_double_box (CellStyle style, uint64_t channels, Cell &ul, Cell &ur, Cell &ll, Cell &lr, Cell &hl, Cell &vl) const NOEXCEPT_MAYBE
{
return load_double_box (static_cast<uint32_t>(style), channels, ul, ur, ll, lr, hl, vl);
}
bool box (const Cell &ul, const Cell &ur, const Cell &ll, const Cell &lr,
const Cell &hline, const Cell &vline, int ystop, int xstop,
unsigned ctlword) const noexcept
const Cell &hline, const Cell &vline, int ystop, int xstop,
unsigned ctlword) const NOEXCEPT_MAYBE
{
return ncplane_box (plane, ul, ur, ll, lr, hline, vline, ystop, xstop, ctlword) != -1;
return error_guard (ncplane_box (plane, ul, ur, ll, lr, hline, vline, ystop, xstop, ctlword), -1);
}
bool box_sized (const Cell &ul, const Cell &ur, const Cell &ll, const Cell &lr,
const Cell &hline, const Cell &vline, int ylen, int xlen,
unsigned ctlword) const noexcept
unsigned ctlword) const NOEXCEPT_MAYBE
{
return ncplane_box_sized (plane, ul, ur, ll, lr, hline, vline, ylen, xlen, ctlword) != -1;
return error_guard (ncplane_box_sized (plane, ul, ur, ll, lr, hline, vline, ylen, xlen, ctlword), -1);
}
bool rounded_box (uint32_t attr, uint64_t channels, int ystop, int xstop, unsigned ctlword) const noexcept
bool rounded_box (uint32_t attr, uint64_t channels, int ystop, int xstop, unsigned ctlword) const NOEXCEPT_MAYBE
{
return ncplane_rounded_box (plane, attr, channels, ystop, xstop, ctlword) != -1;
return error_guard (ncplane_rounded_box (plane, attr, channels, ystop, xstop, ctlword), -1);
}
bool rounded_box_sized (uint32_t attr, uint64_t channels, int ylen, int xlen, unsigned ctlword) const noexcept
bool rounded_box_sized (uint32_t attr, uint64_t channels, int ylen, int xlen, unsigned ctlword) const NOEXCEPT_MAYBE
{
return ncplane_rounded_box_sized (plane, attr, channels, ylen, xlen, ctlword) != -1;
return error_guard (ncplane_rounded_box_sized (plane, attr, channels, ylen, xlen, ctlword), -1);
}
bool double_box (uint32_t attr, uint64_t channels, int ystop, int xstop, unsigned ctlword) const noexcept
bool double_box (uint32_t attr, uint64_t channels, int ystop, int xstop, unsigned ctlword) const NOEXCEPT_MAYBE
{
return ncplane_double_box (plane, attr, channels, ystop, xstop, ctlword) != -1;
return error_guard (ncplane_double_box (plane, attr, channels, ystop, xstop, ctlword), -1);
}
bool double_box_sized (uint32_t attr, uint64_t channels, int ylen, int xlen, unsigned ctlword) const noexcept
bool double_box_sized (uint32_t attr, uint64_t channels, int ylen, int xlen, unsigned ctlword) const NOEXCEPT_MAYBE
{
return ncplane_double_box_sized (plane, attr, channels, ylen, xlen, ctlword) != -1;
return error_guard (ncplane_double_box_sized (plane, attr, channels, ylen, xlen, ctlword), -1);
}
bool perimeter (const Cell &ul, const Cell &ur, const Cell &ll, const Cell &lr, const Cell &hline, const Cell &vline, unsigned ctlword) const noexcept
bool perimeter (const Cell &ul, const Cell &ur, const Cell &ll, const Cell &lr, const Cell &hline, const Cell &vline, unsigned ctlword) const NOEXCEPT_MAYBE
{
return ncplane_perimeter (plane, ul, ur, ll, lr, hline, vline, ctlword) != -1;
return error_guard (ncplane_perimeter (plane, ul, ur, ll, lr, hline, vline, ctlword), -1);
}
int polyfill (int y, int x, const Cell& c) const noexcept
int polyfill (int y, int x, const Cell& c) const NOEXCEPT_MAYBE
{
return ncplane_polyfill_yx (plane, y, x, c);
return error_guard<int> (ncplane_polyfill_yx (plane, y, x, c), -1);
}
uint64_t get_channels () const noexcept
@ -653,9 +663,9 @@ namespace ncpp
return ncplane_fg_alpha (plane);
}
bool set_fg_alpha (int alpha) const noexcept
bool set_fg_alpha (int alpha) const NOEXCEPT_MAYBE
{
return ncplane_set_fg_alpha (plane, alpha) != -1;
return error_guard (ncplane_set_fg_alpha (plane, alpha), -1);
}
unsigned get_bg_alpha () const noexcept
@ -663,9 +673,9 @@ namespace ncpp
return ncplane_bg_alpha (plane);
}
bool set_bg_alpha (int alpha) const noexcept
bool set_bg_alpha (int alpha) const NOEXCEPT_MAYBE
{
return ncplane_set_bg_alpha (plane, alpha) != -1;
return error_guard (ncplane_set_bg_alpha (plane, alpha), -1);
}
unsigned get_fg_rgb (unsigned *r, unsigned *g, unsigned *b) const noexcept
@ -673,24 +683,24 @@ namespace ncpp
return ncplane_fg_rgb (plane, r, g, b);
}
bool set_fg_rgb (int r, int g, int b, bool clipped = false) const noexcept
bool set_fg_rgb (int r, int g, int b, bool clipped = false) const NOEXCEPT_MAYBE
{
if (clipped) {
ncplane_set_fg_rgb_clipped (plane, r, g, b);
return true;
}
return ncplane_set_fg_rgb (plane, r, g, b) != -1;
return error_guard (ncplane_set_fg_rgb (plane, r, g, b), -1);
}
bool set_fg_palindex (int idx) const noexcept
bool set_fg_palindex (int idx) const NOEXCEPT_MAYBE
{
return ncplane_set_fg_palindex (plane, idx) != -1;
return error_guard (ncplane_set_fg_palindex (plane, idx), -1);
}
bool set_fg (uint32_t channel) const noexcept
bool set_fg (uint32_t channel) const NOEXCEPT_MAYBE
{
return ncplane_set_fg (plane, channel) != -1;
return error_guard (ncplane_set_fg (plane, channel), -1);
}
void set_fg_default () const noexcept
@ -703,24 +713,24 @@ namespace ncpp
return ncplane_bg_rgb (plane, r, g, b);
}
bool set_bg_rgb (int r, int g, int b, bool clipped = false) const noexcept
bool set_bg_rgb (int r, int g, int b, bool clipped = false) const NOEXCEPT_MAYBE
{
if (clipped) {
ncplane_set_fg_rgb_clipped (plane, r, g, b);
return true;
}
return ncplane_set_bg_rgb (plane, r, g, b) != -1;
return error_guard (ncplane_set_bg_rgb (plane, r, g, b), -1);
}
bool set_bg_palindex (int idx) const noexcept
bool set_bg_palindex (int idx) const NOEXCEPT_MAYBE
{
return ncplane_set_bg_alpha (plane, idx) != -1;
return error_guard (ncplane_set_bg_alpha (plane, idx), -1);
}
bool set_bg (uint32_t channel) const noexcept
bool set_bg (uint32_t channel) const NOEXCEPT_MAYBE
{
return ncplane_set_bg (plane, channel) != -1;
return error_guard (ncplane_set_bg (plane, channel), -1);
}
void set_bg_default () const noexcept
@ -728,7 +738,7 @@ namespace ncpp
ncplane_set_bg_default (plane);
}
bool set_scrolling (bool scrollp) noexcept
bool set_scrolling (bool scrollp) const noexcept
{
return ncplane_set_scrolling (plane, scrollp);
}
@ -748,14 +758,14 @@ namespace ncpp
ncplane_styles_off (plane, static_cast<unsigned>(styles));
}
int format (int ystop, int xstop, uint32_t attrword) const noexcept
int format (int ystop, int xstop, uint32_t attrword) const NOEXCEPT_MAYBE
{
return ncplane_format (plane, ystop, xstop, attrword);
return error_guard<int> (ncplane_format (plane, ystop, xstop, attrword), -1);
}
int stain (int ystop, int xstop, uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr)
int stain (int ystop, int xstop, uint64_t ul, uint64_t ur, uint64_t ll, uint64_t lr) const NOEXCEPT_MAYBE
{
return ncplane_stain (plane, ystop, xstop, ul, ur, ll, lr);
return error_guard<int> (ncplane_stain (plane, ystop, xstop, ul, ur, ll, lr), -1);
}
Plane* get_below () const noexcept
@ -763,27 +773,31 @@ namespace ncpp
return map_plane (ncplane_below (plane));
}
bool set_base_cell (Cell &c) const noexcept
bool set_base_cell (Cell &c) const NOEXCEPT_MAYBE
{
return ncplane_set_base_cell (plane, c) >= 0;
bool ret = ncplane_set_base_cell (plane, c) < 0;
return error_guard_cond<bool, bool> (ret, ret);
}
bool set_base (uint64_t channels, uint32_t attrword, const char *egc) const noexcept
bool set_base (uint64_t channels, uint32_t attrword, const char *egc) const NOEXCEPT_MAYBE
{
return ncplane_set_base (plane, channels, attrword, egc) >= 0;
bool ret = ncplane_set_base (plane, channels, attrword, egc) < 0;
return error_guard_cond<bool, bool> (ret, ret);
}
bool get_base (Cell &c) const noexcept
bool get_base (Cell &c) const NOEXCEPT_MAYBE
{
return ncplane_base (plane, c) >= 0;
bool ret = ncplane_base (plane, c) < 0;
return error_guard_cond<bool, bool> (ret, ret);
}
bool at_cursor (Cell &c) const noexcept
bool at_cursor (Cell &c) const NOEXCEPT_MAYBE
{
return ncplane_at_cursor (plane, c) >= 0;
bool ret = ncplane_at_cursor (plane, c) < 0;
return error_guard_cond<bool, bool> (ret, ret);
}
bool at_cursor (Cell *c) const
bool at_cursor (Cell *c) const noexcept
{
if (c == nullptr)
return false;
@ -791,9 +805,9 @@ namespace ncpp
return at_cursor (*c);
}
int get_at (int y, int x, Cell &c) const noexcept
int get_at (int y, int x, Cell &c) const NOEXCEPT_MAYBE
{
return ncplane_at_yx (plane, y, x, c);
return error_guard (ncplane_at_yx (plane, y, x, c), -1);
}
int get_at (int y, int x, Cell *c) const
@ -839,19 +853,19 @@ namespace ncpp
// Some Cell APIs go here since they act on individual panels even though it may seem weird at points (e.g.
// release)
int load (Cell &cell, const char *gcluster) const noexcept
int load (Cell &cell, const char *gcluster) const NOEXCEPT_MAYBE
{
return cell_load (plane, cell, gcluster);
return error_guard<int> (cell_load (plane, cell, gcluster), -1);
}
bool load (Cell &cell, char ch) const noexcept
bool load (Cell &cell, char ch) const NOEXCEPT_MAYBE
{
return cell_load_simple (plane, cell, ch) != -1;
return error_guard (cell_load_simple (plane, cell, ch), -1);
}
int prime (Cell &cell, const char *gcluster, uint32_t attr, uint64_t channels) const noexcept
int prime (Cell &cell, const char *gcluster, uint32_t attr, uint64_t channels) const NOEXCEPT_MAYBE
{
return cell_prime (plane, cell, gcluster, attr, channels);
return error_guard<int> (cell_prime (plane, cell, gcluster, attr, channels), -1);
}
void release (Cell &cell) const noexcept
@ -859,14 +873,14 @@ namespace ncpp
cell_release (plane, cell);
}
int duplicate (Cell &target, Cell &source) const noexcept
int duplicate (Cell &target, Cell &source) const NOEXCEPT_MAYBE
{
return cell_duplicate (plane, target, source);
return error_guard<int> (cell_duplicate (plane, target, source), -1);
}
int duplicate (Cell &target, Cell const& source) const noexcept
int duplicate (Cell &target, Cell const& source) const NOEXCEPT_MAYBE
{
return cell_duplicate (plane, target, source);
return error_guard<int> (cell_duplicate (plane, target, source), -1);
}
int duplicate (Cell &target, Cell *source) const
@ -921,12 +935,12 @@ namespace ncpp
return duplicate (*target, source);
}
void translate (const Plane *dst, int *y = nullptr, int *x = nullptr) const
void translate (const Plane *dst, int *y = nullptr, int *x = nullptr) const noexcept
{
ncplane_translate(*this, dst ? dst->plane: nullptr, y, x);
ncplane_translate (*this, dst ? dst->plane: nullptr, y, x);
}
void translate (const Plane &dst, int *y = nullptr, int *x = nullptr) noexcept
void translate (const Plane &dst, int *y = nullptr, int *x = nullptr) const noexcept
{
translate (*this, dst, y, x);
}
@ -936,7 +950,7 @@ namespace ncpp
if (src == nullptr)
throw invalid_argument ("'src' must be a valid pointer");
ncplane_translate(*src, dst ? dst->plane : nullptr, y, x);
ncplane_translate (*src, dst ? dst->plane : nullptr, y, x);
}
static void translate (const Plane &src, const Plane &dst, int *y = nullptr, int *x = nullptr) noexcept
@ -944,19 +958,19 @@ namespace ncpp
ncplane_translate (src.plane, dst.plane, y, x);
}
bool translate_abs (int *y = nullptr, int *x = nullptr) noexcept
bool translate_abs (int *y = nullptr, int *x = nullptr) const noexcept
{
return ncplane_translate_abs (*this, y, x);
return error_guard<bool, bool> (ncplane_translate_abs (plane, y, x), false);
}
bool rotate_cw () const noexcept
bool rotate_cw () const NOEXCEPT_MAYBE
{
return ncplane_rotate_cw (plane) != -1;
return error_guard (ncplane_rotate_cw (plane), -1);
}
bool rotate_ccw () const noexcept
{
return ncplane_rotate_ccw (plane) != -1;
return error_guard (ncplane_rotate_ccw (plane), -1);
}
// Upstream call doesn't take ncplane* but we put it here for parity with has_no_background below
@ -978,14 +992,16 @@ namespace ncpp
static Plane* map_plane (ncplane *ncp, Plane *associated_plane = nullptr) noexcept;
#ifdef USE_FFMPEG
bool blit_bgrx (int placey, int placex, int linesize, const void* data, int begy, int begx, int leny, int lenx) const noexcept
bool blit_bgrx (int placey, int placex, int linesize, const void* data, int begy, int begx, int leny, int lenx) const NOEXCEPT_MAYBE
{
return ncblit_bgrx (plane, placey, placex, linesize, data, begy, begx, leny, lenx) >= 0;
bool ret = ncblit_bgrx (plane, placey, placex, linesize, data, begy, begx, leny, lenx) < 0;
return error_guard_cond<bool, bool> (ret, ret);
}
bool blit_rgba (int placey, int placex, int linesize, const void* data, int begy, int begx, int leny, int lenx) const noexcept
bool blit_rgba (int placey, int placex, int linesize, const void* data, int begy, int begx, int leny, int lenx) const NOEXCEPT_MAYBE
{
return ncblit_rgba (plane, placey, placex, linesize, data, begy, begx, leny, lenx) >= 0;
bool ret = ncblit_rgba (plane, placey, placex, linesize, data, begy, begx, leny, lenx) < 0;
return error_guard_cond<bool, bool> (ret, ret);
}
#endif

@ -48,14 +48,14 @@ namespace ncpp
ncplot_destroy (plot);
}
bool add_sample(uint64_t x, uint64_t y)
bool add_sample(uint64_t x, uint64_t y) const NOEXCEPT_MAYBE
{
return ncplot_add_sample (plot, x, y) >= 0;
return error_guard (ncplot_add_sample (plot, x, y), -1);
}
bool set_sample(uint64_t x, uint64_t y)
bool set_sample(uint64_t x, uint64_t y) const NOEXCEPT_MAYBE
{
return ncplot_set_sample (plot, x, y) >= 0;
return error_guard (ncplot_set_sample (plot, x, y), -1);
}
Plane* get_plane () const noexcept;

@ -72,39 +72,39 @@ namespace ncpp
return ncreel_tabletcount (reel);
}
bool touch (NcTablet *t) const noexcept
bool touch (NcTablet *t) const NOEXCEPT_MAYBE
{
return ncreel_touch (reel, get_tablet (t)) != -1;
return error_guard (ncreel_touch (reel, get_tablet (t)), -1);
}
bool touch (NcTablet &t) const noexcept
bool touch (NcTablet &t) const NOEXCEPT_MAYBE
{
return touch (&t);
}
bool del (NcTablet *t) const noexcept
bool del (NcTablet *t) const NOEXCEPT_MAYBE
{
return ncreel_del (reel, get_tablet (t)) != -1;
return error_guard (ncreel_del (reel, get_tablet (t)), -1);
}
bool del (NcTablet &t) const noexcept
bool del (NcTablet &t) const NOEXCEPT_MAYBE
{
return del (&t);
}
bool del_focused () const noexcept
bool del_focused () const NOEXCEPT_MAYBE
{
return ncreel_del_focused (reel) != -1;
return error_guard (ncreel_del_focused (reel), -1);
}
bool move (int x, int y) const noexcept
bool move (int x, int y) const NOEXCEPT_MAYBE
{
return ncreel_move (reel, x, y) != -1;
return error_guard (ncreel_move (reel, x, y), -1);
}
bool redraw () const noexcept
bool redraw () const NOEXCEPT_MAYBE
{
return ncreel_redraw (reel) != -1;
return error_guard (ncreel_redraw (reel), -1);
}
NcTablet* get_focused () const noexcept

@ -1,18 +1,82 @@
#ifndef __NCPP_ROOT_HH
#define __NCPP_ROOT_HH
#include <type_traits>
#include <string>
#include <notcurses/notcurses.h>
#include "_helpers.hh"
#include "_exceptions.hh"
namespace ncpp {
#if defined (NCPP_EXCEPTIONS_PLEASE)
#define NOEXCEPT_MAYBE
#else
#define NOEXCEPT_MAYBE noexcept
#endif
class NCPP_API_EXPORT Root
{
protected:
static constexpr char ncpp_invalid_state_message[] = "notcurses++ is in an invalid state (already stopped?)";
protected:
template<typename TRet = bool, typename TValue = int>
TRet error_guard (TValue ret, TValue error_value) const
{
static constexpr bool ret_is_bool = std::is_same_v<TRet, bool>;
if constexpr (!ret_is_bool) {
static_assert (std::is_same_v<TRet, TValue>, "Both TRet and TValue must be the same type unless TValue is 'bool'");
}
if (ret != error_value) {
if constexpr (ret_is_bool) {
return true;
} else {
return ret;
}
}
#if defined (NCPP_EXCEPTIONS_PLEASE)
throw call_error ("Call returned an error value");
#else
if constexpr (ret_is_bool) {
return false;
} else {
return ret;
}
#endif
}
template<typename TRet = bool, typename TValue = int>
TRet error_guard_cond ([[maybe_unused]] TValue ret, bool error_value) const
{
static constexpr bool ret_is_bool = std::is_same_v<TRet, bool>;
if constexpr (!ret_is_bool) {
static_assert (std::is_same_v<TRet, TValue>, "Both TRet and TValue must be the same type unless TValue is 'bool'");
}
if (!error_value) {
if constexpr (ret_is_bool) {
return true;
} else {
return ret;
}
}
#if defined (NCPP_EXCEPTIONS_PLEASE)
throw call_error ("Call returned an error value");
#else
if constexpr (ret_is_bool) {
return false;
} else {
return ret;
}
#endif
}
notcurses* get_notcurses () const;
// All the objects which need to destroy notcurses entities (planes, panelreel etc etc) **have to** call this

@ -48,14 +48,14 @@ namespace ncpp
ncselector_destroy (selector, nullptr);
}
bool additem (const selector_item *item) const noexcept
int additem (const selector_item *item) const NOEXCEPT_MAYBE
{
return ncselector_additem (selector, item) >= 0;
return error_guard<int> (ncselector_additem (selector, item), -1);
}
bool delitem (const char *item) const noexcept
int delitem (const char *item) const NOEXCEPT_MAYBE
{
return ncselector_delitem (selector, item) >= 0;
return error_guard<int> (ncselector_delitem (selector, item), -1);
}
const char* previtem () const noexcept

@ -67,20 +67,20 @@ namespace ncpp
return ncvisual_decode (visual, averr);
}
bool render (int begy, int begx, int leny, int lenx) const noexcept
bool render (int begy, int begx, int leny, int lenx) const NOEXCEPT_MAYBE
{
return ncvisual_render (visual, begy, begx, leny, lenx) != -1;
return error_guard (ncvisual_render (visual, begy, begx, leny, lenx), -1);
}
int stream (int *averr, float timescale, streamcb streamer, void *curry = nullptr) const noexcept
int stream (int *averr, float timescale, streamcb streamer, void *curry = nullptr) const NOEXCEPT_MAYBE
{
return ncvisual_stream (get_notcurses (), visual, averr, timescale, streamer, curry);
return error_guard<int> (ncvisual_stream (get_notcurses (), visual, averr, timescale, streamer, curry), -1);
}
char* subtitle () const noexcept
{
return ncvisual_subtitle (visual);
}
char* subtitle () const noexcept
{
return ncvisual_subtitle (visual);
}
Plane* get_plane () const noexcept;

@ -42,5 +42,17 @@ namespace ncpp
: std::invalid_argument (what_arg)
{}
};
class NCPP_API_EXPORT call_error : public std::logic_error
{
public:
explicit call_error (const std::string& what_arg)
: logic_error (what_arg)
{}
explicit call_error (const char* what_arg)
: logic_error (what_arg)
{}
};
}
#endif

@ -1231,7 +1231,7 @@ ncplane_putstr_yx(struct ncplane* n, int y, int x, const char* gclusters){
int wcs;
int cols = ncplane_putegc_yx(n, y, x, gclusters, &wcs);
if(cols < 0){
return -ret; // return -ret in case of error
return ret == 0 ? -1 : -ret; // return -ret in case of error
}
if(wcs == 0){
break;

@ -0,0 +1,60 @@
#define NCPP_EXCEPTIONS_PLEASE
//
// This is a **build** test - it does nothing else except ensure that all the C++ wrapper classes are included and that
// the program builds.
//
// Once there are demos which exercise all the C++ classes this "test" can be removed
//
#include <cstdlib>
#include <clocale>
#include <iostream>
#include <ncpp/NotCurses.hh>
#include <ncpp/Menu.hh>
#include <ncpp/Plane.hh>
#include <ncpp/Reel.hh>
#include <ncpp/MultiSelector.hh>
#include <ncpp/Selector.hh>
#include <ncpp/Visual.hh>
#include <ncpp/Direct.hh>
#include <ncpp/Plot.hh>
using namespace ncpp;
int run ()
{
NotCurses nc;
const char *ncver = nc.version ();
Plane plane (1, 1, 0, 0);
nc.stop ();
Direct direct (getenv ("TERM"));
direct.set_fg (0xb5, 0x0d, 0xff);
std::cout << "notcurses version: ";
direct.set_bg (0x05, 0x6e, 0xee);
direct.set_fg (0xe2, 0xbf, 0x00);
std::cout << ncver << std::endl;
return 0;
}
int main ()
{
if (!setlocale (LC_ALL, "")){
std::cerr << "Couldn't set locale based on user preferences" << std::endl;
return EXIT_FAILURE;
}
try {
return run ();
} catch (ncpp::init_error &e) {
std::cerr << "Initialization error: " << e.what () << std::endl;
} catch (ncpp::invalid_state_error &e) {
std::cerr << "Invalid state error: " << e.what () << std::endl;
} catch (ncpp::invalid_argument &e) {
std::cerr << "Invalid argument error: " << e.what () << std::endl;
}
return 1;
}
Loading…
Cancel
Save