Split the boolean class into an outer module

This commit is contained in:
gfx 2010-09-17 13:25:23 +09:00
parent 5e602fb575
commit d2962d8676
5 changed files with 87 additions and 25 deletions

View File

@ -6,22 +6,21 @@ use 5.008001;
our $VERSION = '0.23'; our $VERSION = '0.23';
our $PreferInteger = 0; our $PreferInteger = 0;
{ sub true () {
package require Data::MessagePack::Boolean;
Data::MessagePack::Boolean; no warnings 'once', 'redefine';
use overload my $t = $Data::MessagePack::Boolean::true;
'bool' => sub { ${ $_[0] } }, *true = sub (){ $t };
'0+' => sub { ${ $_[0] } }, return $t;
'""' => sub { ${ $_[0] } ? 'true' : 'false' },
fallback => 1,
;
} }
our $true = do { bless \(my $dummy = 1), "Data::MessagePack::Boolean" }; sub false () {
our $false = do { bless \(my $dummy = 0), "Data::MessagePack::Boolean" }; require Data::MessagePack::Boolean;
sub true () { $true } no warnings 'once', 'redefine';
sub false () { $false } my $f = $Data::MessagePack::Boolean::false;
*false = sub (){ $f };
return $f;
}
if ( !__PACKAGE__->can('pack') ) { # this idea comes from Text::Xslate if ( !__PACKAGE__->can('pack') ) { # this idea comes from Text::Xslate
my $backend = $ENV{ PERL_DATA_MESSAGEPACK } || ''; my $backend = $ENV{ PERL_DATA_MESSAGEPACK } || '';

View File

@ -0,0 +1,14 @@
package Data::MessagePack::Boolean;
use strict;
use overload
'bool' => sub { ${ $_[0] } },
'0+' => sub { ${ $_[0] } },
'""' => sub { ${ $_[0] } ? 'true' : 'false' },
fallback => 1,
;
our $true = do { bless \(my $dummy = 1) };
our $false = do { bless \(my $dummy = 0) };
1;

View File

@ -1,5 +1,9 @@
#include "xshelper.h" #include "xshelper.h"
#ifndef __cplusplus
#include <stdbool.h>
#endif
XS(xs_pack); XS(xs_pack);
XS(xs_unpack); XS(xs_unpack);
XS(xs_unpacker_new); XS(xs_unpacker_new);
@ -10,13 +14,15 @@ XS(xs_unpacker_data);
XS(xs_unpacker_reset); XS(xs_unpacker_reset);
XS(xs_unpacker_destroy); XS(xs_unpacker_destroy);
void boot_Data__MessagePack_pack(void); void init_Data__MessagePack_pack(pTHX_ bool const cloning);
void init_Data__MessagePack_unpack(pTHX_ bool const cloning);
XS(boot_Data__MessagePack) { XS(boot_Data__MessagePack) {
dXSARGS; dXSARGS;
PERL_UNUSED_VAR(items); PERL_UNUSED_VAR(items);
boot_Data__MessagePack_pack(); init_Data__MessagePack_pack(aTHX_ false);
init_Data__MessagePack_unpack(aTHX_ false);
newXS("Data::MessagePack::pack", xs_pack, __FILE__); newXS("Data::MessagePack::pack", xs_pack, __FILE__);
newXS("Data::MessagePack::unpack", xs_unpack, __FILE__); newXS("Data::MessagePack::unpack", xs_unpack, __FILE__);

View File

@ -83,8 +83,7 @@ MGVTBL pref_int_vtbl = {
#endif #endif
}; };
void boot_Data__MessagePack_pack(void) { void init_Data__MessagePack_pack(pTHX_ bool const cloning) {
dTHX;
SV* var = get_sv("Data::MessagePack::PreferInteger", 0); SV* var = get_sv("Data::MessagePack::PreferInteger", 0);
sv_magicext(var, NULL, PERL_MAGIC_ext, &pref_int_vtbl, NULL, 0); sv_magicext(var, NULL, PERL_MAGIC_ext, &pref_int_vtbl, NULL, 0);
SvSETMAGIC(var); SvSETMAGIC(var);

View File

@ -2,6 +2,13 @@
#define NEED_sv_2pv_flags #define NEED_sv_2pv_flags
#include "xshelper.h" #include "xshelper.h"
#define MY_CXT_KEY "Data::MessagePack::_unpack_guts" XS_VERSION
typedef struct {
SV* msgpack_true;
SV* msgpack_false;
} my_cxt_t;
START_MY_CXT
typedef struct { typedef struct {
bool finished; bool finished;
bool incremented; bool incremented;
@ -22,13 +29,52 @@ typedef struct {
#define msgpack_unpack_user unpack_user #define msgpack_unpack_user unpack_user
void init_Data__MessagePack_unpack(pTHX_ bool const cloning) {
if(!cloning) {
MY_CXT_INIT;
MY_CXT.msgpack_true = NULL;
MY_CXT.msgpack_false = NULL;
}
else {
MY_CXT_CLONE;
MY_CXT.msgpack_true = NULL;
MY_CXT.msgpack_false = NULL;
}
}
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
/* utility functions */ /* utility functions */
STATIC_INLINE SV * static SV*
get_bool (const char* const name) { load_bool(pTHX_ const char* const name) {
CV* const cv = get_cv(name, GV_ADD);
dSP;
PUSHMARK(SP);
call_sv((SV*)cv, G_SCALAR);
SPAGAIN;
SV* const sv = newSVsv(POPs);
PUTBACK;
return sv;
}
static SV*
get_bool(bool const value) {
dTHX; dTHX;
return newSVsv(get_sv( name, GV_ADD )); dMY_CXT;
if(value) {
if(!MY_CXT.msgpack_true) {
MY_CXT.msgpack_true = load_bool(aTHX_ "Data::MessagePack::true");
}
return newSVsv(MY_CXT.msgpack_true);
}
else {
if(!MY_CXT.msgpack_false) {
MY_CXT.msgpack_false = load_bool(aTHX_ "Data::MessagePack::false");
}
return newSVsv(MY_CXT.msgpack_false);
}
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -127,15 +173,13 @@ STATIC_INLINE int template_callback_nil(unpack_user* u PERL_UNUSED_DECL, SV** o)
STATIC_INLINE int template_callback_true(unpack_user* u PERL_UNUSED_DECL, SV** o) STATIC_INLINE int template_callback_true(unpack_user* u PERL_UNUSED_DECL, SV** o)
{ {
dTHX; *o = get_bool(true);
*o = get_bool("Data::MessagePack::true");
return 0; return 0;
} }
STATIC_INLINE int template_callback_false(unpack_user* u PERL_UNUSED_DECL, SV** o) STATIC_INLINE int template_callback_false(unpack_user* u PERL_UNUSED_DECL, SV** o)
{ {
dTHX; *o = get_bool(false);
*o = get_bool("Data::MessagePack::false");
return 0; return 0;
} }