diff options
author | Yves Orton <demerphq@gmail.com> | 2022-04-20 12:24:25 +0200 |
---|---|---|
committer | Karl Williamson <khw@cpan.org> | 2022-05-27 21:18:10 -0600 |
commit | fff0089cdee6ca5d1c000e213f15bb3ea460a21f (patch) | |
tree | c47533083cf97aa9868483317367ec204972c060 /sv.h | |
parent | fd1cd0c604ac258cf945c706768b80f03544f0fe (diff) | |
download | perl-fff0089cdee6ca5d1c000e213f15bb3ea460a21f.tar.gz |
sv.c - add new bool related utility functions and macros
The new bool "type" does not have the usual complement of utility
functions and macros. It only has one encapsulating function, which is
perfectly reasonable for most use cases where one wants to test if an
SV* is a bool, but does a bit too much if one is working on a
serialization tool which is likely to want to unroll a nice chunk of the
logic.
The new type also lacks the usual cohort of utility functions to create
new bool SV's.
This patch adds the following functions:
newSVbool(const bool bool_val)
newSV_true()
newSV_false()
sv_set_true(SV *sv)
sv_set_false(SV *sv)
sv_set_bool(SV *sv, const bool bool_val)
And the following macros:
SvIandPOK(sv)
SvIandPOK_off(sv)
SvIandPOK_on(sv)
The following three are intended very specifically for writing
serialization code like for Sereal, where it is reasonable to want to
unroll the logic contained in Perl_sv_isbool() and SvTRUE(). They are
documented as "you dont want to use this except under special
circumstances".
SvBoolFlagsOK(sv)
BOOL_INTERNALS_sv_isbool(sv)
BOOL_INTERNALS_sv_isbool_true(sv)
BOOL_INTERNALS_sv_isbool_false(sv)
SvBoolFlagsOK() is documented as being the same as SvIandPOK(),
but this abstracts the intent from the implementation.
Diffstat (limited to 'sv.h')
-rw-r--r-- | sv.h | 63 |
1 files changed, 63 insertions, 0 deletions
@@ -746,6 +746,55 @@ Unsets the PV status of an SV. Tells an SV that it is a string and disables all other C<OK> bits. Will also turn off the UTF-8 status. +=for apidoc Am|U32|SvBoolFlagsOK|SV* sv +Returns a bool indicating whether the SV has the right flags set such +that it is safe to call C<BOOL_INTERNALS_sv_isbool()> or +C<BOOL_INTERNALS_sv_isbool_true()> or +C<BOOL_INTERNALS_sv_isbool_false()>. Currently equivalent to +C<SvIandPOK(sv)> or C<SvIOK(sv) && SvPOK(sv)>. Serialization may want to +unroll this check. If so you are strongly recommended to add code like +C<assert(SvBoolFlagsOK(sv));> B<before> calling using any of the +BOOL_INTERNALS macros. + +=for apidoc Am|U32|SvIandPOK|SV* sv +Returns a bool indicating whether the SV is both C<SvPOK()> and +C<SvIOK()> at the same time. Equivalent to C<SvIOK(sv) && SvPOK(sv)> but +more efficient. + +=for apidoc Am|void|SvIandPOK_on|SV* sv +Tells an SV that is a string and a number in one operation. Equivalent +to C<SvIOK_on(sv); SvPOK_on(sv);> but more efficient. + +=for apidoc Am|void|SvIandPOK_off|SV* sv +Unsets the PV and IV status of an SV in one operation. Equivalent to +C<SvIOK_off(sv); SvPK_off(v);> but more efficient. + +=for apidoc Am|bool|BOOL_INTERNALS_sv_isbool|SV* sv +Checks if a C<SvBoolFlagsOK()> sv is a bool. B<Note> that it is the +caller's responsibility to ensure that the sv is C<SvBoolFlagsOK()> before +calling this. This is only useful in specialized logic like +serialization code where performance is critical and the flags have +already been checked to be correct. Almost always you should be using +C<sv_isbool(sv)> instead. + +=for apidoc Am|bool|BOOL_INTERNALS_sv_isbool_true|SV* sv +Checks if a C<SvBoolFlagsOK()> sv is a true bool. B<Note> that it is +the caller's responsibility to ensure that the sv is C<SvBoolFlagsOK()> +before calling this. This is only useful in specialized logic like +serialization code where performance is critical and the flags have +already been checked to be correct. This is B<NOT> what you should use +to check if an SV is "true", for that you should be using +C<SvTRUE(sv)> instead. + +=for apidoc Am|bool|BOOL_INTERNALS_sv_isbool_false|SV* sv +Checks if a C<SvBoolFlagsOK()> sv is a false bool. B<Note> that it is +the caller's responsibility to ensure that the sv is C<SvBoolFlagsOK()> +before calling this. This is only useful in specialized logic like +serialization code where performance is critical and the flags have +already been checked to be correct. This is B<NOT> what you should use +to check if an SV is "false", for that you should be using +C<!SvTRUE(sv)> instead. + =for apidoc Am|bool|SvVOK|SV* sv Returns a boolean indicating whether the SV contains a v-string. @@ -914,6 +963,20 @@ Set the size of the string buffer for the SV. See C<L</SvLEN>>. #define SvIOK_notUV(sv) ((SvFLAGS(sv) & (SVf_IOK|SVf_IVisUV)) \ == SVf_IOK) +#define SvIandPOK(sv) ((SvFLAGS(sv) & (SVf_IOK|SVf_POK)) == (SVf_IOK|SVf_POK)) +#define SvIandPOK_on(sv) (assert_not_glob(sv) \ + (SvFLAGS(sv) |= (SVf_IOK|SVp_IOK|SVf_POK|SVp_POK))) +#define SvIandPOK_off(sv) (SvFLAGS(sv) &= ~(SVf_IOK|SVp_IOK|SVf_IVisUV|SVf_POK|SVp_POK)) + +#define SvBoolFlagsOK(sv) SvIandPOK(sv) + +#define BOOL_INTERNALS_sv_isbool(sv) (SvIsCOW_static(sv) && \ + (SvPVX_const(sv) == PL_Yes || SvPVX_const(sv) == PL_No)) +#define BOOL_INTERNALS_sv_isbool_true(sv) (SvIsCOW_static(sv) && \ + (SvPVX_const(sv) == PL_Yes)) +#define BOOL_INTERNALS_sv_isbool_false(sv) (SvIsCOW_static(sv) && \ + (SvPVX_const(sv) == PL_No)) + #define SvIsUV(sv) (SvFLAGS(sv) & SVf_IVisUV) #define SvIsUV_on(sv) (SvFLAGS(sv) |= SVf_IVisUV) #define SvIsUV_off(sv) (SvFLAGS(sv) &= ~SVf_IVisUV) |