@@ -352,6 +352,16 @@ function copy_to_bitarray_chunks!{T<:Real}(Bc::Vector{UInt64}, pos_d::Int, C::Ar
352
352
end
353
353
end
354
354
355
+ # auxiliary definitions used when filling a BitArray via a Vector{Bool} cache
356
+ # (e.g. when constructing from an iterable, or in broadcast!)
357
+
358
+ const bitcache_chunks = 64 # this can be changed
359
+ const bitcache_size = 64 * bitcache_chunks # do not change this
360
+
361
+ dumpbitcache (Bc:: Vector{UInt64} , bind:: Int , C:: Vector{Bool} ) =
362
+ copy_to_bitarray_chunks! (Bc, ((bind - 1 ) << 6 ) + 1 , C, 1 , min (bitcache_size, (length (Bc)- bind+ 1 ) << 6 ))
363
+
364
+
355
365
# # custom iterator ##
356
366
start (B:: BitArray ) = 0
357
367
next (B:: BitArray , i:: Int ) = (B. chunks[_div64 (i)+ 1 ] & (UInt64 (1 )<< _mod64 (i)) != 0 , i+ 1 )
@@ -562,6 +572,90 @@ convert{T,N}(::Type{AbstractArray{T,N}}, B::BitArray{N}) = convert(Array{T,N}, B
562
572
reinterpret {N} (:: Type{Bool} , B:: BitArray , dims:: NTuple{N,Int} ) = reinterpret (B, dims)
563
573
reinterpret {N} (B:: BitArray , dims:: NTuple{N,Int} ) = reshape (B, dims)
564
574
575
+ # # Constructors from generic iterables ##
576
+
577
+ BitArray {T,N} (A:: AbstractArray{T,N} ) = convert (BitArray{N}, A)
578
+
579
+ BitArray (itr) = gen_bitarray (iteratorsize (itr), itr)
580
+
581
+ # generic constructor from an iterable without compile-time info
582
+ # (we pass start(itr) explicitly to avoid a type-instability with filters)
583
+ gen_bitarray (isz:: IteratorSize , itr) = gen_bitarray_from_itr (itr, start (itr))
584
+
585
+ # generic iterable with known shape
586
+ function gen_bitarray (:: HasShape , itr)
587
+ B = BitArray (size (itr))
588
+ for (I,x) in zip (CartesianRange (indices (itr)), itr)
589
+ B[I] = x
590
+ end
591
+ return B
592
+ end
593
+
594
+ # generator with known shape or length
595
+ function gen_bitarray (:: HasShape , itr:: Generator )
596
+ B = BitArray (size (itr))
597
+ return fill_bitarray_from_itr! (B, itr, start (itr))
598
+ end
599
+ function gen_bitarray (:: HasLength , itr)
600
+ n = length (itr)
601
+ B = BitArray (n)
602
+ return fill_bitarray_from_itr! (B, itr, start (itr))
603
+ end
604
+
605
+ gen_bitarray (:: IsInfinite , itr) = throw (ArgumentError (" infinite-size iterable used in BitArray constructor" ))
606
+
607
+ # The aux functions gen_bitarray_from_itr and fill_bitarray_from_itr! both
608
+ # use a Vector{Bool} cache for performance reasons
609
+
610
+ function gen_bitarray_from_itr (itr, st)
611
+ B = empty! (BitArray (bitcache_size))
612
+ C = Vector {Bool} (bitcache_size)
613
+ Bc = B. chunks
614
+ ind = 1
615
+ cind = 1
616
+ while ! done (itr, st)
617
+ x, st = next (itr, st)
618
+ @inbounds C[ind] = x
619
+ ind += 1
620
+ if ind > bitcache_size
621
+ resize! (B, length (B) + bitcache_size)
622
+ dumpbitcache (Bc, cind, C)
623
+ cind += bitcache_chunks
624
+ ind = 1
625
+ end
626
+ end
627
+ if ind > 1
628
+ @inbounds C[ind: bitcache_size] = false
629
+ resize! (B, length (B) + ind - 1 )
630
+ dumpbitcache (Bc, cind, C)
631
+ end
632
+ return B
633
+ end
634
+
635
+ function fill_bitarray_from_itr! (B:: BitArray , itr, st)
636
+ n = length (B)
637
+ C = Vector {Bool} (bitcache_size)
638
+ Bc = B. chunks
639
+ ind = 1
640
+ cind = 1
641
+ while ! done (itr, st)
642
+ x, st = next (itr, st)
643
+ @inbounds C[ind] = x
644
+ ind += 1
645
+ if ind > bitcache_size
646
+ dumpbitcache (Bc, cind, C)
647
+ cind += bitcache_chunks
648
+ ind = 1
649
+ end
650
+ end
651
+ if ind > 1
652
+ @inbounds C[ind: bitcache_size] = false
653
+ dumpbitcache (Bc, cind, C)
654
+ end
655
+ return B
656
+ end
657
+
658
+
565
659
# # Indexing: getindex ##
566
660
567
661
@inline function unsafe_bitgetindex (Bc:: Vector{UInt64} , i:: Int )
0 commit comments