XS::Framework::Manual::recipe05 - XS::Framework basics
XS::libpanda offers lightweight intrusive smart pointer iptr. Please, referer intrusive pointer from Boost library for introduction. The easiest way to add refcounted property to C++ class is to inherit from panda::Refcnt (1):
iptr
panda::Refcnt (1)
struct TimezoneRecipe05: public panda::Refcnt { // (1) const char* get_name() const { return name.c_str(); } TimezoneRecipe05(const char* name_): name{name_} { } ~TimezoneRecipe05() { std::cerr << "~TimezoneRecipe05()\n"; } private: std::string name; }; using TimezoneRecipe05SP = panda::iptr<TimezoneRecipe05>;
Let's define typemap for timezone:
namespace xs { template <> struct Typemap<TimezoneRecipe05*> : TypemapObject<TimezoneRecipe05*, TimezoneRecipe05*, ObjectTypeRefcntPtr, ObjectStorageMG, StaticCast> { /// (2) (e) static std::string package () { return "MyTest::Cookbook::TimezoneRecipe05"; } }; }
The typemap specialization (2) should be for timezone pointer (TimezoneRecipe05*), as XS::Framework ships with auto-deduced typemaps for iptr<T>. The ObjectTypeRefcntPtr lifetime policy should be specified.
TimezoneRecipe05*
ObjectTypeRefcntPtr
There is no constraint for C++ class to let it inherit panda::Refcnt: all is needed is that the class with refcounter semantics should define global functions refcnt_inc, refcnt_dec and refcnt_get.
panda::Refcnt
refcnt_inc
refcnt_dec
refcnt_get
The xs-adapter is trivial; it should be defined for timezone pointer:
MODULE = MyTest PACKAGE = MyTest::Cookbook::TimezoneRecipe05 PROTOTYPES: DISABLE const char* TimezoneRecipe05::get_name() { RETVAL = THIS->get_name(); } TimezoneRecipe05SP create(const char* name) { RETVAL = TimezoneRecipe05SP(new TimezoneRecipe05(name)); }
For the sake of completeness there is another mapped C++ class, which uses TimezoneRecipe05SP. There is nothing new for a reader familiar with the previous recipes.
TimezoneRecipe05SP
// C++ class struct DateRecipe05 { DateRecipe05() { update() ; } void update() { epoch = std::time(nullptr); } int get_epoch() const { return epoch; } void set_timezone(TimezoneRecipe05SP tz_) { tz = tz_; } TimezoneRecipe05SP get_timezone() { return tz; } private: std::time_t epoch; TimezoneRecipe05SP tz; }; // typemap namespace xs { template <> struct Typemap<DateRecipe05*> : TypemapObject<DateRecipe05*, DateRecipe05*, ObjectTypePtr, ObjectStorageMG, StaticCast> { static std::string package () { return "MyTest::Cookbook::DateRecipe05"; } }; } // xs-adapter MODULE = MyTest PACKAGE = MyTest::Cookbook::DateRecipe05 PROTOTYPES: DISABLE DateRecipe05* DateRecipe05::new() { RETVAL = new DateRecipe05(); } void DateRecipe05::update() std::time_t DateRecipe05::get_epoch() TimezoneRecipe05SP DateRecipe05::get_timezone() void DateRecipe05::set_timezone(TimezoneRecipe05SP tz)
The SV* wrapper identity is not preserved when it is set to Date and returned back, i.e. the same as in previous recipe.
To install XS::Framework, copy and paste the appropriate command in to your terminal.
cpanm
cpanm XS::Framework
CPAN shell
perl -MCPAN -e shell install XS::Framework
For more information on module installation, please visit the detailed CPAN module installation guide.