; docformat = 'rst' ;+ ; ; :Author: Paulo Penteado (pp.penteado@gmail.com), Sep/2009 ;- ;+ ; :Description: ; Creates a pp_buffered_vector object, with the contents of the given array, or empty ; if it is not provided. ; The buffered vector can contain elements of any type. The type is determined by the type of ; the first element put into it (if not at initialization, at the first append operation). ; ; :Params: ; initvec : in, optional ; An array whose elements are to be placed in the object on creation. ; ; :Keywords: ; buffersize : in, optional, default=100 ; Size of the step to use when incrementing the number of elements contained by the object. ; ; :Examples: ; See the example in pp_bufferedvector__define. ; ; :Uses: ; ; :Author: Paulo Penteado (pp.penteado@gmail.com), Oct/2009 ;- function pp_buffered_vector::init,initvec,buffersize=buffersize compile_opt idl2,hidden ;Defaults if (n_elements(buffersize) ne 1) then buffersize=100 ret=0 self.buffersize=buffersize ;If an initializer is provided, put its elements into the vector self.count=n_elements(initvec) if (self.count gt 0) then begin self.size=buffersize*ceil(double(self.count)/buffersize) self.data=ptr_new(replicate(initvec[0],self.size)) (*self.data)[0]=reform(initvec,self.count) endif ret=1 return,ret end ;+ ; :Hidden: ;- pro pp_buffered_vector::cleanup compile_opt idl2,hidden ;Clear the heap variable that contained the data ptr_free,self.data end ;+ ; :Description: ; Adds the given data (scalar or array) to the end of the buffered vector, expanding ; its allocated size if necessary. ; ; :Params: ; data : in, required ; The scalar or array to be put at the end of the buffered vector. ; ; :Examples: ; See the example in pp_bufferedvector__define. ; ; :Uses: ; ; :Author: Paulo Penteado (pp.penteado@gmail.com), Oct/2009 ;- pro pp_buffered_vector::append,data compile_opt idl2,hidden ndata=n_elements(data) if (ndata eq 0) then return ;If nothing to add ;catch,error_status error_status=0 if (error_status ne 0) then begin catch,/cancel ;If an error is caught, nothing gets changed and the object is still valid if (self.size ne oldsize) then begin ;Undo the resizing if the assignment failed self.size=oldsize ptr_free,self.data self.data=ptr_new(olddata) endif print,'pp_buffered_vector: Provided data could not be appended' endif else begin if (self.size ge self.count+ndata) then (*self.data)[self.count]=reform(data,ndata) else begin ;Resizing, if needed oldsize=self.size self.size=self.buffersize*ceil(double(oldsize+ndata)/self.buffersize) if (oldsize gt 0) then begin olddata=*self.data ptr_free,self.data self.data=ptr_new(replicate(olddata[0],self.size)) (*self.data)[0]=olddata endif else self.data=ptr_new(replicate(data[0],self.size)) (*self.data)[self.count]=reform(data,ndata) endelse self.count=self.count+ndata endelse catch,/cancel end ;+ ; :Description: ; Retrieves one or more data elements currently stored in the buffered vector. ; ; :Returns: ; If the buffered vector is empty, returns 0, with a count of 0. Otherwise, returns an array with ; the selected elements from the buffered vector, and the number of elements in count. ; ; :Params: ; nget : in, optional, default=1 ; The number of elements to retrieve. If positive, the nget first elements are returned. If ; negative, the last -nget elements are returned. If abs(nget) is larger than the number of ; elements in the buffered vector, all the elements are returned. The value returned by count ; must be checked to find out how many elements were actually returned. ; ; :Keywords: ; all : in, optional, default=0 ; If set, all the elements stored in the buffered vector are returned. ; count : out, optional ; Returns the number of elements retrieved. ; ; :Examples: ; See the example in pp_bufferedvector__define. ; ; :Uses: ; ; :Author: Paulo Penteado (pp.penteado@gmail.com), Oct/2009 ;- function pp_buffered_vector::getdata,nget,all=all,count=count compile_opt idl2,hidden ;Defaults if (n_elements(nget) ne 1) then nget=1 count=0 ret=0 if keyword_set(all) then begin if (self.count gt 0) then ret=(*self.data)[0:self.count-1] count=self.count endif else begin if (nget lt 0) then begin ;Get the -nget last elements count=(-nget)<self.count ret=(*self.data)[self.count-count:self.count-1] endif else if (nget gt 0) then begin ;Get the nget first elements count=nget<self.count ret=(*self.data)[0:count-1] endif endelse return,ret end ;+ ; :Description: ; Returns the number of elements currently stored in the buffered vector. ; ; :Examples: ; See the example in pp_bufferedvector__define. ; ; :Uses: ; ; :Author: Paulo Penteado (pp.penteado@gmail.com), Oct/2009 ;- function pp_buffered_vector::getcount compile_opt idl2,hidden return,self.count end ;+ ; :Description: ; Returns the currently allocated length for the buffered vector. ; ; :Examples: ; See the example in pp_bufferedvector__define. ; ; :Uses: ; ; :Author: Paulo Penteado (pp.penteado@gmail.com), Oct/2009 ;- function pp_buffered_vector::getsize compile_opt idl2,hidden return,self.size end ;+ ; :Description: ; Returns the step by which the buffered vector is incremented when necessary. ; ; :Examples: ; See the example in pp_bufferedvector__define. ; ; :Uses: ; ; :Author: Paulo Penteado (pp.penteado@gmail.com), Oct/2009 ;- function pp_buffered_vector::getbuffersize compile_opt idl2 return,self.buffersize end ;+ ; :Description: ; Object to keep an adjustable length vector, using a buffer to decrease the frequency of resizing ; ; It is a simple (without DLM) and relatively efficient implementation of a container similar to a list, ; intended for light use. For heavy use, it would take a DLM to implement a proper list. ; ; :Examples: ; Make a new empty buffered vector:: ; ; a=obj_new('pp_buffered_vector') ; print,a->getcount() ; ;0 ; a->append,indgen(10) ; print,a->getcount() ; ;10 ; print,a->getdata(5) ; ;0 1 2 3 4 ; rint,a->getdata(-5) ; ;5 6 7 8 9 ; print,a->getdata(/all) ; ;0 1 2 3 4 5 6 7 8 9 ; print,a->getsize() ; ;100 ; print,a->getbuffersize() ; ;100 ; obj_destroy,a ; ; :Uses: ; ; :Author: Paulo Penteado (pp.penteado@gmail.com), Sep/2009 ;- pro pp_buffered_vector__define compile_opt idl2 ;Object to keep an adjustable length vector, using a buffer to decrease the frequency of resizing ;It is a simple and relatively efficient implementation of a container similar to a list void={pp_buffered_vector,count:0L,data:ptr_new(),buffersize:0L,size:0L} end