NAME
XS::Framework::Manual::SVAPI::Sub - XS::Framework Sub C++ class reference
Sub
Overview
Sub
is C++ wrapper around callable Perl subroutine. It inherits all methods from Sv
and disables a few ones, which have no sense for the class, e.g. construction of Sub
object from array AV*
or coercion to AV*
.
As the Sv
it might hold the underlying Perl SV*
or may not.
Construction
static Sub noinc (SV* val)
static Sub noinc (CV* val)
Sub (std::nullptr_t = nullptr) {}
Sub (SV* sv, bool policy = INCREMENT)
Sub (CV* sv, bool policy = INCREMENT)
The Sub
object can be constructed either from Perl CV*
or from SV*
, which is perl subroutine pointer. If the supplied SV*
/SV*
points to NULL
or undef
, then the object will held NULL. Otherwise, on all other invalid SV*
an exception will be thrown. The valid SV*
should be either CV*
or reference to CV*
or undef
.
explicit Sub (panda::string_view subname, I32 flags = 0)
The Perl subroutine reference can be get via string literal, please refer get_cvn_flags
in perlapi. In other words, if the named Perl subroutine subname
is found, than non-empty Sub
object will be created, e.g.
Sub sub("MyPackage::my_fun");
Copy and move-constructors are also available:
Sub (const Sub& oth)
Sub (Sub&& oth)
Sub (const Sv& oth)
Sub (Sv&& oth)
assignment operators
Sub& operator= (SV* val)
Sub& operator= (CV* val)
Sub& operator= (const Sub& oth)
Sub& operator= (Sub&& oth)
Sub& operator= (const Sv& oth)
Sub& operator= (Sv&& oth)
The assignment operators are complementaty to the constructors above. They inherit behaviour from Sv
, including NULL-safety. The previously held SV*
will be dec
-remented.
void set (SV* val)
The set
method directly assigns the value to the underlying SV*
, bypassing all checks. Use the method with caution.
getters
Theere are zero-cost NULL-safe getters:
CV* operator-> () const
template <typename T = SV> one_of_t<T,SV,CV>* get () const
This are NULL-safe methods.
stash()
Stash stash () const
Returns stash object, i.e. package / symbol table, where underlying subroutine belongs to. This is NULL-unsafe method.
glob()
Glob glob () const;
Returns glob object. This is NULL-unsafe method.
name()
panda::string_view name () const;
Returns subroutine name. This is NULL-unsafe method.
bool named()
bool named () const
Returns true
if the underlying subroutine points to named subrouitene, and false
for anonymous one. This is NULL-unsafe method.
SUPER ()
SUPER_strict ()
Sub SUPER () const
Sub SUPER_strict () const
This methods return Sub
object, which represends the same subroutine but for base class of the current one. They differ in behaviour, when the SUPER subroutine cannot be found. The SUPER()
method just returns empty Sub
, while SUPER_strict()
throwns exception.
The method resolution is performed via DFS
algorithm (see mro).
This are NULL-unsafe methods.
call()
operator()
template <class...Ctx, class...Args>
*depends* call (Args&&...args) const
template <class...Ctx, class...Args>
*depends* operator() (Args&&...args) const
This methods calls perl subroutine. Here are a few examples:
Sub sub = ...;
// invoked in scalar context
Scalar p1 = sub.call();
Scalar p2 = sub.call(Simple(123));
Simple arg1(1), arg2(2), arg3(3);
// scalar context, array ref expected
Array p3 = sub(arg1, arg2, arg3);
// invoked in void context
sub.call<void>(Simple(2), Scalar(Simple(3)), Sv(Simple(4)));
//invoked in list context
List list = sub.call<List>(arg1, arg2);
Supported argument types
- Variadic number of any type that is convertible to SV* (any svapi type, pure SV*, etc)
-
If any of arguments represents non-scalar value (pure array, pure hash, etc), an exception will be thrown
- std::initializer_list<Scalar>
-
Only explicitly specified, as template argument deduction can't decude initializer list constructor type
sub.call(std::initializer_list<Scalar>{ arg1, arg2 }); // well-formed std::initializer_list<Scalar> l{ arg1, arg2 }; sub.call(l); // well-formed sub.call({ arg1, arg2 }); // ill-formed
- SV* arg0, std::initializer_list<Scalar> list
-
arg0
is prepended beforelist
. Useful for proxy-method that adds one arguments in the beginning - SV*const* list, size_t items
-
Useful when proxying calls from XS functions
void some_xs_func () { ... sub.call(&ST(0), items); }
- SV* arg0, SV*const* list, size_t items
-
Same as previous, but adds
arg0
before list. Useful when proxying calls from XS functionsvoid some_xs_func () { ... sub.call(obj, &ST(0), items); }
- const Scalar* list, size_t items
- SV* arg0, const Scalar* list, size_t items
-
same as previous ones
Return type / call context
Return type of the call is specified as one or more template parameters for call()
function. Sub will be called in corresponding context.
sub.call<void>();
sub.call<Scalar>(); // same as sub.call()
sub.call<List>();
// ... etc
List of supported context template parameters in format "template params, sub.call() return type, perl sub call context":
- <void>, void, G_VOID
-
Anything that sub returns is discarded
- <> or <Scalar>, Scalar, G_SCALAR
-
Any scalar expected
- <Sv>, Sv, G_SCALAR
-
Any scalar expected
- <Simple>, Simple, G_SCALAR
-
Sub is expected to return perl primitive (number or string). If returned value is not a primitive, exception is thrown. The same applies for svapi types listed below.
- <Ref>, Ref, G_SCALAR
-
Any reference expected
- <Array>, Array, G_SCALAR
-
Array ref expected
- <Hash>, Hash, G_SCALAR
-
Hash ref expected
- <Stash>, Stash, G_SCALAR
-
Stash(class) ref expected
- <Object>, Object, G_SCALAR
-
Object (blessed reference of any kind) expected
- <Sub>, Sub, G_SCALAR
-
Subroutine reference expected
- <Glob>, Glob, G_SCALAR
-
Glob or reference to glob expected
- <List>, List, G_ARRAY
-
Any number of any types expected. List contains all the returned values.
auto list = sub.call<List>(); for (auto& val : list) { ... }
- <std::array<T,N>>, std::array<T,N>, G_ARRAY
-
T
may be any type of svapi. ExpectedN
return values of typeT
. If sub returns more thanN
values, extra values are discarded. If sub returns less thanN
values, then remaining are returned asundefs
.auto arr = sub.call<std::array<Simple, 3>>(args); for (auto elem : arr) cout << (int)elem << endl;
- <T1, T2, ...> or <std::tuple<T1, T2, ...>, std::tuple<T1, T2, ...>, G_ARRAY
-
Tx
may be any type of svapi. ExpectedN = count of Tx
return values of various Tx(T1, T2, ...) types. If sub returns more thanN
values, extra values are discarded. If sub returns less thanN
values, then remaining are returned asundefs
.auto ret = sub.call<Simple, Array, Hash>(args); auto simple = std::get<0>(ret); auto arr = std::get<1>(ret); auto hash = std::get<2>(ret);
- <panda::string>, panda::string, G_SCALAR
-
Primitive expected
auto str = sub.call<string>();
- <any numeric type>, that type, G_SCALAR
-
Primitive expected
auto num = sub.call<long>();