#ifndef __ZCODE_H
#define __ZCODE_H
#include <limits.h>
#include <stdlib.h>
#if !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(__MINGW32__)
#define __int64 long long
#endif
#ifndef INDEX
#define INDEX unsigned
#endif
#ifndef CODE_TABLE_SIZE
#if INT_MAX <= 32767
#define CODE_TABLE_SIZE 2048
#else
#define CODE_TABLE_SIZE 10240
#endif
#endif
#ifndef CODE_SORT_R_MAX
#define CODE_SORT_R_MAX 64
#endif
#ifndef PERM_N_MAX
#define PERM_N_MAX 256
#endif
enum { CEC_MEMORY=1, CEC_OVERFLOW, CEC_PARAMETER };
typedef struct _code_t {
int ErrorCode,n,r,type;
INDEX**a,**b,size;
#ifdef __cplusplus
char*table;
_code_t() { type=0; table=0; size=0; }
~_code_t() { delete[]table; }
#else
char table[CODE_TABLE_SIZE];
#endif
} code_t;
#ifdef __cplusplus
#define code0_t code_t
#else
typedef struct {
int ErrorCode,n,r,type;
INDEX**a,**b,size;
char*table;
} code0_t;
#endif
extern code0_t DefaultCodeTable[1];
extern volatile unsigned long MaxCodeTableSize;
extern INDEX InitCode_r(code_t*,int,int);
extern INDEX InitPerm_r(code_t*,int,int);
extern INDEX RepeToNum_r(code_t*,int*);
extern INDEX CombToNum_r(code_t*,int*);
extern INDEX PartToNum_r(code_t*,int*);
extern INDEX PermToNum_r(code_t*,int*);
extern void NumToRepe_r(code_t*,int*,INDEX);
extern void NumToComb_r(code_t*,int*,INDEX);
extern void NumToPart_r(code_t*,int*,INDEX);
extern void NumToPerm_r(code_t*,int*,INDEX);
#define InitRepe_r(T,N,R) InitCode_r(T,N,R)
#define InitComb_r(T,N,R) InitCode_r(T,(N)-(R)+1,R)
#define InitPart_r(T,N,R) InitCode_r(T,(N)+1,(R)-1)
#define InitRepe(N,R) InitRepe_r((code_t*)DefaultCodeTable,N,R)
#define InitComb(N,R) InitComb_r((code_t*)DefaultCodeTable,N,R)
#define InitPart(N,R) InitPart_r((code_t*)DefaultCodeTable,N,R)
#define InitPerm(N,R) InitPerm_r((code_t*)DefaultCodeTable,N,R)
#define RepeToNum(V) RepeToNum_r((code_t*)DefaultCodeTable,V)
#define CombToNum(V) CombToNum_r((code_t*)DefaultCodeTable,V)
#define PartToNum(V) PartToNum_r((code_t*)DefaultCodeTable,V)
#define PermToNum(V) PermToNum_r((code_t*)DefaultCodeTable,V)
#define NumToRepe(V,N) NumToRepe_r((code_t*)DefaultCodeTable,V,N)
#define NumToComb(V,N) NumToComb_r((code_t*)DefaultCodeTable,V,N)
#define NumToPart(V,N) NumToPart_r((code_t*)DefaultCodeTable,V,N)
#define NumToPerm(V,N) NumToPerm_r((code_t*)DefaultCodeTable,V,N)
#define CodeErrorCode DefaultCodeTable->ErrorCode
#endif