123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219(*
* ExtList - additional and modified functions for lists.
* Copyright (C) 2005 Richard W.M. Jones (rich @ annexia.org)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version,
* with the special exception on linking described in file LICENSE.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*)moduleArray=struct#ifOCAML<408type'at='aarray#endifincludeArrayletrev_in_placexs=letn=lengthxsinletj=ref(n-1)infori=0ton/2-1doletc=xs.(i)inxs.(i)<-xs.(!j);xs.(!j)<-c;decrjdoneletrevxs=letys=Array.copyxsinrev_in_placeys;ys#ifOCAML<403letfor_allpxs=letn=lengthxsinlet recloopi=ifi=nthentrueelse ifpxs.(i)thenloop(succi)elsefalseinloop0exceptionExistsletexistspxs =tryfori=0toArray.lengthxs-1doifpxs.(i)thenraiseExistsdone;falsewithExists->trueletmemaxs=letn=lengthxsinletrecloopi=ifi=nthenfalseelseifa=xs.(i)thentrueelseloop(succi)inloop0letmemqaxs=letn=lengthxsinletrecloopi=ifi=nthenfalseelseifa== xs.(i)thentrueelseloop(succi)inloop0#endifletfindipxs=letn=lengthxsinletrecloopi=ifi=nthenraiseNot_foundelseifpxs.(i)thenielseloop(succi)inloop 0letfindpxs=xs.(findipxs)(* Use of BitSet suggested by Brian Hurt. *)letfilterpxs=letn=lengthxsin(* Use a bitset to store which elements will be in thefinal array. *)letbs=BitSet.createninfori=0ton-1doifpxs.(i)thenBitSet.setbsidone;(* Allocate the final array and copy elements into it. *)letn'=BitSet.countbsinletj=ref0inletxs'=initn'(fun_->(* Find the next set bit in the BitSet. *)whilenot(BitSet.is_set bs!j)doincrjdone;letr=xs.(!j)inincrj;r)inxs'letfind_all=filter#ifOCAML<411letfor_all2pl1l2=letn1=lengthl1andn2=lengthl2inifn1<>n2theninvalid_arg"Array.for_all2"elseletrecloopi=ifi=n1thentrueelseifp(unsafe_getl1i)(unsafe_getl2i)thenloop(succi)elsefalseinloop0letexists2pl1l2=letn1=lengthl1andn2=lengthl2inifn1<>n2theninvalid_arg"Array.exists2"elseletrecloopi=ifi=n1thenfalseelseifp(unsafe_getl1i)(unsafe_getl2i)then trueelseloop(succi)inloop0#endifletpartitionpxs=letn=lengthxsin(* Use a bitset to store which elements will be in which final array. *)letbs=BitSet.createninfori=0ton-1doifpxs.(i)thenBitSet.setbsidone;(* Allocate the final arrays and copy elements into them. *)letn1=BitSet.countbsinlet n2=n-n1inletj=ref0inletxs1=initn1(fun_->(* Find the next set bit in the BitSet. *)whilenot(BitSet.is_setbs!j)doincrjdone;letr=xs.(!j)inincrj;r)inletj=ref0inletxs2=initn2(fun_->(* Find the next clear bit in the BitSet. *)whileBitSet.is_setbs!jdoincrjdone;letr=xs.(!j)inincrj;r)inxs1,xs2letenumxs=letrecmakestartxs=letn=lengthxsinEnum.make~next:(fun()->if!start<nthen(letr=xs.(!start)inincrstart;r)elseraiseEnum.No_more_elements)~count:(fun()->n-!start)~clone:(fun()->letxs'=Array.subxs!start(n-!start)inmake(ref0)xs')inmake(ref0)xsletof_enume=letn=Enum.countein(* This assumes, reasonably, that init traverses the array in order. *)Array.initn(funi->matchEnum.getewith|Somex->x|None->assertfalse)#ifOCAML<403letiter2fa1a2=ifArray.lengtha1<>Array.lengtha2thenraise(Invalid_argument"Array.iter2");fori=0toArray.lengtha1-1dofa1.(i)a2.(i);doneletmap2fa1a2=ifArray.lengtha1<>Array.lengtha2thenraise(Invalid_argument"Array.map2");Array.init(Array.lengtha1)(funi->fa1.(i)a2.(i))#endif#ifOCAML<403letcreate_float=make_float#endif#ifOCAML>=500externalcreate:int->'a->'aarray="caml_make_vect"letcreate_matrix=make_matrixletmake_float=create_float#endifend