summaryrefslogtreecommitdiff
path: root/handy.h
diff options
context:
space:
mode:
authorPaul "LeoNerd" Evans <leonerd@leonerd.org.uk>2022-10-27 17:05:00 +0100
committerPaul Evans <leonerd@leonerd.org.uk>2022-10-29 20:24:38 +0100
commit888c387824d4a13e2be0a8869a6a6470497ea96c (patch)
tree88e79f8f742efe462f3120a3f9d592bd7f27516a /handy.h
parentafda80099cfa1f2222e944cec21919060821afa7 (diff)
downloadperl-888c387824d4a13e2be0a8869a6a6470497ea96c.tar.gz
Define some xV_FROM_REF() macros
These macros contain assert() calls to check that the `ref` SV really is a reference (SvROK) and that the SvTYPE it points to is that which is expected.
Diffstat (limited to 'handy.h')
-rw-r--r--handy.h28
1 files changed, 28 insertions, 0 deletions
diff --git a/handy.h b/handy.h
index 6dd1a71586..14cf868e68 100644
--- a/handy.h
+++ b/handy.h
@@ -108,6 +108,34 @@ blindly casts away const.
#define MUTABLE_IO(p) ((IO *)MUTABLE_PTR(p))
#define MUTABLE_SV(p) ((SV *)MUTABLE_PTR(p))
+/*
+=for apidoc_section $SV
+=for apidoc Am |AV *|AV_FROM_REF|SV * ref
+=for apidoc_item |CV *|CV_FROM_REF|SV * ref
+=for apidoc_item |HV *|HV_FROM_REF|SV * ref
+
+The C<I<*>V_FROM_REF> macros extract the C<SvRV()> from a given reference SV
+and return a suitably-cast to pointer to the referenced SV. When running
+under C<-DDEBUGGING>, assertions are also applied that check that I<ref> is
+definitely a reference SV that refers to an SV of the right type.
+
+=cut
+*/
+
+#if defined(DEBUGGING) && defined(PERL_USE_GCC_BRACE_GROUPS)
+# define xV_FROM_REF(XV, ref) \
+ ({ SV *_ref = ref; \
+ assert(SvROK(_ref)); \
+ assert(SvTYPE(SvRV(_ref)) == SVt_PV ## XV); \
+ (XV *)(SvRV(_ref)); })
+#else
+# define xV_FROM_REF(XV, ref) ((XV *)(SvRV(ref)))
+#endif
+
+#define AV_FROM_REF(ref) xV_FROM_REF(AV, ref)
+#define CV_FROM_REF(ref) xV_FROM_REF(CV, ref)
+#define HV_FROM_REF(ref) xV_FROM_REF(HV, ref)
+
#ifndef __cplusplus
# include <stdbool.h>
#endif