# ifndef MEXARGS_H

# define MEXARGS_H

# if defined MATLAB_MEX_FILE

 # define str(in) #in
 # define STR(in) str(in)

 /* nargin checks */
 # define CHECK_NARGIN_EQ(NARG) if (nrhs != NARG) mexErrMsgIdAndTxt(STR(MEXNAME)":nargin",STR(MEXNAME)" expects exactly "#NARG" arguments but got %d instead",nrhs)
 # define CHECK_NARGIN_LE(NARG) if (nrhs  > NARG) mexErrMsgIdAndTxt(STR(MEXNAME)":nargin",STR(MEXNAME)" expects at most "#NARG" arguments but got %d instead",nrhs)
 # define CHECK_NARGIN_GE(NARG) if (nrhs  < NARG) mexErrMsgIdAndTxt(STR(MEXNAME)":nargin",STR(MEXNAME)" expects at least "#NARG" arguments but got %d instead",nrhs)

 /* Type checks */
 # define CHECK_TYPE(ARG,ARGNAME,TYPE,CHECK) if (!CHECK(ARG)) mexErrMsgIdAndTxt(STR(MEXNAME)":inputType",STR(MEXNAME)" expects "ARGNAME" to be a "#TYPE" array but got %s instead",mxGetClassName(ARG))
 # define CHECK_NUMERIC(ARG) CHECK_TYPE(ARG,#ARG,numeric,mxIsNumeric)
 # define CHECK_DOUBLE(ARG) CHECK_TYPE(ARG,#ARG,double,mxIsDouble)
 # define CHECK_INT8(ARG) CHECK_TYPE(ARG,#ARG,int8,mxIsInt8)
 # define CHECK_INT32(ARG) CHECK_TYPE(ARG,#ARG,int32,mxIsInt32)
 # define CHECK_UINT32(ARG) CHECK_TYPE(ARG,#ARG,uint32,mxIsUint32)
 # define CHECK_LOGICAL(ARG) CHECK_TYPE(ARG,#ARG,logical,mxIsLogical)
 # define CHECK_REAL(ARG) if (!mxIsDouble(ARG) && !mxIsSingle(ARG)) mexErrMsgIdAndTxt(STR(MEXNAME)":inputType",STR(MEXNAME)" expects "#ARG" to be a double or single array but got %s instead",mxGetClassName(ARG));
 # define CHECK_TYPE_MATCH(ARG1,ARG2) if (mxGetClassID(ARG1) != mxGetClassID(ARG2)) mexErrMsgIdAndTxt(STR(MEXNAME)":inputType",STR(MEXNAME)" expects "#ARG1" to be of the same type as "#ARG2" (%s) but got %s instead",mxGetClassName(ARG2),mxGetClassName(ARG1));

 /* Size checks */
 # define CHECK_SCALAR(ARG) if (!mxIsScalar(ARG)) mexErrMsgIdAndTxt(STR(MEXNAME)":inputSize",STR(MEXNAME)" expects "#ARG" to be a scalar array")
 # define CHECK_SCALAR_OR_EMPTY(ARG) if (!mxIsScalar(ARG) && !mxIsEmpty(ARG)) mexErrMsgIdAndTxt(STR(MEXNAME)":inputSize",STR(MEXNAME)" expects "#ARG" to be a scalar or empty array")
 # define CHECK_NUMEL_MSG(ARG,SIZE,MSG) if (mxGetNumberOfElements(ARG) != SIZE) mexErrMsgIdAndTxt(STR(MEXNAME)":inputSize",STR(MEXNAME)" expects "#ARG" to be an array of size "#SIZE"(%d) but got %d instead"MSG,SIZE,mxGetNumberOfElements(ARG))
 # define CHECK_NUMEL(ARG,SIZE) if (mxGetNumberOfElements(ARG) != SIZE) mexErrMsgIdAndTxt(STR(MEXNAME)":inputSize",STR(MEXNAME)" expects "#ARG" to be an array of size "#SIZE"(%d) but got %d instead",SIZE,mxGetNumberOfElements(ARG))
 # define CHECK_NROWS(ARG,SIZE) if (mxGetM(ARG) != SIZE) mexErrMsgIdAndTxt(STR(MEXNAME)":inputSize",STR(MEXNAME)" expects "#ARG" to be an array with "#SIZE"(%d) lines but got %d instead",SIZE,mxGetM(ARG))
 # define CHECK_NCOLS(ARG,SIZE) if (mxGetN(ARG) != SIZE) mexErrMsgIdAndTxt(STR(MEXNAME)":inputSize",STR(MEXNAME)" expects "#ARG" to be an array with "#SIZE"(%d) columns but got %d instead",SIZE,mxGetN(ARG))

 /* nargout checks */
 # define CHECK_NARGOUT_LE(NARG) if (nlhs  > NARG) mexErrMsgIdAndTxt(STR(MEXNAME)":nargout",STR(MEXNAME)" expects exactly "#NARG" output arguments but got %d instead",nlhs)

 /* argout assignments (always assign plhs[0] to assign MATLAB's ans variable when no output arguments are used) */
 # define ASSIGN_PLHS for(int ilhs=0; ilhs<(nlhs ? nlhs : 1); ilhs++) {plhs[ilhs] = pout[ilhs];}

# endif

# endif 
