Class STRING
Draft Proposal 15 September 1999
compiled by Dominique Colnet and Olivier Zendra
indexing
description: "Resizable sequences of characters, accessible through %
%integer indices in a contiguous range. If not empty, first element%
%is at index 1."
class interface
STRING
creation
make (n: INTEGER)
-- Allocate space for at least n characters.
require
non_negative_size: n >= 0
ensure
empty_string: count = 0
correctly_allocated_size: capacity >= n
make_from_external (ptr: POINTER)
-- Set Current with a copy of the content of ptr.
-- Assume ptr is a null-terminated memory area containing
-- only characters.
-- The extra null character is not part of the Eiffel string
require
ptr_exists: ptr /= default_pointer
make_from_string (s: STRING)
-- Initialize from the characters of s.
-- (Useful in proper descendants of class STRING,
-- to initialize a string-like object from a manifest string.)
require
string_exists: s /= Void
ensure
count_set: count = s.count
feature -- Initialization
make (n: INTEGER)
-- Allocate space for at least n characters.
require
non_negative_size: n >= 0
ensure
empty_string: count = 0
correctly_allocated_size: capacity >= n
make_from_external (ptr: POINTER)
-- Set Current with a copy of the content of ptr.
-- Assume ptr is a null-terminated memory area containing
-- only characters.
-- The extra null character is not part of the Eiffel string
require
ptr_exists: ptr /= default_pointer
make_from_string (s: STRING)
-- Initialize from the characters of s.
-- (Useful in proper descendants of class STRING,
-- to initialize a string-like object from a manifest string.)
require
string_exists: s /= Void
ensure
count_set: count = s.count
feature -- Access
first: CHARACTER
-- First character of Current.
require
not_empty_string: not is_empty
ensure
good_result: Result = item (1)
has (c: CHARACTER): BOOLEAN
-- Does Current contain c ?
ensure
definition: Result = (index_of(c) /= 0);
hash_code: INTEGER
-- Hash code value
-- (From HASHABLE.)
ensure
good_hash_value: Result >= 0
index_from (c: CHARACTER; start_index: INTEGER): INTEGER
-- Index of first occurrence of c at or after start_index;
-- 0 if none.
require
valid_start_index: valid_index (start_index)
ensure
non_negative_result: Result >= 0;
valid_result: Result > 0 implies valid_index (Result)
result_after_start_index: Result > 0 implies Result >= start_index;
at_this_index: Result > 0 implies item (Result) = c;
-- none_before: For every i in start_index..Result-1, item (i) /= c
-- zero_iff_absent:
-- (Result = 0) = For every i in start_index..count, item (i) /= c
index_of (c: CHARACTER): INTEGER
-- Index of first occurrence of c;
-- 0 if none.
ensure
empty_definition: empty implies Result = 0;
non_empty_definition: not empty implies Result = index_from (c, 1);
infix "@", item (i: INTEGER): CHARACTER
-- Character at index i
require
good_key: valid_index (i)
last: CHARACTER
-- Last character of Current.
require
not_empty_string: not is_empty
ensure
good_result: Result = item (count)
reverse_index_from (c: CHARACTER; last_index: INTEGER): INTEGER
-- Index of first occurrence of c at or before last_index;
-- 0 if none.
require
valid_last_index: valid_index (last_index)
ensure
non_negative_result: Result >= 0;
valid_result: Result > 0 implies valid_index(Result)
result_before_last_index: Result <= last_index;
at_this_index: Result > 0 implies item (Result) = c;
-- none_before: Result > 0 implies For every i in Result+1..last_index, item (i) /= c
-- zero_iff_absent:
-- (Result = 0) = For every i in 1..last_index, item (i) /= c
reverse_index_of (c: CHARACTER): INTEGER
-- Index of last occurrence of c;
-- 0 if none.
ensure
empty_definition: empty implies Result = 0;
non_empty_definition: empty implies Result = reverse_index_from (c, count);
reverse_string_index_from (other: STRING; last_index: INTEGER): INTEGER
-- Index of first occurrence of other at or before last_index;
-- 0 if none.
require
other_not_empty: not other.empty;
valid_last_index: valid_index (last_index)
ensure
non_negative_result: Result >= 0;
valid_result: Result > 0 implies valid_index (Result)
result_before_last_index: Result > 0 implies Result <= last_index;
at_this_index: Result > 0 implies other.is_equal (substring (Result, Result - 1 + other.count));
-- none_before: Result > 0 implies
-- For every i in Result+1..last_index, not other.is_equal (substring (i, i - 1 + other.count))
-- zero_iff_absent:
-- (Result = 0) = For every i in 1..last_index, not other.is_equal (substring (i, i - 1 + other.count))
reverse_string_index_of (other: STRING): INTEGER
-- Index of last occurrence of other;
-- 0 if none.
require
other_not_empty: not other.empty
ensure
empty_definition: empty implies Result = 0;
non_empty_definition: not empty implies Result = reverse_string_index_from (other, count);
string_index_from (other: STRING; start_index: INTEGER): INTEGER
-- Index of first occurrence of other at or after start;
-- 0 if none.
require
other_not_empty: not other.empty;
valid_start_index: valid_index (start_index)
ensure
non_negative_result: Result >= 0;
valid_result: Result > 0 implies valid_index (Result)
result_after_start_index: Result > 0 implies Result >= start_index;
at_this_index: Result > 0 implies other.is_equal (substring (Result, Result - 1+ other.count));
-- none_before:
-- For every i in start_index..Result-1, not other.is_equal (substring (i, i - 1 + other.count))
-- zero_iff_absent:
-- (Result = 0) = For every i in start_index..count, not other.is_equal (substring (i, i - 1 + other.count))
string_index_of (other: STRING): INTEGER
-- Index of first occurrence of other;
-- 0 if none.
require
other_not_empty: not other.empty
ensure
empty_definition: empty implies Result = 0;
non_empty_definition: not empty implies Result = reverse_string_index_from (other, 1);
feature -- Measurement
count: INTEGER
-- Current number of characters making up the string
capacity: INTEGER
-- Number of characters that Current can currently contain in the internal storage area.
-- Automatically updated when resizing is needed. Useful for fine tuning.
occurrences (c: CHARACTER): INTEGER
-- Number of times c appears in the string
ensure
non_negative_occurrences: Result >= 0
feature -- Comparison
is_equal (other: like Current): BOOLEAN
-- Is string made of same character sequence as other?
-- (Redefined from GENERAL.)
require
other_exists: other /= Void
infix "<" (other: like Current): BOOLEAN
-- Is string lexicographically lower than other?
-- (False if other is void)
-- (From COMPARABLE.)
require
other_exists: other /= Void
ensure
asymmetric: Result implies not (other < Current)
infix "<=" (other: like Current): BOOLEAN
-- Is current object less than or equal to other?
-- (From COMPARABLE.)
require
other_exists: other /= Void
ensure
definition: Result = (Current < other) or is_equal (other);
infix ">=" (other: like Current): BOOLEAN
-- Is current object greater than or equal to other?
-- (From COMPARABLE.)
require
other_exists: other /= Void
ensure
definition: Result = (other <= Current)
infix ">" (other: like Current): BOOLEAN
-- Is current object greater than other?
-- (From COMPARABLE.)
require
other_exists: other /= Void
ensure
definition: Result = (other < Current)
max (other: like Current): like Current)
-- The greater of current object and other
-- (From COMPARABLE.)
require
other_exists: other /= Void
ensure
current_if_not_smaller: (Current >= other) implies (Result = Current)
other_if_smaller: (Current < other) implies (Result = other)
min (other: like Current): like Current)
-- The smaller of current object and other
-- (From COMPARABLE.)
require
other_exists: other /= Void
ensure
current_if_not_greater: (Current <= other) implies (Result = Current)
other_if_greater: (Current > other) implies (Result = other)
same_as (other: STRING): BOOLEAN
-- Is string made of same character sequence as other?
-- Case insensitive comparison.
require
other_exists: other /= Void
three_way_comparison (other: like Current): INTEGER
-- If current object equal to other, 0; if smaller,
-- -1; if greater, 1.
-- (From COMPARABLE.)
require
other_exists: other /= Void
ensure
equal_zero: (Result = 0) = is_equal (other);
smaller: (Result = -1) = Current < other;
greater_positive: (Result = 1) = Current > other
feature -- Status report
is_empty: BOOLEAN
-- Is string empty?
ensure
definition: Result = (count = 0)
valid_index (index: INTEGER): BOOLEAN
-- Is i within the bounds of the string?
ensure
definition: Result = (1 <= index and index <= count)
is_boolean: BOOLEAN
-- Is Current representing a boolean ("true" or "false" with no
-- case consideration)?
is_double: BOOLEAN
-- Can Current be read as a DOUBLE?
is_integer: BOOLEAN
-- Can Current be read as an INTEGER?
is_real: BOOLEAN
-- Can Current be read as a REAL?
feature -- Element change
add, insert (c: CHARACTER; i: INTEGER)
-- Insert c at index i, shifting characters between ranks i and count rightwards.
require
valid_insertion_index: 1 <= i and i <= count + 1
ensure
inserted: item (i) = c
one_more_character: count = old count + 1
add_first, precede (c: CHARACTER)
-- Prepend c at beginning.
ensure
inserted: first = c
one_more_character: count = old count + 1
add_last, append_character, extend (c: CHARACTER)
-- Append c at end.
ensure
inserted: last = c
one_more_character: count = old count + 1
append, append_string (s: STRING)
-- Append a copy of s at end.
require
other_exists: s /= Void
ensure
new_count: count = old count + old s.count
-- appended: For every i in 1.. old s.count,
-- item (old count + i) = s.item (i)
append_boolean (b: BOOLEAN)
-- Append the string representation of b at end.
ensure
boolean_inserted: reverse_index_of (b.out) = count - b.out.count
new_count: count = old count + b.out.count + 1
append_double (d: DOUBLE)
-- Append the string representation of d at end.
ensure
double_inserted: reverse_index_of (d.out) = count - d.out.count
new_count: count = old count + d.out.count + 1
append_integer (i: INTEGER)
-- Append the string representation of i at end.
ensure
integer_inserted: reverse_index_of (i.out) = count - i.out.count
new_count: count = old count + i.out.count + 1
append_real (r: REAL)
-- Append the string representation of r at end.
ensure
real_inserted: reverse_index_of (r.out) = count - r.out.count
new_count: count = old count + r.out.count + 1
fill (c: CHARACTER)
-- Replace every character with c.
ensure
same_count: old count = count
filled: occurrences(c) = count
head (n: INTEGER)
-- Remove all characters except for the first n;
-- do nothing if n >= count.
require
non_negative_argument: n >= 0
ensure
new_count: count = n.min (old count)
-- first_kept: For every i in 1..n, item (i) = old item (i)
insert_string (s: like Current; i: INTEGER)
-- Insert s at index i, shifting characters between ranks i and count rightwards.
require
string_exists: s /= Void;
valid_insertion_index: 1 <= i and i <= count + 1
ensure
new_count: count = old count + old s.count
inserted: s.is_equal (substring (i, i - 1 + old s.count))
left_adjust
-- Remove leading white space.
ensure
shorter: count <= old count
first_not_white_space: not is_empty implies ("%T%R%N ").index_of (first) = 0
put (c: CHARACTER; i: INTEGER)
-- Replace character at index i by c.
require
good_key: valid_index (i)
ensure
insertion_done: item (i) = c
right_adjust
-- Remove trailing white space.
ensure
shorter: count <= old count
last_not_white_space: not is_empty implies ("%T%R%N ").index_of (last) = 0
subcopy (other: like Current; start_pos, end_pos, from_index: INTEGER) is
-- Copy characters of other within bounds start_pos and
-- end_pos to current string starting at index from_index.
require
other_not_void: other /= Void;
valid_start_pos: other.valid_index (start_pos)
valid_end_pos: other.valid_index (end_pos)
valid_bounds: start_pos <= end_pos
valid_from_index: valid_index (from_index)
enough_space: valid_index (from_index + end_pos - start_pos)
ensure
same_count: old count = count
copied: substring (from_index, from_index + end_pos - start_pos).is_equal
(other.substring (start_pos, end_pos))
tail (n: INTEGER)
-- Remove all characters except for the last n;
-- do nothing if n >= count.
require
non_negative_argument: n >= 0
ensure
new_count: count = n.min (old count)
feature -- Removal
remove (i: INTEGER)
-- Remove i-th character, shifting characters between ranks i + 1 and count leftwards.
require
valid_removal_index: valid_index (i)
ensure
new_count: count = old count - 1
wipe_out
-- Remove all characters.
ensure
empty_string: is_empty
same_capacity: capacity = old capacity
same_lower: lower = old lower
feature -- Conversion
to_boolean: BOOLEAN
-- Boolean value;
-- "true" yields true, "false" yields false
-- (case-insensitive)
require
is_boolean: is_boolean
to_double: DOUBLE
-- Double value; for example, when applied to "123.0",
-- will yield 123.0 (double)
require
is_double: is_integer or is_real or is_double
to_external: POINTER
-- Address of the storage area containing the actual sequence of characters,
-- to be passed to some external (non-Eiffel) routine.
-- Keep in mind that this storage area is subject to garbage collection.
to_integer: INTEGER
-- Integer value;
-- for example, when applied to "123", will yield 123
require
is_integer: is_integer
to_lower
-- Convert to lower case.
to_real: REAL
-- Real value;
-- for example, when applied to "123.0", will yield 123.0
require
is_real: is_integer or is_real
to_upper
-- Convert to upper case.
feature -- Duplication
copy (other: like Current)
-- Reinitialize by copying the characters of other.
-- (From GENERAL.)
ensure
new_result_count: count = other.count
-- same_characters: For every i in 1..count,
-- item (i) = other.item (i)
infix "+" (other: STRING): like Current
-- Create a new object which is the concatenation of Current and other.
require
other_exists: other /= Void
ensure
result_count: Result.count = count + other.count
substring (start_index, end_index: INTEGER): like Current
-- Create a substring containing all characters from start_index
-- to end_pos included.
require
valid_start_index: valid_index (start_index)
valid_end_index: valid_index (end_index)
meaningful_interval: start_index <= end_index
ensure
new_result_count: Result.count = end_index - start_index + 1
-- original_characters: For every i in 1..end_index - start_index + 1,
-- Result.item (i) = item (start_index + i -1)
feature -- Output
out: STRING
-- Printable representation
-- (From GENERAL.)
ensure
result_not_void: Result /= Void
duplicated_result: Result /= Current and Result.is_equal (Current)
feature -- Optimization
adjust_capacity (n: INTEGER)
-- Rearrange string so that it can accommodate
-- at least n characters.
-- Do not lose any previously entered character.
require
no_item_lost: n >= count
ensure
enough_capacity: capacity >= n
invariant
non_negative_count: count >= 0
capacity_big_enough: capacity >= count
end
Last Updated: 15 September 1999