/****************************************************************************
**
*W  vecgf2.h                    GAP source                       Frank Celler
**
**
*Y  Copyright (C)  1997,  Lehrstuhl D für Mathematik,  RWTH Aachen,  Germany
*Y  (C) 1998 School Math and Comp. Sci., University of St Andrews, Scotland
*Y  Copyright (C) 2002 The GAP Group
*/

#ifndef libGAP_GAP_VECGF2_H
#define libGAP_GAP_VECGF2_H

/****************************************************************************
**

*F  IS_GF2VEC_REP( <obj> )  . . . . . . check that <obj> is in GF2 vector rep
*/
#define libGAP_IS_GF2VEC_REP(obj) \
  (libGAP_TNUM_OBJ(obj)==libGAP_T_DATOBJ && libGAP_DoFilter(libGAP_IsGF2VectorRep,obj) == libGAP_True)


/****************************************************************************
**
*F  NEW_GF2VEC( <vec>, <type>, <len> )  . . . . . . . create a new GF2 vector
*/
#define libGAP_NEW_GF2VEC( vec, type, len ) \
    do { \
        vec = libGAP_NewBag( libGAP_T_DATOBJ, libGAP_SIZE_PLEN_GF2VEC(len) ); \
        libGAP_SetTypeDatObj(vec, type); \
    } while (0)


/****************************************************************************
**
*F  LEN_GF2VEC( <vec> ) . . . . . . . . . . . . . . . . length of a GF vector
**
**  'LEN_GF2VEC' returns the logical length of the GF2 vector <list>,  as a C
**  integer.
**
**  Note that 'LEN_GF2VEC' is a macro, so do not call it with  arguments that
**  have side effects.
*/
#define libGAP_LEN_GF2VEC(list)         ((libGAP_Int)(libGAP_ADDR_OBJ(list)[1]))


/****************************************************************************
**
*F  NUMBER_BLOCKS_GF2VEC( <vec> ) . . . . . . . number of UInt blocks in list
*/
#define libGAP_NUMBER_BLOCKS_GF2VEC(list)      ((libGAP_LEN_GF2VEC((list))+ libGAP_BIPEB-1)/libGAP_BIPEB)


/****************************************************************************
**
*F  BLOCKS_GF2VEC( <list> ) . . . . . . . . . . . first block of a GF2 vector
**
**  returns a pointer to the start of the data of the GF2 vector
*/
#define libGAP_BLOCKS_GF2VEC(list)             ((libGAP_UInt*)(libGAP_ADDR_OBJ(list)+2))


/****************************************************************************
**
*F  BLOCK_ELM_GF2VEC( <list>, <pos> ) . . . . . . . . . block of a GF2 vector
**
**  'BLOCK_ELM_GF2VEC' return the   block containing the <pos>-th  element of
**  the  GF2 vector <list> as  a UInt value, which is  also a valid left hand
**  side.  <pos> must be a positive integer less  than or equal to the length
**  of <list>.
**
**  Note that 'BLOCK_ELM_GF2VEC' is a macro, so do not call it with arguments
**  that have side effects.
*/
#define libGAP_BLOCK_ELM_GF2VEC(list, pos)    (libGAP_BLOCKS_GF2VEC(list)[((pos)-1)/libGAP_BIPEB])


/****************************************************************************
**
*F  SET_LEN_GF2VEC( <list>, <len> ) .  set the logical length of a GF2 vector
**
**  'SET_LEN_GF2VEC' sets the length of the boolean list  <list> to the value
**  <len>, which must be a positive C integer.
**
**  Note that 'SET_LEN_GF2VEC' is a macro, so do  not  call it with arguments
**  that have side effects.
*/
#define libGAP_SET_LEN_GF2VEC(list,len)        (libGAP_ADDR_OBJ(list)[1] = (libGAP_Obj)(len))


/****************************************************************************
**
*F  SIZE_PLEN_GF2VEC( <len> ) . . . . . . . . physical length of a GF2 vector
*/
#define libGAP_SIZE_PLEN_GF2VEC(len) \
                           (2*sizeof(libGAP_Obj)+((len)+libGAP_BIPEB-1)/libGAP_BIPEB*sizeof(libGAP_UInt))


/****************************************************************************
**
*F  MASK_POS_GF2VEC( <pos> )  . . . . bit mask for position of a Boolean list
**
**  MASK_POS_GF2VEC(<pos>) returns a UInt with  a single set bit in  position
**  (pos-1) % BIPEB, useful for accessing the pos'th element of a blist
**
**  Note that 'MASK_POS_GF2VEC' is a  macro, so do not call it with arguments
**  that have side effects.
*/
#define libGAP_MASK_POS_GF2VEC( pos ) (((libGAP_UInt) 1)<<((pos)-1)%libGAP_BIPEB)


/****************************************************************************
**
*F  ELM_GF2VEC( <list>, <pos> ) . . . . . . . . . . element of a a GF2 vector
**
**  'ELM_GF2VEC' return the <pos>-th element of  the GF2 vector <list>, which
**  is either 'Z(2)' or '0*Z(2)'.  <pos> must be a positive integer less than
**  or equal to the length of <list>.
**
**  Note that 'ELM_GF2VEC' is a macro, so do  not call it with arguments that
**  have side effects.
*/
#define libGAP_ELM_GF2VEC(list,pos) \
  ((libGAP_BLOCK_ELM_GF2VEC(list,pos) & libGAP_MASK_POS_GF2VEC(pos)) ?  libGAP_GF2One : libGAP_GF2Zero)


/****************************************************************************
**
*F  LEN_GF2MAT( <list> )  . . . . . . . . . . . . . . . length of a GF matrix
**
**  'LEN_GF2MAT' returns the logical length of the GF2 matrix <list>,  as a C
**  integer.
**
**  Note that 'LEN_GF2MAT' is a macro, so do not call it with  arguments that
**  have side effects.
*/
#define libGAP_LEN_GF2MAT(list)         (libGAP_INT_INTOBJ(libGAP_ADDR_OBJ(list)[1]))


/****************************************************************************
**
*F  SET_LEN_GF2MAT( <list>, <len> ) . . . . . . set the length of a GF matrix
**
**  'SET_LEN_GF2MAT' sets the logical length of the GF2 matrix <list>, as a C
**  integer.
**
**  Note that 'SET_LEN_GF2MAT' is a  macro, so do not  call it with arguments
**  that have side effects.
*/
#define libGAP_SET_LEN_GF2MAT(list,len)    (libGAP_ADDR_OBJ(list)[1]=libGAP_INTOBJ_INT(len))


/****************************************************************************
**
*F  ELM_GF2MAT( <list>, <pos> ) . . . . . . . . . . element of a a GF2 matrix
**
**  'ELM_GF2MAT' returns the <pos>-th element of the GF2 matrix <list>, which
**  is a GF2 vector.  <pos> must be a positive  integer less than or equal to
**  the length of <list>.
**
**  Note that 'ELM_GF2MAT' is a macro, so do  not call it with arguments that
**  have side effects.
*/
#define libGAP_ELM_GF2MAT(list,pos)    (libGAP_ADDR_OBJ(list)[pos+1])


/****************************************************************************
**
*F  SET_ELM_GF2MAT( <list>, <pos>, <elm> )  . . set element of a a GF2 matrix
**
**  'SET_ELM_GF2MAT'  sets the <pos>-th element   of  the GF2 matrix  <list>,
**  which must be a  GF2 vector.  <pos> must  be a positive integer less than
**  or equal to the length of <list>.
**
**  Note that 'ELM_GF2MAT' is a macro, so do  not call it with arguments that
**  have side effects.
*/
#define libGAP_SET_ELM_GF2MAT(list,pos,elm)    (libGAP_ADDR_OBJ(list)[pos+1]=elm)


/****************************************************************************
**
*F  SIZE_PLEN_GF2MAT( <len> ) . . . . . . . . physical length of a GF2 matrix
*/
#define libGAP_SIZE_PLEN_GF2MAT(len)   (((len)+2)*sizeof(libGAP_Obj))

/****************************************************************************
**
*V  TYPE_LIST_GF2VEC  . . . . . . . . . . . . . . type of a GF2 vector object
*/
extern libGAP_Obj libGAP_TYPE_LIST_GF2VEC;


/****************************************************************************
**
*V  TYPE_LIST_GF2VEC_IMM  . . . . . .  type of an immutable GF2 vector object
*/
extern libGAP_Obj libGAP_TYPE_LIST_GF2VEC_IMM;

/****************************************************************************
**
*V  TYPE_LIST_GF2VEC_IMM_LOCKED. . . .  type of an immutable GF2 vector object
**                                          with locked representation
*/
extern libGAP_Obj libGAP_TYPE_LIST_GF2VEC_IMM_LOCKED;

/****************************************************************************
**
*V  TYPE_LIST_GF2VEC_LOCKED. . . .  type of a GF2 vector object
**                                          with locked representation
*/
extern libGAP_Obj libGAP_TYPE_LIST_GF2VEC_LOCKED;


/****************************************************************************
**
*V  TYPE_LIST_GF2MAT  . . . . . . . . . . . . . . type of a GF2 matrix object
*/
extern libGAP_Obj libGAP_TYPE_LIST_GF2MAT;


/****************************************************************************
**
*V  TYPE_LIST_GF2MAT_IMM  . . . . . .  type of an immutable GF2 matrix object
*/
extern libGAP_Obj libGAP_TYPE_LIST_GF2MAT_IMM;


extern libGAP_Obj libGAP_IsGF2VectorRep;

/****************************************************************************
**

*F * * * * * * * * * * * * * initialize package * * * * * * * * * * * * * * *
*/


/****************************************************************************
**

*F  InitInfoGF2Vec()  . . . . . . . . . . . . . . . . table of init functions
*/
libGAP_StructInitInfo * libGAP_InitInfoGF2Vec ( void );


#endif // GAP_VECGF2_H

/****************************************************************************
**

*E  vecgf2.h  . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here
*/
