/*____________________________________________________________________________
by Martin Robinson
collection of function and macro
______________________________________________________________________________
todo:

preprocessor________________________________________________________________*/

#pragma once
#ifndef _STACK
#define _STACK


/*STACK_______________________________________________________________________
using a simple array and a stack pointer
it become easy to have a stack.
usage: 
array[push(sp)] = ....
... = array[pop(sp)]
very efficient______________________________________________________________*/

#ifdef SS
    //having only one stack, define size as SS
    #define sp() (0)
    #define push(SP) (SP<SS?SP++:SP)
    #define pop(SP) (SP>0?--SP:SP)
    #define stof(SP) (SP>=SS)

    #define rsp() (SS-1)
    #define rpush(RSP) (RSP>0?RSP--:RSP)
    #define rpop(RSP) (RSP<SS?++RSP:RSP)
    #define rstof(RSP) (RSP<=0)
#else
    //many stack...then do with it
    #define sp(SP) (0)
    #define push(SP) (SP++)
    #define pop(SP) (--SP)
    #define stof(SP,SIZE) (SP>=SIZE)

    #define rsp(SIZE) (SIZE-1)
    #define rpush(RSP) (RSP--)
    #define rpop(RSP) (++RSP)
    #define rstof(RSP) (RSP<=0)
#endif


/*DUAL STACK SWAP_____________________________________________________________
two stack : one pushing, the other poping
when poping one is empty, then we swap both
simple.
with some thinking, you only need one stack with two pointer 
and a directional pivot
---------this part should not be macro but functional------------
____________________________________________________________________________*/
#ifndef DSSS
    #define DSSS 80
#else
    struct dualStackSwap{
        int stack[DSSS],
            left,
            right,
            pivot;
    };

    #define initDSS(DSS) (do{DSS.left=sp(); DSS.right=rsp(DSSS); DSS.pivot=0;}while(0))
    #define popDSS(DSS) (DSS.pivot?DSS.stack[rpop(DSS.right)]:DSS.stack[pop(DSS.left)])
    #define pushDSS(DSS, DATA) (DSS.pivot?DSS.stack[push(DSS.left)]=DATA:DSS.stack[rpush(DSS.right)]=DATA)
    #define endDSS(DSS) (DSS.pivot?DSS.right<0:DSS.left>=DSSS)
    #define corruptDSS(DSS) (DSS.left>=DSS.right)
    #define reverseDSS(DSS) (~DSS.pivot)
#endif


#endif
