Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GAP_NewRange, GAP_NewObjIntFromInt, GAP_ValueInt to the libgap API #4621

Merged
merged 2 commits into from
Aug 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions src/exprs.c
Original file line number Diff line number Diff line change
Expand Up @@ -980,13 +980,7 @@ static Obj EvalRangeExpr(Expr expr)
ErrorQuit("Range: the length of a range must be a small integer",
0, 0);
}
if ( 0 < inc )
range = NEW_RANGE_SSORT();
else
range = NEW_RANGE_NSORT();
SET_LEN_RANGE( range, (high-low) / inc + 1 );
SET_LOW_RANGE( range, low );
SET_INC_RANGE( range, inc );
range = NEW_RANGE((high - low) / inc + 1, low, inc);
}

/* return the range */
Expand Down
8 changes: 1 addition & 7 deletions src/intrprtr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2221,13 +2221,7 @@ void IntrListExprEnd(
0, 0);
}

if ( 0 < inc )
list = NEW_RANGE_SSORT();
else
list = NEW_RANGE_NSORT();
SET_LEN_RANGE( list, (high-low) / inc + 1 );
SET_LOW_RANGE( list, low );
SET_INC_RANGE( list, inc );
list = NEW_RANGE((high - low) / inc + 1, low, inc);
}

/* push the list again */
Expand Down
27 changes: 27 additions & 0 deletions src/libgap-api.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "opers.h"
#include "plist.h"
#include "precord.h"
#include "range.h"
#include "records.h"
#include "streams.h"
#include "stringobj.h"
Expand Down Expand Up @@ -355,6 +356,16 @@ Obj GAP_MakeObjInt(const UInt * limbs, Int size)
return MakeObjInt(limbs, size);
}

Obj GAP_NewObjIntFromInt(Int val)
{
return ObjInt_Int(val);
}

Int GAP_ValueInt(Obj obj)
{
return Int_ObjInt(obj);
}

Int GAP_SizeInt(Obj obj)
{
RequireInt("GAP_SizeInt", obj);
Expand Down Expand Up @@ -406,6 +417,22 @@ Obj GAP_NewPlist(Int capacity)
return NEW_PLIST(T_PLIST_EMPTY, capacity);
}

static BOOL fitsInIntObj(Int i)
{
return INT_INTOBJ_MIN <= i && i <= INT_INTOBJ_MAX;
}

Obj GAP_NewRange(Int len, Int low, Int inc)
{
if (!inc) return GAP_Fail;
if (!fitsInIntObj(len)) return GAP_Fail;
if (!fitsInIntObj(low)) return GAP_Fail;
if (!fitsInIntObj(inc)) return GAP_Fail;
Int high = low + (len - 1) * inc;
if (!fitsInIntObj(high)) return GAP_Fail;
return NEW_RANGE(len, low, inc);
}


////
//// matrix obj
Expand Down
23 changes: 21 additions & 2 deletions src/libgap-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,8 @@ int GAP_IsSmallInt(Obj obj);
int GAP_IsLargeInt(Obj obj);


// Construct an integer object from the limbs at which <limbs> points (for a
// definition of "limbs", please consult the comment at the top of
// Construct a GAP integer object from the limbs at which <limbs> points (for
// a definition of "limbs", please consult the comment at the top of
// `integer.c`). The absolute value of <size> determines the number of limbs.
// If <size> is zero, then `INTOBJ_INT(0)` is returned. Otherwise, the sign
// of the returned integer object is determined by the sign of <size>.
Expand All @@ -325,6 +325,16 @@ int GAP_IsLargeInt(Obj obj);
// small integer, it will be returned as such.
Obj GAP_MakeObjInt(const UInt * limbs, Int size);

// Return a GAP integer object with value equal to <val>.
Obj GAP_NewObjIntFromInt(Int val);

// Return an integer equal to the given GAP integer object. If <obj> is not
// a GAP integer, or does not fit into an Int, an error is raised.
//
// If `GAP_IsSmallInt(obj)` return 1, then it is guaranteed that this will
// succeed and no error is raised.
Int GAP_ValueInt(Obj);

// If <obj> is a GAP integer, returns the number of limbs needed to store the
// integer, times the sign. If <obj> is the integer 0, then 0 is returned. If
// <obj> is any other small integer, then 1 or -1 is returned, depending on
Expand Down Expand Up @@ -369,6 +379,15 @@ Obj GAP_ElmList(Obj list, UInt pos);
// Returns a new empty plain list with capacity <capacity>
Obj GAP_NewPlist(Int capacity);

// Returns a new range with <len> elements, starting at <low>, and proceeding
// in increments of <inc>. So the final element in the range will be equal to
// <high> := <low> + <inc> * (<len> - 1).
//
// Note that <inc> must be non-zero, and all three arguments as
// well as the value <high> must fit into a GAP small integer.
// If any of these conditions is violated, then GAP_Fail is returned.
Obj GAP_NewRange(Int len, Int low, Int inc);


////
//// matrix obj
Expand Down
39 changes: 20 additions & 19 deletions src/range.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,22 @@ static Obj TypeRangeSSort(Obj list)
}


Obj NEW_RANGE(Int len, Int low, Int inc)
{
Obj range;

if (0 < inc)
range = NewBag(T_RANGE_SSORT, 3 * sizeof(Obj));
else
range = NewBag(T_RANGE_NSORT, 3 * sizeof(Obj));
SET_LEN_RANGE(range, len);
SET_LOW_RANGE(range, low);
SET_INC_RANGE(range, inc);

return range;
}


#if !defined(USE_THREADSAFE_COPYING)

/****************************************************************************
Expand Down Expand Up @@ -394,14 +410,8 @@ static Obj ElmsRange(Obj list, Obj poss)
}

/* make the result range */
if ( 0 < inc * GET_INC_RANGE(list) )
elms = NEW_RANGE_SSORT();
else
elms = NEW_RANGE_NSORT();
SET_LEN_RANGE( elms, lenPoss );
SET_LOW_RANGE( elms, INT_INTOBJ( GET_ELM_RANGE( list, pos ) ) );
SET_INC_RANGE( elms, inc * GET_INC_RANGE( list ) );

inc *= GET_INC_RANGE(list);
elms = NEW_RANGE(lenPoss, INT_INTOBJ( GET_ELM_RANGE( list, pos ) ), inc);
}

return elms;
Expand Down Expand Up @@ -765,10 +775,7 @@ Obj Range2Check (
SET_ELM_PLIST( range, 1, first );
}
else {
range = NEW_RANGE_SSORT();
SET_LEN_RANGE( range, (l-f) + 1 );
SET_LOW_RANGE( range, f );
SET_INC_RANGE( range, 1 );
range = NEW_RANGE((l-f) + 1, f, 1);
}
return range;
}
Expand Down Expand Up @@ -805,13 +812,7 @@ Obj Range3Check (
SET_ELM_PLIST( range, 1, first );
}
else {
if ( 0 < i )
range = NEW_RANGE_SSORT();
else
range = NEW_RANGE_NSORT();
SET_LEN_RANGE( range, (l - f) / i + 1 );
SET_LOW_RANGE( range, f );
SET_INC_RANGE( range, i );
range = NEW_RANGE((l - f) / i + 1, f, i);
}
return range;
}
Expand Down
12 changes: 2 additions & 10 deletions src/range.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,10 @@
**
*F NEW_RANGE() . . . . . . . . . . . . . . . . . . . . . . make a new range
**
** 'NEW_RANGE' returns a new range. Note that you must set the length, the
** low value, and the increment before you can use the range.
** 'NEW_RANGE' returns a new range.
*/
EXPORT_INLINE Obj NEW_RANGE_NSORT(void)
{
return NewBag(T_RANGE_NSORT, 3 * sizeof(Obj));
}
Obj NEW_RANGE(Int len, Int low, Int inc);

EXPORT_INLINE Obj NEW_RANGE_SSORT(void)
{
return NewBag(T_RANGE_SSORT, 3 * sizeof(Obj));
}

/****************************************************************************
**
Expand Down
42 changes: 42 additions & 0 deletions tst/testlibgap/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,42 @@ void lists(void)
assert(ret == 0);
}

void ranges(void)
{
const int len = 5;
int i;
Obj r, val;

r = GAP_NewRange(len, 1, 1); // [1..5]
assert(GAP_IsList(r));
assert(GAP_LenList(r) == len);
for (i = 1; i <= len; ++i) {
val = GAP_ElmList(r, i);
assert(GAP_IsSmallInt(val));
assert(GAP_EQ(val, GAP_NewObjIntFromInt(i)));
}

r = GAP_NewRange(len, 1, 3); // [1,4..16]
assert(GAP_IsList(r));
assert(GAP_LenList(r) == len);
for (i = 1; i <= len; ++i) {
val = GAP_ElmList(r, i);
assert(GAP_IsSmallInt(val));
assert(GAP_EQ(val, GAP_NewObjIntFromInt(1 + (i-1) * 3)));
}


r = GAP_NewRange(len, 10, -2); // [10,8..2]
assert(GAP_IsList(r));
assert(GAP_LenList(r) == len);
for (i = 1; i <= len; ++i) {
val = GAP_ElmList(r, i);
assert(GAP_IsSmallInt(val));
assert(GAP_EQ(val, GAP_NewObjIntFromInt(10 - 2*(i-1))));
}

}

void matrices(void)
{
Obj mat, val, row, ret;
Expand Down Expand Up @@ -124,6 +160,8 @@ void integers(void)
assert(GAP_IsInt(i1));
assert(GAP_IsSmallInt(i1));
assert(!GAP_IsLargeInt(i1));
assert(GAP_EQ(i1, GAP_NewObjIntFromInt(0)));
assert(GAP_ValueInt(i1) == 0);

const UInt limbs2[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
i2 = GAP_MakeObjInt(limbs2, -8);
Expand Down Expand Up @@ -211,6 +249,10 @@ int main(int argc, char ** argv)
lists();
printf("success\n");

printf("# Testing ranges... ");
ranges();
printf("success\n");

printf("# Testing matrices... ");
matrices();
printf("success\n");
Expand Down
1 change: 1 addition & 0 deletions tst/testlibgap/api.expect
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Testing strings... success
# Testing records... success
# Testing lists... success
# Testing ranges... success
# Testing matrices... success
# Testing integers... success
# Testing operations... success
Expand Down