Skip to content

Commit

Permalink
Add CallListFuncWrap
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisJefferson authored and fingolfin committed Jan 24, 2017
1 parent 2840c81 commit 1986893
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 6 deletions.
13 changes: 13 additions & 0 deletions lib/function.g
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ end);
## <#GAPDoc Label="CallFuncList">
## <ManSection>
## <Oper Name="CallFuncList" Arg='func, args'/>
## <Oper Name="CallFuncListWrap" Arg='func, args'/>
##
## <Description>
## returns the result, when calling function <A>func</A> with the arguments
Expand Down Expand Up @@ -415,6 +416,17 @@ end);
## gap> PrintDigits( 1, 9, 7, 3, 2 );
## [ 1, 9, 7, 3, 2 ]
## ]]></Example>
## <Ref Oper="CallFuncListWrap"/> differs only in that the result is a list.
## This returned list is empty if the called function returned no value,
## else it contains the returned value as it's single member. This allows
## wrapping functions which may, or may not return a value.
##
## <Example><![CDATA[
## gap> CallFuncListWrap( x -> x, [1] );
## [ 1 ]
## gap> CallFuncListWrap( function(x) end, [1] );
## [ ]
## ]]></Example>
## </Description>
## </ManSection>
## <#/GAPDoc>
Expand All @@ -423,6 +435,7 @@ end);
##
UNBIND_GLOBAL("CallFuncList"); # was declared 2b defined
DeclareOperationKernel( "CallFuncList", [IS_OBJECT, IS_LIST], CALL_FUNC_LIST );
DeclareOperationKernel( "CallFuncListWrap", [IS_OBJECT, IS_LIST], CALL_FUNC_LIST_WRAP );


#############################################################################
Expand Down
40 changes: 34 additions & 6 deletions src/calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1513,6 +1513,7 @@ Obj FuncCALL_FUNC (
** i.e., it is equivalent to '<func>( <list>[1], <list>[2]... )'.
*/
Obj CallFuncListOper;
Obj CallFuncListWrapOper;

Obj CallFuncList ( Obj func, Obj list )
{
Expand Down Expand Up @@ -1574,16 +1575,39 @@ Obj FuncCALL_FUNC_LIST (
Obj func,
Obj list )
{
/* check that the second argument is a list */
while ( ! IS_SMALL_LIST( list ) ) {
list = ErrorReturnObj(
"CallFuncList: <list> must be a small list",
0L, 0L,
"you can replace <list> via 'return <list>;'" );
/* check that the second argument is a list */
if ( ! IS_SMALL_LIST( list ) ) {
ErrorMayQuit("CallFuncList: <list> must be a small list", 0L, 0L);
}
return CallFuncList(func, list);
}

Obj FuncCALL_FUNC_LIST_WRAP (
Obj self,
Obj func,
Obj list )
{
Obj retval, retlist;
/* check that the second argument is a list */
if ( ! IS_SMALL_LIST( list ) ) {
ErrorMayQuit("CallFuncListWrap: <list> must be a small list", 0L, 0L);
}
retval = CallFuncList(func, list);

if (retval == 0)
{
retlist = NEW_PLIST(T_PLIST_EMPTY + IMMUTABLE, 0);
}
else
{
retlist = NEW_PLIST(T_PLIST, 1);
SET_LEN_PLIST(retlist, 1);
SET_ELM_PLIST(retlist, 1, retval);
CHANGED_BAG(retlist);
}
return retlist;
}

/****************************************************************************
**
Expand Down Expand Up @@ -2017,6 +2041,9 @@ static StructGVarOper GVarOpers [] = {
{ "CALL_FUNC_LIST", 2, "func, list", &CallFuncListOper,
FuncCALL_FUNC_LIST, "src/calls.c:CALL_FUNC_LIST" },

{ "CALL_FUNC_LIST_WRAP", 2, "func, list", &CallFuncListWrapOper,
FuncCALL_FUNC_LIST_WRAP, "src/calls.c:CALL_FUNC_LIST_WRAP" },

{ "NAME_FUNC", 1, "func", &NAME_FUNC_Oper,
FuncNAME_FUNC, "src/calls.c:NAME_FUNC" },

Expand Down Expand Up @@ -2073,6 +2100,7 @@ static StructGVarFunc GVarFuncs [] = {

{ "ENDLINE_FUNC", 1, "func",
FuncENDLINE_FUNC, "src/calls.c:ENDLINE_FUNC" },

{ 0 }

};
Expand Down
24 changes: 24 additions & 0 deletions tst/testinstall/callfunc.tst
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
gap> START_TEST("callfunc.tst");

# Union([1]) = 1 :(
gap> ForAll([0,2..100], x -> [1..x] = CallFuncList(Union, List([1..x], y -> [y]) ) );
true
gap> CallFuncList(Group, [ (1,2) ]) = Group((1,2));
true
gap> ForAll([0,2..100], x -> [[1..x]] = CallFuncListWrap(Union, List([1..x], y -> [y]) ) );
true
gap> CallFuncListWrap(Group, [ (1,2) ]) = [ Group((1,2)) ];
true
gap> CallFuncList(Group, [ (1,2) ]) = Group((1,2)) ;
true
gap> CallFuncList(Group, [ (1,2) ]) = Group((1,2)) ;
true
gap> l := [];;
gap> CallFuncList(Add, [ l, 2 ] );
gap> CallFuncList(Add, [ l, 3, 4] );
gap> l = [2,,,3];
true
gap> swallow := function(x...) end;;
gap> ForAll([0..100], x -> CallFuncListWrap(swallow, List([1..x], y -> [y]) ) = [] );
true
gap> STOP_TEST( "callfunc.tst", 1);

0 comments on commit 1986893

Please sign in to comment.