11# TODO : Make this file less loathsome.
22
3+ # These iterators are only somewhat useful.
4+ # The biggest issue is that we can't, at the moment, use one to change values in another.
5+ # So in place map! is doable like this, as is just simply getting values.
6+ # But if you wanted to say `C[I] = <transform>(A[I])` even with identical structures
7+ # there's no method. Non-identical patterns are off the table entirely.
8+
39abstract type IndexIteratorType end
410struct IndicesIterator <: IndexIteratorType end # return the indices as integers
511struct NeighborIterator <: IndexIteratorType end # Used only for Vector iterators
612struct NoIndexIterator <: IndexIteratorType end # Used when we don't want the indices, just the value
13+ struct IteratorIterator <: IndexIteratorType end # return the iterator object itself. Spooky!
714# just returns the free index, only useful for single column/row iterators.
815
916abstract type AbstractGBIterator end
@@ -143,13 +150,20 @@ end
143150 return unsafe_load (Ptr {T} (I. p. Ax[]), I. p. iso[] ? 1 : I. p. p[] + 1 )
144151end
145152
153+ @inline function setval (I:: GxBIterator{<:Any, T} , x:: T ) where T
154+ I. p. iso[] && throw (ArgumentError (" Cannot set value of iso valued matrix using iterator." ))
155+ unsafe_store! (Ptr {T} (I. p. Ax[]), x, I. p. p[] + 1 )
156+ end
157+
146158# TODO : Inelegant
147159@inline get_element (I:: GxBIterator{<:Any, <:Any, true, IndicesIterator()} ) = ((getrow (I), getcol (I)), getval (I))
148160@inline get_element (I:: GxBIterator{<:Any, <:Any, false, IndicesIterator()} ) = (getrow (I), getcol (I))
149161@inline get_element (I:: GxBIterator{<:Any, <:Any, true, NeighborIterator()} ) = (increment (_rc_geti (I)), getval (I))
150162@inline get_element (I:: GxBIterator{<:Any, <:Any, false, NeighborIterator()} ) = increment (_rc_geti (I))
151163@inline get_element (I:: GxBIterator{<:Any, <:Any, true, NoIndexIterator()} ) = getval (I)
152164@inline get_element (:: GxBIterator{<:Any, <:Any, false, NoIndexIterator()} ) = throw (ArgumentError (" Must iterate over either indices or values." ))
165+ @inline get_element (I:: GxBIterator{<:Any, <:Any, <:Any, IteratorIterator()} ) = I
166+
153167
154168struct VectorIterator{B, O, T, IterateValues, IterationType, I<: GxBIterator }
155169 iterator:: I
@@ -228,10 +242,14 @@ end
228242end
229243
230244get_element (I:: VectorIterator ) = get_element (I. iterator)
245+ get_element (I:: VectorIterator{<:Any, <:Any, <:Any, <:Any, IteratorIterator()} ) = I
231246
232247const RowIterator{B, T, IterateValues, IterationType} = VectorIterator{B, RowMajor (), T, IterateValues, IterationType}
233248const ColIterator{B, T, IterateValues, IterationType} = VectorIterator{B, ColMajor (), T, IterateValues, IterationType}
234249
250+ defaultiteration (:: Integer ) = NeighborIterator ()
251+ defaultiteration (:: AbstractVector ) = IndicesIterator ()
252+
235253RowIterator (A:: AbstractGBArray , v, iteratevalues:: Bool , indexiteration:: IndexIteratorType = NeighborIterator ()) =
236254 storageorder (A) === RowMajor () ? VectorIterator {iteratevalues, indexiteration} (A, v) :
237255 throw (ArgumentError (" A is not in RowMajor() order. Row iteration is only supported on RowMajor AbstractGBArrays. Try setstorageorder[!]" ))
@@ -255,4 +273,9 @@ iteraterows(A::AbstractGBArray, v, indexiteration::IndexIteratorType = NeighborI
255273function Base. iterate (I:: VectorIterator )
256274 return _seek (I. iterator, I. v isa Int64 ? I. v : I. v. start) == LibGraphBLAS. GrB_NO_VALUE ? knext (I) : (get_element (I), nothing )
257275end
258- Base. iterate (I:: VectorIterator , :: Nothing ) = inext (I)
276+ Base. iterate (I:: VectorIterator , :: Nothing ) = inext (I)
277+
278+ Base. getindex (A:: AbstractArray , I:: GxBIterator ) = getindex (A, getrow (I), getcol (I))
279+ Base. getindex (A:: AbstractArray , v:: VectorIterator ) = getindex (A, v. iterator)
280+ Base. setindex! (A:: AbstractArray , x, I:: GxBIterator ) = setindex! (A, x, getrow (I), getcol (I))
281+ Base. setindex! (A:: AbstractArray , x, v:: VectorIterator ) = setindex! (A, x, v. iterator)
0 commit comments