=head1 NAME
XS::Framework::Manual::SVAPI::Sub - XS::Framework Sub C++ class reference
=head1 Sub
=head2 Overview
C<Sub> is C++ wrapper around callable Perl subroutine. It inherits all methods
from C<Sv> and disables a few ones, which have no sense for the class, e.g.
construction of C<Sub> object from array C<AV*> or coercion to C<AV*>.
As the C<Sv> it might hold the underlying Perl C<SV*> or may not.
=head2 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 C<Sub> object can be constructed either from Perl C<CV*> or from C<SV*>, which
is perl subroutine pointer. If the supplied C<SV*>/C<SV*> points to C<NULL> or
C<undef>, then the object will held NULL. Otherwise, on all other invalid C<SV*>
an exception will be thrown. The valid C<SV*> should be either C<CV*> or
reference to C<CV*> or C<undef>.
explicit Sub (panda::string_view subname, I32 flags = 0)
The Perl subroutine reference can be get via string literal, please refer
C<get_cvn_flags> in L<perlapi>. In other words, if the named Perl subroutine
C<subname> is found, than non-empty C<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)
=head2 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 C<Sv>, including NULL-safety. The previously held
C<SV*> will be C<dec>-remented.
void set (SV* val)
The C<set> method directly assigns the value to the underlying C<SV*>,
I<bypassing all checks>. Use the method with caution.
=head2 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.
=head2 stash()
Stash stash () const
Returns stash object, i.e. package / symbol table, where underlying subroutine
belongs to. This is NULL-unsafe method.
=head2 glob()
Glob glob () const;
Returns glob object. This is NULL-unsafe method.
=head2 name()
panda::string_view name () const;
Returns subroutine name. This is NULL-unsafe method.
=head2 bool named()
bool named () const
Returns C<true> if the underlying subroutine points to named subrouitene, and
C<false> for anonymous one. This is NULL-unsafe method.
=head2 SUPER ()
=head2 SUPER_strict ()
Sub SUPER () const
Sub SUPER_strict () const
This methods return C<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 C<SUPER()> method just returns empty C<Sub>,
while C<SUPER_strict()> throwns exception.
The method resolution is performed via C<DFS> algorithm (see L<mro>).
This are NULL-unsafe methods.
=head2 call()
=head2 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);
=head3 Supported argument types
=over
=item 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
=item 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
=item SV* arg0, std::initializer_list<Scalar> list
C<arg0> is prepended before C<list>. Useful for proxy-method that adds one arguments in the beginning
=item SV*const* list, size_t items
Useful when proxying calls from XS functions
void some_xs_func () {
...
sub.call(&ST(0), items);
}
=item SV* arg0, SV*const* list, size_t items
Same as previous, but adds C<arg0> before list. Useful when proxying calls from XS functions
void some_xs_func () {
...
sub.call(obj, &ST(0), items);
}
=item const Scalar* list, size_t items
=item SV* arg0, const Scalar* list, size_t items
same as previous ones
=back
=head3 Return type / call context
Return type of the call is specified as one or more template parameters for C<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":
=over
=item <void>, void, G_VOID
Anything that sub returns is discarded
=item <> or <Scalar>, Scalar, G_SCALAR
Any scalar expected
=item <Sv>, Sv, G_SCALAR
Any scalar expected
=item <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.
=item <Ref>, Ref, G_SCALAR
Any reference expected
=item <Array>, Array, G_SCALAR
Array ref expected
=item <Hash>, Hash, G_SCALAR
Hash ref expected
=item <Stash>, Stash, G_SCALAR
Stash(class) ref expected
=item <Object>, Object, G_SCALAR
Object (blessed reference of any kind) expected
=item <Sub>, Sub, G_SCALAR
Subroutine reference expected
=item <Glob>, Glob, G_SCALAR
Glob or reference to glob expected
=item <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) { ... }
=item <std::array<T,N>>, std::array<T,N>, G_ARRAY
C<T> may be any type of svapi. Expected C<N> return values of type C<T>.
If sub returns more than C<N> values, extra values are discarded.
If sub returns less than C<N> values, then remaining are returned as C<undefs>.
auto arr = sub.call<std::array<Simple, 3>>(args);
for (auto elem : arr) cout << (int)elem << endl;
=item <T1, T2, ...> or <std::tuple<T1, T2, ...>, std::tuple<T1, T2, ...>, G_ARRAY
C<Tx> may be any type of svapi. Expected C<N = count of Tx> return values of various Tx(T1, T2, ...) types.
If sub returns more than C<N> values, extra values are discarded.
If sub returns less than C<N> values, then remaining are returned as C<undefs>.
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);
=item <panda::string>, panda::string, G_SCALAR
Primitive expected
auto str = sub.call<string>();
=item <any numeric type>, that type, G_SCALAR
Primitive expected
auto num = sub.call<long>();
=back
=head1 SEE ALSO
L<XS::Framework>
L<XS::Framework::Manual::SVAPI>
L<XS::Framework::Manual::SVAPI::Sv>
=cut