alib 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/a.rb +1 -0
- data/alib-0.4.0.gem +0 -0
- data/b.rb +1 -0
- data/build +0 -0
- data/gemspec.rb +23 -0
- data/install +143 -0
- data/install.rb +143 -0
- data/lib/alib-0.4.0.rb +104 -0
- data/lib/alib-0.4.0/autohash.rb +11 -0
- data/lib/alib-0.4.0/bsearch.rb +255 -0
- data/lib/alib-0.4.0/configfile.rb +113 -0
- data/lib/alib-0.4.0/find2.rb +294 -0
- data/lib/alib-0.4.0/listfile.rb +42 -0
- data/lib/alib-0.4.0/logging.rb +152 -0
- data/lib/alib-0.4.0/main.rb +594 -0
- data/lib/alib-0.4.0/open4.rb +175 -0
- data/lib/alib-0.4.0/orderedautohash.rb +23 -0
- data/lib/alib-0.4.0/orderedhash.rb +243 -0
- data/lib/alib-0.4.0/util.rb +1167 -0
- data/lib/alib.rb +63 -3831
- metadata +23 -3
- data/lib/alib-0.3.1.rb +0 -3872
data/alib-0.4.0.gem
ADDED
File without changes
|
data/build
ADDED
File without changes
|
data/gemspec.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
lib, version = File::basename(File::dirname(File::expand_path(__FILE__))).split %r/-/, 2
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
Gem::Specification::new do |spec|
|
6
|
+
spec.name = lib
|
7
|
+
spec.version = version
|
8
|
+
spec.platform = Gem::Platform::RUBY
|
9
|
+
spec.summary = lib
|
10
|
+
|
11
|
+
spec.files = Dir::glob "**/**"
|
12
|
+
spec.executables = Dir::glob("bin/*").map{|exe| File::basename exe}
|
13
|
+
|
14
|
+
spec.require_path = "lib"
|
15
|
+
spec.autorequire = lib
|
16
|
+
|
17
|
+
spec.has_rdoc = File::exist? "doc"
|
18
|
+
spec.test_suite_file = "test/#{ lib }.rb" if File::directory? "test"
|
19
|
+
|
20
|
+
spec.author = "Ara T. Howard"
|
21
|
+
spec.email = "ara.t.howard@noaa.gov"
|
22
|
+
spec.homepage = "http://codeforpeople.com/lib/ruby/#{ lib }/"
|
23
|
+
end
|
data/install
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rbconfig'
|
3
|
+
require 'find'
|
4
|
+
require 'ftools'
|
5
|
+
require 'tempfile'
|
6
|
+
include Config
|
7
|
+
|
8
|
+
LIBDIR = "lib"
|
9
|
+
LIBDIR_MODE = 0644
|
10
|
+
|
11
|
+
BINDIR = "bin"
|
12
|
+
BINDIR_MODE = 0755
|
13
|
+
|
14
|
+
|
15
|
+
$srcdir = CONFIG["srcdir"]
|
16
|
+
$version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
|
17
|
+
$libdir = File.join(CONFIG["libdir"], "ruby", $version)
|
18
|
+
$archdir = File.join($libdir, CONFIG["arch"])
|
19
|
+
$site_libdir = $:.find {|x| x =~ /site_ruby$/}
|
20
|
+
$bindir = CONFIG["bindir"]
|
21
|
+
$ruby_install_name = CONFIG['ruby_install_name'] || CONFIG['RUBY_INSTALL_NAME']
|
22
|
+
$ruby = File.join($bindir, $ruby_install_name || 'ruby')
|
23
|
+
|
24
|
+
if !$site_libdir
|
25
|
+
$site_libdir = File.join($libdir, "site_ruby")
|
26
|
+
elsif $site_libdir !~ %r/#{Regexp.quote($version)}/
|
27
|
+
$site_libdir = File.join($site_libdir, $version)
|
28
|
+
end
|
29
|
+
|
30
|
+
def install_rb(srcdir=nil, destdir=nil, mode=nil, bin=nil)
|
31
|
+
#{{{
|
32
|
+
path = []
|
33
|
+
dir = []
|
34
|
+
Find.find(srcdir) do |f|
|
35
|
+
next unless FileTest.file?(f)
|
36
|
+
next if (f = f[srcdir.length+1..-1]) == nil
|
37
|
+
next if (/CVS$/ =~ File.dirname(f))
|
38
|
+
path.push f
|
39
|
+
dir |= [File.dirname(f)]
|
40
|
+
end
|
41
|
+
for f in dir
|
42
|
+
next if f == "."
|
43
|
+
next if f == "CVS"
|
44
|
+
File::makedirs(File.join(destdir, f))
|
45
|
+
end
|
46
|
+
for f in path
|
47
|
+
next if (/\~$/ =~ f)
|
48
|
+
next if (/^\./ =~ File.basename(f))
|
49
|
+
unless bin
|
50
|
+
File::install(File.join(srcdir, f), File.join(destdir, f), mode, true)
|
51
|
+
else
|
52
|
+
from = File.join(srcdir, f)
|
53
|
+
to = File.join(destdir, f)
|
54
|
+
shebangify(from) do |sf|
|
55
|
+
$deferr.print from, " -> ", File::catname(from, to), "\n"
|
56
|
+
$deferr.printf "chmod %04o %s\n", mode, to
|
57
|
+
File::install(sf, to, mode, false)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
#}}}
|
62
|
+
end
|
63
|
+
def shebangify f
|
64
|
+
#{{{
|
65
|
+
open(f) do |fd|
|
66
|
+
buf = fd.read 42
|
67
|
+
if buf =~ %r/^\s*#\s*!.*ruby/o
|
68
|
+
ftmp = Tempfile::new("#{ $$ }_#{ File::basename(f) }")
|
69
|
+
begin
|
70
|
+
fd.rewind
|
71
|
+
ftmp.puts "#!#{ $ruby }"
|
72
|
+
while((buf = fd.read(8192)))
|
73
|
+
ftmp.write buf
|
74
|
+
end
|
75
|
+
ftmp.close
|
76
|
+
yield ftmp.path
|
77
|
+
ensure
|
78
|
+
ftmp.close!
|
79
|
+
end
|
80
|
+
else
|
81
|
+
yield f
|
82
|
+
end
|
83
|
+
end
|
84
|
+
#}}}
|
85
|
+
end
|
86
|
+
def ARGV.switch
|
87
|
+
#{{{
|
88
|
+
return nil if self.empty?
|
89
|
+
arg = self.shift
|
90
|
+
return nil if arg == '--'
|
91
|
+
if arg =~ /^-(.)(.*)/
|
92
|
+
return arg if $1 == '-'
|
93
|
+
raise 'unknown switch "-"' if $2.index('-')
|
94
|
+
self.unshift "-#{$2}" if $2.size > 0
|
95
|
+
"-#{$1}"
|
96
|
+
else
|
97
|
+
self.unshift arg
|
98
|
+
nil
|
99
|
+
end
|
100
|
+
#}}}
|
101
|
+
end
|
102
|
+
def ARGV.req_arg
|
103
|
+
#{{{
|
104
|
+
self.shift || raise('missing argument')
|
105
|
+
#}}}
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
#
|
110
|
+
# main program
|
111
|
+
#
|
112
|
+
|
113
|
+
libdir = $site_libdir
|
114
|
+
bindir = $bindir
|
115
|
+
|
116
|
+
begin
|
117
|
+
while switch = ARGV.switch
|
118
|
+
case switch
|
119
|
+
when '-d', '--destdir'
|
120
|
+
libdir = ARGV.req_arg
|
121
|
+
when '-l', '--libdir'
|
122
|
+
libdir = ARGV.req_arg
|
123
|
+
when '-b', '--bindir'
|
124
|
+
bindir = ARGV.req_arg
|
125
|
+
when '-r', '--ruby'
|
126
|
+
$ruby = ARGV.req_arg
|
127
|
+
else
|
128
|
+
raise "unknown switch #{switch.dump}"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
rescue
|
132
|
+
STDERR.puts $!.to_s
|
133
|
+
STDERR.puts File.basename($0) +
|
134
|
+
" -d <destdir>" +
|
135
|
+
" -l <libdir>" +
|
136
|
+
" -b <bindir>"
|
137
|
+
" -r <ruby>"
|
138
|
+
exit 1
|
139
|
+
end
|
140
|
+
|
141
|
+
install_rb(LIBDIR, libdir, LIBDIR_MODE)
|
142
|
+
install_rb(BINDIR, bindir, BINDIR_MODE, bin=true)
|
143
|
+
|
data/install.rb
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rbconfig'
|
3
|
+
require 'find'
|
4
|
+
require 'ftools'
|
5
|
+
require 'tempfile'
|
6
|
+
include Config
|
7
|
+
|
8
|
+
LIBDIR = "lib"
|
9
|
+
LIBDIR_MODE = 0644
|
10
|
+
|
11
|
+
BINDIR = "bin"
|
12
|
+
BINDIR_MODE = 0755
|
13
|
+
|
14
|
+
|
15
|
+
$srcdir = CONFIG["srcdir"]
|
16
|
+
$version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
|
17
|
+
$libdir = File.join(CONFIG["libdir"], "ruby", $version)
|
18
|
+
$archdir = File.join($libdir, CONFIG["arch"])
|
19
|
+
$site_libdir = $:.find {|x| x =~ /site_ruby$/}
|
20
|
+
$bindir = CONFIG["bindir"]
|
21
|
+
$ruby_install_name = CONFIG['ruby_install_name'] || CONFIG['RUBY_INSTALL_NAME']
|
22
|
+
$ruby = File.join($bindir, $ruby_install_name || 'ruby')
|
23
|
+
|
24
|
+
if !$site_libdir
|
25
|
+
$site_libdir = File.join($libdir, "site_ruby")
|
26
|
+
elsif $site_libdir !~ %r/#{Regexp.quote($version)}/
|
27
|
+
$site_libdir = File.join($site_libdir, $version)
|
28
|
+
end
|
29
|
+
|
30
|
+
def install_rb(srcdir=nil, destdir=nil, mode=nil, bin=nil)
|
31
|
+
#{{{
|
32
|
+
path = []
|
33
|
+
dir = []
|
34
|
+
Find.find(srcdir) do |f|
|
35
|
+
next unless FileTest.file?(f)
|
36
|
+
next if (f = f[srcdir.length+1..-1]) == nil
|
37
|
+
next if (/CVS$/ =~ File.dirname(f))
|
38
|
+
path.push f
|
39
|
+
dir |= [File.dirname(f)]
|
40
|
+
end
|
41
|
+
for f in dir
|
42
|
+
next if f == "."
|
43
|
+
next if f == "CVS"
|
44
|
+
File::makedirs(File.join(destdir, f))
|
45
|
+
end
|
46
|
+
for f in path
|
47
|
+
next if (/\~$/ =~ f)
|
48
|
+
next if (/^\./ =~ File.basename(f))
|
49
|
+
unless bin
|
50
|
+
File::install(File.join(srcdir, f), File.join(destdir, f), mode, true)
|
51
|
+
else
|
52
|
+
from = File.join(srcdir, f)
|
53
|
+
to = File.join(destdir, f)
|
54
|
+
shebangify(from) do |sf|
|
55
|
+
$deferr.print from, " -> ", File::catname(from, to), "\n"
|
56
|
+
$deferr.printf "chmod %04o %s\n", mode, to
|
57
|
+
File::install(sf, to, mode, false)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
#}}}
|
62
|
+
end
|
63
|
+
def shebangify f
|
64
|
+
#{{{
|
65
|
+
open(f) do |fd|
|
66
|
+
buf = fd.read 42
|
67
|
+
if buf =~ %r/^\s*#\s*!.*ruby/o
|
68
|
+
ftmp = Tempfile::new("#{ $$ }_#{ File::basename(f) }")
|
69
|
+
begin
|
70
|
+
fd.rewind
|
71
|
+
ftmp.puts "#!#{ $ruby }"
|
72
|
+
while((buf = fd.read(8192)))
|
73
|
+
ftmp.write buf
|
74
|
+
end
|
75
|
+
ftmp.close
|
76
|
+
yield ftmp.path
|
77
|
+
ensure
|
78
|
+
ftmp.close!
|
79
|
+
end
|
80
|
+
else
|
81
|
+
yield f
|
82
|
+
end
|
83
|
+
end
|
84
|
+
#}}}
|
85
|
+
end
|
86
|
+
def ARGV.switch
|
87
|
+
#{{{
|
88
|
+
return nil if self.empty?
|
89
|
+
arg = self.shift
|
90
|
+
return nil if arg == '--'
|
91
|
+
if arg =~ /^-(.)(.*)/
|
92
|
+
return arg if $1 == '-'
|
93
|
+
raise 'unknown switch "-"' if $2.index('-')
|
94
|
+
self.unshift "-#{$2}" if $2.size > 0
|
95
|
+
"-#{$1}"
|
96
|
+
else
|
97
|
+
self.unshift arg
|
98
|
+
nil
|
99
|
+
end
|
100
|
+
#}}}
|
101
|
+
end
|
102
|
+
def ARGV.req_arg
|
103
|
+
#{{{
|
104
|
+
self.shift || raise('missing argument')
|
105
|
+
#}}}
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
#
|
110
|
+
# main program
|
111
|
+
#
|
112
|
+
|
113
|
+
libdir = $site_libdir
|
114
|
+
bindir = $bindir
|
115
|
+
|
116
|
+
begin
|
117
|
+
while switch = ARGV.switch
|
118
|
+
case switch
|
119
|
+
when '-d', '--destdir'
|
120
|
+
libdir = ARGV.req_arg
|
121
|
+
when '-l', '--libdir'
|
122
|
+
libdir = ARGV.req_arg
|
123
|
+
when '-b', '--bindir'
|
124
|
+
bindir = ARGV.req_arg
|
125
|
+
when '-r', '--ruby'
|
126
|
+
$ruby = ARGV.req_arg
|
127
|
+
else
|
128
|
+
raise "unknown switch #{switch.dump}"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
rescue
|
132
|
+
STDERR.puts $!.to_s
|
133
|
+
STDERR.puts File.basename($0) +
|
134
|
+
" -d <destdir>" +
|
135
|
+
" -l <libdir>" +
|
136
|
+
" -b <bindir>"
|
137
|
+
" -r <ruby>"
|
138
|
+
exit 1
|
139
|
+
end
|
140
|
+
|
141
|
+
install_rb(LIBDIR, libdir, LIBDIR_MODE)
|
142
|
+
install_rb(BINDIR, bindir, BINDIR_MODE, bin=true)
|
143
|
+
|
data/lib/alib-0.4.0.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
#
|
2
|
+
# the ALib module is a namespace for things i've found useful
|
3
|
+
#
|
4
|
+
module ALib
|
5
|
+
#--{{{
|
6
|
+
VERSION = '0.4.0'
|
7
|
+
|
8
|
+
def self.version() VERSION end
|
9
|
+
|
10
|
+
require 'pathname'
|
11
|
+
require 'socket'
|
12
|
+
require 'tmpdir'
|
13
|
+
require 'rbconfig'
|
14
|
+
require 'logger'
|
15
|
+
require 'yaml'
|
16
|
+
require 'fileutils'
|
17
|
+
require 'tempfile'
|
18
|
+
require 'optparse'
|
19
|
+
require 'sync'
|
20
|
+
require 'time'
|
21
|
+
require 'fcntl'
|
22
|
+
require 'uri'
|
23
|
+
require 'net/http'
|
24
|
+
|
25
|
+
|
26
|
+
# TODO - bundle open4!!
|
27
|
+
|
28
|
+
LIBDIR = 'alib-%s/' % VERSION
|
29
|
+
|
30
|
+
AUTOLOAD = {
|
31
|
+
|
32
|
+
'Util' => 'util',
|
33
|
+
|
34
|
+
'Logging' => 'logging',
|
35
|
+
|
36
|
+
'ConfigFile' => 'configfile',
|
37
|
+
'Configfile' => 'configfile',
|
38
|
+
|
39
|
+
'ListFile' => 'listfile',
|
40
|
+
'Listfile' => 'listfile',
|
41
|
+
|
42
|
+
'AutoHash' => 'autohash',
|
43
|
+
|
44
|
+
'OrderedHash' => 'orderedhash',
|
45
|
+
|
46
|
+
'OrderedAutoHash' => 'orderedautohash',
|
47
|
+
'AutoOrderedHash' => 'orderedautohash',
|
48
|
+
|
49
|
+
'Find' => 'find2',
|
50
|
+
'Find2' => 'find2',
|
51
|
+
|
52
|
+
'Bsearch' => 'bsearch',
|
53
|
+
|
54
|
+
'AbstractMain' => 'main',
|
55
|
+
'SimpleMain' => 'main',
|
56
|
+
'ConfigurableMain' => 'main',
|
57
|
+
|
58
|
+
}
|
59
|
+
|
60
|
+
AUTOLOAD.each{|const, basename| autoload const.to_s, LIBDIR + basename.to_s}
|
61
|
+
|
62
|
+
METACLASS =
|
63
|
+
class << self
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
AUTOLOAD.each{ |const, m| METACLASS.module_eval{ define_method(m){ ALib.send 'const_get', const}}}
|
68
|
+
|
69
|
+
begin
|
70
|
+
require 'open4'
|
71
|
+
rescue LoadError
|
72
|
+
require LIBDIR + 'open4'
|
73
|
+
end
|
74
|
+
|
75
|
+
class << self
|
76
|
+
#--{{{
|
77
|
+
def load basename
|
78
|
+
#--{{{
|
79
|
+
require LIBDIR + basename.to_s
|
80
|
+
#--}}}
|
81
|
+
end
|
82
|
+
def simple_main &b
|
83
|
+
#--{{{
|
84
|
+
b ? Class::new(ALib::SimpleMain, &b) : ALib::SimpleMain
|
85
|
+
#--}}}
|
86
|
+
end
|
87
|
+
alias_method 'main', 'simple_main'
|
88
|
+
alias_method 'smain', 'simple_main'
|
89
|
+
def configurable_main &b
|
90
|
+
#--{{{
|
91
|
+
b ? Class::new(ALib::ConfigurableMain, &b) : ALib::ConfigurableMain
|
92
|
+
#--}}}
|
93
|
+
end
|
94
|
+
alias_method 'cmain', 'configurable_main'
|
95
|
+
#--}}}
|
96
|
+
end
|
97
|
+
#--}}}
|
98
|
+
end
|
99
|
+
|
100
|
+
Alib = ALib
|
101
|
+
|
102
|
+
class Object
|
103
|
+
def alib() Alib end
|
104
|
+
end
|
@@ -0,0 +1,255 @@
|
|
1
|
+
#
|
2
|
+
# Ruby/Bsearch - a binary search library for Ruby.
|
3
|
+
#
|
4
|
+
# Copyright (C) 2001 Satoru Takabayashi <satoru@namazu.org>
|
5
|
+
# All rights reserved.
|
6
|
+
# This is free software with ABSOLUTELY NO WARRANTY.
|
7
|
+
#
|
8
|
+
# You can redistribute it and/or modify it under the terms of
|
9
|
+
# the Ruby's licence.
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
#
|
13
|
+
# % irb -r ./bsearch.rb
|
14
|
+
# >> %w(a b c c c d e f).bsearch_first {|x| x <=> "c"}
|
15
|
+
# => 2
|
16
|
+
# >> %w(a b c c c d e f).bsearch_last {|x| x <=> "c"}
|
17
|
+
# => 4
|
18
|
+
# >> %w(a b c e f).bsearch_first {|x| x <=> "c"}
|
19
|
+
# => 2
|
20
|
+
# >> %w(a b e f).bsearch_first {|x| x <=> "c"}
|
21
|
+
# => nil
|
22
|
+
# >> %w(a b e f).bsearch_last {|x| x <=> "c"}
|
23
|
+
# => nil
|
24
|
+
# >> %w(a b e f).bsearch_lower_boundary {|x| x <=> "c"}
|
25
|
+
# => 2
|
26
|
+
# >> %w(a b e f).bsearch_upper_boundary {|x| x <=> "c"}
|
27
|
+
# => 2
|
28
|
+
# >> %w(a b c c c d e f).bsearch_range {|x| x <=> "c"}
|
29
|
+
# => 2...5
|
30
|
+
# >> %w(a b c d e f).bsearch_range {|x| x <=> "c"}
|
31
|
+
# => 2...3
|
32
|
+
# >> %w(a b d e f).bsearch_range {|x| x <=> "c"}
|
33
|
+
# => 2...2
|
34
|
+
|
35
|
+
module ALib::Bsearch
|
36
|
+
#--{{{
|
37
|
+
VERSION = '1.5'
|
38
|
+
|
39
|
+
module BsearchMethods
|
40
|
+
#--{{{
|
41
|
+
#
|
42
|
+
# The binary search algorithm is extracted from Jon Bentley's
|
43
|
+
# Programming Pearls 2nd ed. p.93
|
44
|
+
#
|
45
|
+
|
46
|
+
#
|
47
|
+
# Return the lower boundary. (inside)
|
48
|
+
#
|
49
|
+
# old
|
50
|
+
def bsearch_lower_boundary (range = 0 ... self.length, &block)
|
51
|
+
#--{{{
|
52
|
+
lower = range.first() -1
|
53
|
+
upper = if range.exclude_end? then range.last else range.last + 1 end
|
54
|
+
while lower + 1 != upper
|
55
|
+
mid = ((lower + upper) / 2).to_i # for working with mathn.rb (Rational)
|
56
|
+
if yield(self[mid]) < 0
|
57
|
+
lower = mid
|
58
|
+
else
|
59
|
+
upper = mid
|
60
|
+
end
|
61
|
+
end
|
62
|
+
return upper
|
63
|
+
#--}}}
|
64
|
+
end
|
65
|
+
# new
|
66
|
+
def bsearch_lower_boundary (arg = nil, &block)
|
67
|
+
#--{{{
|
68
|
+
range = nil
|
69
|
+
if arg and not block
|
70
|
+
block = lambda{|x| x <=> arg}
|
71
|
+
range = 0 ... self.length
|
72
|
+
end
|
73
|
+
range ||= (arg ? arg : (0...self.length))
|
74
|
+
|
75
|
+
lower = range.first() -1
|
76
|
+
upper = if range.exclude_end? then range.last else range.last + 1 end
|
77
|
+
while lower + 1 != upper
|
78
|
+
mid = ((lower + upper) / 2).to_i # for working with mathn.rb (Rational)
|
79
|
+
if block[ self[mid] ] < 0
|
80
|
+
lower = mid
|
81
|
+
else
|
82
|
+
upper = mid
|
83
|
+
end
|
84
|
+
end
|
85
|
+
return upper
|
86
|
+
#--}}}
|
87
|
+
end
|
88
|
+
|
89
|
+
#
|
90
|
+
# This method searches the FIRST occurrence which satisfies a
|
91
|
+
# condition given by a block in binary fashion and return the
|
92
|
+
# index of the first occurrence. Return nil if not found.
|
93
|
+
#
|
94
|
+
# old
|
95
|
+
def bsearch_first (range = 0 ... self.length, &block)
|
96
|
+
#--{{{
|
97
|
+
boundary = bsearch_lower_boundary(range, &block)
|
98
|
+
if boundary >= self.length || yield(self[boundary]) != 0
|
99
|
+
return nil
|
100
|
+
else
|
101
|
+
return boundary
|
102
|
+
end
|
103
|
+
#--}}}
|
104
|
+
end
|
105
|
+
# new
|
106
|
+
def bsearch_first (arg = nil, &block)
|
107
|
+
#--{{{
|
108
|
+
range = nil
|
109
|
+
if arg and not block
|
110
|
+
block = lambda{|x| x <=> arg}
|
111
|
+
range = 0 ... self.length
|
112
|
+
end
|
113
|
+
range ||= (arg ? arg : (0...self.length))
|
114
|
+
boundary = bsearch_lower_boundary(range, &block)
|
115
|
+
if boundary >= self.length || block[ self[boundary] ] != 0
|
116
|
+
return nil
|
117
|
+
else
|
118
|
+
return boundary
|
119
|
+
end
|
120
|
+
#--}}}
|
121
|
+
end
|
122
|
+
|
123
|
+
# alias bsearch bsearch_first
|
124
|
+
def bsearch(*a, &b)
|
125
|
+
#--{{{
|
126
|
+
unless b
|
127
|
+
obj = a.first
|
128
|
+
b = lambda{|x| x <=> obj}
|
129
|
+
bsearch_first(&b)
|
130
|
+
else
|
131
|
+
bsearch_first(*a, &b)
|
132
|
+
end
|
133
|
+
#--}}}
|
134
|
+
end
|
135
|
+
#
|
136
|
+
# Return the upper boundary. (outside)
|
137
|
+
#
|
138
|
+
# old
|
139
|
+
def bsearch_upper_boundary (range = 0 ... self.length, &block)
|
140
|
+
#--{{{
|
141
|
+
lower = range.first() -1
|
142
|
+
upper = if range.exclude_end? then range.last else range.last + 1 end
|
143
|
+
while lower + 1 != upper
|
144
|
+
mid = ((lower + upper) / 2).to_i # for working with mathn.rb (Rational)
|
145
|
+
if yield(self[mid]) <= 0
|
146
|
+
lower = mid
|
147
|
+
else
|
148
|
+
upper = mid
|
149
|
+
end
|
150
|
+
end
|
151
|
+
return lower + 1 # outside of the matching range.
|
152
|
+
#--}}}
|
153
|
+
end
|
154
|
+
# new
|
155
|
+
def bsearch_upper_boundary (arg = nil, &block)
|
156
|
+
#--{{{
|
157
|
+
range = nil
|
158
|
+
if arg and not block
|
159
|
+
block = lambda{|x| x <=> arg}
|
160
|
+
range = 0 ... self.length
|
161
|
+
end
|
162
|
+
range ||= (arg ? arg : (0...self.length))
|
163
|
+
|
164
|
+
lower = range.first() -1
|
165
|
+
upper = if range.exclude_end? then range.last else range.last + 1 end
|
166
|
+
while lower + 1 != upper
|
167
|
+
mid = ((lower + upper) / 2).to_i # for working with mathn.rb (Rational)
|
168
|
+
if block[ self[mid] ] <= 0
|
169
|
+
lower = mid
|
170
|
+
else
|
171
|
+
upper = mid
|
172
|
+
end
|
173
|
+
end
|
174
|
+
return lower + 1 # outside of the matching range.
|
175
|
+
#--}}}
|
176
|
+
end
|
177
|
+
#
|
178
|
+
# This method searches the LAST occurrence which satisfies a
|
179
|
+
# condition given by a block in binary fashion and return the
|
180
|
+
# index of the last occurrence. Return nil if not found.
|
181
|
+
#
|
182
|
+
# old
|
183
|
+
def bsearch_last (range = 0 ... self.length, &block)
|
184
|
+
#--{{{
|
185
|
+
# `- 1' for canceling `lower + 1' in bsearch_upper_boundary.
|
186
|
+
boundary = bsearch_upper_boundary(range, &block) - 1
|
187
|
+
|
188
|
+
if (boundary <= -1 || yield(self[boundary]) != 0)
|
189
|
+
return nil
|
190
|
+
else
|
191
|
+
return boundary
|
192
|
+
end
|
193
|
+
#--}}}
|
194
|
+
end
|
195
|
+
# new
|
196
|
+
def bsearch_last (arg = nil, &block)
|
197
|
+
#--{{{
|
198
|
+
range = nil
|
199
|
+
if arg and not block
|
200
|
+
block = lambda{|x| x <=> arg}
|
201
|
+
range = 0 ... self.length
|
202
|
+
end
|
203
|
+
range ||= (arg ? arg : (0...self.length))
|
204
|
+
|
205
|
+
# `- 1' for canceling `lower + 1' in bsearch_upper_boundary.
|
206
|
+
boundary = bsearch_upper_boundary(range, &block) - 1
|
207
|
+
|
208
|
+
if (boundary <= -1 || block[ self[boundary] ] != 0)
|
209
|
+
return nil
|
210
|
+
else
|
211
|
+
return boundary
|
212
|
+
end
|
213
|
+
#--}}}
|
214
|
+
end
|
215
|
+
#
|
216
|
+
# Return the search result as a Range object.
|
217
|
+
#
|
218
|
+
# old
|
219
|
+
def bsearch_range (range = 0 ... self.length, &block)
|
220
|
+
#--{{{
|
221
|
+
lower = bsearch_lower_boundary(range, &block)
|
222
|
+
upper = bsearch_upper_boundary(range, &block)
|
223
|
+
return lower ... upper
|
224
|
+
#--}}}
|
225
|
+
end
|
226
|
+
# new
|
227
|
+
def bsearch_range (arg = nil, &block)
|
228
|
+
#--{{{
|
229
|
+
range = nil
|
230
|
+
if arg and not block
|
231
|
+
block = lambda{|x| x <=> arg}
|
232
|
+
range = 0 ... self.length
|
233
|
+
end
|
234
|
+
range ||= (arg ? arg : (0...self.length))
|
235
|
+
|
236
|
+
lower = bsearch_lower_boundary(range, &block)
|
237
|
+
upper = bsearch_upper_boundary(range, &block)
|
238
|
+
return lower ... upper
|
239
|
+
#--}}}
|
240
|
+
end
|
241
|
+
#--}}}
|
242
|
+
end
|
243
|
+
|
244
|
+
if false
|
245
|
+
def Bsearch::append_features klass
|
246
|
+
#--{{{
|
247
|
+
::Array.module_eval{ include BsearchMethods }
|
248
|
+
super
|
249
|
+
#--}}}
|
250
|
+
end
|
251
|
+
end
|
252
|
+
::Array.module_eval{ include BsearchMethods }
|
253
|
+
#--}}}
|
254
|
+
end # module Bsearch
|
255
|
+
ALib::BSearch = ALib::Bsearch
|