Sha256: 69c54cf7503471b541497da0e6d5211f44c2664030d0daa4b01e095da5804b2d

Contents?: true

Size: 1.3 KB

Versions: 3

Compression:

Stored size: 1.3 KB

Contents

unless Range.method_defined? :bsearch
  class Range
    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', from.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
  end
end

Version data entries

3 entries across 3 versions & 2 rubygems

Version Path
mdg-1.0.1 vendor/bundle/ruby/2.3.0/gems/backports-3.6.8/lib/backports/2.0.0/range/bsearch.rb
backports-3.6.8 lib/backports/2.0.0/range/bsearch.rb
backports-3.6.7 lib/backports/2.0.0/range/bsearch.rb