
| Current Path : /proc/thread-self/root/usr/include/gap/ |
Linux ift1.ift-informatik.de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64 |
| Current File : //proc/thread-self/root/usr/include/gap/plist.h |
/****************************************************************************
**
*W plist.h GAP source Martin Schönert
**
**
*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
**
** This file declares the functions that deal with plain lists.
**
** A plain list is a list that may have holes and may contain elements of
** arbitrary types. A plain list may also have room for elements beyond its
** current logical length. The last position to which an element can be
** assigned without resizing the plain list is called the physical length.
**
** This representation is encoded by the macros 'NEW_PLIST', 'GROW_PLIST',
** 'SHRINK_PLIST', 'SET_LEN_PLIST', 'LEN_PLIST', 'SET_ELM_PLIST', and
** 'ELM_PLIST', which are used by the functions in this package and the rest
** of the {\GAP} kernel to access plain lists.
**
** This package also contains the list functions for plain lists, which are
** installed in the appropriate tables by 'InitPlist'.
*/
#ifndef GAP_PLIST_H
#define GAP_PLIST_H
#include "objects.h"
/****************************************************************************
**
*F NEW_PLIST(<type>,<plen>) . . . . . . . . . . . allocate a new plain list
**
** 'NEW_PLIST' allocates a new plain list of type <type> that has room for
** at least <plen> elements.
**
*/
static inline Obj NEW_PLIST(UInt type, Int plen)
{
GAP_ASSERT(plen >= 0);
GAP_ASSERT(plen <= INT_INTOBJ_MAX);
GAP_ASSERT(FIRST_PLIST_TNUM <= type && type <= LAST_PLIST_TNUM);
return NewBag(type, (plen + 1) * sizeof(Obj));
}
static inline Obj NEW_PLIST_IMM(UInt type, Int plen)
{
return NEW_PLIST(type | IMMUTABLE, plen);
}
static inline Obj NEW_PLIST_WITH_MUTABILITY(Int mut, UInt type, Int plen)
{
if (!mut)
type |= IMMUTABLE;
return NEW_PLIST(type, plen);
}
/****************************************************************************
**
*F IS_PLIST( <list> ) . . . . . . . . . . . check if <list> is a plain list
*/
static inline Int IS_PLIST(Obj list)
{
return FIRST_PLIST_TNUM <= TNUM_OBJ(list) &&
TNUM_OBJ(list) <= LAST_PLIST_TNUM;
}
/****************************************************************************
**
*F IS_PLIST_OR_POSOBJ( <list> ) . . . . . . . . . . . . check type of <list>
**
** Checks if this is 'PLIST'-like.
** This function is used in a GAP_ASSERT checking if calling functions like
** SET_ELM_PLIST is acceptable on an Obj.
**
** Unlike IS_PLIST, this function also accepts positional objects
** (which have the same memory layout as plists), as the plist APIs using it
** for assertion checks are in practice invoked on such objects, too.
*/
static inline Int IS_PLIST_OR_POSOBJ(Obj list)
{
UInt tnum = TNUM_OBJ(list);
return (FIRST_PLIST_TNUM <= tnum && tnum <= LAST_PLIST_TNUM) ||
tnum == T_POSOBJ;
}
/****************************************************************************
**
*F CAPACITY_PLIST(<list>) . . . . . . . . . . . capacity of a plain list
**
** 'CAPACITY_PLIST' returns the maximum capacity of a PLIST.
**
*/
static inline Int CAPACITY_PLIST(Obj list)
{
return SIZE_OBJ(list) / sizeof(Obj) - 1;
}
extern void GrowPlist (
Obj list,
UInt need );
/****************************************************************************
**
*F GROW_PLIST(<list>,<plen>) . . . . make sure a plain list is large enough
**
** 'GROW_PLIST' grows the plain list <list> if necessary to ensure that it
** has room for at least <plen> elements.
**
*/
static inline void GROW_PLIST(Obj list, Int plen)
{
GAP_ASSERT(IS_PLIST_OR_POSOBJ(list));
GAP_ASSERT(plen >= 0);
if (plen > CAPACITY_PLIST(list)) {
GrowPlist(list, plen);
}
}
/****************************************************************************
**
*F SHRINK_PLIST(<list>,<plen>) . . . . . . . . . . . . . shrink a plain list
**
** 'SHRINK_PLIST' shrinks the plain list <list> if possible so that it has
** still room for at least <plen> elements.
**
*/
static inline void SHRINK_PLIST(Obj list, Int plen)
{
GAP_ASSERT(IS_PLIST_OR_POSOBJ(list));
GAP_ASSERT(plen >= 0);
GAP_ASSERT(plen <= CAPACITY_PLIST(list));
ResizeBag(list, (plen + 1) * sizeof(Obj));
}
/****************************************************************************
**
*F SET_LEN_PLIST(<list>,<len>) . . . . . . . set the length of a plain list
**
** 'SET_LEN_PLIST' sets the length of the plain list <list> to <len>.
**
*/
static inline void SET_LEN_PLIST(Obj list, Int len)
{
GAP_ASSERT(IS_PLIST_OR_POSOBJ(list));
GAP_ASSERT(len >= 0);
GAP_ASSERT(len <= CAPACITY_PLIST(list));
ADDR_OBJ(list)[0] = (Obj)len;
}
/****************************************************************************
**
*F LEN_PLIST(<list>) . . . . . . . . . . . . . . . . length of a plain list
**
** 'LEN_PLIST' returns the logical length of the list <list> as a C integer.
**
*/
static inline Int LEN_PLIST(Obj list)
{
GAP_ASSERT(IS_PLIST_OR_POSOBJ(list));
return ((Int)(CONST_ADDR_OBJ(list)[0]));
}
/****************************************************************************
**
*F SET_ELM_PLIST(<list>,<pos>,<val>) . . . assign an element to a plain list
**
** 'SET_ELM_PLIST' assigns the value <val> to the plain list <list> at the
** position <pos>. <pos> must be a positive integer less than or equal to
** the length of <list>.
**
*/
static inline void SET_ELM_PLIST(Obj list, Int pos, Obj val)
{
GAP_ASSERT(IS_PLIST_OR_POSOBJ(list));
GAP_ASSERT(pos >= 1);
GAP_ASSERT(pos <= CAPACITY_PLIST(list));
ADDR_OBJ(list)[pos] = val;
}
/****************************************************************************
**
*F ELM_PLIST(<list>,<pos>) . . . . . . . . . . . . . element of a plain list
**
** 'ELM_PLIST' return the <pos>-th element of the list <list>. <pos> must
** be a positive integer less than or equal to the physical length of
** <list>. If <list> has no assigned element at position <pos>, 'ELM_PLIST'
** returns 0.
*/
static inline Obj ELM_PLIST(Obj list, Int pos)
{
GAP_ASSERT(IS_PLIST_OR_POSOBJ(list));
GAP_ASSERT(pos >= 1);
GAP_ASSERT(pos <= CAPACITY_PLIST(list));
return CONST_ADDR_OBJ(list)[pos];
}
/****************************************************************************
**
*F BASE_PTR_PLIST(<list>) . . . . . . . . . . . . . element of a plain list
**
** 'BASE_PTR_PLIST' returns a point to the first element of the plist <list>
**
** This point will be invalidated whenever a garbage collection occurs.
*/
static inline Obj * BASE_PTR_PLIST(Obj list)
{
GAP_ASSERT(IS_PLIST_OR_POSOBJ(list));
return ADDR_OBJ(list) + 1;
}
/****************************************************************************
**
*F IS_DENSE_PLIST( <list> ) . . . . . check if <list> is a dense plain list
**
** Note that this only checks for plists that are known to be dense. This is
** very fast. If you want to also handle plists for which it is now known
** whether they are dense or not (i.e. of type 'T_PLIST'),
** use 'IS_DENSE_LIST' instead.
*/
static inline Int IS_DENSE_PLIST(Obj list)
{
return T_PLIST_DENSE <= TNUM_OBJ(list) &&
TNUM_OBJ(list) <= LAST_PLIST_TNUM;
}
/****************************************************************************
**
*F IS_PLIST_MUTABLE( <list> ) . . . . . . . . . . . is a plain list mutable
*/
static inline Int IS_PLIST_MUTABLE(Obj list)
{
GAP_ASSERT(IS_PLIST(list));
return !((TNUM_OBJ(list) - T_PLIST) % 2);
}
/****************************************************************************
**
*F AssPlist( <list>, <pos>, <val>) . . . . . . . . . assign to a plain list
*/
extern void AssPlist (
Obj list,
Int pos,
Obj val );
/****************************************************************************
**
*F PushPlist( <list>, <val> ) . . . . . . . . assign to end of a plain list
**
** Note that this function does not adjust the TNUM of the list object. It
** also does not attempt to convert the list to a different representation,
** such as a string or blist. If your need that, use AddList or AddPlist
** instead.
**
*/
static inline UInt PushPlist(Obj list, Obj val)
{
const UInt pos = LEN_PLIST(list) + 1;
GROW_PLIST(list, pos);
SET_LEN_PLIST(list, pos);
SET_ELM_PLIST(list, pos, val);
if (IS_BAG_REF(val))
CHANGED_BAG(list);
return pos;
}
/****************************************************************************
**
*F PopPlist( <list> ) . . . . . . . . . remove last element of a plain list
**
** Also returns the removed element. Caller is responsible for ensuring that
** the list is non-empty. Otherwise an assertion may be raised or the plist
** be left in an invalid state.
**
** Also clear the slot used by the pop'ed object, to avoid stale references
** preventing the garbage collector from collecting the pop'ed object.
**
*/
static inline Obj PopPlist(Obj list)
{
const UInt pos = LEN_PLIST(list);
Obj val = ELM_PLIST(list, pos);
SET_LEN_PLIST(list, pos - 1);
SET_ELM_PLIST(list, pos, 0);
return val;
}
/****************************************************************************
**
*F AssPlistEmpty( <list>, <pos>, <val> ) . . . . . assignment to empty list
*F UnbPlistImm( <list>, <pos> ) . . . . unbind an element from a plain list
*/
extern void AssPlistEmpty (
Obj list,
Int pos,
Obj val );
extern void AssPlistFfe (
Obj list,
Int pos,
Obj val );
extern Int KTNumPlist (
Obj list,
Obj *famfirst);
void UnbPlistImm (
Obj list,
Int pos );
/****************************************************************************
**
*F * * * * * * * * * * * * * initialize module * * * * * * * * * * * * * * *
*/
/****************************************************************************
**
*F InitInfoPlist() . . . . . . . . . . . . . . . . . table of init functions
*/
StructInitInfo * InitInfoPlist ( void );
#endif // GAP_PLIST_H