Class: Range

Inherits:
Object show all
Defined in:
lib/vendor/backports-3.3.5/lib/backports/2.0.0/range/bsearch.rb

Instance Method Summary collapse

Instance Method Details

#bsearchObject



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/vendor/backports-3.3.5/lib/backports/2.0.0/range/bsearch.rb', line 3

def bsearch
  return to_enum(:bsearch) unless block_given?
  from = self.begin
  to   = self.end
  unless from.is_a?(Numeric) && to.is_a?(Numeric)
    raise TypeError, "can't do binary search for #{from.class}"
  end

  midpoint = nil
  if from.is_a?(Integer) && to.is_a?(Integer)
    convert = Proc.new{ midpoint }
  else
    map = Proc.new do |pk, unpk, nb|
      result, = [nb.abs].pack(pk).unpack(unpk)
      nb < 0 ? -result : result
    end
    from = map['D', 'q', to.to_f]
    to   = map['D', 'q', to.to_f]
    convert = Proc.new{ map['q', 'D', midpoint] }
  end
  to -= 1 if exclude_end?
  satisfied = nil
  while from <= to do
    midpoint = (from + to).div(2)
    result = yield(cur = convert.call)
    case result
    when Numeric
      return cur if result == 0
      result = result < 0
    when true
      satisfied = cur
    when nil, false
      # nothing to do
    else
      raise TypeError, "wrong argument type #{result.class} (must be numeric, true, false or nil)"
    end

    if result
      to = midpoint - 1
    else
      from = midpoint + 1
    end
  end
  satisfied
end