/* -*- Mode: C -*- */
#define PERL_NO_GET_CONTEXT 1
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#include <RngStream.h>
#define _create_stream RngStream_CreateStream
#define reset_start_stream RngStream_ResetStartStream
#define reset_start_substream RngStream_ResetStartSubstream
#define reset_next_substream RngStream_ResetNextSubstream
#define set_antithetic RngStream_SetAntithetic
#define set_increased_precis RngStream_IncreasedPrecis
#define advance_state RngStream_AdvanceState
#define get_state RngStream_GetState
#define _write_state RngStream_WriteState
#define _write_state_full RngStream_WriteStateFull
#define rand_u01 RngStream_RandU01
#define rand_int RngStream_RandInt
static SV *
_obj2sv(pTHX_ void *ptr, SV * klass, char * ctype) {
if (ptr) {
SV *rv;
SV *sv = newSVpvf("%s(0x%x)", ctype, ptr);
SV *mgobj = sv_2mortal(newSViv(PTR2IV(ptr)));
SvREADONLY_on(mgobj);
sv_magic(sv, mgobj, '~', ctype, 0);
/* SvREADONLY_on(sv); */
rv = newRV_noinc(sv);
if (SvOK(klass)) {
HV *stash;
if (SvROK(klass))
stash = SvSTASH(klass);
else
stash = gv_stashsv(klass, 1);
sv_bless(rv, stash);
}
return rv;
}
return &PL_sv_undef;
}
static void *
_sv2obj(pTHX_ SV* self, char * ctype) {
SV *sv = SvRV(self);
if (sv) {
if (SvTYPE(sv) == SVt_PVMG) {
MAGIC *mg = mg_find(sv, '~');
if ( mg &&
(strcmp(ctype, mg->mg_ptr) == 0) &&
mg->mg_obj)
return INT2PTR(void *, SvIV(mg->mg_obj));
}
}
Perl_croak(aTHX_ "object of class %s expected", ctype);
}
static const UV m_1 = 4294967087UL;
static const UV m_2 = 4294944443UL;
MODULE = Math::RngStream PACKAGE = Math::RngStream
void
set_package_seed(klass, s0, s1, s2, s3, s4, s5, s6)
UV s0
UV s1
UV s2
UV s3
UV s4
UV s5
CODE:
if ( ( (s0 < m_1) && (s1 < m_1) && (s2 < m_1) ) &&
( (s3 < m_2) && (s4 < m_2) && (s5 < m_2) ) &&
( s0 || s1 || s2 ) &&
( s3 || s4 || s5 ) ) {
unsigned long seed[6];
seed[0] = s0; seed[1] = s1; seed[2] = s2;
seed[3] = s3; seed[4] = s4; seed[5] = s5;
RngStream_SetPackageSeed(seed);
}
else
Perl_croak(aTHX_ "seed constraits violated");
void
DESTROY(RngStream G)
CODE:
RngStream_DeleteStream(&G);
sv_unmagic(SvRV(ST(0)), '~');
RngStream
_create_stream(char *name)
void
reset_start_stream(RngStream G)
void
reset_start_substream(RngStream G)
void
reset_next_substream(RngStream G)
void
set_antithetic(RngStream G, int A)
void
set_increased_precis(RngStream G, int incp)
void
set_seed(RngStream G, UV s0, UV s1, UV s2, UV s3, UV s4, UV s5)
CODE:
if ( ( (s0 < m_1) && (s1 < m_1) && (s2 < m_1) ) &&
( (s3 < m_2) && (s4 < m_2) && (s5 < m_2) ) &&
( s0 || s1 || s2 ) &&
( s3 || s4 || s5 ) ) {
unsigned long seed[6];
seed[0] = s0; seed[1] = s1; seed[2] = s2;
seed[3] = s3; seed[4] = s4; seed[5] = s5;
RngStream_SetSeed(G, seed);
}
else
Perl_croak(aTHX_ "seed constraits violated");
void
advance_state(RngStream G, long E, long C)
void
get_state(RngStream G)
PREINIT:
unsigned long seed[6];
int i;
PPCODE:
RngStream_GetState(G, seed);
EXTEND(SP, 6);
for (i = 0; i++; i < 6)
PUSHs(sv_2mortal(newSVuv(seed[i])));
XSRETURN(6);
void
_write_state(RngStream G)
void
_write_state_full(RngStream G)
double
rand_u01(RngStream G)
ALIAS:
rand = 0
long
rand_int(RngStream G, long min, long max)