range: add some nitunit and examples
[nit.git] / lib / standard / collection / range.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2004-2008 Jean Privat <jean@pryen.org>
4 #
5 # This file is free software, which comes along with NIT. This software is
6 # distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
7 # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
8 # PARTICULAR PURPOSE. You can modify it is you want, provided this header
9 # is kept unaltered, and a notification of the changes is added.
10 # You are allowed to redistribute it and sell it, alone or is a part of
11 # another product.
12
13 # Module for range of discrete objects.
14 module range
15
16 import abstract_collection
17
18 # Range of discrete objects.
19 class Range[E: Discrete]
20 super Collection[E]
21
22 redef var first: E
23
24 # Get the last element.
25 var last: E
26
27 # Get the element after the last one.
28 var after: E
29
30 # assert [1..10].has(5)
31 # assert [1..10].has(10)
32 # assert not [1..10[.has(10)
33 redef fun has(item) do return item >= first and item <= last
34
35 # assert [1..1].has_only(1)
36 # assert not [1..10].has_only(1)
37 redef fun has_only(item) do return first == item and item == last or is_empty
38
39 # assert [1..10].count(1) == 1
40 # assert [1..10].count(0) == 0
41 redef fun count(item)
42 do
43 if has(item) then
44 return 1
45 else
46 return 0
47 end
48 end
49
50 redef fun iterator do return new IteratorRange[E](self)
51
52 redef fun length
53 do
54 var nb = first.distance(after)
55 if nb > 0 then
56 return nb
57 else
58 return 0
59 end
60 end
61
62 # assert not [1..10[.is_empty
63 # assert not [1..1].is_empty
64 # assert [1..-10].is_empty
65 redef fun is_empty do return first >= after
66
67 # Create a range [`from`, `to`].
68 # The syntax `[from..to]` is equivalent.
69 #
70 # var a = [10..15]
71 # var b = new Range[Int] (10,15)
72 # assert a == b
73 # assert a.to_a == [10, 11, 12, 13, 14, 15]
74 init(from: E, to: E) is old_style_init do
75 first = from
76 last = to
77 after = to.successor(1)
78 end
79
80 # Create a range [`from`, `to`[.
81 # The syntax `[from..to[` is equivalent.
82 #
83 # var a = [10..15[
84 # var b = new Range[Int].without_last(10,15)
85 # assert a == b
86 # assert a.to_a == [10, 11, 12, 13, 14]
87 init without_last(from: E, to: E)
88 do
89 first = from
90 last = to.predecessor(1)
91 after = to
92 end
93 end
94
95 private class IteratorRange[E: Discrete]
96 # Iterator on ranges.
97 super Iterator[E]
98 var range: Range[E]
99 redef var item is noinit
100
101 redef fun is_ok do return _item < _range.after
102
103 redef fun next do _item = _item.successor(1)
104
105 init
106 do
107 _item = _range.first
108 end
109 end
110
111 redef class Int
112 # Returns the range from 0 to `self-1`, is used to do:
113 #
114 # var s = new Array[String]
115 # for i in 3.times do s.add "cool"
116 # assert s.join(" ") == "cool cool cool"
117 #
118 # s.clear
119 # for i in 10.times do s.add(i.to_s)
120 # assert s.to_s == "0123456789"
121 fun times: Range[Int] do return [0 .. self[
122 end