Algorithm-CP-IZ

 view release on metacpan or  search on metacpan

IZ.xs  view on Meta::CPAN

  ENTER;
  SAVETMPS;
  PUSHMARK(sp);

  XPUSHs(sv_2mortal(newSViv(val)));
  XPUSHs(sv_2mortal(newSViv(index)));

  PUTBACK;
  count = call_sv((SV*)ext, G_SCALAR);
  SPAGAIN;
  ret = -1;

  if (count == 0) {
    croak("eventKnownPerlWrapper: error");
  }
  ret = sv_true(POPs);

  FREETMPS;
  LEAVE;

  return (IZBOOL)ret;
}

static IZBOOL eventNewMinMaxNeqPerlWrapper(CSint* vint, int index, int oldValue, CSint **tint, int size, void *ext)
{
  int count, ret;
  dTHX;
  dSP;

  ENTER;
  SAVETMPS;
  PUSHMARK(sp);

  XPUSHs(sv_2mortal(newSViv(index)));
  XPUSHs(sv_2mortal(newSViv(oldValue)));

  PUTBACK;
  count = call_sv((SV*)ext, G_SCALAR);
  SPAGAIN;
  ret = -1;

  if (count == 0) {
    croak("eventNewMinMaxNeqPerlWrapper: error");
  }
  ret = sv_true(POPs);

  FREETMPS;
  LEAVE;

  return (IZBOOL)ret;
}



#if (IZ_VERSION_MAJOR == 3 && IZ_VERSION_MINOR >= 6)

/* Helper functions for Algorithm::CP::IZ::ValueSelector::Simple */

/*
 * Callback functions don't take class parameter therefore useer defined
 * value selectors distincted by its index (when search function is called).
 */

typedef struct {
  SV* init;
  SV* next;
  SV* end;
} vsSimple;

static vsSimple* vsSimpleArray = NULL;
static size_t vsSimpleArraySize = 0;

static int vsSimpleObjRef = 0;
static CSvalueSelector* vsSimpleObj = NULL;

static IZBOOL prepareSimpleVS(int index) {
  if (!vsSimpleArray) {
    size_t size = (size_t)index * 2;
    size_t i;

    if (size < 1000)
      size = 1000;

    Newx(vsSimpleArray, size, vsSimple);
    if (!vsSimpleArray)
      return FALSE;

    vsSimpleArraySize = size;

    for (i = 0; i < size; i++) {
      vsSimpleArray[i].init = NULL;
      vsSimpleArray[i].next = NULL;
      vsSimpleArray[i].end = NULL;
    }
  }
  else if (index >= vsSimpleArraySize) {
    size_t newSize = index + 1000;
    size_t i;

    vsSimple* newArray;
    Newx(newArray, newSize, vsSimple);
    if (!newArray)
      return FALSE;

    memcpy(newArray, vsSimpleArray, sizeof(vsSimple) * vsSimpleArraySize);

    for (i = vsSimpleArraySize; i < newSize; i++) {
      newArray[i].init = NULL;
      newArray[i].next = NULL;
      newArray[i].end = NULL;
    }

    Safefree(vsSimpleArray);
    vsSimpleArray = newArray;
    vsSimpleArraySize = newSize;
  }

  return TRUE;
}

static IZBOOL vsSimpleInit(int index, CSint** vars, int size, void* pData) {

IZ.xs  view on Meta::CPAN

{
  SV* ngsObj = (SV*)ext;

  {
    dTHX;
    SvREFCNT_dec(ngsObj);
  }
}

static void searchNotify_searchStart(int maxFails, CSint** allvars, int nbVars, void* ext) {
  dTHX;
  dSP;

  ENTER;
  SAVETMPS;
  PUSHMARK(SP);

  XPUSHs(sv_2mortal((SV*)newRV(ext)));
  XPUSHs(sv_2mortal((SV*)newSViv(maxFails)));

  PUTBACK;
  call_method("search_start", G_DISCARD);

  FREETMPS;
  LEAVE;
}

static void searchNotify_searchEnd(IZBOOL result, int nbFails, int maxFails, CSint** allvars, int nbVars, void* ext) {
  dTHX;
  dSP;

  ENTER;
  SAVETMPS;
  PUSHMARK(SP);
  XPUSHs(sv_2mortal((SV*)newRV(ext)));
  XPUSHs(sv_2mortal((SV*)newSViv(result)));
  XPUSHs(sv_2mortal((SV*)newSViv(nbFails)));
  XPUSHs(sv_2mortal((SV*)newSViv(maxFails)));

  PUTBACK;
  call_method("search_end", G_DISCARD);

  FREETMPS;
  LEAVE;
}

static void searchNotify_BeforeValueSelection(int depth, int index, const CSvalueSelection* vs, CSint** allvars, int nbVars, void* ext) {
  dTHX;
  dSP;

  ENTER;
  SAVETMPS;
  PUSHMARK(SP);
  XPUSHs(sv_2mortal((SV*)newRV(ext)));
  XPUSHs(sv_2mortal((SV*)newSViv(depth)));
  XPUSHs(sv_2mortal((SV*)newSViv(index)));
  XPUSHs(sv_2mortal((SV*)newSViv(vs->method)));
  XPUSHs(sv_2mortal((SV*)newSViv(vs->value)));

  PUTBACK;
  call_method("before_value_selection", G_DISCARD);

  FREETMPS;
  LEAVE;
}

static void searchNotify_AfterValueSelection(IZBOOL result, int depth, int index, const CSvalueSelection* vs, CSint** allvars, int nbVars, void* ext) {
  dTHX;
  dSP;

  ENTER;
  SAVETMPS;
  PUSHMARK(SP);
  XPUSHs(sv_2mortal((SV*)newRV(ext)));
  XPUSHs(sv_2mortal((SV*)newSViv(result)));
  XPUSHs(sv_2mortal((SV*)newSViv(depth)));
  XPUSHs(sv_2mortal((SV*)newSViv(index)));
  XPUSHs(sv_2mortal((SV*)newSViv(vs->method)));
  XPUSHs(sv_2mortal((SV*)newSViv(vs->value)));

  PUTBACK;
  call_method("after_value_selection", G_DISCARD);

  FREETMPS;
  LEAVE;
}

static void searchNotify_Enter(int depth, int index, CSint** allvars, int nbVars, void* ext) {
  dTHX;
  dSP;

  ENTER;
  SAVETMPS;
  PUSHMARK(SP);
  XPUSHs(sv_2mortal((SV*)newRV(ext)));
  XPUSHs(sv_2mortal((SV*)newSViv(depth)));
  XPUSHs(sv_2mortal((SV*)newSViv(index)));

  PUTBACK;
  call_method("enter", G_DISCARD);

  FREETMPS;
  LEAVE;
}

static void searchNotify_Leave(int depth, int index, CSint** allvars, int nbVars, void* ext) {
  dTHX;
  dSP;

  ENTER;
  SAVETMPS;
  PUSHMARK(SP);
  XPUSHs(sv_2mortal((SV*)newRV(ext)));
  XPUSHs(sv_2mortal((SV*)newSViv(depth)));
  XPUSHs(sv_2mortal((SV*)newSViv(index)));

  PUTBACK;
  call_method("leave", G_DISCARD);

  FREETMPS;
  LEAVE;
}

static IZBOOL searchNotify_Found(int depth, CSint** allvars, int nbVars, void* ext) {
  int count, ret;
  dTHX;
  dSP;

  ENTER;
  SAVETMPS;
  PUSHMARK(SP);
  XPUSHs(sv_2mortal((SV*)newRV(ext)));
  XPUSHs(sv_2mortal((SV*)newSViv(depth)));

  PUTBACK;
  count = call_method("found", G_SCALAR);
  SPAGAIN;

  ret = 0;
  if (count > 0) {
    ret = sv_true(POPs);
  }

IZ.xs  view on Meta::CPAN

    else if (cs_isIn(vint, val)) {
        cur = val;

	while (1) {
	    if (cur == maxValue) {
	        RETVAL = maxValue;
		break;
	    }

	    prev = cur;
	    cur++;
	    if (!cs_isIn(vint, cur)) {
	        RETVAL = prev;
		break;
	    }
	}
    }
    else {
        RETVAL = cs_getNextValue(vint, val);
    }
OUTPUT:
    RETVAL

#if (IZ_VERSION_MAJOR == 3 && IZ_VERSION_MINOR >= 6)

void
cancel_search(iz)
    void* iz
CODE:
    cs_cancelSearch();

void*
cs_getValueSelector(vs)
    int vs
CODE:
    RETVAL = (void*)cs_getValueSelector(vs);
OUTPUT:
    RETVAL

void*
valueSelector_init(vs, index, array, size)
    void* vs;
    int index
    void* array
    int size
PREINIT:
    void* ext;
CODE:
    if (sizeof(void*) > sizeof(int))
      Newx(ext, 1, void*);
    else
      Newx(ext, 1, int);
    if (ext) {
      cs_initValueSelector(vs, index, array, size, ext);
    }
    RETVAL = ext;
OUTPUT:
    RETVAL

void
cs_selectNextValue(vs, index, array, size, ext)
    void* vs
    int index
    void* array
    int size
    void* ext
PREINIT:
    CSvalueSelection r;
    int rc;
PPCODE:
    rc = cs_selectNextValue(&r, vs, index, array, size, ext);
    if (rc) {
      XPUSHs(sv_2mortal(newSViv(r.method)));
      XPUSHs(sv_2mortal(newSViv(r.value)));
    }
    
int
cs_endValueSelector(vs, index, array, size, ext)
    void* vs
    int index
    void* array
    int size
    void* ext
PREINIT:
    int rc;
CODE:
    rc = cs_endValueSelector(vs, index, array, size, ext);
    Safefree(ext);
    RETVAL = rc;
OUTPUT:
    RETVAL

void*
createSimpleValueSelector()
CODE:
    if (vsSimpleObjRef == 0) {
      vsSimpleObj = cs_createValueSelector(vsSimpleInit, vsSimpleNext, vsSimpleEnd);
    }
    vsSimpleObjRef++;
    RETVAL = vsSimpleObj;
OUTPUT:
    RETVAL

void
deleteSimpleValueSelector()
CODE:
    vsSimpleObjRef--;

    if (vsSimpleObjRef == 0) {
      cs_freeValueSelector(vsSimpleObj);
      vsSimpleObj = NULL;

      if (vsSimpleArray) {
	Safefree(vsSimpleArray);
	vsSimpleArray = NULL;
	vsSimpleArraySize = 0;
      }
    }

int
registerSimpleValueSelectorClass(index, init)
     int index;
     SV* init;
CODE:
    if (prepareSimpleVS(index)) {
      vsSimpleArray[index].init = init;
      RETVAL = TRUE;
    }
    else {
      RETVAL = FALSE;
    }

IZ.xs  view on Meta::CPAN

    SV* findvar_ref
    SV* max_fail_func
    int max_fail
    SV* ngs
    SV* nf_ref
PREINIT:
    CSint** array;
    const CSvalueSelector** vs_array;
    SSize_t alen;
    SSize_t i;
CODE:
    alen = av_len(av) + 1;
    Newx(array, alen, CSint*);
    Newx(vs_array, alen, const CSvalueSelector*);

    for (i = 0; i<alen; i++) {
      SV** pptr = av_fetch(av, i, 0);
      SV** vsptr = av_fetch(vs, i, 0);
      SV** vsvs = hv_fetch((HV*)SvRV((*vsptr)), "_vs", 3, 0);

      array[i] = INT2PTR(CSint*, SvIV(*pptr));
      vs_array[i] = INT2PTR(CSvalueSelector*, SvIV(*vsvs));
    }

    currentArray2IndexFunc = 0;
    findFreeVarPerlFunc = 0;

    if (findvar_id < 0) {
      findFreeVarPerlFunc = SvRV(findvar_ref);
      currentArray2IndexFunc = findFreeVarPerlWrapper;
    }
    else {
      if (findvar_id >= sizeof(findFreeVarTbl)/sizeof(findFreeVarTbl[0])) {
	Safefree(array);
	croak("search: Bad FindFreeVar value");
      }
      currentArray2IndexFunc = findFreeVarTbl[findvar_id];
    }

    if (max_fail < 0)
        max_fail = INT_MAX;

    maxFailPerlFunc = max_fail_func;

    RETVAL = cs_searchValueSelectorRestartNG(array,
					     vs_array,
					     (int)alen,
					     currentArray2IndexFunc,
					     maxFailFuncPerlWrapper,
					     NULL,
					     max_fail,
					     INT2PTR(CSnoGoodSet*, SvIV(ngs)),
					     (nf_ref ? INT2PTR(CSsearchNotify*, SvIV(nf_ref)) : NULL));
    Safefree(array);
    Safefree(vs_array);
OUTPUT:
    RETVAL


int
cs_selectValue(rv, method, value)
    SV *rv
    int method
    int value
PREINIT:
    CSvalueSelection vs;
CODE:
    vs.method = method;
    vs.value = value;
    RETVAL = cs_selectValue(INT2PTR(CSint*, SvIV(SvRV(rv))), &vs);
OUTPUT:
    RETVAL

void*
cs_createSearchNotify(obj)
    SV* obj
CODE:
    RETVAL = cs_createSearchNotify(SvRV(obj));
OUTPUT:
    RETVAL

void
searchNotify_set_search_start(notify)
    SV* notify
CODE:
    cs_searchNotifySetSearchStart(INT2PTR(void*, SvIV(notify)),
				  searchNotify_searchStart);

void
searchNotify_set_search_end(notify)
    SV* notify
CODE:
    cs_searchNotifySetSearchEnd(INT2PTR(void*, SvIV(notify)),
				searchNotify_searchEnd);

void
searchNotify_set_before_value_selection(notify)
    SV* notify
CODE:
    cs_searchNotifySetBeforeValueSelection(INT2PTR(void*, SvIV(notify)),
					   searchNotify_BeforeValueSelection);

void
searchNotify_set_after_value_selection(notify)
    SV* notify
CODE:
    cs_searchNotifySetAfterValueSelection(INT2PTR(void*, SvIV(notify)),
					  searchNotify_AfterValueSelection);

void
searchNotify_set_enter(notify)
    SV* notify
CODE:
    cs_searchNotifySetEnter(INT2PTR(void*, SvIV(notify)),
			    searchNotify_Enter);

void
searchNotify_set_leave(notify)
    SV* notify
CODE:
    cs_searchNotifySetLeave(INT2PTR(void*, SvIV(notify)),
			    searchNotify_Leave);

void
searchNotify_set_found(notify)
    SV* notify
CODE:
    cs_searchNotifySetFound(INT2PTR(void*, SvIV(notify)),
			    searchNotify_Found);

void
cs_freeSearchNotify(notify)
    void* notify
CODE:
    cs_freeSearchNotify(notify);
    
#endif /* (IZ_VERSION_MAJOR == 3 && IZ_VERSION_MINOR >= 6) */

MODULE = Algorithm::CP::IZ		PACKAGE = Algorithm::CP::IZ::Int

int
nb_elements(rv)
    SV* rv;
CODE:
    RETVAL = cs_getNbElements(INT2PTR(CSint*, SvIV(SvRV(rv))));
OUTPUT:
    RETVAL

int
nb_constraints(rv)
    SV* rv;
CODE:
    RETVAL = cs_getNbConstraints(INT2PTR(CSint*, SvIV(SvRV(rv))));
OUTPUT:
    RETVAL

int
min(rv)
    SV* rv;
CODE:
    RETVAL = cs_getMin(INT2PTR(CSint*, SvIV(SvRV(rv))));
OUTPUT:
    RETVAL



( run in 0.492 second using v1.01-cache-2.11-cpan-63c85eba8c4 )