=head1 NAME XS::Framework::Manual::SVAPI::Sub - XS::Framework Sub C++ class reference =head1 Sub =head2 Overview C is C++ wrapper around callable Perl subroutine. It inherits all methods from C and disables a few ones, which have no sense for the class, e.g. construction of C object from array C or coercion to C. As the C it might hold the underlying Perl C 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 object can be constructed either from Perl C or from C, which is perl subroutine pointer. If the supplied C/C points to C or C, then the object will held NULL. Otherwise, on all other invalid C an exception will be thrown. The valid C should be either C or reference to C or C. explicit Sub (panda::string_view subname, I32 flags = 0) The Perl subroutine reference can be get via string literal, please refer C in L. In other words, if the named Perl subroutine C is found, than non-empty C 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, including NULL-safety. The previously held C will be C-remented. void set (SV* val) The C method directly assigns the value to the underlying C, I. Use the method with caution. =head2 getters Theere are zero-cost NULL-safe getters: CV* operator-> () const template one_of_t* 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 if the underlying subroutine points to named subrouitene, and C for anonymous one. This is NULL-unsafe method. =head2 SUPER () =head2 SUPER_strict () Sub SUPER () const Sub SUPER_strict () const This methods return C 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 method just returns empty C, while C throwns exception. The method resolution is performed via C algorithm (see L). This are NULL-unsafe methods. =head2 call() =head2 operator() template *depends* call (Args&&...args) const template *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(Simple(2), Scalar(Simple(3)), Sv(Simple(4))); //invoked in list context List list = sub.call(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 Only explicitly specified, as template argument deduction can't decude initializer list constructor type sub.call(std::initializer_list{ arg1, arg2 }); // well-formed std::initializer_list l{ arg1, arg2 }; sub.call(l); // well-formed sub.call({ arg1, arg2 }); // ill-formed =item SV* arg0, std::initializer_list list C is prepended before C. 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 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 function. Sub will be called in corresponding context. sub.call(); sub.call(); // same as sub.call() sub.call(); // ... etc List of supported context template parameters in format "template params, sub.call() return type, perl sub call context": =over =item , void, G_VOID Anything that sub returns is discarded =item <> or , Scalar, G_SCALAR Any scalar expected =item , Sv, G_SCALAR Any scalar expected =item , 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, G_SCALAR Any reference expected =item , Array, G_SCALAR Array ref expected =item , Hash, G_SCALAR Hash ref expected =item , Stash, G_SCALAR Stash(class) ref expected =item , Object, G_SCALAR Object (blessed reference of any kind) expected =item , Sub, G_SCALAR Subroutine reference expected =item , Glob, G_SCALAR Glob or reference to glob expected =item , List, G_ARRAY Any number of any types expected. List contains all the returned values. auto list = sub.call(); for (auto& val : list) { ... } =item >, std::array, G_ARRAY C may be any type of svapi. Expected C return values of type C. If sub returns more than C values, extra values are discarded. If sub returns less than C values, then remaining are returned as C. auto arr = sub.call>(args); for (auto elem : arr) cout << (int)elem << endl; =item or , std::tuple, G_ARRAY C may be any type of svapi. Expected C return values of various Tx(T1, T2, ...) types. If sub returns more than C values, extra values are discarded. If sub returns less than C values, then remaining are returned as C. auto ret = sub.call(args); auto simple = std::get<0>(ret); auto arr = std::get<1>(ret); auto hash = std::get<2>(ret); =item , panda::string, G_SCALAR Primitive expected auto str = sub.call(); =item , that type, G_SCALAR Primitive expected auto num = sub.call(); =back =head1 SEE ALSO L L L =cut