/****************************************************************************
**
*W  objfgelm.h                  GAP source                       Frank Celler
**
**
*Y  Copyright (C)  1996,  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_OBJFGELM_H
#define libGAP_GAP_OBJFGELM_H


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

*D  AWP_SOMETHING
*/
#define libGAP_AWP_FIRST_ENTRY          5
#define libGAP_AWP_PURE_TYPE            (libGAP_AWP_FIRST_ENTRY+0)
#define libGAP_AWP_NR_BITS_EXP          (libGAP_AWP_FIRST_ENTRY+1)
#define libGAP_AWP_NR_GENS              (libGAP_AWP_FIRST_ENTRY+2)
#define libGAP_AWP_NR_BITS_PAIR         (libGAP_AWP_FIRST_ENTRY+3)
#define libGAP_AWP_FUN_OBJ_BY_VECTOR    (libGAP_AWP_FIRST_ENTRY+4)
#define libGAP_AWP_FUN_ASSOC_WORD       (libGAP_AWP_FIRST_ENTRY+5)
#define libGAP_AWP_FIRST_FREE           (libGAP_AWP_FIRST_ENTRY+6)


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

*F  BITS_WORDTYPE( <type> )
*/
#define libGAP_BITS_WORDTYPE( type ) \
    ( libGAP_INT_INTOBJ( libGAP_ELM_PLIST( (type), libGAP_AWP_NR_BITS_PAIR ) ) )


/****************************************************************************
**
*F  EBITS_WORDTYPE( <type> )
*/
#define libGAP_EBITS_WORDTYPE( type ) \
    ( libGAP_INT_INTOBJ( libGAP_ELM_PLIST( (type), libGAP_AWP_NR_BITS_EXP ) ) )


/****************************************************************************
**
*F  RANK_WORDTYPE( <type> )
*/
#define libGAP_RANK_WORDTYPE( type ) \
    ( libGAP_INT_INTOBJ( libGAP_ELM_PLIST( (type), libGAP_AWP_NR_GENS ) ) )


/****************************************************************************
**
*F  PURETYPE_WORDTYPE( <type> )
*/
#define libGAP_PURETYPE_WORDTYPE( type ) \
    ( libGAP_ELM_PLIST( (type), libGAP_AWP_PURE_TYPE ) )


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

*F  BITS_WORD( <word> )
*/
#define libGAP_BITS_WORD( word ) \
    ( libGAP_BITS_WORDTYPE( libGAP_TYPE_DATOBJ( (word) ) ) )


/****************************************************************************
**
*F  DATA_WORD( <word> )
**
**  'DATA_WORD' returns a pointer to the data area of <word>.
*/
#define libGAP_DATA_WORD( word ) \
    ( (libGAP_Char*)libGAP_ADDR_OBJ( (word) ) + 2*sizeof(libGAP_Obj) )


/****************************************************************************
**
*F  EBITS_WORD( <word> )
*/
#define libGAP_EBITS_WORD( word ) \
    ( libGAP_EBITS_WORDTYPE( libGAP_TYPE_DATOBJ( (word) ) ) )


/****************************************************************************
**
*F  NPAIRS_WORD( <word> )
**
**  'NPAIRS_WORD' returns the  number of pairs of  generator  number/exponent
**  pairs of <word>.
*/
#define libGAP_NPAIRS_WORD( word ) \
    ( libGAP_INT_INTOBJ( libGAP_ADDR_OBJ( (word) )[1]) )


/****************************************************************************
**
*F  RANK_WORD( <word> )
*/
#define libGAP_RANK_WORD( word ) \
    ( libGAP_RANK_WORDTYPE( libGAP_TYPE_DATOBJ( (word) ) ) )


/****************************************************************************
**
*F  PURETYPE_WORD( <word> )
*/
#define libGAP_PURETYPE_WORD( word ) \
    ( libGAP_PURETYPE_WORDTYPE( libGAP_TYPE_DATOBJ( (word) ) ) )


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

*F  NEW_WORD( <word>, <type>, <npairs> )
**
**  'NEW_WORD' creates  a new object which has  the given <type> and room for
**  <npairs> pairs of generator number/exponent.  The new  word is return  in
**  <word>.
*/
static inline libGAP_Obj libGAP_NewWord(libGAP_Obj type, libGAP_UInt npairs) {
  libGAP_Obj word;
  word = libGAP_NewBag(libGAP_T_DATOBJ,2*sizeof(libGAP_Obj)+npairs*libGAP_BITS_WORDTYPE(type)/8L);
  (libGAP_ADDR_OBJ(word)[1] = libGAP_INTOBJ_INT(npairs));
  libGAP_SET_TYPE_DATOBJ( word, type);
  return word;
}

#define libGAP_NEW_WORD(word, type, npairs) \
  libGAP_ReadGuard(type), \
  (word) = libGAP_NewWord((type), (npairs));


/****************************************************************************
**
*F  RESIZE_WORD( <word>, <npairs> )
*/
static inline libGAP_Obj libGAP_RESIZE_WORD( libGAP_Obj word, libGAP_UInt npairs )
{
  libGAP_WriteGuard(word);
  libGAP_ResizeBag( (word), 2*sizeof(libGAP_Obj)+((npairs)*libGAP_BITS_WORD((word))/8L));
  (libGAP_ADDR_OBJ((word))[1] = libGAP_INTOBJ_INT((npairs)));
  return word;
}


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

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

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

*F  InitInfoFreeGroupElements() . . . . . . . . . . . table of init functions
*/
libGAP_StructInitInfo * libGAP_InitInfoFreeGroupElements ( void );


#endif // GAP_OBJFGELM_H

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

*E  objfgelm.h  . . . . . . . . . . . . . . . . . . . . . . . . . . ends here
*/
