INDEX CLUSTER FEATURES SHORT FRAMES NO FRAMES

indexing

title: "Sequences of characters, accessible through integer indices in a contiguous range starting from one."
project: "Eiffel Kernel Library"
revision: "$Revision: 1.2 $"
copyright: "Copyright (C) 1996-2005 Object Tools Group"
license: "http://visual-eiffel.com/license"
cluster: kernel
class STRING
inherit

COMPARABLE
redefine
compare,
copy,
is_equal,
out,
three_way_comparison
end

HASHABLE
redefine
copy,
is_equal,
out
end

DATA_OUTPUT
rename
put_boolean as append_boolean,
put_character as append_character,
put_double as append_double,
put_integer as append_integer,
put_real as append_real,
put_string as append_string
redefine
copy,
is_equal,
out
end
creation

make,
make_empty,
make_filled,
make_from_string
creation -- Eiffel/S 1.3 compatibility

adapt
feature {NONE}-- Creation

make_empty
-- Create empty string.
ensure
empty: count = 0

make_filled (c: CHARACTER; n: INTEGER)
-- Create string of length `n' filled with `c'.
require
valid_count: n >= 0
ensure
count_set: count = n
filled: occurrences (c) = count
feature -- Initialization

make (suggested_capacity: INTEGER)
-- Create empty string or remove all characters from existing string.
require
non_negative_suggested_capacity: suggested_capacity >= 0
ensure
empty_string: count = 0

from_c (c_string: POINTER)
-- Set the current STRING from a copy of the
-- zero-byte-terminated memory starting at `c_string'.
require
c_string_exists: c_string /= default_pointer
ensure
no_zero_byte: not has ('%U')
correct_count:

make_from_string (s: STRING)
-- Initialize from the character sequence of `s'.
require
s_not_void: s /= void
ensure
initialized: same_string (s)
feature -- Basic specifiers

count: INTEGER

item (i: INTEGER): CHARACTER
-- Character at index `i'
require
valid_index: valid_index (i)
feature -- Access

hash_code: INTEGER
-- Hash code value (vendor dependent hashing function)

index_of (c: CHARACTER; start_index: INTEGER): INTEGER
-- Index of first occurrence of `c' at or after `start_index'
-- 0 if none
require
valid_start_index: start_index >= 1 and start_index <= count + 1
ensure
valid_result: Result = 0 or (start_index <= Result and Result <= count)
zero_if_absent: (Result = 0) = not substring (start_index, count).has (c)
found_if_present: substring (start_index, count).has (c) implies item (Result) = c
none_before: substring (start_index, count).has (c) implies not substring (start_index, Result - 1).has (c)

string: STRING
-- New STRING having the same character sequence as `Current'
ensure
string_not_void: Result /= void
string_type: Result.same_type ()
first_item: count > 0 implies Result.item (1) = item (1)
recurse: count > 1 implies Result.substring (2, count).is_equal (substring (2, count).string)

substring (start_index, end_index: INTEGER): like Current
-- New object containing all characters
-- from `start_index' to `end_index' inclusive
require
valid_start_index: 1 <= start_index
valid_end_index: end_index <= count
meaningful_interval: start_index <= end_index + 1
ensure
substring_not_void: Result /= void
substring_count: Result.count = end_index - start_index + 1
first_item: Result.count > 0 implies Result.item (1) = item (start_index)
recurse: Result.count > 0 implies Result.substring (2, Result.count).is_equal (substring (start_index + 1, end_index))

substring_index (other: STRING; start_index: INTEGER): INTEGER
-- Index of first occurrence of `other' at or after `start_index'
-- 0 if none
require
other_non_void: other /= void
valid_start_index: start_index >= 1 and start_index <= count + 1
ensure
valid_result: Result = 0 or else (start_index <= Result and Result <= count - other.count + 1)
zero_if_absent: (Result = 0) = not substring (start_index, count).has_substring (other)
at_this_index: Result >= start_index implies other.same_string (substring (Result, Result + other.count - 1))
none_before: Result > start_index implies not substring (start_index, Result + other.count - 2).has_substring (other)

infix "@" (i: INTEGER): CHARACTER
-- Character at index `i'
require
valid_index: valid_index (i)
ensure
definition: Result = item (i)
feature -- Measurement

occurrences (c: CHARACTER): INTEGER
-- Number of times `c' appears in the string
ensure
zero_if_empty: count = 0 implies Result = 0
recurse_if_not_found_at_first_position: (count > 0 and then item (1) /= c) implies Result = substring (2, count).occurrences (c)
recurse_if_found_at_first_position: (count > 0 and then item (1) = c) implies Result = 1 + substring (2, count).occurrences (c)
feature -- Comparison

is_equal (other: like Current): BOOLEAN
-- Is `other' attached to an object considered equal
-- to current object?
-- (Redefined from GENERAL.)
ensure
definition: Result = (same_type (other) and then count = other.count and then (count > 0 implies (item (1) = other.item (1) and substring (2, count).is_equal (other.substring (2, count)))))

same_string (other: STRING): BOOLEAN
-- Do `Current' and `other' have the same character sequence?
require
other_not_void: other /= void
ensure
definition: Result = string.is_equal (other.string)

infix "<" (other: like Current): BOOLEAN
-- Is string lexicographically lower than `other'?
-- (Inherited from COMPARABLE.)
ensure
definition: Result = (count = 0 and other.count > 0 or count > 0 and then other.count > 0 and then (item (1) < other.item (1) or item (1) = other.item (1) and substring (2, count) < other.substring (2, other.count)))

three_way_comparison (other: like Current): INTEGER
-- If string lexicographically equal to 'other', 0; if smaller, -1; if greater, 1
feature -- Status report

has (c: CHARACTER): BOOLEAN
-- Does `Current' contain `c'?
ensure
false_if_empty: count = 0 implies not Result
true_if_first: count > 0 and then item (1) = c implies Result
recurse: (count > 0 and then item (1) /= c) implies (Result = substring (2, count).has (c))

has_substring (other: STRING): BOOLEAN
-- Does `Current' contain `other'?
require
other_not_void: other /= void
ensure
false_if_too_small: count < other.count implies not Result
true_if_initial: (count >= other.count and then other.same_string (substring (1, other.count))) implies Result
recurse: (count >= other.count and then not other.same_string (substring (1, other.count))) implies (Result = substring (2, count).has_substring (other))

is_boolean: BOOLEAN
-- Does `Current' represent a BOOLEAN?
ensure
is_boolean: Result = (same_string (true) or same_string (false))

is_double: BOOLEAN
-- Does `Current' represent a DOUBLE?
ensure
syntax_and_range:

is_empty: BOOLEAN
-- Is string empty?
ensure
definition: Result = (count = 0)

is_integer: BOOLEAN
-- Does `Current' represent an INTEGER?
ensure
syntax_and_range:

is_real: BOOLEAN
-- Does `Current' represent a REAL?
ensure
syntax_and_range:

valid_index (i: INTEGER): BOOLEAN
-- Is `i' within the bounds of the string?
ensure
definition: Result = (1 <= i and i <= count)
feature -- Element change

append_character (c: CHARACTER)
-- Append `c' at end.
ensure
new_count: count = count + 1
appended: item (count) = c
stable_before: substring (1, count - 1).is_equal ( clone (Current) )

append_string (s: STRING)
-- Append a copy of `s' at end.
ensure
appended: is_equal ( clone (Current) + clone (s) )

fill_with (c: CHARACTER)
-- Replace every character with `c'.
ensure
same_count: count = count
filled: occurrences (c) = count

insert_character (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
one_more_character: count = count + 1
inserted: item (i) = c
stable_before_i: substring (1, i - 1).is_equal ( substring (1, i - 1) )
stable_after_i: substring (i + 1, count).is_equal ( substring (i, count) )

insert_string (s: STRING; i: INTEGER)
-- Insert `s' at index `i', shifting characters between ranks
-- `i' and `count' rightwards.
require
string_not_void: s /= void
valid_insertion_index: 1 <= i and i <= count + 1
ensure
inserted: is_equal ( substring (1, i - 1) + clone (s) + substring (i, count) )

put (c: CHARACTER; i: INTEGER)
-- Replace character at index `i' by `c'.
require
valid_index: valid_index (i)
ensure
stable_count: count = count
replaced: item (i) = c
stable_before_i: substring (1, i - 1).is_equal ( substring (1, i - 1) )
stable_after_i: substring (i + 1, count).is_equal ( substring (i + 1, count) )

replace_substring (s: like Current; start_index, end_index: INTEGER)
-- Replace the substring from `start_index' to `end_index',
-- inclusive, with `s'.
require
string_not_void: s /= void
valid_start_index: 1 <= start_index
valid_end_index: end_index <= count
meaningful_interval: start_index <= end_index + 1
ensure
replaced: is_equal ( (substring (1, start_index - 1) + s + substring (end_index + 1, count)) )
feature -- Removal

keep_head (n: INTEGER)
-- Remove all the characters except for the first `n'
-- if `n' >= `count', do nothing.
require
n_non_negative: n >= 0
ensure
kept: is_equal ( substring (1, n.min (count)) )

keep_tail (n: INTEGER)
-- Remove all the characters except for the last `n'
-- if `n' > `count', do nothing.
require
n_non_negative: n >= 0
ensure
kept: is_equal ( substring (count - n.min (count) + 1, count) )

remove (i: INTEGER)
-- Remove 'i-th' character, shifting characters between
-- ranks i + 1 and `count' leftwards.
require
valid_removal_index: valid_index (i)
ensure
removed: is_equal ( substring (1, i - 1) + substring (i + 1, count) )

remove_head (n: INTEGER)
-- Remove the first `n' characters
-- if `n' > `count', remove all.
require
n_non_negative: n >= 0
ensure
removed: is_equal ( substring (n.min (count) + 1, count) )

remove_substring (start_index, end_index: INTEGER)
-- Remove all characters from `start_index'
-- to `end_index' inclusive.
require
valid_start_index: 1 <= start_index
valid_end_index: end_index <= count
meaningful_interval: start_index <= end_index + 1
ensure
removed: is_equal ( substring (1, start_index - 1) + substring (end_index + 1, count) )

remove_tail (n: INTEGER)
-- Remove the last `n' characters
-- if `n' > `count', remove all.
require
n_non_negative: n >= 0
ensure
removed: is_equal ( substring (1, count - n.min (count)) )

wipe_out
-- Remove all characters.
ensure
empty_string: count = 0
feature -- Conversion

as_lower: like Current
-- New object with all letters in lower case
ensure
length: Result.count = count
anchor: count > 0 implies Result.item (1) = item (1).as_lower
recurse: count > 1 implies Result.substring (2, count).is_equal (substring (2, count).as_lower)

as_upper: like Current
-- New object with all letters in upper case
ensure
length: Result.count = count
anchor: count > 0 implies Result.item (1) = item (1).as_upper
recurse: count > 1 implies Result.substring (2, count).is_equal (substring (2, count).as_upper)

to_boolean: BOOLEAN
-- Boolean value
-- "true" yields `true', "false" yields `false'
require
represents_a_boolean: is_boolean
ensure
to_boolean: Result = same_string (true)

to_double: DOUBLE
-- Double value
-- for example, when applied to "123.0", will yield 123.0 (double)
require
represents_a_double: is_double

to_integer: INTEGER
-- Integer value
-- for example, when applied to "123", will yield 123
require
represents_an_integer: is_integer
ensure
single_digit: count = 1 implies Result = (0123456789).index_of (item (1), 1) - 1
minus_sign_followed_by_single_digit: count = 2 and item (1) = '-' implies Result = - substring (2, 2).to_integer
plus_sign_followed_by_single_digit: count = 2 and item (1) = '+' implies Result = substring (2, 2).to_integer
recurse_to_reduce_length: count > 2 or count = 2 and not ((+-).has (item (1))) implies Result // 10 = substring (1, count - 1).to_integer and (Result \\ 10).abs = substring (count, count).to_integer

to_lower
-- Convert all letters to lower case.
ensure
length_and_content: is_equal ( as_lower )

to_real: REAL
-- Real value
-- for example, when applied to "123.0", will yield 123.0
require
represents_a_real: is_real

to_upper
-- Convert all letters to upper case.
ensure
length_and_content: is_equal ( as_upper )
feature -- Duplication

copy (other: like Current)
-- Reinitialize by copying the characters of `other'.
-- (This is also used by clone.)
-- (From GENERAL.)

infix "+" (other: STRING): like Current
-- New object which is a clone of `Current' extended
-- by the characters of `other'.
-- Create a new object which is the concatenation of Current and other
require
other_exists: other /= void
ensure
result_not_void: Result /= void
result_count: Result.count = count + other.count
initial: Result.substring (1, count).is_equal (Current)
final: Result.substring (count + 1, count + other.count).same_string (other)
feature -- Output

out: STRING
-- New STRING containing terse printable representation
-- of current object
ensure
same_items: same_type () implies Result.same_string (Current)
feature -- Initialization: Visual Eiffel 3.2 compatibility

frozen remake (n: INTEGER)
obsolete "Visual Eiffel 3.2 compatibility, use wipe_out or make"
-- Allocate space for at least 'n' characters
require
non_negative_size: n >= 0
ensure
empty_string: count = n
feature -- Initialization: Eiffel/S 1.3 compatibility

adapt (other: STRING)
obsolete "Eiffel/S 1.3 compatibility, use make_from_string"
-- Initialize Current's text from string 's'
require
not_void_other: other /= void
feature -- Access: ELKS'1995 compatibility

item_code (i: INTEGER): INTEGER
-- Numeric code of character at position 'i'
require
valid_index: valid_index (i)
feature -- Comparison: Visual Eiffel 3.2 compatibility

same_as (other: STRING): BOOLEAN
-- Is string made of same character sequence as other?
-- Case insensitive comparison.
require
other_exists: other /= void
feature -- Comparison: Eiffel/S 1.3 compatibility

compare (other: like Current): INTEGER
obsolete "Eiffel/S 1.3 compatibility, use three_way_comparison"
require
not_void_other: other /= void
feature -- Status report: Visual Eiffel specific

is_open: BOOLEAN
feature -- Status report: ELKS'1995 compatibility

empty: BOOLEAN
obsolete "ELKS'1995 compatibility, use is_empty"
-- Is string empty?
feature -- Element change: ELKS'1995 compatibility

append_boolean (b: BOOLEAN)
-- Append the string representation of 'b' at end

append_double (d: DOUBLE)
-- Append the string representation of 'd' at end

append_integer (i: INTEGER)
-- Append the string representation of 'i' at end

append_real (r: REAL)
-- Append the string representation of 'r' at end

fill_blank
-- Fill with blanks

head (n: INTEGER)
obsolete "ELKS'1995 compatibility, use keep_head"
-- 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 ( count )

insert (s: like Current; i: INTEGER)
-- Add 's' to the left of position 'i'
require
string_exists: s /= void
good_key: valid_index (i)
ensure
new_count: count = (count + s.count)

left_adjust
-- Remove leading white space
ensure
new_count: (count /= 0) implies (item (1).code > (' ').code)

precede (ch: CHARACTER)
-- Add 'ch' at front
ensure
new_count: count = count + 1

prepend (s: STRING)
-- Prepend a copy of 's' at front
require
argument_not_void: s /= void
ensure
new_count: count = (count + s.count)

right_adjust
-- Remove trailing white space
ensure
new_count: (count /= 0) implies (item (count) /= ' ')

set (t: like Current; n1, n2: INTEGER)
-- Set current string to substring of 't' from indices 'n1'
-- to 'n2', or to empty string if no such substring
require
argument_not_void: t /= void
meaningful_origin: 1 <= n1
meaningful_interval: n1 <= n2
meaningful_end: n2 <= t.count
ensure
is_substring: is_equal ( clone (t.substring (n1, n2)) )

tail (n: INTEGER)
obsolete "ELKS'1995 compatibility, use keep_tail"
-- Remove all characters except for the last 'n'
require
non_negative_element: n >= 0
ensure
new_count: count = n.min ( count )
feature -- Element change: Visual Eiffel 3.3 compatibility

fill (c: CHARACTER)
obsolete "Visual Eiffel 3.3 compatibility, use fill_with"
-- Replace every character with `c'.
ensure
same_count: count = count
filled: occurrences (c) = count

put_substring (s: like Current; start_pos, end_pos: INTEGER)
obsolete "Visual Eiffel 3.3 compatibility, use replace_substring"
-- Copy the characters of 's' to positions 'start_pos'..'end_pos'
require
string_exists: s /= void
index_small_enough: end_pos <= count
order_respected: start_pos <= end_pos
index_large_enough: start_pos > 0
ensure
new_count: count = (count + s.count) - end_pos + start_pos - 1
feature -- Element change: Eiffel/S 1.3 compatibility

append (other: STRING)
obsolete "Eiffel/S 1.3 compatibility, use append_string"
-- Append 'other' to Current
require
not_void_other: other /= void

extend (ch: CHARACTER)
obsolete "Eiffel/S 1.3 compatibility, use append_character"
-- Append 'ch' to string
feature -- Removal: ELKS'1995 compatibility

prune (c: CHARACTER)
-- Remove first occurrence of 'c', if any

prune_all (c: CHARACTER)
-- Remove all occurrences of 'c'
ensure
changed_count: count = ( count ) - ( occurrences (c) )
no_more_occurrences: not has (c)
feature -- Resizing: ELKS'1995 compatibility

resize (newsize: INTEGER)
-- Rearrange string so that it can accommodate
-- at least 'newsize' characters.
-- Do not lose any previously entered characters
require
new_size_non_negative: newsize >= 0
feature -- Conversion: ELKS'1995 compatibility

mirror
-- Reverse the order of characters.
-- "Hello world" -> "dlrow olleH"
ensure
same_count: count = count
reversed:

mirrored: like Current
-- Mirror image of string
-- result for "Hello world" is "dlrow olleH"
ensure
same_count: Result.count = count

to_pointer: POINTER
-- A pointer to a C from of current string.
-- Useful only for interfacing with C software
feature -- Conversion: Visual Eiffel 3.2 compatibility

to_external, to_c: POINTER
-- A pointer to a C from of current string.
-- Useful only for interfacing with C software
feature -- Output: Visual Eiffel specific

code_sequence: STRING
-- Printable representation of the string with all the special
-- characters replaced by the special character codes
-- This is a newly created string
-- Examples:
-- code_sequence ("ABC") = "ABC" -- printed as ABC
-- code_sequence ("A%B") = "A%%B" -- printed as A%B
-- code_sequence ("%Ax") = "@x" -- printed as @x
-- code_sequence ("5%%") = "5%%%%" -- printed as 5%%
-- code_sequence ("%"") = "%%%"" -- printed as %"
-- code_sequence ("%/130/") = "%%/130/" -- printed as %/130/
-- So, the output enclosed in double quotes gives the original string
ensure
non_void_result: Result /= void
long_enough: Result.count >= count
invariant

non_negative_count: count >= 0
end -- class STRING

INDEX CLUSTER FEATURES SHORT FRAMES NO FRAMES