@@ -392,12 +392,19 @@ be 1.
392
392
"""
393
393
struct OneTo{T<: Integer } <: AbstractUnitRange{T}
394
394
stop:: T
395
- OneTo {T} (stop) where {T<: Integer } = new (max (zero (T), stop))
395
+ function OneTo {T} (stop) where {T<: Integer }
396
+ throwbool (r) = (@_noinline_meta ; throw (ArgumentError (" invalid index: $r of type Bool" )))
397
+ T === Bool && throwbool (stop)
398
+ return new (max (zero (T), stop))
399
+ end
400
+
396
401
function OneTo {T} (r:: AbstractRange ) where {T<: Integer }
397
402
throwstart (r) = (@_noinline_meta ; throw (ArgumentError (" first element must be 1, got $(first (r)) " )))
398
403
throwstep (r) = (@_noinline_meta ; throw (ArgumentError (" step must be 1, got $(step (r)) " )))
404
+ throwbool (r) = (@_noinline_meta ; throw (ArgumentError (" invalid index: $r of type Bool" )))
399
405
first (r) == 1 || throwstart (r)
400
406
step (r) == 1 || throwstep (r)
407
+ T === Bool && throwbool (r)
401
408
return new (max (zero (T), last (r)))
402
409
end
403
410
end
@@ -748,6 +755,7 @@ _in_unit_range(v::UnitRange, val, i::Integer) = i > 0 && val <= v.stop && val >=
748
755
749
756
function getindex (v:: UnitRange{T} , i:: Integer ) where T
750
757
@_inline_meta
758
+ i isa Bool && throw (ArgumentError (" invalid index: $i of type Bool" ))
751
759
val = convert (T, v. start + (i - 1 ))
752
760
@boundscheck _in_unit_range (v, val, i) || throw_boundserror (v, i)
753
761
val
@@ -758,19 +766,22 @@ const OverflowSafe = Union{Bool,Int8,Int16,Int32,Int64,Int128,
758
766
759
767
function getindex (v:: UnitRange{T} , i:: Integer ) where {T<: OverflowSafe }
760
768
@_inline_meta
769
+ i isa Bool && throw (ArgumentError (" invalid index: $i of type Bool" ))
761
770
val = v. start + (i - 1 )
762
771
@boundscheck _in_unit_range (v, val, i) || throw_boundserror (v, i)
763
772
val % T
764
773
end
765
774
766
775
function getindex (v:: OneTo{T} , i:: Integer ) where T
767
776
@_inline_meta
777
+ i isa Bool && throw (ArgumentError (" invalid index: $i of type Bool" ))
768
778
@boundscheck ((i > 0 ) & (i <= v. stop)) || throw_boundserror (v, i)
769
779
convert (T, i)
770
780
end
771
781
772
782
function getindex (v:: AbstractRange{T} , i:: Integer ) where T
773
783
@_inline_meta
784
+ i isa Bool && throw (ArgumentError (" invalid index: $i of type Bool" ))
774
785
ret = convert (T, first (v) + (i - 1 )* step_hp (v))
775
786
ok = ifelse (step (v) > zero (step (v)),
776
787
(ret <= last (v)) & (ret >= first (v)),
@@ -781,22 +792,26 @@ end
781
792
782
793
function getindex (r:: Union{StepRangeLen,LinRange} , i:: Integer )
783
794
@_inline_meta
795
+ i isa Bool && throw (ArgumentError (" invalid index: $i of type Bool" ))
784
796
@boundscheck checkbounds (r, i)
785
797
unsafe_getindex (r, i)
786
798
end
787
799
788
800
# This is separate to make it useful even when running with --check-bounds=yes
789
801
function unsafe_getindex (r:: StepRangeLen{T} , i:: Integer ) where T
802
+ i isa Bool && throw (ArgumentError (" invalid index: $i of type Bool" ))
790
803
u = i - r. offset
791
804
T (r. ref + u* r. step)
792
805
end
793
806
794
807
function _getindex_hiprec (r:: StepRangeLen , i:: Integer ) # without rounding by T
808
+ i isa Bool && throw (ArgumentError (" invalid index: $i of type Bool" ))
795
809
u = i - r. offset
796
810
r. ref + u* r. step
797
811
end
798
812
799
813
function unsafe_getindex (r:: LinRange , i:: Integer )
814
+ i isa Bool && throw (ArgumentError (" invalid index: $i of type Bool" ))
800
815
lerpi (i- 1 , r. lendiv, r. start, r. stop)
801
816
end
802
817
@@ -808,12 +823,27 @@ end
808
823
809
824
getindex (r:: AbstractRange , :: Colon ) = copy (r)
810
825
811
- function getindex (r:: AbstractUnitRange , s:: AbstractUnitRange{<:Integer} )
826
+ function getindex (r:: AbstractUnitRange , s:: AbstractUnitRange{T} ) where {T <: Integer }
812
827
@_inline_meta
813
828
@boundscheck checkbounds (r, s)
814
- f = first (r)
815
- st = oftype (f, f + first (s)- 1 )
816
- range (st, length= length (s))
829
+
830
+ if T === Bool
831
+ if length (s) == 0
832
+ return r
833
+ elseif length (s) == 1
834
+ if first (s)
835
+ return r
836
+ else
837
+ return range (r[1 ], length= 0 )
838
+ end
839
+ else # length(s) == 2
840
+ return range (r[2 ], length= 1 )
841
+ end
842
+ else
843
+ f = first (r)
844
+ st = oftype (f, f + first (s)- 1 )
845
+ return range (st, length= length (s))
846
+ end
817
847
end
818
848
819
849
function getindex (r:: OneTo{T} , s:: OneTo ) where T
@@ -822,36 +852,96 @@ function getindex(r::OneTo{T}, s::OneTo) where T
822
852
OneTo (T (s. stop))
823
853
end
824
854
825
- function getindex (r:: AbstractUnitRange , s:: StepRange{<:Integer} )
855
+ function getindex (r:: AbstractUnitRange , s:: StepRange{T} ) where {T <: Integer }
826
856
@_inline_meta
827
857
@boundscheck checkbounds (r, s)
828
- st = oftype (first (r), first (r) + s. start- 1 )
829
- range (st, step= step (s), length= length (s))
858
+
859
+ if T === Bool
860
+ if length (s) == 0
861
+ return range (first (r), step= one (eltype (r)), length= 0 )
862
+ elseif length (s) == 1
863
+ if first (s)
864
+ return range (first (r), step= one (eltype (r)), length= 1 )
865
+ else
866
+ return range (first (r), step= one (eltype (r)), length= 0 )
867
+ end
868
+ else # length(s) == 2
869
+ return range (r[2 ], step= one (eltype (r)), length= 1 )
870
+ end
871
+ else
872
+ st = oftype (first (r), first (r) + s. start- 1 )
873
+ return range (st, step= step (s), length= length (s))
874
+ end
830
875
end
831
876
832
- function getindex (r:: StepRange , s:: AbstractRange{<:Integer} )
877
+ function getindex (r:: StepRange , s:: AbstractRange{T} ) where {T <: Integer }
833
878
@_inline_meta
834
879
@boundscheck checkbounds (r, s)
835
- st = oftype (r. start, r. start + (first (s)- 1 )* step (r))
836
- range (st, step= step (r)* step (s), length= length (s))
880
+
881
+ if T === Bool
882
+ if length (s) == 0
883
+ return range (first (r), step= step (r), length= 0 )
884
+ elseif length (s) == 1
885
+ if first (s)
886
+ return range (first (r), step= step (r), length= 1 )
887
+ else
888
+ return range (first (r), step= step (r), length= 0 )
889
+ end
890
+ else # length(s) == 2
891
+ return range (r[2 ], step= step (r), length= 1 )
892
+ end
893
+ else
894
+ st = oftype (r. start, r. start + (first (s)- 1 )* step (r))
895
+ return range (st, step= step (r)* step (s), length= length (s))
896
+ end
837
897
end
838
898
839
- function getindex (r:: StepRangeLen{T} , s:: OrdinalRange{<:Integer } ) where {T}
899
+ function getindex (r:: StepRangeLen{T} , s:: OrdinalRange{S } ) where {T, S <: Integer }
840
900
@_inline_meta
841
901
@boundscheck checkbounds (r, s)
842
- # Find closest approach to offset by s
843
- ind = LinearIndices (s)
844
- offset = max (min (1 + round (Int, (r. offset - first (s))/ step (s)), last (ind)), first (ind))
845
- ref = _getindex_hiprec (r, first (s) + (offset- 1 )* step (s))
846
- return StepRangeLen {T} (ref, r. step* step (s), length (s), offset)
902
+
903
+ if S === Bool
904
+ if length (s) == 0
905
+ return StepRangeLen {T} (first (r), step (r), 0 , 1 )
906
+ elseif length (s) == 1
907
+ if first (s)
908
+ return StepRangeLen {T} (first (r), step (r), 1 , 1 )
909
+ else
910
+ return StepRangeLen {T} (first (r), step (r), 0 , 1 )
911
+ end
912
+ else # length(s) == 2
913
+ return StepRangeLen {T} (r[2 ], step (r), 1 , 1 )
914
+ end
915
+ else
916
+ # Find closest approach to offset by s
917
+ ind = LinearIndices (s)
918
+ offset = max (min (1 + round (Int, (r. offset - first (s))/ step (s)), last (ind)), first (ind))
919
+ ref = _getindex_hiprec (r, first (s) + (offset- 1 )* step (s))
920
+ return StepRangeLen {T} (ref, r. step* step (s), length (s), offset)
921
+ end
847
922
end
848
923
849
- function getindex (r:: LinRange{T} , s:: OrdinalRange{<:Integer } ) where {T}
924
+ function getindex (r:: LinRange{T} , s:: OrdinalRange{S } ) where {T, S <: Integer }
850
925
@_inline_meta
851
926
@boundscheck checkbounds (r, s)
852
- vfirst = unsafe_getindex (r, first (s))
853
- vlast = unsafe_getindex (r, last (s))
854
- return LinRange {T} (vfirst, vlast, length (s))
927
+
928
+ if S === Bool
929
+ if length (s) == 0
930
+ return LinRange (first (r), first (r), 0 )
931
+ elseif length (s) == 1
932
+ if first (s)
933
+ return LinRange (first (r), first (r), 1 )
934
+ else
935
+ return LinRange (first (r), first (r), 0 )
936
+ end
937
+ else # length(s) == 2
938
+ return LinRange (r[2 ], r[2 ], 1 )
939
+ end
940
+ else
941
+ vfirst = unsafe_getindex (r, first (s))
942
+ vlast = unsafe_getindex (r, last (s))
943
+ return LinRange {T} (vfirst, vlast, length (s))
944
+ end
855
945
end
856
946
857
947
show (io:: IO , r:: AbstractRange ) = print (io, repr (first (r)), ' :' , repr (step (r)), ' :' , repr (last (r)))
0 commit comments