Author:halw

Date:2008-10-25T08:00:01.000000Z


git-svn-id: https://svn.eiffel.com/eiffel-org/trunk@97 abb3cda0-5349-4a8f-a601-0c33ac3a8c38
This commit is contained in:
halw
2008-10-25 08:00:01 +00:00
parent 2e37ddeca3
commit 19bcd2b1ec
26 changed files with 454 additions and 354 deletions

View File

@@ -260,7 +260,7 @@ The way to avoid this is to use the non-strict booleans " <code> and then </code
name_not_empty: a_nm /= Void and then not a_nm.is_empty
offset_valid: a_offset >= -12 and a_offset <= 12
do
name := clone (a_nm)
name := a_nm.twin
utcoffset := a_offset
ensure
name_initialized: name.is_equal (a_nm)

View File

@@ -14,17 +14,23 @@ The list and chain classes are characterized, for their traversal properties, as
[[ref:/libraries/base/reference/linear_chart|LINEAR]] describes sequential structures that may be traversed one way. It introduces in particular the following features, illustrated on the figure below:
* <eiffel>after</eiffel>, a boolean-valued query which determines whether you have moved past the last position (a more precise specification is given below).
* <eiffel>off</eiffel>, a boolean-valued query which is false if and only if there is no item at the current position; for [[ref:/libraries/base/reference/linear_chart|LINEAR]] this is the same as:
<code>is_empty and not after</code>
<code>
is_empty and not after</code>
* <eiffel>item</eiffel>, a query which returns the item at the current position - provided of course there is one, as expressed by the precondition:
<code>not off</code>
<code>
not off</code>
* <eiffel>start</eiffel>, a command to move to the first position if any (if is_empty is true the command has no effect).
* <eiffel>forth</eiffel>, a command to advance by one position; the precondition is not after.
* <eiffel>finish</eiffel>, a command to move to the last position; the precondition is: <br/>
<code>not is_empty</code>
<code>
not is_empty</code>
[[Image:linear|fig.1: Linear Structure]]
[[Image:linear|fig.1: Linear Structure]]
There is also a procedure <eiffel>search</eiffel> with one argument, which determines whether the value of that argument appears in the structure at or after the current position, and if not makes <eiffel>after</eiffel> become true. This procedure is internally used by the default implementation of the <eiffel>has</eiffel> function (the general membership test) for linear structures. Like has for all containers, <eiffel>search</eiffel> uses object or reference equality depending on the value set for <eiffel>object_comparison</eiffel>.
An invariant property of [[ref:/libraries/base/reference/linear_chart|LINEAR]] structures is that the current position may go off one step past the last item if any, but no further. The precondition of <eiffel>forth</eiffel> - not after - helps ensure this. The first item (if any) being at position 1, the maximum allowable position is <eiffel>count</eiffel> + 1, where <eiffel>count</eiffel> is the number of items.
@@ -36,57 +42,69 @@ An invariant property of [[ref:/libraries/base/reference/linear_chart|LINEAR]]
* <eiffel>back</eiffel>, a command to move backward by one position; the precondition is not before.
For bilinear structures the position can range between 0 (not just 1) and count + 1. Query off is accordingly redefined so as to yield the value of after or before.
[[Image:bilinear|fig.2: Bilinear Structure]]
[[Image:bilinear|fig.2: Bilinear Structure]]
==Invariant properties for after, before and off==
The redefinition of <eiffel>off</eiffel> illustrates a general methodological advice about invariants: be careful about not over-constraining the invariant by including properties that may be made more general in descendants. It might have been tempting to include in [[ref:/libraries/base/reference/linear_chart|LINEAR]] an invariant clause of the form
<code>off = is_empty or after</code>
<code>
off = is_empty or after</code>
This property, however, would be too constraining. More precisely, it is always true that the right-hand side implies the left-hand-side: if a linear structure is either empty or after, then it is off. But the converse is not true, since certain kinds of linear structure, for example bilinear ones, may be off but neither empty nor after. <br/>
The actual invariant for class [[ref:/libraries/base/reference/bilinear_chart|BILINEAR]] is obtained in three stages. In class [[ref:/libraries/base/reference/traversable_chart|TRAVERSABLE]] the feature off is deferred and a basic property of that feature is expressed by the invariant clause
<code>empty_constraint:is_empty implies off</code>
<code>
empty_constraint:is_empty implies off</code>
In [[ref:/libraries/base/reference/linear_chart|LINEAR]] , feature <eiffel>off</eiffel> is effected through an implementation which returns the value of the expression <eiffel>is_empty</eiffel> or <eiffel>after</eiffel>. The class adds an invariant clause which, however, says less than the implementation to leave some room for variation:
<code>after_constraint:after implies off</code>
<code>
after_constraint:after implies off</code>
Finally [[ref:/libraries/base/reference/bilinear_chart|BILINEAR]] , an heir of [[ref:/libraries/base/reference/linear_chart|LINEAR]] , redefines <eiffel>off</eiffel> to return the value of the expression
<code>before or after</code>
<code>
before or after</code>
and adds the invariant clause
<code>before_constraint: before implies off</code>
<code>
before_constraint: before implies off</code>
The new implementation of <eiffel>off</eiffel>
<code>after or before</code>
<code>
after or before</code>
would not guarantee the invariant clause inherited from [[ref:/libraries/base/reference/traversable_chart|TRAVERSABLE]] were it not for another clause introduced in [[ref:/libraries/base/reference/bilinear_chart|BILINEAR]] :
<code>empty_property: is_empty implies (after or before )</code>
<code>
empty_property: is_empty implies (after or before )</code>
which indicates that an empty bilinear structure must always be <eiffel>after</eiffel> or <eiffel>before</eiffel> but not both, however, as stated by the last new clause, the reason for which is discussed in detail below:
<code>not_both: not(after and before)</code>
<code>
not_both: not(after and before)</code>
The flat-short form of [[ref:/libraries/base/reference/bilinear_chart|BILINEAR]] shows the complete reconstructed invariant:
<code>
not_both: not (after and before)
empty_property: is_empty implies (after or before)
before_constraint: before implies off
after_constraint: after implies off
empty_constraint: is_empty implies off</code>
not_both: not (after and before)
empty_property: is_empty implies (after or before)
before_constraint: before implies off
after_constraint: after implies off
empty_constraint: is_empty implies off</code>
==Iteration patterns==
For a more general form of this scheme, applicable to circular chains as well as other linear structures, replace <eiffel>off</eiffel> by <eiffel>exhausted</eiffel>. With the features shown above, a typical iteration mechanism on a non-empty linear structure 'lin' is of the form:
<code>
from
lin.start
some_optional_initializing_operation (lin)
until
lin.off
loop
lin.some_action (lin.item)
lin.forth
end</code>
from
lin.start
some_optional_initializing_operation (lin)
until
lin.off
loop
lin.some_action (lin.item)
lin.forth
end</code>
The value of <code> lin </code> <code> . </code>off is always true for an empty structure, so in this case the loop will, correctly, execute only its initialization actions if present. <br/>
The value of <code>lin.off</code> is always true for an empty structure, so in this case the loop will, correctly, execute only its initialization actions if present. <br/>
This is a very common pattern, which you will find in the library classes themselves (for example has is implemented in this way) and many application clients. The iterator classes corresponding to linear structures ([[ref:/libraries/base/reference/linear_iterator_chart|LINEAR_ITERATOR]] , [[ref:/libraries/base/reference/two_way_chain_iterator_chart|TWO_WAY_CHAIN_ITERATOR]] ) turn this pattern and several related ones into actual reusable routines. <br/>
For bilinear structures there is another traversal mechanism going backward rather than forward; it is the same as above except that <eiffel>finish</eiffel> replaces <eiffel>start</eiffel> and <eiffel>back</eiffel> replaces <eiffel>finish</eiffel>. The exit condition remains <eiffel>off</eiffel> since <eiffel>before</eiffel>, like <eiffel>after</eiffel>, implies <eiffel>off</eiffel>.
@@ -98,23 +116,27 @@ For every one of the structures under discussion there is a notion of current po
* <eiffel>finish</eiffel>, <eiffel>back</eiffel>, <eiffel>before</eiffel>.
So for an empty list both <eiffel>before</eiffel> and <eiffel>after</eiffel> should be true. This scheme was used in early version of the Base libraries. It has some disadvantages, however; in particular it is not compatible with the simple, symmetric properties:
<code>after = (index = count + 1)
before = (index = 0)</code>
<code>
after = (index = count + 1)
before = (index = 0)</code>
which express elementary definitions for <eiffel>after</eiffel> and <eiffel>before</eiffel> in terms of <eiffel>index</eiffel>, the current position, and <eiffel>count</eiffel>, the number of items (items being numbered from 1 to count). For an empty structure <eiffel>count</eiffel> is zero, so if we want <eiffel>after</eiffel> and <eiffel>before</eiffel> to be both true in this case we have to sacrifice one of the above properties, since the first would imply index to 1 and the second to 0. But again symmetry reigns supreme: we should either keep both properties or renounce both. The solution was to renounce both and replace them by slightly more complicated ones:
<code>after = (is_empty or (index = count + 1))
before = (is_empty or (index = 0))</code>
<code>
after = (is_empty or (index = count + 1))
before = (is_empty or (index = 0))</code>
When a structure is created, some initializations will have to be made; the default initializations will usually lead to a value of 0 rather than 1 for index, although this dissymetry is not apparent in the assertions. Although acceptable, this solution leads to small but unpleasant complications, in particular frequent conditional instructions of the form
<code>if after and not is_empty then...</code>
<code>
if after and not is_empty then...</code>
The solution finally retained for the Base libraries uses a different technique, which has turned out to be preferable. The idea is to replace the conceptual picture by one in which there are always two fictitious sentinel items. The two sentinel items are only present conceptually. They are of course not taken into account for the computation of <eiffel>count</eiffel> and, although it is possible to conceive of an implementation which would actually reserve space for them (for example in an array representation), none of the implementations used in Base for the classes of this documentation and other descendants of [[ref:/libraries/base/reference/linear_chart|LINEAR]] do. The only purpose of the sentinels is to provide two valid theoretical cursor positions, which exist regardless of the number of actual (non-sentinel) items in the structure. <br/>
The sentinel items always appear at positions 0 and <eiffel>count</eiffel> + 1; this property is true even if the structure is empty of items, in which case count is zero. As a result, the following properties are part of the invariant:
<code>0 <= index
index <= count + 1
before = (index = 0)
after = (index = count + 1)
not (after and before)</code>
<code>
0 <= index
index <= count + 1
before = (index = 0)
after = (index = count + 1)
not (after and before)</code>
The last property given indicates that a structure can never be both <eiffel>after</eiffel> <code>and</code> <eiffel>before</eiffel>, since even in an empty structure the two sentinels are still present, with the cursor on one of them. For an empty structure, <eiffel>index</eiffel> will be zero by convention, so that <eiffel>before</eiffel> will be true and <eiffel>after</eiffel> false. But this property is not reflected in any of the invariant clauses.
@@ -137,20 +159,20 @@ SEQUENCE is constructed with the full extent of the technique described in the d
* FINITE, from the storage hierarchy, indicates that the class describes finite sequences. (A class [[ref:/libraries/base/reference/countable_sequence_chart|COUNTABLE_SEQUENCE]] is also present, as described below.)
To the features of [[ref:/libraries/base/reference/bilinear_chart|BILINEAR]] , [[ref:/libraries/base/reference/sequence_chart|SEQUENCE]] principally adds features for adding, changing and removing items. A few procedures in particular serve to insert items at the end:
* <code> s .put ( v ) adds v at the end of a sequence s </code>.
* <code>s .put ( v )</code> adds v at the end of a sequence s.
* <eiffel> extend</eiffel> and <eiffel>force</eiffel>, at the [[ref:/libraries/base/reference/sequence_chart|SEQUENCE]] level, do the same as <eiffel>put</eiffel>.
* <code> s .append ( s1 )</code> adds to the end of s the items of s1 (another sequence), preserving their s1 order.
* <code>s .append ( s1 )</code> adds to the end of s the items of s1 (another sequence), preserving their s1 order.
Other procedures work on the current position:
* <code> s . </code><eiffel>remove</eiffel> removes the item at current position.
* <code> s .replace ( v ) replaces by v </code> the item at current position.
* <code>s.</code><eiffel>remove</eiffel> removes the item at current position.
* <code>s.replace ( v )</code> replaces by v the item at current position.
SEQUENCE, however, does not provide a procedure to insert an item at the current position, since not all implementations of sequences support this possibility; you will find it in descendants of [[ref:/libraries/base/reference/sequence_chart|SEQUENCE]] seen below. <br/>
Yet another group of features are based on the first occurrence of a certain item, or on all occurrences:
* <code> s .prune ( v ) removes the first occurrence of v in s </code>, if any.
* <code> s .prune_all ( v ) removes all occurrences of v </code>.
* <code>s.prune ( v ) removes the first occurrence of v in s</code>, if any.
* <code>s.prune_all ( v ) removes all occurrences of v</code>.
These procedures have various abstract preconditions: <code> s .extendible for additions, s .writable for replacements, s . </code><eiffel>prunable</eiffel> for removals. Properties <eiffel>extendible</eiffel> and <eiffel>prunable</eiffel> characterize general categories of container structures rather than individual instances; for example <eiffel>extendible</eiffel> is always true for the 'dynamic' structures seen below. In contrast, <eiffel>writable</eiffel> depends on the current status of each instance. In general <eiffel>writable</eiffel> will be true if there is an item at the current position.
These procedures have various abstract preconditions: <code>s .extendible for additions, s .writable for replacements, s .</code><eiffel>prunable</eiffel> for removals. Properties <eiffel>extendible</eiffel> and <eiffel>prunable</eiffel> characterize general categories of container structures rather than individual instances; for example <eiffel>extendible</eiffel> is always true for the 'dynamic' structures seen below. In contrast, <eiffel>writable</eiffel> depends on the current status of each instance. In general <eiffel>writable</eiffel> will be true if there is an item at the current position.
==Chains==
@@ -168,7 +190,7 @@ By default, chains can only be extended at the end, through <eiffel>extend</eiff
* Procedure <eiffel>put_front</eiffel> adds an item before the first. (As noted, the procedures to add an item after the last are already available in chains.)
* Procedures <eiffel>put_left</eiffel> and <eiffel>put_right</eiffel> add an item at the left and right of the cursor position.
* Procedures <eiffel>remove_left</eiffel> and remove_right remove an item at the left and right or the cursor position.
* Procedures <eiffel>merge_left</eiffel> and <eiffel>merge_right</eiffel> are similar to <eiffel>put_left</eiffel> and <eiffel>put_right</eiffel> but insert another dynamic chain rather than a single item. As the word 'merge' suggests, the merged structure, passed as argument, does not survive the process; it is emptied of its items. To preserve it, perform a <eiffel>clone</eiffel> or <eiffel>copy</eiffel> before the merge operation.
* Procedures <eiffel>merge_left</eiffel> and <eiffel>merge_right</eiffel> are similar to <eiffel>put_left</eiffel> and <eiffel>put_right</eiffel> but insert another dynamic chain rather than a single item. As the word 'merge' suggests, the merged structure, passed as argument, does not survive the process; it is emptied of its items. To preserve it, perform a <eiffel>twin</eiffel> or <eiffel>copy</eiffel> before the merge operation.
The class also provides implementations of <eiffel>prune</eiffel>, <eiffel>prune_all</eiffel> and <eiffel>wipe_out</eiffel> from [[ref:libraries/base/reference/collection_chart|COLLECTION]] . To make these implementations useful, it defines queries <eiffel>extendible</eiffel> and <eiffel>prunable</eiffel> so that they return the value true.
@@ -185,10 +207,12 @@ first. The symmetric property applies to <eiffel>back</eiffel>. The cyclic natur
<code>not after</code>
Similarly, the precondition for back is
<code>not before</code>
<code>
not before</code>
For lists, after becomes true when the cursor moves past the last item. For circular chains, however, after and before are never true except for an empty structure; this is expressed by the invariant clauses of class [[ref:/libraries/base/reference/circular_chart|CIRCULAR]] :
<code>not before</code>
<code>
not before</code>
For a non-empty circular chain, then, you can circle forever around the items, using forth or back.
@@ -199,43 +223,45 @@ A circular chain also needs a notion of first item, if only to enable a client t
For circular chains, however, there is no reason why the first item should always remain the same. One of the benefits that clients may expect from the use of a circular <br/>
structure is the ability to choose any item as the logical first. Class [[ref:/libraries/base/reference/circular_chart|CIRCULAR]] offers for that purpose the procedure <eiffel>set_start</eiffel> which designates the current cursor position as the first in the circular chain. Subsequent calls to <eiffel>start</eiffel> will move the cursor to this position; calls to <eiffel>finish</eiffel> will move the cursor to the cyclically preceding position. With most implementations, there will then be two notions of first position: the logical first, which clients may freely choose through calls to <eiffel>set_start</eiffel>; and the <eiffel>physical first</eiffel>, which results from the implementation. In a representation using an array with indices from 1 to <eiffel>capacity</eiffel>, for example, the physical first is position 1, and the logical first may be any index in the permitted range. In a linked representation, there will be a cell first element corresponding to the physical first, but the logical first is any cell in the chain. <br/>
In such cases the circular chain classes have features called <eiffel>standard_first</eiffel>, <eiffel>standard_last</eiffel>, <eiffel>standard_start</eiffel> and so on, which are not exported (so that you will not see them in the flat-short forms) but serve to implement visible features such as <eiffel>first</eiffel>, <eiffel>last</eiffel> and <eiffel>forth</eiffel>. For example a possible implementation of <eiffel>forth</eiffel> for circular chains is
<code>forth is
-- Move cursor to next item, cyclically.
do
standard_forth
if standard_after then
standard_start
end
if isfirst then
exhausted := True
end
end</code>
<code>
forth
-- Move cursor to next item, cyclically.
do
standard_forth
if standard_after then
standard_start
end
if isfirst then
exhausted := True
end
end</code>
==Traversing a list or circular chain==
The properties of <eiffel>forth</eiffel> for circular chains imply that a traversal loop written as
<code>from
lin.start
until
lin.off
loop
...
lin.forth
end </code>
<code>
from
lin.start
until
lin.off
loop
...
lin.forth
end</code>
would not work if <code> lin </code> is a non-empty circular structure: <eiffel>off</eiffel> would never become true, so that the loop would forever cycle over the structure's items. The same would apply to a loop using finish and back instead of <eiffel>start</eiffel> and <eiffel>forth</eiffel>. This behavior is the natural result of the semantics defined for <eiffel>off</eiffel> , <eiffel>forth</eiffel> and <eiffel>back</eiffel> for circular structures. But it prevents us from using these features to perform a single traversal which will visit every item once. <br/>
would not work if <code>lin</code> is a non-empty circular structure: <eiffel>off</eiffel> would never become true, so that the loop would forever cycle over the structure's items. The same would apply to a loop using finish and back instead of <eiffel>start</eiffel> and <eiffel>forth</eiffel>. This behavior is the natural result of the semantics defined for <eiffel>off</eiffel> , <eiffel>forth</eiffel> and <eiffel>back</eiffel> for circular structures. But it prevents us from using these features to perform a single traversal which will visit every item once. <br/>
Using <eiffel>exhausted</eiffel> in lieu of off solves this problem. In class [[ref:/libraries/base/reference/circular_chart|CIRCULAR]] , <eiffel>exhausted</eiffel> is an attribute which is set to false by <eiffel>start</eiffel> and <eiffel>finish</eiffel>, and is set to true by <eiffel>forth</eiffel> when advancing from the last item to the first and by <eiffel>back</eiffel> when backing up from the first item to the last. So you should write the loop as
<code>from
lin.start
some_optional_initializing_operation (lin)
until
lin.exhausted
loop
...
lin.some_action (lin.item)
lin.forth
end</code>
<code>
from
lin.start
some_optional_initializing_operation (lin)
until
lin.exhausted
loop
...
lin.some_action (lin.item)
lin.forth
end</code>
This form is applicable to all linear structures, circular or not, since <eiffel>exhausted</eiffel> is introduced in class [[ref:/libraries/base/reference/linear_chart|LINEAR]] as a function which returns the same value as <eiffel>off</eiffel> .Its redefinition into an attribute, modified by <eiffel>start</eiffel>,<eiffel> finish</eiffel>, <eiffel>forth</eiffel> and <eiffel>back</eiffel>, does not occur until class [[ref:/libraries/base/reference/circular_chart|CIRCULAR]] . <br/>
Because <eiffel>exhausted</eiffel> is more general than <eiffel>off</eiffel> , the iteration scheme just given (and its equivalent going backwards) is preferable to the earlier one using <eiffel>off </eiffel>, especially if there is any chance that the iteration might one day be applied to a lin structure that is circular. Classes of the Iteration library, in particular [[ref:/libraries/base/reference/linear_iterator_chart|LINEAR_ITERATOR]] , rely on this scheme for iterating over linear structures.
@@ -268,20 +294,28 @@ An arrayed implementation uses an array to represent a linear structure. If the
==Linked structures==
A linked structure requires two classes: one, such as [[ref:/libraries/base/reference/linked_list_chart|LINKED_LIST]] , describes the list proper; the other, such as [[ref:/libraries/base/reference/linkable_chart|LINKABLE]] , describes the individual list cells. The figure should help understand the difference; it describes a linked list, but the implementation of linked circular chains is similar.
[[Image:linked-list|fig.3: Linked list and linked cells]]
[[Image:linked-list|fig.3: Linked list and linked cells]]
The instance of type [[ref:/libraries/base/reference/linked_list_chart|LINKED_LIST]] shown at the top contains general information about the list, such as the number of items (<eiffel>count</eiffel>) and a reference to the first element (first). Because lists are active structures with a notion of current position, there is also a reference active to the cell at the current position. An entity declared as
<code>my_list: LINKED_LIST [SOME_TYPE] </code>
<code>my_list: LINKED_LIST [SOME_TYPE]</code>
will have as its run-time value (if not void) a reference to such an object, which is really a list header. The actual list content is given by the [[ref:/libraries/base/reference/linkable_chart|LINKABLE]] instances, each of which contains a value of type <eiffel>SOME_TYPE</eiffel> and a reference to the next item, called <eiffel>right</eiffel>. <br/>
Clearly, a header of type <code>LINKED_LIST [SOME_TYPE]</code> will be associated with cells of type <code>LINKABLE [SOME_TYPE]</code>. <br/>
Features such as active and first are used only for the implementation; they are not exported, and so you will not find them in the flat-short specifications, although the figures show them to illustrate the representation technique. <br/>
A similar implementation is used for two-way-linked structures such as two-way lists and two-way circular chains.
[[Image:two-way-list|fig.4: Two way linked list]]
[[Image:two-way-list|fig.4: Two way linked list]]
==Linked cells==
The classes describing list cells are descendants of a deferred class called [[ref:/libraries/base/reference/cell_chart|CELL]] , whose features are:
* <eiffel>item</eiffel>, the contents of the cell.
* <eiffel>put </eiffel> <code> ( v : </code> <code> like </code> <eiffel>item</eiffel> <code> ) </code>, which replaces the contents of the cell by a new value.
* <eiffel>put </eiffel> <code>(v : like</code> <eiffel>item</eiffel><code>)</code>, which replaces the contents of the cell by a new value.
Class [[ref:/libraries/base/reference/linkable_chart|LINKABLE]] is an effective descendant of [[ref:/libraries/base/reference/cell_chart|CELL]] , used for one-way linked structures. It introduces features <eiffel>right</eiffel>, a reference to another cell to which the current <br/>
cell will be linked. Two-way linked structures use [[ref:/libraries/base/reference/bi_linkable_chart|BI_LINKABLE]] , an heir of [[ref:/libraries/base/reference/linkable_chart|LINKABLE]] which to the above features adds <eiffel>left</eiffel>, a reference to the preceding cell in the structure.
@@ -289,11 +323,12 @@ cell will be linked. Two-way linked structures use [[ref:/libraries/base/referen
{{caution|Do not confuse the <eiffel>item</eiffel> feature of [[ref:/libraries/base/reference/cell_chart|CELL]] and its descendants, such as [[ref:/libraries/base/reference/linkable_chart|LINKABLE]] , with the <eiffel>item</eiffel> feature of the classes describing linear structures, such as [[ref:/libraries/base/reference/linked_list_chart|LINKED_LIST]] . For a linked list, <eiffel>item</eiffel> returns the item at cursor position. }}
It may be implemented as
<code>item: G is
-- Current item
do
Result := active.item
end</code>
<code>
item: G
-- Current item
do
Result := active.item
end</code>
using the <eiffel>item</eiffel> feature of [[ref:/libraries/base/reference/linkable_chart|LINKABLE]] , applied to <eiffel>active</eiffel>.
@@ -328,12 +363,13 @@ divided into a number of blocks. Each block is an array, but the successive arra
=Sorted Linear Structures=
The class [[ref:/libraries/base/reference/comparable_struct_chart|COMPARABLE_STRUCT]] , an heir of [[ref:/libraries/base/reference/bilinear_chart|BILINEAR]] , is declared as
<code>deferred class
COMPARABLE_STRUCT [G -> COMPARABLE]
inherit
BILINEAR
feature
... </code>
<code>
deferred class
COMPARABLE_STRUCT [G -> COMPARABLE]
inherit
BILINEAR
feature
...</code>
As indicated by the constrained generic parameter it describes bilinear structures whose items may be compared by a total order relation.
@@ -342,8 +378,9 @@ As indicated by the constrained generic parameter it describes bilinear structur
COMPARABLE_STRUCT introduces the features <eiffel>min</eiffel> and <eiffel>max</eiffel>, giving access to the minimum and maximum elements of a structure; these are always present for a finite <br/>
structure with a total order relation. [[ref:/libraries/base/reference/sorted_struct_chart|SORTED_STRUCT]] , an heir of [[ref:/libraries/base/reference/comparable_struct_chart|COMPARABLE_STRUCT]] , describes structures that can be sorted; it introduces the query sorted and the command sort. <br/>
The deferred class [[ref:/libraries/base/reference/part_sorted_list_chart|PART_SORTED_LIST]] describes lists whose items are kept ordered in a way that is compatible with a partial order relation defined on them. The class is declared as
<code>deferred class
PART_SORTED_LIST [G -> COMPARABLE]...</code>
<code>
deferred class
PART_SORTED_LIST [G -> COMPARABLE]...</code>
An implementation based on two-way linked lists is available through the effective heir [[ref:/libraries/base/reference/sorted_two_way_list_chart|SORTED_TWO_WAY_LIST]] . <br/>
The deferred class [[ref:/libraries/base/reference/sorted_list_chart|SORTED_LIST]] , which inherits from [[ref:/libraries/base/reference/part_sorted_list_chart|PART_SORTED_LIST]] , assumes that the order relation on G is a total order. As a result, the class is able to introduce features <eiffel>min</eiffel>, <eiffel>max</eiffel> and <eiffel>median</eiffel>. Here too a two-way linked list implementation is available, through the effective class [[ref:/libraries/base/reference/sorted_two_way_list_chart|SORTED_TWO_WAY_LIST]] .

View File

@@ -53,13 +53,16 @@ The classes of the Iteration library address this need. Using them offers two be
To get a first grasp of how one can work with the Iteration library, let us look at a typical iteration class and a typical iteration client.
==An example iterator routine==
Here, given with its full implementation, is a typical Iteration library routine: the procedure until_do from [[ref:libraries/base/reference/linear_iterator_chart]] , the class defining iteration mechanisms on linear (sequential) structures.
<code>
until_do is
until_do
-- Apply action to every item of target,
-- up to but excluding first one satisfying test.
-- (Apply to full list if no item satisfies test.)
@@ -86,7 +89,7 @@ This procedure will traverse the linear structure identified by target and apply
The class similarly offers <eiffel>do_all</eiffel>, <eiffel>do_while</eiffel>, <eiffel>do_for</eiffel>, <eiffel>do_if</eiffel> and other procedures representing the common control structures. It also includes functions such as <eiffel>exists</eiffel> and <eiffel>forall</eiffel>, corresponding to the usual quantifiers. <br/>
These iteration schemes depend on the procedure <eiffel>action</eiffel>, defining the action to be applied to successive elements, and on the function <eiffel>test</eiffel>, defining the boolean query to be applied to these elements. These features are declared in class [[ref:/libraries/base/reference/iterator_chart|ITERATOR]] (the highest-level deferred class of the Iteration library); here is <eiffel>test</eiffel>:
<code>
test: BOOLEAN is
test: BOOLEAN
-- Test to be applied to item at current position in
-- target (default: value of item_test on item)
require
@@ -128,7 +131,7 @@ inherit
feature
resize_paragraphs (t: TEXT) is
resize_paragraphs (t: TEXT)
-- Resize all the paragraphs of t up to but excluding
-- the first one that has been modified.
do
@@ -138,13 +141,13 @@ feature
feature {NONE}
item_test (p PARAGRAPH): BOOLEAN is
item_test (p PARAGRAPH): BOOLEAN
-- Has p been modified?
do
Result := p.modified
end
item_action (p: PARAGRAPH) is
item_action (p: PARAGRAPH)
-- Resize p.
do
p.resize
@@ -153,7 +156,7 @@ feature {NONE}
end</code>
Thanks to the iteration mechanism, the procedure <eiffel>resize_paragraphs</eiffel> simply needs two procedure calls:
* To set its argument <code> t </code> as the iteration target, it uses procedure <eiffel>set</eiffel>. (This procedure is from class [[ref:/libraries/base/reference/iterator_chart|ITERATOR]] which passes it on to all iterator classes.)
* To set its argument <code>t</code> as the iteration target, it uses procedure <eiffel>set</eiffel>. (This procedure is from class [[ref:/libraries/base/reference/iterator_chart|ITERATOR]] which passes it on to all iterator classes.)
* Then it simply calls <eiffel>until_do</eiffel> as defined above.
Procedure <eiffel>item_action</eiffel> is redefined to describe the operation to be performed on each successive element. Function <eiffel>item_test</eiffel> is redefined to describe the exit test. <br/>
@@ -195,17 +198,17 @@ Each one of the iterator classes is paired with a traversal class (or two in one
|}
Each iterator class relies on the corresponding traversal class to provide the features for traversing the corresponding data structures, such as <eiffel>start</eiffel>, <eiffel>forth</eiffel> and <eiffel>exhausted</eiffel> for linear structures. <br/>
Each iterator class relies on the corresponding traversal class to provide the features for traversing the corresponding data structures, such as <eiffel>start</eiffel>, <eiffel>forth</eiffel>, and <eiffel>exhausted</eiffel> for linear structures. <br/>
Of course the data structure class used in connection with a given iterator class does not need to be the iterator's exact correspondent as given by the above table; it may be any one of its descendants. For example you may use [[ref:/libraries/base/reference/linear_iterator_chart|LINEAR_ITERATOR]] to iterate over data structures described not just by [[ref:/libraries/base/reference/linear_chart|LINEAR]] but also by such descendants as [[ref:/libraries/base/reference/list_chart|LIST]] , [[ref:/libraries/base/reference/linked_list_chart|LINKED_LIST]] , [[ref:/libraries/base/reference/arrayed_list_chart|ARRAYED_LIST]] , or even [[ref:/libraries/base/reference/two_way_list_chart|TWO_WAY_LIST]] if you do not need the backward iteration features (for which you will have to use [[ref:/libraries/base/reference/two_way_chain_iterator_chart|TWO_WAY_CHAIN_ITERATOR]] ).
==General iteration facilities==
Class [[ref:/libraries/base/reference/iterator_chart|ITERATOR]] defines the features that apply to all forms of iterator. <br/>
An iterator will always apply to a certain target structure. The target is introduced in [[ref:/libraries/base/reference/iterator_chart|ITERATOR]] by the feature target: [[ref:/libraries/base/reference/traversable_chart|TRAVERSABLE]] [G] <br/>
Both the iterator classes and the traversal classes are generic, with a formal generic parameter G. The actual generic parameters will be matched through the choice of iteration target: for a generic derivation of the form <eiffel>SOME_ITERATOR</eiffel> [ <eiffel>ACTUAL_TYPE</eiffel>] the target can only be of type <eiffel>SOME_TRAVERSABLE</eiffel> [ <eiffel>ACTUAL_TYPE</eiffel>] for the same <eiffel>ACTUAL_TYPE</eiffel>, where <eiffel>SOME_TRAVERSABLE</eiffel> is the traversal class matching <eiffel>SOME_ITERATOR</eiffel> according to the preceding table ([[ref:/libraries/base/reference/linear_chart|LINEAR]] for [[ref:/libraries/base/reference/linear_iterator_chart|LINEAR_ITERATOR]] and so on), or one of its proper descendants. <br/>
Both the iterator classes and the traversal classes are generic, with a formal generic parameter G. The actual generic parameters will be matched through the choice of iteration target: for a generic derivation of the form <eiffel>SOME_ITERATOR</eiffel> [<eiffel>ACTUAL_TYPE</eiffel>] the target can only be of type <eiffel>SOME_TRAVERSABLE</eiffel> [<eiffel>ACTUAL_TYPE</eiffel>] for the same <eiffel>ACTUAL_TYPE</eiffel>, where <eiffel>SOME_TRAVERSABLE</eiffel> is the traversal class matching <eiffel>SOME_ITERATOR</eiffel> according to the preceding table ([[ref:/libraries/base/reference/linear_chart|LINEAR]] for [[ref:/libraries/base/reference/linear_iterator_chart|LINEAR_ITERATOR]] and so on), or one of its proper descendants. <br/>
Each of the proper descendants of [[ref:/libraries/base/reference/iterator_chart|ITERATOR]] redefines the type of target to the matching proper descendant of [[ref:/libraries/base/reference/traversable_chart|TRAVERSABLE]] , to cover more specific variants of the iteration target, For example in [[ref:/libraries/base/reference/linear_iterator_chart|LINEAR_ITERATOR]] the feature is redefined to be of type [[ref:/libraries/base/reference/linear_chart|LINEAR]] . [[ref:/libraries/base/reference/iterator_chart|ITERATOR]] also introduces the procedure for selecting a target:
<code>
set (s: like target) is
set (s: like target)
-- Make s the new target of iterations.
require
s /= Void
@@ -218,7 +221,7 @@ Each of the proper descendants of [[ref:/libraries/base/reference/iterator_chart
Next [[ref:/libraries/base/reference/iterator_chart|ITERATOR]] introduces the routines describing the elementary action and test that will be applied to items of the iteration targets:
<code>
action is
action
-- Action to be applied to item at current position in
-- target.
-- (default: item_action on item at current position.)
@@ -236,7 +239,7 @@ Next [[ref:/libraries/base/reference/iterator_chart|ITERATOR]] introduces the r
invariant_satisfied: invariant_value
end
test: BOOLEAN is
test: BOOLEAN
-- Test to be applied to item at current position in
-- target (default: value of item_test on item)
require
@@ -269,11 +272,12 @@ All these features, and most of the other iteration features introduced in prope
[[ref:/libraries/base/reference/linear_iterator_chart|LINEAR_ITERATOR]] , an effective class, refines the iteration mechanisms for cases in which the target is a linear structure, such as a list in any implementation or a circular chain. <br/>
The class effects all the deferred features inherited from [[ref:/libraries/base/reference/iterator_chart|ITERATOR]] , taking advantage of the linear traversal mechanisms present in the corresponding traversal class, [[ref:/libraries/base/reference/linear_chart|LINEAR]] . Here for example is the effecting of <eiffel>do_if</eiffel>:
<code>
do_if is
do_if
-- Apply action to every item of target satisfying
-- test.
do
from
target.start
invariant
invariant_value
@@ -289,7 +293,7 @@ The class effects all the deferred features inherited from [[ref:/libraries/base
This routine text relies on features <eiffel>start</eiffel>, <eiffel>forth</eiffel> and <eiffel>exhausted</eiffel> which, together with <eiffel>off</eiffel>, have for convenience been carried over to [[ref:/libraries/base/reference/linear_iterator_chart|LINEAR_ITERATOR]] from their counterparts in [[ref:/libraries/base/reference/linear_chart|LINEAR]] , with feature declarations such as
<code>
off: BOOLEAN is
off: BOOLEAN
-- Is position of target off?
require
traversable_exists: target /= Void
@@ -363,13 +367,13 @@ feature -- Status report
feature -- Cursor movement
finish is
finish
-- Move cursor of target to last position.
do
target.finish
end
back is
back
-- Move cursor of target backward one position.
do
target.back
@@ -383,11 +387,11 @@ This class provides a good example of the economy of expression that the full in
Tree iterations, provided by class [[ref:/libraries/base/reference/cursor_tree_iterator_chart|CURSOR_TREE_ITERATOR]] , work on trees of the cursor tree form; only with this form of tree are traversal operations possible. Three forms of iteration are provided: preorder, postorder and breadth-first. They correspond to the three traversal policies described in the discussion of trees. Here too it would seem that a rather lengthy class is needed, but repeated inheritance works wonders. <br/>
[[ref:/libraries/base/reference/cursor_tree_iterator_chart|CURSOR_TREE_ITERATOR]] simply inherits three times from [[ref:/libraries/base/reference/linear_iterator_chart|LINEAR_ITERATOR]] , renaming the features appropriately in each case:
* <eiffel>pre_do_all</eiffel>, <eiffel>pre_until</eiffel> and so on.
* <eiffel>post_do_all</eiffel>, <eiffel>post_until</eiffel> and so on.
* <eiffel>breadth_do_all</eiffel>, <eiffel>breadth_until</eiffel> and so on.
* <eiffel>pre_do_all</eiffel>, <eiffel>pre_until</eiffel>, and so on.
* <eiffel>post_do_all</eiffel>, <eiffel>post_until</eiffel>, and so on.
* <eiffel>breadth_do_all</eiffel>, <eiffel>breadth_until</eiffel>, and so on.
All it needs to do then is to redefine the type of target to be [[ref:/libraries/base/reference/cursor_tree_chart|CURSOR_TREE]] <code> [ </code> <eiffel>G</eiffel> <code> ] </code>, and to redefine six features: the three renamed start ( <eiffel>pre_start</eiffel> etc.) and the three forth ( <eiffel>pre_ forth</eiffel> and so on). These seven redefinitions give us a full-fledged battery of tree iteration mechanisms.
All it needs to do then is to redefine the type of target to be [[ref:/libraries/base/reference/cursor_tree_chart|CURSOR_TREE [G]]] , and to redefine six features: the three renamed start (<eiffel>pre_start</eiffel>, etc.) and the three forth ( <eiffel>pre_ forth</eiffel>, and so on). These seven redefinitions give us a full-fledged battery of tree iteration mechanisms.
=Building and Using Iterators=
@@ -396,7 +400,7 @@ An application class may use one of the iteration classes in either of two ways:
==The single descendant technique==
Assume an application class <eiffel>PROCESSOR</eiffel> that is a proper descendant of one of the effective iteration classes studied in this chapter. Then a routine of <eiffel>PROCESSOR</eiffel>, say <eiffel>iterate</eiffel>, may iterate a certain action over a data structure, subject to a certain test. First, class <eiffel>PROCESSOR</eiffel> must specify the action by redefining item_action and item_test (or, in the most general case, action and test). Then routine iterate must specify the target data structure through a call of the form set <code> ( </code> <code> t ) where t represents the selected target data structure. The type of t must correspond tothe iteration class selected as ancestor of </code> <eiffel>PROCESSOR</eiffel>: for [[ref:/libraries/base/reference/linear_iterator_chart|LINEAR_ITERATOR]] it must be a descendant of [[ref:/libraries/base/reference/linear_chart|LINEAR]] (such as [[ref:/libraries/base/reference/linked_list_chart|LINKED_LIST]] , [[ref:/libraries/base/reference/arrayed_list_chart|ARRAYED_LIST]] , LINKED_CIRCULAR or any other list or circular chain classes); for [[ref:/libraries/base/reference/two_way_chain_iterator_chart|TWO_WAY_CHAIN_ITERATOR]] it must be a descendant of [[ref:/libraries/base/reference/linear_chart|BILINEAR]] such as [[ref:/libraries/base/reference/two_way_list_chart|TWO_WAY_LIST]] or [[ref:/libraries/base/reference/two_way_circular_chart|TWO_WAY_CIRCULAR]] ; for [[ref:/libraries/base/reference/cursor_tree_iterator_chart|CURSOR_TREE_ITERATOR]] it must be a descendant of [[ref:/libraries/base/reference/cursor_tree_chart|CURSOR_TREE]] . In all cases the actual generic parameters of the iterator class and ofthe data structure class must be compatible. Then the iteration proper is obtained simply by calling the appropriate procedure, without any qualification or arguments, for example: do_ if <br/>
Assume an application class <eiffel>PROCESSOR</eiffel> that is a proper descendant of one of the effective iteration classes studied in this chapter. Then a routine of <eiffel>PROCESSOR</eiffel>, say <eiffel>iterate</eiffel>, may iterate a certain action over a data structure, subject to a certain test. First, class <eiffel>PROCESSOR</eiffel> must specify the action by redefining item_action and item_test (or, in the most general case, action and test). Then routine iterate must specify the target data structure through a call of the form <code>set (t)</code> where t represents the selected target data structure. The type of t must correspond to the iteration class selected as ancestor of <eiffel>PROCESSOR</eiffel>: for [[ref:/libraries/base/reference/linear_iterator_chart|LINEAR_ITERATOR]] it must be a descendant of [[ref:/libraries/base/reference/linear_chart|LINEAR]] (such as [[ref:/libraries/base/reference/linked_list_chart|LINKED_LIST]] , [[ref:/libraries/base/reference/arrayed_list_chart|ARRAYED_LIST]] , LINKED_CIRCULAR or any other list or circular chain classes); for [[ref:/libraries/base/reference/two_way_chain_iterator_chart|TWO_WAY_CHAIN_ITERATOR]] it must be a descendant of [[ref:/libraries/base/reference/linear_chart|BILINEAR]] such as [[ref:/libraries/base/reference/two_way_list_chart|TWO_WAY_LIST]] or [[ref:/libraries/base/reference/two_way_circular_chart|TWO_WAY_CIRCULAR]] ; for [[ref:/libraries/base/reference/cursor_tree_iterator_chart|CURSOR_TREE_ITERATOR]] it must be a descendant of [[ref:/libraries/base/reference/cursor_tree_chart|CURSOR_TREE]] . In all cases the actual generic parameters of the iterator class and ofthe data structure class must be compatible. Then the iteration proper is obtained simply by calling the appropriate procedure, without any qualification or arguments, for example: do_ if <br/>
It is hard to imagine a simpler scheme: no loops, no initialization, no arguments. Feature item_action may need to rely on some variable values. Because it does not take any argument, such values will have to be treated as attributes, with the corresponding <eiffel>set_...</eiffel> procedures to set and change their values. This also applies to the two schemes set next. <br/>
The single descendant technique has one drawback: it provides the iterating class, <eiffel>PROCESSOR</eiffel>, with only one set of iteration particulars. This limitation does not affect the number of targets: you may use as many targets as you wish, as long as they are of compatible types, by calling a routine such as iterate several times, or calling several such routines, each call being preceded by a call to set to define a new target. The limitation also does not affect the iterating scheme: one iteration could use do_if, the next do_all and so on. But it does require the action and test to be the same in all cases. <br/>
The next two techniques will remove this limitation.
@@ -431,38 +435,38 @@ inherit
feature
action1 is
action1
-- Action for the first scheme
do
...
end
test1: BOOLEAN is
test1: BOOLEAN
-- Test for the first scheme
do
...
end
action2 is
action2
-- Action for the second scheme
do
...
end
test2: BOOLEAN is
test2: BOOLEAN
-- Test for the second scheme
do
...
end
iterate1 is
iterate1
-- Execute iteration of first kind.
do
set (...)
do_if1
end
iterate2 is
iterate2
-- Execute iteration of second kind.
do
set (...)
@@ -495,7 +499,7 @@ end
In the feature clause we want to provide the appropriate effectings for the deferred features of class <eiffel>FIGURE</eiffel>: <eiffel>display</eiffel>, <eiffel>hide</eiffel>, <eiffel>translate</eiffel> and all other basic figure operations. <br/>
We can use loops for that purpose, for example
<code>
display is
display
-- Recursively display all components of the complex
-- figure
do
@@ -548,7 +552,7 @@ create
feature
item_action (f: FIGURE) is
item_action (f: FIGURE)
-- Action to be applied to each figure: display
-- it.
do
@@ -559,7 +563,7 @@ end
Similarly, you may define <eiffel>FIGURE_HIDER</eiffel>, <eiffel>FIGURE_MOVER</eiffel> and others. Then the features of <eiffel>COMPLEX_FIGURE</eiffel> are written almost trivially, without any explicit loops; for example:
<code>
display is
display
-- Recursively display all components of the complex
-- figure
local

View File

@@ -15,18 +15,18 @@ The most general class describing sets is [[ref:libraries/base/reference/set_cha
The deferred class [[ref:libraries/base/reference/comparable_set_chart|COMPARABLE_SET]] , declared as
<code>
deferred class
COMPARABLE_SET [G -> COMPARABLE]
deferred class
COMPARABLE_SET [G -> COMPARABLE]
inherit
SUBSET [G]
COMPARABLE_STRUCT [G]
...
inherit
SUBSET [G]
COMPARABLE_STRUCT [G]
...
</code>
describes sets whose items may be compared by a total order relation. The class has the features [[ref:libraries/base/reference/comparable_set_chart|min]] and [[ref:libraries/base/reference/comparable_set_chart|max]] . <br/>
Two implementations of [[ref:libraries/base/reference/comparable_set_chart|COMPARABLE_SET]] are provided. One, [[ref:libraries/base/reference/two_way_sorted_set_chart|TWO_WAY_SORTED_SET]] , uses sorted two-way lists. The other, [[ref:libraries/base/reference/binary_search_tree_set_chart|BINARY_SEARCH_TREE_SET]] , uses binary search trees. <br/>
If the items are partially rather than totally ordered, you may use the class [[ref:libraries/base/reference/part_sorted_set_chart|PART_SORTED_SET]] [G -> [[ref:libraries/base/reference/part_comparable_chart|PART_COMPARABLE]] ], which uses a two-way sorted list implementation.
If the items are partially rather than totally ordered, you may use the class PART_SORTED_SET [G -> PART_COMPARABLE]], which uses a two-way sorted list implementation.

View File

@@ -6,9 +6,9 @@ Hash tables are a convenient mechanism tostore and retrieve objects identified b
The main advantage of hash tables is the efficiency of the basic operations: store ( [[ref:libraries/base/reference/hash_table_chart|put]] ) and retrieve ( [[ref:libraries/base/reference/hash_table_chart|item]] , [[ref:libraries/base/reference/hash_table_chart|remove]] ). <br/>
The idea behind hash tables is to try to emulate the data structure that provides the ultimate in efficiency: the array. On an array <eiffel>a</eiffel>, for some integer <eiffel>i</eiffel> whose value lies within the bounds of <eiffel>a</eiffel>, the basic operations are
<code>
a.put (x, i)
x := a.item (i)
x := a @ i </code>
a.put (x, i)
x := a.item (i)
x := a @ i </code>
The first causes the value of a at index <eiffel>i</eiffel> to be <eiffel>x</eiffel>; the second (and the third, which is simply a syntactical variant) access the value at index <eiffel>i</eiffel> and assign it to <eiffel>x</eiffel>. With the usual computer architectures, these operations are very fast: because arrays items are stored contiguously in memory, a computer will need just one addition (base address plus index) and one memory access to perform a put or item. <br/>
Not only are the operation times small; they are constant (or more precisely bounded by a constant). This is a great advantage over structures such as lists or trees which you must traverse at least in part to retrieve an item, so that access and modification times grow with the number of items. With an array, disregarding the influence of other factors such as memory paging, the time for a put or item is for all practical purposes the same whether the array has five items or five hundred thousand. These properties make arrays excellent data structures for keeping objects. Unfortunately, they are only applicable if the objects satisfy three requirements:
@@ -22,8 +22,9 @@ Thanks to the hashing mechanism we will indeed be able to store suitable objects
* Different keys may hash into the same integer value, requiring extra processing to find an acceptable index.
With good implementations, however, it is possible to use hash tables with a performance that is not much worse than that of arrays and, most importantly, may be treated as if the time for a put, an item or a remove were constant. This will mean that you can consider operations such as
<code>h.put (x, k)
h := a.item (k)</code>
<code>
h.put (x, k)
h := a.item (k)</code>
where <eiffel>h</eiffel> is a hash-table and <eiffel>k</eiffel> is a key (for example a string) as conceptually equivalentto the array operations mentioned above. <br/>
The quality of a hashed implementation will depend both on the data structure that will store the objects, and on the choice of hashing function. Class [[ref:libraries/base/reference/hash_table_chart|HASH_TABLE]] attempts to address the first concern; for the second, client developers will be responsible for choosing the proper hashing function, although Base provides a few predefined functions, in particular for class [[ref:/libraries/base/reference/string_8_chart|STRING]] .
@@ -45,7 +46,8 @@ class HASH_TABLE [G, H -> HASHABLE] ... </code>
G represents the type of the objects to be stored in the hash table, H the type of their keys. <br/>
When viewed as an implementation of containers, [[ref:libraries/base/reference/hash_table_chart|HASH_TABLE]] , in a strict sense, represents bags rather than sets: unlike the other classes in this chapter, it allows an object to have two or more distinct occurrences in a single container. But this is only true if we consider a hash table as a repository of objects of type G. In reality each item of the table is identified by a pair of values, one from G and one from H. Because the keys must uniquely identify objects, the hash table viewed as a container of such pairs is indeed a set. The creation procedure make takes an integer argument, as in
<code>create my_table.make (n)</code>
<code>
create my_table.make (n)</code>
The value of <eiffel>n</eiffel> indicates how many items the hash table is expected to have to accommodate. This number of items is not a hardwired size, just information passed to the class. In particular:
* The actual size of the underlying array representation will be higher than n since efficient operation of hash table algorithms require the presence of enough breathing space - unoccupied positions.

View File

@@ -7,7 +7,11 @@ Trees, in particular binary trees and their variants, also provide convenient im
==Basic Terminology==
A tree consists of a set of nodes. Each node may have zero or more children, other nodes of which it is the parent. Each node has at most one parent, although it may have an arbitrary number of children.
[[Image:tree|tree]]
[[Image:tree|tree]]
A node with no parent, such as the node marked ''A'' on the figure, is called a root; a node with no children, such as ''E'', ''F'', ''G'', ''H'' and ''I'', is called a leaf. The length of a path from the root to a leaf (that is to say, the number of nodes on the path minus one) is the height of the tree; the average length of all such paths is the average height. On the figure the height is 2 and the average height is 11/6 since of the six paths five have length 2 and one has length 1.
The children of a common node are called siblings. For example ''G'', ''H'' and ''I'' are siblings on the figure. The siblings of a node are usually considered to be ordered; the order corresponds to the direction from left to right on conventional figures such as this one.
@@ -60,10 +64,12 @@ Binary trees are a special case of fixed trees in which nodes always have two ch
===Basic binary trees===
Class [[ref:libraries/base/reference/binary_tree_chart|BINARY_TREE]] describes binary trees. <br/>
<br/>
[[Image:binary-tree|binary_tree]] <br/>
<br/>
Class [[ref:libraries/base/reference/binary_tree_chart|BINARY_TREE]] describes binary trees.
[[Image:binary-tree|binary_tree]]
The children are represented by features [[ref:libraries/base/reference/binary_tree_chart|left_child]] and [[ref:libraries/base/reference/binary_tree_chart|right_child]] . Queries [[ref:libraries/base/reference/binary_tree_chart|has_left]] and [[ref:libraries/base/reference/binary_tree_chart|has_right]] indicate whether any of these is non-void; arity is redefined to yield the number of non-void children (0, 1 or 2).
===Binary representations of trees===
@@ -106,7 +112,11 @@ The cursor attached to a cursor tree is not just a conceptual notion but an actu
A useful notion associated with trees and particularly applicable to cursor trees is that of traversal. <br/>
A traversal is a certain policy for ordering all the nodes in a tree - usually to apply an operation to all these nodes in the resulting order. [[ref:libraries/base/reference/cursor_tree_chart|CURSOR_TREE]] and its descendants support three forms of traversal: preorder, postorder and breadth-first. They correspond to the most commonly used traversal policies on trees, illustrated on the figure (where the children of each node are assumed to be ordered from left to right):
[[Image:tree|tree]]
[[Image:tree|tree]]
* Preorder is the traversal that visits the root first, then (recursively) traverses each subtree in order. On the figure we will visit node ''A'' first then, recursively, the subtrees rooted at ''B'' (which implies visiting ''E'' and ''F''), ''C'' and ''D''. The resulting order is: ''A B E F C D G H I''.
* Postorder first traverses (recursively) the subtrees, then visits the root. On the example this gives: '' E F B C G H I D A''.
* Breadth-first visits the nodes level by level, starting with the root: first the root, then all its children, then all their children and so on. Here the resulting order is: ''A B C D E F G H I''.

View File

@@ -31,7 +31,7 @@ The Eiffel inheritance mechanism is set up in such a way that every class is a d
Every class which has no inheritance clause is understood to have an inheritance clause of the form
<code>
inherit
ANY
ANY
</code>
As a result, every developer-defined class is a descendant of [[ref:/libraries/base/reference/any_chart|ANY]] . You may introduce your own project specific features in [[ref:/libraries/base/reference/any_chart|ANY]] so that all the classes of your system will be able to use these features.
@@ -41,24 +41,31 @@ As a result, every developer-defined class is a descendant of [[ref:/libraries/b
If you need to rename or redefine a feature inherited from one of the universal classes, you should include an explicit inheritance clause, as in
<code>
class
C
C
inherit
ANY
rename
out as basic_out
redefine
print
end
...
ANY
rename
out as basic_out
redefine
print
end
...
feature
...
...
end
</code>
The features of [[ref:/libraries/base/reference/any_chart|ANY]] are usable in both qualified and unqualified form. For example, the argumentless function out, which produces a printable representation of any object, may be called under either of the forms
<code>
x := out
x := a.out
x := out
x := a.out
</code>
The first call yields a printable representation of the current object; the second, which assumes that a is not void, yields a printable representation of the object attached to a.
@@ -66,26 +73,31 @@ The first call yields a printable representation of the current object; the seco
==Input and output features==
Some of the features of [[ref:/libraries/base/reference/any_chart|ANY]] cover common input and output needs. <br/>
Feature <eiffel>io</eiffel>, of type [[ref:/libraries/base/reference/std_files_chart|STD_FILES]] , gives access to standard input and output facilities. For example, <eiffel>io</eiffel> <code> . </code><eiffel>input</eiffel> is the standard input file and <eiffel>io</eiffel>.<eiffel>new_line</eiffel> will print a line feed on the standard output. Feature <eiffel>io</eiffel> is declared as a once function which, when first called, returns the value of an instance of [[ref:/libraries/base/reference/std_files_chart|STD_FILES]] that provides access to the standard input, the standard output and the error output. As a result, <eiffel>io</eiffel> is never void, so that operations such as <eiffel>io</eiffel> <code> . </code><eiffel>new_line</eiffel> are always possible. <br/>
Function <eiffel>out</eiffel>, of type [[ref:/libraries/base/reference/string_8_chart|STRING]] , is a universal mechanism for obtaining a simple external representation of any object. For non-void <code> x </code> of any type, the string <code> x </code> <code> . </code><eiffel>out</eiffel> is a printable representation of <code> x </code>. This works for <code> x </code> of all types, reference or expanded. For example, if <code> x </code> is an integer expression, <code> x </code> <code> . </code><eiffel>out</eiffel> is its string representation, such as <code> -897 </code>; if n is a non-void reference, <code> x </code> <code> . </code><eiffel>out</eiffel> is (recursively) the concatenation of the result of applying out to the successive fields of the attached object, each labeled by the name of the corresponding attribute. You may redefine out in any class to specify any suitable format for displaying instances of the class. To obtain the default representation regardless of any redefinition of out, use tagged_out, declared as a frozen synonym of the original out. <br/>
The call print <code> ( </code> <code> x </code> <code> ) </code> will output the value of <code> x </code> <code> . </code><eiffel>out</eiffel> on the default output if <code> x </code> is not void, and do nothing otherwise.
Feature <eiffel>io</eiffel>, of type [[ref:/libraries/base/reference/std_files_chart|STD_FILES]] , gives access to standard input and output facilities. For example, <eiffel>io.input</eiffel> is the standard input file and <eiffel>io</eiffel>.<eiffel>new_line</eiffel> will print a line feed on the standard output. Feature <eiffel>io</eiffel> is declared as a once function which, when first called, returns the value of an instance of [[ref:/libraries/base/reference/std_files_chart|STD_FILES]] that provides access to the standard input, the standard output and the error output. As a result, <eiffel>io</eiffel> is never void, so that operations such as <eiffel>io</eiffel>.<eiffel>new_line</eiffel> are always possible. <br/>
Function <eiffel>out</eiffel>, of type [[ref:/libraries/base/reference/string_8_chart|STRING]] , is a universal mechanism for obtaining a simple external representation of any object. For non-void <code>x</code> of any type, the string <code>x.out</code> is a printable representation of <code>x</code>. This works for <code>x</code> of all types, reference or expanded. For example, if <code>x</code> is an integer expression, <code>x.out</code> is its string representation, such as <code>-897</code>; if n is a non-void reference, <code>x.out</code> is (recursively) the concatenation of the result of applying out to the successive fields of the attached object, each labeled by the name of the corresponding attribute. You may redefine out in any class to specify any suitable format for displaying instances of the class. To obtain the default representation regardless of any redefinition of out, use tagged_out, declared as a frozen synonym of the original out. <br/>
The call <code>print (x)</code> will output the value of <code>x.out</code> on the default output if <code>x</code> is not void, and do nothing otherwise.
==Copy and comparison routines==
Procedure copy copies the fields of an object onto those of another. It is used under the form
<code>
target.copy (source)
target.copy (source)
</code>
Here both target and source must be non-void; this means that <eiffel>copy</eiffel> is only good for copying onto an object that already exists. If you need both to allocate a new object and to initialize it as a copy of another, use the function clone. For non-void source, the assignment
Here both target and source must be non-void; this means that <eiffel>copy</eiffel> is only good for copying onto an object that already exists. If you need both to allocate a new object and to initialize it as a copy of another, use the function <code>twin</code>. For non-void source, the assignment
<code>
target := clone (source)
target := source.twin
</code>
starts by creating a new object, then populates its fields to be identical to <code>source</code>.
starts by creating a new object. If <code> source </code> is void, <code> target </code> will be made void too. The boolean function <eiffel>equal</eiffel> compares two objects for field-by-field equality. This is different from the equality operators <code> = </code> and <code> /= </code> which, in the case of reference types, compare references, not objects. <br/>
The function <eiffel>deep_clone</eiffel> produces a duplicate of an entire object structure. The boolean function <eiffel>deep_equal</eiffel> determines whether two object structures are recursively identical. These routines are the ''deep'' counterparts of the shallow copy and equality tests provided by <eiffel>clone</eiffel> and <eiffel>equal</eiffel>. <br/>
A class that needs a specific notion of equality and the corresponding copy semantics may redefine <eiffel>copy</eiffel> and <eiffel>is_equal</eiffel> (from which equal follows, since equal <code> ( </code> <code> a </code> <code> , </code> <code> b </code> <code> ) </code> is defined as <code> a </code> <code> . </code><eiffel>is_equal </eiffel> <code> ( </code> <code> b </code> <code> ) </code> for non-void <code> a </code>). You will find such redefinitions in a number of classes of the Base libraries. For example an instance of [[ref:/libraries/base/reference/string_8_chart|STRING]] is a string descriptor containing a reference to the actual character sequence, not that sequence itself, so that what the default equal compares and the default copy copies is the descriptor, not the string. Class [[ref:/libraries/base/reference/string_8_chart|STRING]] redefines these routines to yield the semantics normally expected by string clients; the frozen variants <eiffel>standard_copy</eiffel> and <eiffel>standard_equal</eiffel>, originally declared as synonyms to <eiffel>equal</eiffel> and <eiffel>copy</eiffel>, remain available with the default semantics. <br/>
The function <eiffel>clone</eiffel> is defined in terms of <eiffel>copy</eiffel>, and so will follow any redefinition of <eiffel>copy</eiffel>. This makes it impossible to change the semantics of one but not of the other, which would be a mistake. The variant <eiffel>standard_clone</eiffel> is defined in terms of <eiffel>standard_copy</eiffel>.
The boolean function <eiffel>equal</eiffel> compares two objects for field-by-field equality. This is different from the equality operators <code>=</code> and <code>/=</code> which, in the case of reference types, compare references, not objects. <br/>
The function <eiffel>deep_twin</eiffel> produces a duplicate of an entire object structure. The boolean function <eiffel>deep_equal</eiffel> determines whether two object structures are recursively identical. These routines are the ''deep'' counterparts of the shallow copy and equality tests provided by <eiffel>twin</eiffel> and <eiffel>equal</eiffel>. <br/>
A class that needs a specific notion of equality and the corresponding copy semantics may redefine <eiffel>copy</eiffel> and <eiffel>is_equal</eiffel> (from which <code>equal</code> follows, since <code>equal (a, b)</code> is defined as <code>a.is_equal (b)</code> for non-void <code>a</code>). You will find such redefinitions in a number of classes of the Base libraries. For example an instance of [[ref:/libraries/base/reference/string_8_chart|STRING]] is a string descriptor containing a reference to the actual character sequence, not that sequence itself, so that what the default equal compares and the default copy copies is the descriptor, not the string. Class [[ref:/libraries/base/reference/string_8_chart|STRING]] redefines these routines to yield the semantics normally expected by string clients; the frozen variants <eiffel>standard_copy</eiffel> and <eiffel>standard_equal</eiffel>, originally declared as synonyms to <eiffel>equal</eiffel> and <eiffel>copy</eiffel>, remain available with the default semantics. <br/>
The function <eiffel>twin</eiffel> is defined in terms of <eiffel>copy</eiffel>, and so will follow any redefinition of <eiffel>copy</eiffel>. This makes it impossible to change the semantics of one but not of the other, which would be a mistake. The variant <eiffel>standard_twin</eiffel> is defined in terms of <eiffel>standard_copy</eiffel>.
{{note|In some existing Eiffel code you may encounter the use of a function <code>clone</code> which is used to do the job of <code>twin</code>, but has a form like <code>copy</code>, as in <code>target.clone (source)</code>. <code>clone</code> is an obsolete function. Use <code>twin</code> instead.
}}
==Type information==
@@ -96,7 +108,7 @@ These two features enable clients to ascertain the dynamic type of an entity at
The query Void, of type <eiffel>NONE</eiffel>, denotes a reference that is always void - not attached to any object. <br/>
Procedure <eiffel>do_nothing</eiffel> does what its name implies. <br/>
Function default also has an empty body; its result type is <code> like Current </code>, so what it returns is the default value of the current type. This is mostly interesting for expanded types, since for reference types the default value is simply a void reference.
Function default also has an empty body; its result type is <code>like Current</code>, so what it returns is the default value of the current type. This is mostly interesting for expanded types, since for reference types the default value is simply a void reference.
=Language-related Facilities=
@@ -107,7 +119,7 @@ A number of classes offer facilities which are very close to the language level.
The basic types [[ref:/libraries/base/reference/boolean_chart|BOOLEAN]] , [[ref:/libraries/base/reference/character_8_chart|CHARACTER]] , [[ref:/libraries/base/reference/integer_32_chart|INTEGER]] , [[ref:/libraries/base/reference/real_32_chart|REAL]] and [[ref:/libraries/base/reference/real_64_chart|DOUBLE]] are defined by classes of the Kernel library. <br/>
In reading the class specifications for the numeric types [[ref:/libraries/base/reference/integer_32_chart|INTEGER]] , [[ref:/libraries/base/reference/real_32_chart|REAL]] and [[ref:/libraries/base/reference/real_64_chart|DOUBLE]] , you might think that the type declarations are too restrictive. For example the addition operation in class [[ref:/libraries/base/reference/real_32_chart|REAL]] reads
<code>
infix "+" (other: REAL): REAL
infix "+" (other: REAL): REAL
</code>
but there is actually no problem here. A language convention applicable to all arithmetic expressions, the Balancing rule, states that in any such expression all operands are considered to be converted to the heaviest type, where [[ref:/libraries/base/reference/real_64_chart|DOUBLE]] is heavier than [[ref:/libraries/base/reference/real_32_chart|REAL]] and [[ref:/libraries/base/reference/real_32_chart|REAL]] is heavier than [[ref:/libraries/base/reference/integer_32_chart|INTEGER]] . So mixed-type arithmetic, consistent with common practice, is possible and indeed frequent.
@@ -117,52 +129,54 @@ but there is actually no problem here. A language convention applicable to all a
To create and manipulate one-dimensional arrays, use class [[ref:/libraries/base/reference/array_chart|ARRAY]] of the Kernel Library. Arrays are not primitive language elements; instead, they are handled through class [[ref:/libraries/base/reference/array_chart|ARRAY]] . This class is 'normal' in the sense that it may be used just as any other class by client and descendant classes. It is also somewhat special, however, in that the Eiffel compiler knows about it and uses this knowledge to generate efficient code for array operations. <br/>
To create an instance of [[ref:/libraries/base/reference/array_chart|ARRAY]] , use the creation instruction
<code>
create my_array.make (1, u)
create my_array.make (1, u)
</code>
where the arguments indicate the lower and upper bounds. These bounds will then be accessible as <code> my_array </code> <code> . </code>lower and <code> my_array </code> <code> . </code><eiffel>upper</eiffel>. The number of items is <code> my_array </code> <code> . </code><eiffel>count</eiffel>; feature <eiffel>capacity</eiffel> is a synonym for <eiffel>count</eiffel>. The class invariant expresses the relation between <eiffel>count</eiffel>, <eiffel>lower</eiffel> and <eiffel>upper</eiffel>. <br/>
where the arguments indicate the lower and upper bounds. These bounds will then be accessible as <code>my_array</code> <code>.</code>lower and <code>my_array</code> <code>.</code><eiffel>upper</eiffel>. The number of items is <code>my_array</code> <code>.</code><eiffel>count</eiffel>; feature <eiffel>capacity</eiffel> is a synonym for <eiffel>count</eiffel>. The class invariant expresses the relation between <eiffel>count</eiffel>, <eiffel>lower</eiffel> and <eiffel>upper</eiffel>. <br/>
To access and change the item at index ''i'' in array a, you may use features <eiffel>item</eiffel> and <eiffel>put</eiffel>, as in
<code>
x := my_array.item (i)
my_array.put (new_value, i)
x := my_array.item (i)
my_array.put (new_value, i)
</code>
Function item has an infix synonym, <code> infix </code> <code> " </code>@ <code> " </code>, so that you may also write the first assignment above more concisely as
Function item has an infix synonym, <code>infix</code> <code>"</code>@ <code>"</code>, so that you may also write the first assignment above more concisely as
<code>
x := my_array @ i
x := my_array @ i
</code>
<br/>
Features <eiffel>item</eiffel>, <code> infix </code> <code> " </code>@ <code> " </code>and <eiffel>put</eiffel> have preconditions requiring the index ( <code> i </code>in the above calls) to be within the bounds of the array. This means that you can detect bounds violations (which correspond to bugs in the client software) by using a version of class [[ref:/libraries/base/reference/array_chart|ARRAY]] compiled with precondition checking on. The bounds of an array may be changed dynamically through procedure <eiffel>resize</eiffel>. Previously entered elements are retained. Rather than an explicit resize, you may use calls to procedure <eiffel>force</eiffel> which has the same signature as put but no precondition; if the index is not within the current bounds force will perform a resize as necessary.
Features <eiffel>item</eiffel>, <code>infix</code> <code>"</code>@ <code>" </code>and <eiffel>put</eiffel> have preconditions requiring the index ( <code>i</code>in the above calls) to be within the bounds of the array. This means that you can detect bounds violations (which correspond to bugs in the client software) by using a version of class [[ref:/libraries/base/reference/array_chart|ARRAY]] compiled with precondition checking on. The bounds of an array may be changed dynamically through procedure <eiffel>resize</eiffel>. Previously entered elements are retained. Rather than an explicit resize, you may use calls to procedure <eiffel>force</eiffel> which has the same signature as put but no precondition; if the index is not within the current bounds force will perform a resize as necessary.
==Optimizing array computations==
''' CAUTION''': Although [[ref:/libraries/base/reference/array_chart|ARRAY]] benefits from an efficient implementation, its more advanced facilities such as resizing do not come for free. For extensive computations on large arrays, an optimization may be desirable, bypassing these facilities. The technique yields loops that run at about the same speed as the corresponding loops written in C or Fortran (the usual references for array computations). It is of interest for advanced uses only, so that you may safely skip this section on first reading unless your domain of application is numerical computation or some other area requiring high-performance array manipulations.
The optimization relies on the class SPECIAL, used internally by [[ref:/libraries/base/reference/array_chart|ARRAY]] but of no direct interest to client developers in most common uses. With the declarations
<code>
my_array: ARRAY [SOME_TYPE]
direct_access: SPECIAL [SOME_TYPE]
my_array: ARRAY [SOME_TYPE]
direct_access: SPECIAL [SOME_TYPE]
</code>
you may use <eiffel>direct_access</eiffel> in lieu of 'my_array' within a critical loop, provided none of the operations may resize the array. Typically, the operations should only include put and item. In such a case you can use the following scheme:
<code>
direct_access:= my_array.area
direct_access:= my_array.area
-- The critical loop:
from
some_initialization
index := some_initial_index
until
index = some_final_index
loop
...
x := direct_access.item (index)
...
direct_access.put (some_value, index)
...
end
-- The critical loop:
from
some_initialization
index := some_initial_index
until
index = some_final_index
loop
...
x := direct_access.item (index)
...
direct_access.put (some_value, index)
...
end
</code>
This replaces an original loop where the operations were on <code> my_array </code>. Feature <eiffel>area</eiffel> of [[ref:/libraries/base/reference/array_chart|ARRAY]] gives direct access to the special object, an instance of SPECIAL, containing the array values. Features <eiffel>put</eiffel> and <eiffel>item</eiffel> are available in SPECIAL as in [[ref:/libraries/base/reference/array_chart|ARRAY]] , but without the preconditions; in other words, you will not get any bounds checking. Instances of SPECIAL are always indexed from zero, in contrast with arrays, whose lower bound is arbitrary, 1 being the most common value. But rather than performing index translations (that is to say, subtracting <code> my_array </code> <code> . </code><eiffel>lower</eiffel> from index throughout the loop) it is preferable to use the following simple technique: if the lower bound 'lb' of <code> my_array </code> is 1 or another small integer, use 0 as lower bound instead when creating <code> my_array </code>, but only use the positions starting at 'lb'. You will waste a few memory positions (0 to lb-1), but will not have to change anything in your algorithm and will avoid costly subtractions. <br/>
This replaces an original loop where the operations were on <code>my_array</code>. Feature <eiffel>area</eiffel> of [[ref:/libraries/base/reference/array_chart|ARRAY]] gives direct access to the special object, an instance of SPECIAL, containing the array values. Features <eiffel>put</eiffel> and <eiffel>item</eiffel> are available in SPECIAL as in [[ref:/libraries/base/reference/array_chart|ARRAY]] , but without the preconditions; in other words, you will not get any bounds checking. Instances of SPECIAL are always indexed from zero, in contrast with arrays, whose lower bound is arbitrary, 1 being the most common value. But rather than performing index translations (that is to say, subtracting <code>my_array</code> <code>.</code><eiffel>lower</eiffel> from index throughout the loop) it is preferable to use the following simple technique: if the lower bound 'lb' of <code>my_array</code> is 1 or another small integer, use 0 as lower bound instead when creating <code>my_array</code>, but only use the positions starting at 'lb'. You will waste a few memory positions (0 to lb-1), but will not have to change anything in your algorithm and will avoid costly subtractions. <br/>
It is important to note that this optimization, if at all necessary, should at most affect a few loops in a large system. You should always begin by writing your software using the normal [[ref:/libraries/base/reference/array_chart|ARRAY]] facilities; then once you have the certainty that the software is correct, if you detect that a large array computation is hampering the efficiency of the system, you may apply the above technique to get the fastest performance out of that computation. The change to the software will be minimal - a few lines - and will be easy to undo if necessary.
==Tuples==
@@ -273,9 +287,9 @@ The implementation of tuples has the following limitations:
Strings are handled by class [[ref:/libraries/base/reference/string_8_chart|STRING]] , similar in many respects to [[ref:/libraries/base/reference/array_chart|ARRAY]] . Strings are of arbitrary size. The make creation procedure takes an integer argument, as in:
<code>
s, s1, s2, s3: STRING
...
create s.make (30)</code>
s, s1, s2, s3: STRING
...
create s.make (30)</code>
The argument indicates the number of characters for the initial allocation. This is not an absolute limit: the string will automatically grow or shrink as a result of future operations. You may always request a resizing explicitly by calling procedure resize.
@@ -284,12 +298,12 @@ The argument indicates the number of characters for the initial allocation. This
The object attached at run-time to an entity such declared of type [[ref:/libraries/base/reference/string_8_chart|STRING]] is not the actual sequence of characters but a string descriptor, which contains a reference to the actual string contents.
As a result, four assignment or assignment-like operations are possible:
* '''A1''' <code> s1 := s </code>
* '''A2''' <code> s2.share (s) </code>
* '''A3''' <code> s3 := clone (s) </code>
* '''A4''' <code> s4.copy (s) </code>
* '''A1''' <code>s1 := s</code>
* '''A2''' <code>s2.share (s)</code>
* '''A3''' <code>s3 := s.twin</code>
* '''A4''' <code>s4.copy (s)</code>
As illustrated below, ''' A1''' is a reference assignment: <code> s1 </code> will be attached to the same descriptor as s. ''' A2''' keeps the descriptors distinct, but make them refer to the same sequence of characters. ''' A3''' uses the redefinition of clone for class [[ref:/libraries/base/reference/string_8_chart|STRING]] : <code> s3 </code> will be attached to a new string, completely distinct from the string attached to <code> s1 </code> although made of identical characters. ''' A4''' has almost the same effect as '''A3''', but is only applicable if <code> s4 </code> was not void, and will override the existing descriptor rather than creating a new one.
As illustrated below, ''' A1''' is a reference assignment: <code>s1</code> will be attached to the same descriptor as s. ''' A2''' keeps the descriptors distinct, but make them refer to the same sequence of characters. In ''' A3''', <code>s3</code> will be attached to a new string, completely distinct from the string attached to <code>s1</code> although made of identical characters. ''' A4''' has almost the same effect as '''A3''', but is only applicable if <code>s4</code> was not void, and will override the existing descriptor rather than creating a new one.
[[Image:strings]]
fig. 1: Effect of string assignment and copy operations
@@ -314,7 +328,7 @@ Queries are available to determine the status of a file, in particular <eiffel>e
{{caution|You will notice in the flat-short form that all these queries except the first have exists as a precondition. This precondition is good for efficiency since it saves an existence test - a relatively expensive operation - when you know that a certain file exists. But it also means that if you have any doubt about the file's existence you must use the queries in the style <br/>
<br/>
<code> if my_file.exists and then my_file.is_readable then </code>... }}
<code>if my_file.exists and then my_file.is_readable then</code>... }}
FILE is a deferred class. Various implementations are possible. A quite detailed one is PLAIN_TEXT_FILE, which adds many features for accessing reading and writing data from/to a file. <br/>
[[ref:/libraries/base/reference/unix_file_info_chart|UNIX_FILE_INFO]] describes objects that contain internal information, such as protection mode and size, about a file. <br/>
@@ -341,7 +355,7 @@ Storing an object just by itself would usually result in wrong semantics: most o
==Using the storage and retrieval facilities==
Class [[ref:/libraries/base/reference/storable_chart|STORABLE]] is meant to be used as ancestor. You can use its features in any descendant <eiffel>C</eiffel>; for example a routine of <eiffel>C</eiffel> may contain a call of the form <eiffel>basic_store</eiffel> <code> ( </code> <code> my_descriptor </code> <code> ) </code>. <br/>
Class [[ref:/libraries/base/reference/storable_chart|STORABLE]] is meant to be used as ancestor. You can use its features in any descendant <eiffel>C</eiffel>; for example a routine of <eiffel>C</eiffel> may contain a call of the form <eiffel>basic_store</eiffel> <code>(</code> <code>my_descriptor</code> <code>)</code>. <br/>
The effect of this call will be to store the current object and all its dependents into the file denoted by my_descriptor. <br/>
Although basic_store and other procedures of [[ref:/libraries/base/reference/storable_chart|STORABLE]] will in general process objects of many different types, only the generating class of the structure's initial object, <eiffel>C</eiffel> in our example, needs to be a descendant of [[ref:/libraries/base/reference/storable_chart|STORABLE]] .
@@ -357,7 +371,7 @@ Feature <eiffel>retrieved</eiffel> returns a result of type [[ref:/libraries/bas
<code>x ?= retrieved (my_descriptor)</code>
<br/>
The assignment attempt is necessary because <eiffel>retrieved</eiffel> returns a result of type [[ref:/libraries/base/reference/storable_chart|STORABLE]] whereas the type of <code> x </code> will be based on a proper descendant of [[ref:/libraries/base/reference/storable_chart|STORABLE]] . If the structure in the file has been corrupted and <eiffel>retrieved</eiffel> is unable to do its job, it will trigger an exception. The code for that exception in class [[ref:/libraries/base/reference/exceptions_chart|EXCEPTIONS]] (which inherits it from EXCEP_CONST and is discussed in the next section, together with the notion of exception code) is <eiffel>Retrieve_exception</eiffel>.
The assignment attempt is necessary because <eiffel>retrieved</eiffel> returns a result of type [[ref:/libraries/base/reference/storable_chart|STORABLE]] whereas the type of <code>x</code> will be based on a proper descendant of [[ref:/libraries/base/reference/storable_chart|STORABLE]] . If the structure in the file has been corrupted and <eiffel>retrieved</eiffel> is unable to do its job, it will trigger an exception. The code for that exception in class [[ref:/libraries/base/reference/exceptions_chart|EXCEPTIONS]] (which inherits it from EXCEP_CONST and is discussed in the next section, together with the notion of exception code) is <eiffel>Retrieve_exception</eiffel>.
==Recoverable storable==
@@ -435,7 +449,7 @@ As you will see from the header comments in the flat-short form of class [[ref:/
The features of class [[ref:/libraries/base/reference/exceptions_chart|EXCEPTIONS]] enable you to determine whether a certain exception is a signal - an operating system event such as may result from a child process that disappears, a window that is resized, a user that hits the Break key and many others. But they do not give you more details because the exact set of possible signals is highly platform-dependent. <br/>
Class [[ref:/libraries/base/reference/unix_signals_chart|UNIX_SIGNALS]] complements EXCEP_CONST by providing codes for the signals of Unix and similar systems, such as Sigkill for the 'kill' signal and Sigbus for bus error. <br/>
Query <eiffel>is_defined </eiffel> <code> ( </code> <code> some_signal </code> <code> ) </code>, where <code> some_signal </code> is an integer code, will determine whether some_signal is supported on the platform. <br/>
Query <eiffel>is_defined </eiffel> <code>(</code> <code>some_signal</code> <code>)</code>, where <code>some_signal</code> is an integer code, will determine whether some_signal is supported on the platform. <br/>
A class whose routines need to perform specific processing depending on the nature of signals received should inherit from [[ref:/libraries/base/reference/unix_signals_chart|UNIX_SIGNALS]] , or a similar class for another platform. <br/>
Because signal codes are platform-dependent, the features of [[ref:/libraries/base/reference/unix_signals_chart|UNIX_SIGNALS]] are implemented as once functions - computed on the first call - rather than constants, although this makes no difference to clients.
@@ -452,11 +466,11 @@ MEM_INFO, the result type for query <eiffel>memory_statistics</eiffel> in [[ref:
==Command-line arguments==
Writing, assembling and compiling a system yields an executable command. The system's users will call that command with arguments. These are normally provided in textual form on the command line, as in
<code>your_system arg1 arg2 arg3 </code>
<code>your_system arg1 arg2 arg3</code>
although one may conceive of other ways of entering the command arguments, such as tabular or graphical form-filling. In any case the software must be able to access the values passed as command arguments. <br/>
A language mechanism is available for that purpose: the Root Class rule indicates that the creation procedure of the root class may have a single argument (in the Eiffel sense of argument to a routine) of type [[ref:/libraries/base/reference/array_chart|ARRAY]] [ [[ref:/libraries/base/reference/string_8_chart|STRING]] <code> ] </code>. The corresponding array of strings will be initialized at the beginning of the system's execution with the values entered as arguments to that execution of the command. <br/>
A language mechanism is available for that purpose: the Root Class rule indicates that the creation procedure of the root class may have a single argument (in the Eiffel sense of argument to a routine) of type [[ref:/libraries/base/reference/array_chart|ARRAY]] [ [[ref:/libraries/base/reference/string_8_chart|STRING]] <code>]</code>. The corresponding array of strings will be initialized at the beginning of the system's execution with the values entered as arguments to that execution of the command. <br/>
Although this facility suffices in many cases, it is not always convenient if you suddenly need to access the command arguments in a class that is far-away from the root. An alternative mechanism, class ARGUMENTS, is available. Once again, this is a class from which you should inherit if you need its facilities. It has just two exported features:
* <eiffel>argument_count</eiffel>, a non-negative integer, is the number of command arguments.
* <eiffel>argument</eiffel> <code>(</code>i<code>)</code>, a string, is the i-th command argument. Here <code> i </code> must be between 0 and <eiffel>argument_count</eiffel>; the convention is that for <code> i </code> <code> = 0 </code> the result is the name of the command itself.
* <eiffel>argument</eiffel> <code>(</code>i<code>)</code>, a string, is the i-th command argument. Here <code>i</code> must be between 0 and <eiffel>argument_count</eiffel>; the convention is that for <code>i </code> <code>= 0</code> the result is the name of the command itself.

View File

@@ -21,7 +21,7 @@ The origin is 0 hour 0 minute and 0 second. Notion of time is relative to a day
====Comparison====
Instances of [[ref:libraries/time/reference/time_chart|TIME ]] may be compared. Functions <, + > and >= are available. Function is_equal must be use to test equality. = will compare references.
Instances of [[ref:libraries/time/reference/time_chart|TIME ]] may be compared. Functions <, +, >, and >= are available. Function is_equal or ~ can be used to test object equality, while = will compare references.
====Measurement====
@@ -46,7 +46,7 @@ The origin is 01/01/1600.
====Comparison====
Instances of <eiffel>DATE</eiffel> may be compared. Functions <, + > and >= are available. Function is_equal must be use to test equality, = will compare references.
Instances of <eiffel>DATE</eiffel> may be compared. Functions <, +, >, and >= are available. Function is_equal or ~ can be used to test object equality, while = will compare references.
====Measurement====
@@ -59,9 +59,9 @@ Much information may be gotten from functions written in this part. Most of them
====Operations====
<eiffel>DATE</eiffel> operations looks like <eiffel>TIME</eiffel> operations:
* Setting directly year, month and day with set_year, set_month and set_day. Arguments must satisfy the rules of creation. These rules are more complicated than those of <eiffel>TIME</eiffel>. For example it is not allowed to set day to 31 if the current month is April, whereas it is allowed if the month is January. It is the same rules as for make. The same thing for years: It is not allowed to set year to a non-leap year if the current date is February 29th of a leap year. However, two features are available to set month and year even if day is too large: set_month_cut_days and set_year_cut_days will cut day down to the largest value allowed.
* Adding years, months and days with features year_add, month_add and day_add. There is no requirement to add a year or a month. However, these features have to return a correct result, i.e. day is checked before each addition-. Adding one month to August 31st will yield September 30th. 31 is cut to 30 since there are only 30 days in September. Features add and + take an instance of DATE_DURATION in argument and add it to the current date. It is written so that years and months are added first, the days last.(see DATE_DURATION below)
* Moving to the next or the previous year, month or day with features year_forth, year_back, month_forth, month_back, day_forth and day_back. It is the same but faster to use these features rather than those upper (year_back <-> year_add (-1)).
* Setting directly year, month and day with set_year, set_month, and set_day. Arguments must satisfy the rules of creation. These rules are more complicated than those of <eiffel>TIME</eiffel>. For example it is not allowed to set day to 31 if the current month is April, whereas it is allowed if the month is January. It is the same rules as for make. The same thing for years: It is not allowed to set year to a non-leap year if the current date is February 29th of a leap year. However, two features are available to set month and year even if day is too large: set_month_cut_days and set_year_cut_days will cut day down to the largest value allowed.
* Adding years, months and days with features year_add, month_add, and day_add. There is no requirement to add a year or a month. However, these features have to return a correct result, i.e. day is checked before each addition-. Adding one month to August 31st will yield September 30th. 31 is cut to 30 since there are only 30 days in September. Features add and + take an instance of DATE_DURATION in argument and add it to the current date. It is written so that years and months are added first, the days last.(see DATE_DURATION below)
* Moving to the next or the previous year, month or day with features year_forth, year_back, month_forth, month_back, day_forth, and day_back. It is the same but faster to use these features rather than those upper (year_back <-> year_add (-1)).
* Features relative_duration and definite_duration return the duration between the current date and the argument. The first one returns a result which is canonical (See definitions below), while the second one returns a definite result but may be not canonical.
For example, date1 is April 20th and date2 is May 28th. Both features will yield instances of DURATION; however, relative_duration will yield 1 month and 8 days whereas definite_duration will yield 38 days.
@@ -86,7 +86,7 @@ To make it easier calls to features of <eiffel>TIME</eiffel> and <eiffel>DATE</e
====Comparison====
Instances of <eiffel>DATE_TIME</eiffel> are totally ordered (the class inherit from <eiffel>ABSOLUTE</eiffel>). Functions <, + > and >= are available. Function is_equal must be used to test equality, = will compare references.
Instances of <eiffel>DATE_TIME</eiffel> are totally ordered (the class inherit from <eiffel>ABSOLUTE</eiffel>). Functions <, +, >, and >= are available. Function is_equal or ~ is used to test object equality. = will compare references.
====Measurement====

View File

@@ -3,9 +3,9 @@
[[Property:uuid|64672bd0-b696-0c39-1e30-5ac64aae4a99]]
<eiffel>TIME_DURATION</eiffel>, <eiffel>DATE_DURATION</eiffel>, and <eiffel>DATE_TIME_DURATION</eiffel>
The classes dealing with duration inherit DURATION, which inherits GROUP_ELEMENT and PART_COMPARABLE. An instance of <eiffel>TIME_DURATION</eiffel>, <eiffel>DATE_DURATION</eiffel>, or <eiffel>DATE_TIME_DURATION</eiffel> is an element of a group, i.e. there is a zero and addition operations (infix +, infix -, prefix + and prefix -). Duration is used as an amount of time, without link to an origin. It may be added to the respective absolute notion (time + time_duration is possible, not time + date_time_duration nor date_time + time_duration...see classes <eiffel>TIME</eiffel>, <eiffel>DATE</eiffel>, and <eiffel>DATE_TIME</eiffel>).
The classes dealing with duration inherit DURATION, which inherits GROUP_ELEMENT and PART_COMPARABLE. An instance of <eiffel>TIME_DURATION</eiffel>, <eiffel>DATE_DURATION</eiffel>, or <eiffel>DATE_TIME_DURATION</eiffel> is an element of a group, i.e. there is a zero and addition operations (infix <eiffel>+</eiffel>, infix <eiffel>-</eiffel>, prefix <eiffel>+</eiffel>, and prefix <eiffel>-</eiffel>). Duration is used as an amount of time, without link to an origin. It may be added to the respective absolute notion (time + time_duration is possible, not time + date_time_duration nor date_time + time_duration...see classes <eiffel>TIME</eiffel>, <eiffel>DATE</eiffel>, and <eiffel>DATE_TIME</eiffel>).
Attributes are allowed to take negative values or values which do not stand in the usual range (hour = -1, minute = 75, day = 40...). However, features are available in each class to convert instances into the usual format: functions canonical and to_canonical are present in each class. An instance is canonical (canonical = True) if its attributes stand into the usual range. For example, an instance of <eiffel>TIME_DURATION</eiffel> such as 12:-10:60 is not canonical. to_canonical will return 11:51:0. In <eiffel>DATE_DURATION</eiffel> and <eiffel>DATE_TIME_DURATION</eiffel>, these features are also present.
Attributes are allowed to take negative values or values which do not stand in the usual range (<eiffel>hour = -1</eiffel>, <eiffel>minute = 75</eiffel>, <eiffel>day = 40</eiffel>...). However, features are available in each class to convert instances into the usual format: functions <eiffel>canonical</eiffel> and <eiffel>to_canonical</eiffel> are present in each class. An instance is canonical (<eiffel>canonical = True</eiffel>) if its attributes stand into the usual range. For example, an instance of <eiffel>TIME_DURATION</eiffel> such as 12:-10:60 is not canonical. to_canonical will return 11:51:0. In <eiffel>DATE_DURATION</eiffel> and <eiffel>DATE_TIME_DURATION</eiffel>, these features are also present.
The order is partially implemented. <eiffel>TIME_DURATION</eiffel> has a complete order whereas <eiffel>DATE_DURATION</eiffel> and <eiffel>DATE_TIME_DURATION</eiffel> are more specific.
@@ -13,47 +13,49 @@ The order is partially implemented. <eiffel>TIME_DURATION</eiffel> has a complet
====Creation====
Two ways are possible: by choosing the value of each attributes hour, minute and second (feature make), or by giving an amount of seconds (make_by_seconds). Any integer value is accepted. It is possible to create a duration with 1 hour and -60 minutes.
Two ways are possible: by choosing the value of each attributes hour, minute and second (feature make), or by giving an amount of seconds (<eiffel>make_by_seconds</eiffel>). Any integer value is accepted. It is possible to create a duration with 1 hour and -60 minutes.
====Access====
Zero is a once feature with 0 hour, 0 minute and 0 second. The total amount of second of the current duration is the result of feature seconds_count.
<eiffel>zero</eiffel> is a once feature with 0 hour, 0 minute and 0 second.
The total number of seconds in the current duration can be obtained by applying the feature <eiffel>seconds_count</eiffel>.
====Comparison====
Instances of <eiffel>TIME_DURATION</eiffel> may be compared easily. The order is the order oft he respective total amount of second. 1:-40:0 is less than 0:0:1800, etc... Functions <, >,<= and >= are available. Is_equal tests equality, = will compare references.
Instances of <eiffel>TIME_DURATION</eiffel> may be compared easily. The order is the order oft he respective total amount of second. 1:-40:0 is less than 0:0:1800, etc... Functions <, >, <=, and >= are available. <eiffel>is_equal</eiffel> (or <eiffel>~</eiffel>) tests object equality, <eiffel>=</eiffel> will compare references.
====Element change====
Set directly hour, minute and second with set_hour, set_minute and set_second. Arguments do not need to satisfy any range rule.
Set directly <eiffel>hour</eiffel>, <eiffel>minute</eiffel>, and <eiffel>second</eiffel> with <eiffel>set_hour</eiffel>, <eiffel>set_minute</eiffel>, and <eiffel>set_second</eiffel>. Arguments do not need to satisfy any range rule.
====Operations====
* Adding hours, minutes and seconds with features hour_add, minute_add and second_add.
* <eiffel>TIME_DURATION</eiffel> inherits from GROUP_ELEMENT. infix and prefix +, infix and prefix - are available to compose instances of each other.
* Adding hours, minutes and seconds with features <eiffel>hour_add</eiffel>, <eiffel>minute_add</eiffel> and <eiffel>second_add</eiffel>.
* <eiffel>TIME_DURATION</eiffel> inherits from GROUP_ELEMENT. infix and prefix <eiffel>+</eiffel>, infix and prefix <eiffel>-</eiffel> are available to compose instances of each other.
====Conversion====
Two features ensure a link with the notion of day: to_days returns the number of days equivalent to the current duration. For example, a duration such as 23:60:0 is equivalent to one day. For negative duration, the result is never 0. -1 hour is equivalent to -1 day (i.e. the result of the function is -1). To_days is associated with time_modulo_day. This second function returns an instance of <eiffel>TIME_DURATION</eiffel>. The result represents the difference between the current duration and the number of days yielded by to_days. It implies that the result is always positive and less than one day.
Two features ensure a link with the notion of day: <eiffel>to_days</eiffel> returns the number of days equivalent to the current duration. For example, a duration such as 23:60:0 is equivalent to one day. For negative duration, the result is never 0. -1 hour is equivalent to -1 day (i.e. the result of the function is -1). <eiffel>to_days</eiffel> is associated with <eiffel>time_modulo_day</eiffel>. This second function returns an instance of <eiffel>TIME_DURATION</eiffel>. The result represents the difference between the current duration and the number of days yielded by <eiffel>to_days</eiffel>. It implies that the result is always positive and less than one day.
For example, the current duration is 25:70:600. to_days will returns 1 (one day) and time_modulo_day will return 2:20:0:. If the current duration is negative: -23:-80:300,to_days will return -2 (minus two days) and time_modulo_day will return 23:45:0.
For example, the current duration is 25:70:600. <eiffel>to_days</eiffel> will return 1 (one day) and <eiffel>time_modulo_day</eiffel> will return 2:20:0:. If the current duration is negative: -23:-80:300, <eiffel>to_days</eiffel> will return -2 (minus two days) and <eiffel>time_modulo_day</eiffel> will return 23:45:0.
Durations may be canonical or not canonical (BOOLEAN canonical). That means the features hour, minute and second are included in a particular range, or not. An instance of <eiffel>TIME_DURATION</eiffel> is canonical if:
* in the case of a positive duration (> zero), all of the three features have to be positive or 0, minute and second less than 60.
* in the case of a negative duration (< zero), all of the three features have to be negative or 0, minute and second strictly greater than -60. The function canonical tests if the duration is canonical or not, the function to_canonical yields a new duration equivalent to the current one and canonical.
Durations may be canonical or not canonical (<eiffel>BOOLEAN canonical</eiffel>). That means the features <eiffel>hour</eiffel>, <eiffel>minute</eiffel>, and <eiffel>second</eiffel> are included in a particular range, or not. An instance of <eiffel>TIME_DURATION</eiffel> is canonical if:
* in the case of a positive duration (> zero), all of the three features have to be positive or 0, <eiffel>minute</eiffel> and <eiffel>second</eiffel> less than 60.
* in the case of a negative duration (< zero), all of the three features have to be negative or 0, <eiffel>minute</eiffel> and <eiffel>second</eiffel> strictly greater than -60. The function <eiffel>canonical</eiffel> tests if the duration is canonical or not, the function <eiffel>to_canonical</eiffel> yields a new duration equivalent to the current one and canonical.
==DATE_DURATION==
Dealing with the Gregorian calendar is not so easy because of irregularities. A duration of one month may be equal to 28 up to 31 days, depending on the current date! On the other hand, it could be useful to deal with precise duration. This point leads to an original design of the class: A separation is made between two kinds of instances.
The definite ones and the relative ones. The function definite which returns a BOOLEAN, is true for definite duration and false otherwise. An instance is definite if and only if its attributes month and year are 0. Then only the number of days is used. Relative (non definite) durations have their attributes year, month and day meaningful but it is then impossible to compare them to each other (is one month greater than 30 days?, is one year greater than 365 days?). The main difference appears when a duration is added to a date. In the case of a definite duration, there is no ambiguity. A given number of days are added to the date, taking care of the calendar. In the other case, the result is relative to the origin date. For example, a one month duration may be equal to 28 days if the date is in February or 31 days if the date is in August. A duration becomes definite when its attributes year and month become 0. However it is possible to deal with instances of <eiffel>DATE_DURATION</eiffel> without taking care of this distinction.
The definite ones and the relative ones. The function <eiffel>definite</eiffel> which returns a <eiffel>BOOLEAN</eiffel>, is true for definite duration and false otherwise. An instance is definite if and only if its attributes <eiffel>month</eiffel> and <eiffel>year</eiffel> are 0. Then only the number of days is used. Relative (non definite) durations have their attributes <eiffel>year</eiffel>, <eiffel>month</eiffel>, and <eiffel>day</eiffel> meaningful but it is then impossible to compare them to each other (is one month greater than 30 days?, is one year greater than 365 days?). The main difference appears when a duration is added to a date. In the case of a definite duration, there is no ambiguity. A given number of days are added to the date, taking care of the calendar. In the other case, the result is relative to the origin date. For example, a one month duration may be equal to 28 days if the date is in February or 31 days if the date is in August. A duration becomes definite when its attributes <eiffel>year</eiffel> and <eiffel>month</eiffel> become 0. However it is possible to deal with instances of <eiffel>DATE_DURATION</eiffel> without taking care of this distinction.
===Relative date_duration===
Relative duration cannot be compared with any other durations (including zero). The reason is simple. It is not possible to say if 30 days are less than 1 month: it depends on the date: it is true in August (in a 31 days month) and it is false in February.
If feature > (or <, + + is called with at least one non definite member (the current instance or the argument), the result will be always False. We may only know if two durations are equal, with the feature is_equal. It compares field by field the two durations. When adding a relative date_duration to a date, the years and the months are added first, then the date may be cut (June 31 -> June 30) and finally the days are added. For example, if one month is added to the date August 31st, the result is September 30th.
If feature <eiffel>></eiffel> (or <eiffel><</eiffel>) is called with at least one non definite member (the current instance or the argument), the result will be always False. We may only know if two durations have equal value with the feature <eiffel>is_equal</eiffel> (or <eiffel>~</eiffel>). It compares field by field the two durations. When adding a relative date_duration to a date, the years and the months are added first, then the date may be cut (June 31 -> June 30) and finally the days are added. For example, if one month is added to the date August 31st, the result is September 30th.
Nevertheless there is a way to compare relative durations: a relative date_duration may be canonical. It means that the duration has its attributes month and day in a fixed range.month must be between 1 and 12, and day larger than 1 and less than a value between 27 and 30. This value is fixed simply: (in the case of a positive duration) when setting day to 0 and adding one more month, the addition of the start date and this new duration must yield a date strictly after the final date (yielded by adding date and tested duration). For example is 0/0/30 (i.e. 0 year, 0 month and 30 days) canonical?
Nevertheless, there is a way to compare relative durations: a relative date_duration may be canonical. It means that the duration has its attributes <eiffel>month</eiffel> and <eiffel>day</eiffel> in a fixed range. <eiffel>month</eiffel> must be between 1 and 12, and <eiffel>day</eiffel> larger than 1 and less than a value between 27 and 30. This value is fixed simply: (in the case of a positive duration) when setting day to 0 and adding one more month, the addition of the start date and this new duration must yield a date strictly after the final date (yielded by adding date and tested duration). For example is 0/0/30 (i.e. 0 year, 0 month and 30 days) canonical?
* If the origin date is 01/15 (15th of January), the final date is 02/14. We cannot convert 30 days into 1 month in this case. The duration is canonical.
* If the origin date is 04/15 (15th of April), the final date is 05/15. The duration is not canonical since it is possible to convert days into 1 month. The origin date is used to determine whether the duration is positive or not. If the final date is after the origin date the duration is positive, otherwise it is negative. That does not mean we can compare it to zero, that is only used to determine the sign of the canonical standard. If the duration is negative, it is canonical only if all the attributes are negative.
@@ -71,23 +73,23 @@ A definite duration may be canonical or not. It is canonical if the number of da
====Creation====
Two creation features are available: make takes three arguments (year, month and day). If year and month are null, the duration will be definite; make_by_days takes only the number of day. The duration is automatically definite.
Two creation features are available: <eiffel>make</eiffel> takes three arguments (<eiffel>year</eiffel>, <eiffel>month</eiffel>, and <eiffel>day</eiffel>). If year and month are null, the duration will be definite; <eiffel>make_by_days</eiffel> takes only the number of day. The duration is automatically definite.
====Comparison====
Features <, >, <= and >= are available. If both instances are definite, numbers of days are compared. If one of them is non definite, the result is False.
Features <, >, <=, and >= are available. If both instances are definite, numbers of days are compared. If one of them is non definite, the result is False.
====Element change====
Features set_day, set_month and set_year are available to set one of these three attributes day, month, year.
Features <eiffel>set_day</eiffel>, <eiffel>set_month</eiffel>, and <eiffel>set_year</eiffel> are available to set one of these three attributes <eiffel>day</eiffel>, <eiffel>month</eiffel>, <eiffel>year</eiffel>.
====Operation====
* Add years, months and days with features year_add, month_add and day_add.
* <eiffel>DATE_DURATION</eiffel> inherits from GROUP_ELEMENT. infix and prefix +, infix and prefix - are available to compose instances of each other.
* Add years, months and days with features <eiffel>year_add</eiffel>, <eiffel>month_add</eiffel>, and <eiffel>day_add</eiffel>.
* <eiffel>DATE_DURATION</eiffel> inherits from GROUP_ELEMENT. infix and prefix <eiffel>+</eiffel>, infix and prefix <eiffel>-</eiffel> are available to compose instances of each other.
====Conversion====
* to_canonical is used to get a new duration equivalent to the current one and canonical. It needs an argument from class <eiffel>DATE</eiffel>, which is the origin of calculations.
* to_definite is used to get a new duration equivalent to the current one and definite. As with the previous feature, one argument is needed. - to_date_time is used to get an instance of <eiffel>DATE_TIME_DURATION</eiffel>. It will have the same date of the current duration and time set to zero.
* <eiffel>to_canonical</eiffel> is used to get a new duration equivalent to the current one and canonical. It needs an argument from class <eiffel>DATE</eiffel>, which is the origin of calculations.
* <eiffel>to_definite</eiffel> is used to get a new duration equivalent to the current one and definite. As with the previous feature, one argument is needed. - <eiffel>to_date_time</eiffel> is used to get an instance of <eiffel>DATE_TIME_DURATION</eiffel>. It will have the same date of the current duration and time set to zero.
==DATE_TIME_DURATION==
@@ -98,29 +100,29 @@ There are, as in <eiffel>DATE_DURATION</eiffel>, definite and non definite durat
====Creation====
There are still several ways to create an instance:
* by choosing values for all the attributes of date and time (make). - by choosing a value for day and values for all the attributes of time. The instance is then definite (make_definite).
* by gathering an instance of <eiffel>DATE</eiffel> with an instance of <eiffel>TIME</eiffel> (make_by_date_time). This feature copies the references of its arguments, so that if the time (or the date) is changed, the instance previously initialized will be also changed. If this effect has to be avoided, the use of clones is required.
* by encapsulating an instance of <eiffel>DATE</eiffel> (make_by_date). The attribute time is set to zero, i.e. 0:0:0. The attribute date is set with the same reference than the argument.
* by choosing values for all the attributes of date and time (<eiffel>make</eiffel>). - by choosing a value for day and values for all the attributes of time. The instance is then definite (<eiffel>make_definite</eiffel>).
* by gathering an instance of <eiffel>DATE</eiffel> with an instance of <eiffel>TIME</eiffel> (<eiffel>make_by_date_time</eiffel>). This feature copies the references of its arguments, so that if the time (or the date) is changed, the instance previously initialized will be also changed. If this effect has to be avoided, the use of twins is required.
* by encapsulating an instance of <eiffel>DATE</eiffel> (<eiffel>make_by_date</eiffel>). The attribute <eiffel>time</eiffel> is set to zero, i.e. 0:0:0. The attribute <eiffel>date</eiffel> is set with the same reference than the argument.
====Access====
Seconds_count is the amount of seconds of the time part only. To get the total amount of seconds of the current duration, first shift it to a definite duration, then multiply day by the number of seconds in day and add to it seconds_count. Take care that the duration is not more than 68 years. If it is, the number of seconds will be larger than 2 billion, which is the upper limit for INTEGER (4 bytes).
<eiffel>seconds_count</eiffel> is the amount of seconds of the time part only. To get the total amount of seconds of the current duration, first shift it to a definite duration, then multiply day by the number of seconds in day and add to it <eiffel>seconds_count</eiffel>. Take care that the duration is not more than 68 years. If it is, the number of seconds will be larger than 2 billion, which is the upper limit for INTEGER (4 bytes).
====Comparison====
The rules are the same than those for <eiffel>DATE_DURATION</eiffel>. Features <, >,<= and >= are available. If both instances are definite, numbers of days are compared. If one of them is non definite, the result is False.
The rules are the same than those for <eiffel>DATE_DURATION</eiffel>. Features <, >,<=, and >= are available. If both instances are definite, numbers of days are compared. If one of them is non definite, the result is False.
====Element change====
It is possible to change reference of time and date with the features set_time and set_date. To change only one element (for example hour), features from <eiffel>TIME_DURATION</eiffel> or <eiffel>DATE_DURATION</eiffel>have to be used.
It is possible to change reference of time and date with the features <eiffel>set_time</eiffel> and <eiffel>set_date</eiffel>. To change only one element (for example <eiffel>hour</eiffel>), features from <eiffel>TIME_DURATION</eiffel> or <eiffel>DATE_DURATION</eiffel>have to be used.
====Operation====
* <eiffel>DATE_TIME_DURATION</eiffel> inherits from GROUP_ELEMENT. infix and prefix +, infix and prefix - are available to compose instances to each other.
* Only day_add is present. To add only one element, features from <eiffel>TIME_DURATION</eiffel> or <eiffel>DATE_DURATION</eiffel> have to be used.
* <eiffel>DATE_TIME_DURATION</eiffel> inherits from GROUP_ELEMENT. infix and prefix <eiffel>+</eiffel>, infix and prefix <eiffel>-</eiffel> are available to compose instances to each other.
* Only <eiffel>day_add</eiffel> is present. To add only one element, features from <eiffel>TIME_DURATION</eiffel> or <eiffel>DATE_DURATION</eiffel> have to be used.
====Conversion====
* canonical and to_canonical are available in the class. To be canonical an instance of the class must have its attributes time and date canonical. Then time must have the same sign than the one of the current duration. The sign of the current instance is determined by adding it to the argument (from <eiffel>DATE_TIME</eiffel>). That will yield a final date. If this final date is after the origin (= the argument), the current duration is considered positive. Otherwise, it is considered negative. Finally time must be less than one day (if positive) or more than minus one day (if negative). To_canonical returns a duration equivalent to the current one (for the argument) and canonical.
* time_to_canonical looks like to_canonical but focuses mainly on time. It requires a definite duration so that it is possible to compare it to zero. It yields a definite duration equivalent to the current one with a canonical time. hour is then cut so that it stands in the range of one day (0 to 23 if positive and -23 to 0 if negative). The attributes day is also modified to keep the result equivalent to the current duration.time_to_canonical does not need any argument because only time and day are modified.
* <eiffel>canonical</eiffel> and <eiffel>to_canonical</eiffel> are available in the class. To be canonical an instance of the class must have its attributes <eiffel>time</eiffel> and <eiffel>date</eiffel> canonical. Then time must have the same sign than the one of the current duration. The sign of the current instance is determined by adding it to the argument (from <eiffel>DATE_TIME</eiffel>). That will yield a final date. If this final date is after the origin (= the argument), the current duration is considered positive. Otherwise, it is considered negative. Finally time must be less than one day (if positive) or more than minus one day (if negative). <eiffel>to_canonical</eiffel> returns a duration equivalent to the current one (for the argument) and canonical.
* <eiffel>time_to_canonical</eiffel> looks like <eiffel>to_canonical</eiffel> but focuses mainly on time. It requires a definite duration so that it is possible to compare it to zero. It yields a definite duration equivalent to the current one with a canonical time. <eiffel>hour</eiffel> is then cut so that it stands in the range of one day (0 to 23 if positive and -23 to 0 if negative). The attribute <eiffel>day</eiffel> is also modified to keep the result equivalent to the current duration. <eiffel>time_to_canonical</eiffel> does not need any argument because only time and day are modified.

View File

@@ -9,7 +9,7 @@ You can access [[EiffelBuild Notation|objects]] from both the [[Builder window|
{{note|Although window and dialog objects may be accessed within the [[Widget selector|widget selector]] , it is not possible to build into these objects, you should use the [[Layout constructor|layout constructor]] or [[Builder window|builder window]] directly in this situation. }}
For more information about an [[EiffelBuild Notation|objects]] capacity and permitted children, see the [[EiffelVision Introduction|EiffelVision2]] documentation.
For more information about an [[EiffelBuild Notation|objects]] capacity and permitted children, see the [[EiffelVision Introduction|EiffelVision 2]] documentation.
{{seealso|<br/>
[[Create an object|Create an object]] <br/>

View File

@@ -7,7 +7,7 @@ This window may either be shown or hidden (default). To change between these two
[[Image:builder-window]]
The content of this window is a representation of the [[EiffelBuild Notation|objects]] you have defined in your project. Each [[EiffelBuild Notation|object]] is represented by the [[EiffelVision Introduction|EiffelVision2]] control matching its type. For example, an [[EiffelBuild Notation|object]] representing an <eiffel>EV_BUTTON</eiffel> will be displayed in here using an <eiffel>EV_BUTTON</eiffel>. As this view provides direct access to the objects ( [[EiffelBuild Notation|Pick]] any of the controls in this window), it enables you to build your interface within a view which provides rich visual feedback.
The content of this window is a representation of the [[EiffelBuild Notation|objects]] you have defined in your project. Each [[EiffelBuild Notation|object]] is represented by the [[EiffelVision Introduction|EiffelVision 2]] control matching its type. For example, an [[EiffelBuild Notation|object]] representing an <eiffel>EV_BUTTON</eiffel> will be displayed in here using an <eiffel>EV_BUTTON</eiffel>. As this view provides direct access to the objects ( [[EiffelBuild Notation|Pick]] any of the controls in this window), it enables you to build your interface within a view which provides rich visual feedback.
Because this window is just a view of the [[EiffelBuild Notation|objects]] , it will be always synchronized with the [[Layout constructor| layout constructor]] . This means you can [[Reparent an Object| re-parent objects]] , using the [[EiffelBuild Notation|pick and drop]] transport method, seamlessly between the two views. <br/>
{{note|Holding Ctrl while right clicking on an [[EiffelBuild Notation|object]] in the Builder Window creates a new [[Object editor|object editor]] targeted to the [[EiffelBuild Notation|object]] . Holding Ctrl and Shift while right clicking on an [[EiffelBuild Notation|object]] , highlights it within the [[Layout constructor|layout constructor]] .}}
@@ -16,7 +16,7 @@ Because this window is just a view of the [[EiffelBuild Notation|objects]] , it
Although the builder window attempts to show you the interface you are developing, it is not a completely accurate representation (Unlike the [[Display window|display window]] ). The main difference is that all [[EiffelBuild Notation|objects]] representing descendents of EV_CONTAINER are parented in a frame. This was implemented so that you would be able to easily manipulate the containers.
Imagine that this was not the case, and each container [[EiffelBuild Notation|object]] was just represented by an [[EiffelVision Introduction|EiffelVision2]] object matching its type. Because these containers have no visible screen space when filled with children, manipulation of them would have been difficult, and the functionality of this view would be compromised.
Imagine that this was not the case, and each container [[EiffelBuild Notation|object]] was just represented by an [[EiffelVision Introduction|EiffelVision 2]] object matching its type. Because these containers have no visible screen space when filled with children, manipulation of them would have been difficult, and the functionality of this view would be compromised.
In the screenshot above, you can see that there are two [[EiffelBuild Notation|objects]] representing containers in your project, an <eiffel>EV_VERTICAL_BOX</eiffel>, and an <eiffel>EV_HORIZONTAL_BOX</eiffel> (Excluding the <eiffel>EV_TITLED_WINDOW</eiffel> [[EiffelBuild Notation|object]] represented by this window).

View File

@@ -16,8 +16,8 @@ Alternatively, you can hold down the Ctrl key while starting a [[EiffelBuild Not
==View types==
Looking at the left-hand screenshot above, you can see that the [[Image:icon-component-display-view-color]] button is depressed, meaning the component viewer is in display view mode. Clicking on [[Image:icon-component-build-view-color]] will put the component viewer into build mode view as shown in the right-hand screenshot. These modes are mutually exclusive and are described below:
* '''Builder view''' - This view is similar to the view used by the [[Display window|display window]] . i.e. the [[EiffelVision Introduction|EiffelVision2]] controls are displayed exactly as is defined in the [[EiffelBuild Notation|component]] .
* '''Display view''' - This view is similar to the view used by the [[Builder window|builder window]] . i.e. all [[EiffelVision Introduction|EiffelVision2]] containers are represented by frames so they are immediately visible. This makes the actual structure represented by the [[EiffelBuild Notation|component]] completely visible.
* '''Builder view''' - This view is similar to the view used by the [[Display window|display window]] . i.e. the [[EiffelVision Introduction|EiffelVision 2]] controls are displayed exactly as is defined in the [[EiffelBuild Notation|component]] .
* '''Display view''' - This view is similar to the view used by the [[Builder window|builder window]] . i.e. all [[EiffelVision Introduction|EiffelVision 2]] containers are represented by frames so they are immediately visible. This makes the actual structure represented by the [[EiffelBuild Notation|component]] completely visible.
{{note|The type of the "root_object" within the component is displayed in the toolbar of the component viewer. }}

View File

@@ -56,11 +56,11 @@ As objects are reliant on the constant you are removing, you must confirm that y
A String constant represents an Eiffel STRING, and may be any valid STRING. For example, in the generated constants file, for a String constant named `modify_button_text', the following code is generated:
<code>
modify_button_text: STRING is
-- `Result' is STRING constant named modify_button_text.
once
Result := "Modify"
end
modify_button_text: STRING
-- `Result' is STRING constant named modify_button_text.
once
Result := "Modify"
end
</code>
@@ -68,21 +68,21 @@ A String constant represents an Eiffel STRING, and may be any valid STRING. For
A Integer constant represents an Eiffel INTEGER, and may be any valid INTEGER value. For example, in the generated constants file, for an Integer constant named `medium_padding', the following code is generated:
<code>
medium_padding: INTEGER is
-- `Result' is INTEGER constant named medium_padding.
once
Result := 8
end</code>
medium_padding: INTEGER
-- `Result' is INTEGER constant named medium_padding.
once
Result := 8
end</code>
==Directory constant==
A Directory constant is an Eiffel representation of a directory, as a STRING value. For example, in the generated constants file, for a Directory constant named `pixmap_location', the following code is generated:
<code>
pixmap_location: STRING is
-- `Result' is DIRECTORY constant named pixmap_location.
once
Result := "C:\pixmaps"
end</code>
pixmap_location: STRING
-- `Result' is DIRECTORY constant named pixmap_location.
once
Result := "C:\pixmaps"
end</code>
==Pixmap constant==
@@ -90,30 +90,30 @@ A Directory constant is an Eiffel representation of a directory, as a STRING val
A pixmap constant is a representation of a pixmap image, and two types are available:
* '''Absolute''' - The generated code contains a constant of type EV_PIXMAP, built from a single, absolute path, based on the location of the original pixmap on disk as follows:
<code>
main_pixmap: EV_PIXMAP is
-- `Result' is PIXMAP constant named main_pixmap.
local
a_file_name: FILE_NAME
once
create Result
create a_file_name.make_from_string ("C:\pixmaps\main_pixmap.png")
-- Now set `Result' based on `a_file_name'.
set_with_named_file(Result, a_file_name)
end</code>
main_pixmap: EV_PIXMAP
-- `Result' is PIXMAP constant named main_pixmap.
local
a_file_name: FILE_NAME
once
create Result
create a_file_name.make_from_string ("C:\pixmaps\main_pixmap.png")
-- Now set `Result' based on `a_file_name'.
set_with_named_file(Result, a_file_name)
end</code>
* '''Relative''' - The generated code contains a constant of type EV_PIXMAP, built from a file name and a directory constant. This type of pixmap constant is the most frequently used, as it is more flexible. By redefining the value of the directory constant on which it is based, your systems may easily account for the installation location of the pixmap. A relative Pixmap constant is generated as follows:
<code>
main_pixmap: EV_PIXMAP is
-- `Result' is PIXMAP constant named main_pixmap.
local
a_file_name: FILE_NAME
once
create Result
create a_file_name.make_from_string (pixmap_location)
a_file_name.set_file_name("main_pixmap.png")
-- Now set `Result' based on `a_file_name'.
set_with_named_file(Result, a_file_name)
end</code>
main_pixmap: EV_PIXMAP
-- `Result' is PIXMAP constant named main_pixmap.
local
a_file_name: FILE_NAME
once
create Result
create a_file_name.make_from_string (pixmap_location)
a_file_name.set_file_name("main_pixmap.png")
-- Now set `Result' based on `a_file_name'.
set_with_named_file(Result, a_file_name)
end</code>
Where `pixmap_location' is the name of the Directory constant to which the pixmap is relative.
@@ -121,25 +121,27 @@ Where `pixmap_location' is the name of the Directory constant to which the pixma
==Font constant==
A Font constant represents an EV_FONT. For example, in the generated constants file, for a font constant named `times_new_roman', the following code is generated:
<code>times_new_roman: EV_FONT is
-- `Result' is EV_FONT constant named `times_new_roman'.
once
create Result
Result.set_family (feature {EV_FONT_CONSTANTS}.Family_roman)
Result.set_weight (feature {EV_FONT_CONSTANTS}.Weight_regular)
Result.set_shape (feature {EV_FONT_CONSTANTS}.Shape_regular)
Result.set_height_in_points (12)
Result.preferred_families.extend ("Times New Roman")
end</code>
<code>
times_new_roman: EV_FONT
-- `Result' is EV_FONT constant named `times_new_roman'.
once
create Result
Result.set_family (feature {EV_FONT_CONSTANTS}.Family_roman)
Result.set_weight (feature {EV_FONT_CONSTANTS}.Weight_regular)
Result.set_shape (feature {EV_FONT_CONSTANTS}.Shape_regular)
Result.set_height_in_points (12)
Result.preferred_families.extend ("Times New Roman")
end</code>
==Color constant==
A Color constant represents an EV_COLOR. For example, in the generated constants file, for a color constant named `red', the following code is generated:
<code>red: EV_COLOR is
-- `Result' is EV_COLOR constant named `red'.
once
Result := create {EV_COLOR}.make_with_8_bit_rgb (255, 0, 0)
end</code>
<code>
red: EV_COLOR
-- `Result' is EV_COLOR constant named `red'.
once
Result := create {EV_COLOR}.make_with_8_bit_rgb (255, 0, 0)
end</code>
===Pixmap constant dialog===

View File

@@ -7,9 +7,9 @@ This window may either be shown or hidden (default). To change between these two
[[Image:display-window]]
This view is provided so that you can really see what your project will look like when it has been generated and is running as a stand alone [[EiffelVision Introduction|EiffelVision2]] system.
This view is provided so that you can really see what your project will look like when it has been generated and is running as a stand alone [[EiffelVision Introduction|EiffelVision 2]] system.
All properties that have been set on the [[EiffelBuild Notation|objects]] in your project are set in the [[EiffelVision Introduction|EiffelVision2]] control matching its type.
All properties that have been set on the [[EiffelBuild Notation|objects]] in your project are set in the [[EiffelVision Introduction|EiffelVision 2]] control matching its type.
{{seealso|<br/>
[[Builder window|Builder window]] <br/>

View File

@@ -7,10 +7,18 @@ The docking mechanism permits customization of the EiffelBuild interface through
To dock one of the three supported tools, press and hold the left mouse button on the title of the tool, and move the mouse so that it points to the new location for the tool. Upon releasing the mouse button, the dock completes, and based on the mouse location, the following may occur:
* '''Re-positioning in the main window''' - If the mouse is held over the three part vertical split area displayed to the left hand side of the EiffelBuild window, the position of the tool within this structure may be modified, providing simple re-ordering. A small grayed area indicates the insertion position of the tool, only displayed if the tools position will be changed upon release. The gray area indicating the new insertion point has the following appearance:
[[Image:docking-insert]]
In this case, the tool being docked will be moved to immediately above the component selector. If no feedback is provided regarding the insertion, upon releasing the mouse button to complete the dock, the tool is moved to an external window.
* '''Docking externally''' - Completing a dock while not above the left hand area of the main window, or if no insert feedback is provided, causes the tool to be moved from its current location to an external window. A tool that is docked externally has the following appearance:
[[Image:docked-external]]
The tool may now be freely moved to any location on screen, in the same fashion as you would move any standard window. The window in which the tool is contained is always displayed "on top" of the main window. There are two methods of restoring the dialog back to its original location in the main window:
** '''Docking back''' - Start a drag from the title of the tool, and point the mouse to the position in which you wish to insert the tool within the main window. If the position is valid, feedback (the gray bar) is displayed, and completing the dock closes the dialog, and re-inserts the tool. If no feedback is provided, the pointed position is not valid, and completing the dock simply moves the window to that position on screen.
** '''Closing the window''' - Clicking the cross displayed to the right hand side of the windows title bar causes the window to be destroyed, and the tool contained to be restored back to its original position within the main window.
@@ -21,6 +29,8 @@ The tool may now be freely moved to any location on screen, in the same fashion
==Main window with externally docked tools==
The following screenshot illustrates the appearance of the main window with all dockable tools external:
[[Image:main-window-with-docked-tools]]

View File

@@ -7,7 +7,7 @@ The layout constructor provides a view of the [[EiffelBuild Notation|objects]]
[[Image:layout-constructor]]
Each item in the tree represents one object. The screenshot above represents the following [[EiffelVision Introduction|EiffelVision2]] interface definition - An EV_TITLED_WINDOW containing one child, of type EV_VERTICAL_BOX. Within the vertical box there is an EV_HORIZONTAL_BOX and an EV_LIST. The list is empty, but the horizontal box contains three different objects of type EV_BUTTON.
Each item in the tree represents one object. The screenshot above represents the following [[EiffelVision Introduction|EiffelVision 2]] interface definition - An EV_TITLED_WINDOW containing one child, of type EV_VERTICAL_BOX. Within the vertical box there is an EV_HORIZONTAL_BOX and an EV_LIST. The list is empty, but the horizontal box contains three different objects of type EV_BUTTON.
{{note|The widget displayed as the root of the Layout Constructor is the currently selected object in the [[Widget selector|Widget Selector]] . To edit the contents of a different widget, select the widget you wish to manipulate from the [[Widget selector|widget selector]] .}}

View File

@@ -29,9 +29,9 @@ When an object editor is targeted to an [[EiffelBuild Notation|object]] , you wi
* String properties inputted via a text field are updated within the object every time a key is pressed
* Integer properties inputted via a text field are only updated within the object when return is pressed, or the input box looses the focus.
* Almost without exception, a push button which controls a property, will open up a dialog, allowing the property to be edited. Examples are colors, pixmaps and events.
* If when you attempt to modify a property, it returns back to its original value, it means that the value you attempted to enter was invalid. For example, looking at the screen show above, if you enter -50 into the minimum_height text field and press return, it will revert back to 23. This is because the minimum_height of an <eiffel>EV_BUTTON</eiffel> may not be set to less than 0. To find allowable values for properties of an [[EiffelBuild Notation|object]] , consult the [[EiffelVision Introduction|EiffelVision2]] documentation.
* If when you attempt to modify a property, it returns back to its original value, it means that the value you attempted to enter was invalid. For example, looking at the screen show above, if you enter -50 into the minimum_height text field and press return, it will revert back to 23. This is because the minimum_height of an <eiffel>EV_BUTTON</eiffel> may not be set to less than 0. To find allowable values for properties of an [[EiffelBuild Notation|object]] , consult the [[EiffelVision Introduction|EiffelVision 2]] documentation.
All properties that may be manipulated in an object editor correspond directly to a property of the [[EiffelVision Introduction|EiffelVision2]] control that is represented by the [[EiffelBuild Notation|object]] (Displayed in an object editor as '''type'''). There is one exception to that rule though, and that is the '''Name''' field which is specific to EiffelBuild. This field is used for your identification of the [[EiffelBuild Notation|object]] and as the attribute name in the generated code. For example, when EiffelBuild generates code corresponding to the [[EiffelBuild Notation|object]] targeted in the editor shown above, it would declare the vision2 component as - button1: EV_BUTTON
All properties that may be manipulated in an object editor correspond directly to a property of the [[EiffelVision Introduction|EiffelVision 2]] control that is represented by the [[EiffelBuild Notation|object]] (Displayed in an object editor as '''type'''). There is one exception to that rule though, and that is the '''Name''' field which is specific to EiffelBuild. This field is used for your identification of the [[EiffelBuild Notation|object]] and as the attribute name in the generated code. For example, when EiffelBuild generates code corresponding to the [[EiffelBuild Notation|object]] targeted in the editor shown above, it would declare the EiffelVision 2 component as - button1: EV_BUTTON
{{note|You may have as many object editors targeted to the same [[EiffelBuild Notation|object]] as you wish. Whenever a change is made to the [[EiffelBuild Notation|object]] through one of the editors, all other editors targeted to that [[EiffelBuild Notation|object]] are synchronized. }}

View File

@@ -1,13 +1,13 @@
[[Property:title|Type selector]]
[[Property:weight|4]]
[[Property:uuid|893343c2-417f-90c5-147e-941bc232fe43]]
The type selector contains all the available Vision2 types supported by EiffelBuild. These are the basic building blocks for your system.
The type selector contains all the available EiffelVision 2 types supported by EiffelBuild. These are the basic building blocks for your system.
[[Image:type-selector]]
The types are organized into three groups - Primitives, Containers and Items. All types that may be used in EiffelBuild have a text in uppercase, corresponding to their type in [[EiffelVision Introduction|EiffelVision2]] . For example, looking at the screenshot above, the <eiffel>BUTTON</eiffel> item represents an <eiffel>EV_BUTTON</eiffel>, and the <eiffel>EV_COMBO_BOX</eiffel> item represents <eiffel>EV_COMBO_BOX</eiffel>.
The types are organized into three groups - Primitives, Containers and Items. All types that may be used in EiffelBuild have a text in uppercase, corresponding to their type in [[EiffelVision Introduction|EiffelVision 2]] . For example, looking at the screenshot above, the <eiffel>BUTTON</eiffel> item represents an <eiffel>EV_BUTTON</eiffel>, and the <eiffel>EV_COMBO_BOX</eiffel> item represents <eiffel>EV_COMBO_BOX</eiffel>.
{{note|The types available in the type selector are fixed, and cannot be modified. Almost all [[EiffelVision Introduction|EiffelVision2]] components are available. }}
{{note|The types available in the type selector are fixed, and cannot be modified. Almost all [[EiffelVision Introduction|EiffelVision 2]] components are available. }}
==Creating a new object==
[[EiffelBuild Notation|Objects]] are the building blocks used in EiffelBuild to construct your interface. To create a new [[EiffelBuild Notation|object]] for use in your system, [[EiffelBuild Notation|pick]] the type corresponding to the type of object you wish to create,and [[EiffelBuild Notation|drop]] onto an [[EiffelBuild Notation|object]] representation. If an object is full, or does not allow other objects of the new type to be contained, then you will not be able to [[EiffelBuild Notation|drop]] on it. <br/>
@@ -18,7 +18,7 @@ This shows how simple it is to Build new [[EiffelBuild Notation|objects]] in Ei
You may drop an object directly from the Type Selector into the [[Widget selector|widget selector]] which creates the object as a "top level object" ensuring that upon generation, it is represented by an individual set of classes. These top level objects may then be re-used within your interface as desired.
{{note|To understand the types accepted, and the capacity of objects, you should consult the [[EiffelVision Introduction|EiffelVision2]] library reference. }}
{{note|To understand the types accepted, and the capacity of objects, you should consult the [[EiffelVision Introduction|EiffelVision 2]] library reference. }}
==Changing the type of an existing object==

View File

@@ -1,7 +1,7 @@
[[Property:title|EiffelVision 2 Samples]]
[[Property:weight|3]]
[[Property:uuid|79c05bf8-367e-001d-0c13-f668e34fa5b0]]
Vision2 ships with a number of samples provided to demonstrate different aspects of the library. If you are a new vision2 user then it is suggested that you first compile and run the
EiffelVision 2 ships with a number of samples provided to demonstrate different aspects of the library. If you are a new EiffelVision 2 user then it is suggested that you first compile and run the
* [[Widgets Sample|Widgets]] sample. Demonstrates both the appearance and behavior of the available widgets.

View File

@@ -18,7 +18,7 @@
After launching the application, you will see a window displayed with a similar appearance to the one above. You may exit the application at any time, by clicking on the close icon, or you may select "exit" from the "File" menu. Selected "Help", "about" displays a dialog with details about the application.
The left hand side of the main window contains a tree, showing the widgets available within vision2. If you select one of these widgets in the tree, then the type of widget you selected will be displayed in the middle of the main_window. Controls will also the be available to the right hand side of the widget, which allow you to modify its state. These controls do not represent all the available feature of the widget, but demonstrate many of the most common. The text area below the currently selected widget displays the events that have occurred on the widget. Only those events inherited by EV_WIDGET are displayed.
The left hand side of the main window contains a tree, showing the widgets available within EiffelVision 2. If you select one of these widgets in the tree, then the type of widget you selected will be displayed in the middle of the main_window. Controls will also the be available to the right hand side of the widget, which allow you to modify its state. These controls do not represent all the available feature of the widget, but demonstrate many of the most common. The text area below the currently selected widget displays the events that have occurred on the widget. Only those events inherited by EV_WIDGET are displayed.
==Under the Hood==

View File

@@ -1,23 +1,27 @@
[[Property:title|EiffelVision Introduction]]
[[Property:weight|0]]
[[Property:uuid|f964651a-e36d-4e9e-00ea-37803a26373a]]
The EiffelVision library offers an object-oriented framework for graphical user interface (GUI) development. Using EiffelVision, developers can access all necessary GUI components, called [[Widgets|widgets]] (buttons, windows, list views) as well as truly graphical elements such as points, lines, arcs, polygons and the like -- to develop a modern, functional and good-looking graphical interactive application.
The EiffelVision 2 library offers an object-oriented framework for graphical user interface (GUI) development. Using EiffelVision 2, developers can access all necessary GUI components, called [[Widgets|widgets]] (buttons, windows, list views) as well as truly graphical elements such as points, lines, arcs, polygons and the like -- to develop a modern, functional and good-looking graphical interactive application.
EiffelVision has played a major role at Eiffel Software and provided numerous Eiffel projects with a powerful, portable graphics development platform. EiffelStudio is totally reliant on EiffelVision for its graphical elements and overall interaction with the user.
EiffelVision 2 has played a major role at Eiffel Software and provided numerous Eiffel projects with a powerful, portable graphics development platform. EiffelStudio is totally reliant on EiffelVision 2 for its graphical elements and overall interaction with the user.
==Scope==
The EiffelVision library addresses all the major needs of developers of systems supporting modern graphical interfaces. EiffelVision runs on Microsoft Windows and all major variations of Unix (including Linux). All versions are fully source-compatible; with only a recompile, applications will run on every supported platform with the native look-and-feel.
The EiffelVision 2 library addresses all the major needs of developers of systems supporting modern graphical interfaces. EiffelVision 2 runs on Microsoft Windows and all major variations of Unix (including Linux). All versions are fully source-compatible; with only a recompile, applications will run on every supported platform with the native look-and-feel.
EiffelVision provides an effective way of building advanced graphical applications using user interface standards and toolkits (such as Microsoft Windows and GTK) without having to learn the details of the toolkits. Instead, you can use EiffelVision to work entirely in terms of high level abstractions representing windows, buttons, labels, graphical figures, menus, buttons etc., and apply clearly understandable operations to the corresponding objects.
EiffelVision 2 provides an effective way of building advanced graphical applications using user interface standards and toolkits (such as Microsoft Windows and GTK) without having to learn the details of the toolkits. Instead, you can use EiffelVision 2 to work entirely in terms of high level abstractions representing windows, buttons, labels, graphical figures, menus, buttons etc., and apply clearly understandable operations to the corresponding objects.
==Architecture==
EiffelVision relies on a two-tiered architecture illustrated by the following figure.
[[Image:vision2--figure1]]
EiffelVision 2 relies on a two-tiered architecture illustrated by the following figure.
[[Image:vision2--figure1]]
The two tiers play complementary roles:
* At the top level, EiffelVision provides fully portable graphics.
* At the top level, EiffelVision 2 provides fully portable graphics.
* At the lower level, platform-specific libraries cover the graphical mechanisms of graphics platforms such as Windows and GTK.
The lower tier serves for the implementation of the upper tier, but can also be used independently. For example [[WEL]] has had a resounding success with Windows developers who need an advanced mechanism for building Windows-specific graphical applications, taking advantage of every facility of the Windows API (Application Programming Interface) and of the Eiffel approach, but do not need portability on the client side. The GEL library is a '''wrapper''' library, automatically generated from the entire GTK API by a tool named '''The Gote Converter'''.
@@ -31,30 +35,46 @@ As stated before, the library has undergone some drastic changes since the previ
==Design==
EiffelVision provides programmers with high-level classes, that provide all mechanism and data structures needed to build advanced user interfaces for deployment on almost all platforms without having to worry about detailed requirements of toolkits.
EiffelVision 2 provides programmers with high-level classes, that provide all mechanism and data structures needed to build advanced user interfaces for deployment on almost all platforms without having to worry about detailed requirements of toolkits.
The abstract design has been derived from an analysis of user interfaces. Therefore we have classes with names like MENU, WINDOW, BUTTON, LINE or POLYGON. The features of these classes are simple, clearly defined properties or commands, like the feature `minimize' (a command) on WINDOW or `text' (a property of type STRING) on BUTTON.
{{note| All class names in EiffelVision are pre-pended with EV_ to avoid name clashes with existing classes. BUTTON hence becomes <eiffel>EV_BUTTON</eiffel>, etc. }}
{{note| All class names in EiffelVision 2 are pre-pended with EV_ to avoid name clashes with existing classes. BUTTON hence becomes <eiffel>EV_BUTTON</eiffel>, etc. }}
==Properties==
When talking about a property of a class, like `text', in fact we are talking about multiple features. One is a query of the state of the property, in this case simply the query `text'. The other is the set-routine, which is by convention named `set_text' taking exactly one argument of the type of property. A property can be read-only, which means that it cannot be set by clients of the class.
<code>
text: STRING
set_text (a_text: STRING) is ...
text: STRING
set_text (a_text: STRING)
...
do
...
end
</code>
Boolean properties have a different convention. Instead of one set-routine, it has one enable-routine and one disable-routine. The first one sets the property to true, the second to false. This has been done like this because sometimes these enable/disable features have trivial equivalents, for example for feature `enable_visible' a clearer name is `show'.
<code>
is_sensitive: BOOLEAN
enable_sensitive is ...
disable_sensitive is ...
is_sensitive: BOOLEAN
enable_sensitive
...
do
...
end
disable_sensitive
...
do
...
end
</code>
==Implementation==
For flexibility, EiffelVision is built using the bridge pattern. This means that every platform-dependent component of the library consist of two classes, plus an implementation class for each platform (currently two). One is the <eiffel>interface</eiffel>. All the features of interfaces do nothing except delegate the call to the implementation object which is coupled to it. This object has the static type of the implementation-interface with the name of the interface class, with _I appended to it. From this implementation-interface, implementation classes inherit to implement platform-specific features.
For flexibility, EiffelVision 2 is built using the bridge pattern. This means that every platform-dependent component of the library consist of two classes, plus an implementation class for each platform (currently two). One is the <eiffel>interface</eiffel>. All the features of interfaces do nothing except delegate the call to the implementation object which is coupled to it. This object has the static type of the implementation-interface with the name of the interface class, with <eiffel>_I</eiffel> appended to it. From this implementation-interface, implementation classes inherit to implement platform-specific features.

View File

@@ -1,11 +1,11 @@
[[Property:title|Events]]
[[Property:weight|4]]
[[Property:uuid|fc32d1b5-72d6-2955-18fd-bce988ed8323]]
This cluster contains classes for event handling within Vision2.
This cluster contains classes for event handling within EiffelVision 2.
==What is an event?==
An event is considered to be an external action that occurs during a program's execution. Correctly dealing with events is an important part of developing a Vision2 application. For example, if a user clicks on a button, you will want to respond to this event by calling a routine that deals with the request. Vision2 contains action sequences for all kinds of widget events. To view the kind of events available to every widget, click [[ref:libraries/vision2/reference/ev_widget_action_sequences_chart|here]] .
An event is considered to be an external action that occurs during a program's execution. Correctly dealing with events is an important part of developing a EiffelVision 2 application. For example, if a user clicks on a button, you will want to respond to this event by calling a routine that deals with the request. EiffelVision 2 contains action sequences for all kinds of widget events. To view the kind of events available to every widget, click [[ref:libraries/vision2/reference/ev_widget_action_sequences_chart|here]] .
==How do I connect to an event?==
@@ -13,10 +13,10 @@ Every widget and item has an action sequence associated with it that relates to
An example of adding an agent to an action_sequence is as follows.
<code>
button.select_actions.extend (agent print ("Button Clicked!%N"))
button.select_actions.extend (agent print ("Button Clicked!%N"))
</code>
All Vision2 action sequences inherit [[ref:libraries/vision2/reference/ev_action_sequence_chart|EV_ACTION_SEQUENCE]] and when it is called, all of the agents held within are fired, thus calling all of the procedures represented by the agents. The signature of any agent that you place in an action sequence must conform to those of the action sequences actual generic parameter.
All EiffelVision 2 action sequences inherit [[ref:libraries/vision2/reference/ev_action_sequence_chart|EV_ACTION_SEQUENCE]] and when it is called, all of the agents held within are fired, thus calling all of the procedures represented by the agents. The signature of any agent that you place in an action sequence must conform to those of the action sequences actual generic parameter.
When you want an agent to be called from a certain action sequence and the signatures do not match, you may use [[ref:libraries/vision2/reference/ev_action_sequence_chart|force_extend]] . This will call your agent but has no guarantees on the arguments passed to your procedure.

View File

@@ -1,7 +1,7 @@
[[Property:title|Figures]]
[[Property:weight|7]]
[[Property:uuid|c12fee6e-5e99-ae59-8ac5-f57abb4c1878]]
The EiffelVision figure cluster can be considered a high-level way of drawing on an [[ref:libraries/vision2/reference/ev_drawable_chart|EV_DRAWABLE]] descendant. Here are some advantages:
The EiffelVision 2 figure cluster can be considered a high-level way of drawing on an [[ref:libraries/vision2/reference/ev_drawable_chart|EV_DRAWABLE]] descendant. Here are some advantages:
* The model is separated from the representation by using projectors that take a world of figures and project it to any device, not just a drawing area.
* Instead of drawing with static API's like draw_line, real figure objects are used that can move, change color or morph.
* For projection devices that allow this, events may be caught and fired through the appropriate figure object.
@@ -81,6 +81,7 @@ As top-level group of a world of figures you must use [[ref:libraries/vision2/re
| a string positioned by its top-left point displayed in the specified font
|}
A closed figure is a figure that has some area enclosed when drawn that can optionally be filled with a color. Closed figures inherit [[ref:libraries/vision2/reference/ev_closed_figure_chart|EV_CLOSED_FIGURE]] which gives them the property fill_color. Open figures inherit [[ref:libraries/vision2/reference/ev_atomic_figure_chart|EV_ATOMIC_FIGURE]] directly just as [[ref:libraries/vision2/reference/ev_closed_figure_chart|EV_CLOSED_FIGURE]] .
===Points===

View File

@@ -1,7 +1,7 @@
[[Property:title|Items]]
[[Property:weight|3]]
[[Property:uuid|3143511c-28bd-cc5c-c710-700796778982]]
All Vision2 items inherit [[ref:libraries/vision2/reference/ev_item_chart|EV_ITEM]] .
All EiffelVision 2 items inherit [[ref:libraries/vision2/reference/ev_item_chart|EV_ITEM]] .
==What is an item?==
@@ -25,8 +25,6 @@ Below is a structure showing the Vision2 components and the items that they acce
**** [[ref:libraries/vision2/reference/ev_radio_menu_item_chart|EV_RADIO_MENU_ITEM]]
**** [[ref:libraries/vision2/reference/ev_check_menu_item_chart|EV_CHECK_MENU_ITEM]]
* [[ref:libraries/vision2/reference/ev_multi_column_list_chart|EV_MULTI_COLUMN_LIST]] accepts items of type:
** [[ref:libraries/vision2/reference/ev_multi_column_list_row_chart|EV_MULTI_COLUMN_LIST_ROW]]

View File

@@ -1,38 +1,38 @@
[[Property:title|Properties]]
[[Property:weight|5]]
[[Property:uuid|0d46c1eb-bce4-2d67-0272-da4aa5950c65]]
This cluster contains all the common properties available for Vision2 [[Widgets|widgets]] and [[Items|items]] . Every Vision2 widget has the same set of properties inherited from EV_WIDGET, but many widgets also inherit additional properties, further refining the behavior of the widget.
This cluster contains all the common properties available for EiffelVision 2 [[Widgets|widgets]] and [[Items|items]] . Every EiffelVision 2 widget has the same set of properties inherited from EV_WIDGET, but many widgets also inherit additional properties, further refining the behavior of the widget.
EV_WIDGET inherits the following properties:
* [[ref:libraries/vision2/reference/ev_pick_and_dropable_chart|EV_PICK_AND_DROPABLE]]
** For an overview of the Pick and Drop mechanism, click [[EiffelVision Pick and Drop|here]] .
* [[ref:libraries/vision2/reference/ev_sensitive_chart|EV_SENSITIVE]]
** If a Vision2 component inherits [[ref:libraries/vision2/reference/ev_sensitive_chart|EV_SENSITIVE]] , it can be made to ignore events. <br/>
** If an EiffelVision 2 component inherits [[ref:libraries/vision2/reference/ev_sensitive_chart|EV_SENSITIVE]] , it can be made to ignore events. <br/>
Use <eiffel>disable_sensitive</eiffel> to disable event handling, and <eiffel>enable_sensitive</eiffel> to restore event handling.
* [[ref:libraries/vision2/reference/ev_colorizable_chart|EV_COLORIZABLE]]
** If a Vision2 component inherits [[ref:libraries/vision2/reference/ev_colorizable_chart|EV_COLORIZABLE]] it has facilities for modifying its foreground and background colors. <br/>
** If a EiffelVision 2 component inherits [[ref:libraries/vision2/reference/ev_colorizable_chart|EV_COLORIZABLE]] it has facilities for modifying its foreground and background colors. <br/>
Use <eiffel>set_foreground_color</eiffel> to set the <eiffel>foreground_color</eiffel> and <eiffel>set_background_color</eiffel> to set the <eiffel>background_color</eiffel>. <br/>
Use <eiffel>set_default_colors</eiffel> to restore the colors to their defaults.
* [[ref:libraries/vision2/reference/ev_help_contextable_chart|EV_HELP_CONTEXTABLE]]
** If a Vision2 component inherits [[ref:libraries/vision2/reference/ev_help_contextable_chart|EV_HELP_CONTEXTABLE]] , facilities are provided for associating help to the component when F1 or Shift F1 is pressed.
** If a EiffelVision 2 component inherits [[ref:libraries/vision2/reference/ev_help_contextable_chart|EV_HELP_CONTEXTABLE]] , facilities are provided for associating help to the component when F1 or Shift F1 is pressed.
* [[ref:libraries/vision2/reference/ev_positioned_chart|EV_POSITIONED]]
** If a Vision2 component inherits [[ref:libraries/vision2/reference/ev_positioned_chart|EV_POSITIONED]] it is possible to query its current position, size and minimum size. <br/>
** If a EiffelVision 2 component inherits [[ref:libraries/vision2/reference/ev_positioned_chart|EV_POSITIONED]] it is possible to query its current position, size and minimum size. <br/>
Use <eiffel>x_position</eiffel> and <eiffel>y_position</eiffel> to find its position relative to its parent. <br/>
Use <eiffel>width</eiffel> and <eiffel>height</eiffel> to find its size. <br/>
Use <eiffel>minimum_width</eiffel> and <eiffel>minimum_height</eiffel> to find its size.
* [[ref:libraries/vision2/reference/ev_containable_chart|EV_CONTAINABLE]]
** If a Vision2 component inherits [[ref:libraries/vision2/reference/ev_containable_chart|EV_CONTAINABLE]] it is able question its parent. Use parent to query the current parent.
** If a EiffelVision 2 component inherits [[ref:libraries/vision2/reference/ev_containable_chart|EV_CONTAINABLE]] it is able question its parent. Use parent to query the current parent.
{{note|[[ref:libraries/vision2/reference/ev_containable_chart|EV_CONTAINABLE]] has no features for setting the parent. In Vision2, a child has no features for setting its parent, while a parent such as ev_container contains routines for adding children (one example is <eiffel>extend</eiffel>). }}
{{note|[[ref:libraries/vision2/reference/ev_containable_chart|EV_CONTAINABLE]] has no features for setting the parent. In EiffelVision 2, a child has no features for setting its parent, while a parent such as ev_container contains routines for adding children (one example is <eiffel>extend</eiffel>). }}
The following properties are also used within Vision2:
The following properties are also used within EiffelVision 2:
* [[ref:libraries/vision2/reference/ev_deselectable_chart|EV_DESELECTABLE]]
* [[ref:libraries/vision2/reference/ev_drawable_chart|EV_DRAWABLE]]
* [[ref:libraries/vision2/reference/ev_fontable_chart|EV_FONTABLE]]

View File

@@ -1,7 +1,7 @@
[[Property:title|Revisions and Bug Fixes]]
[[Property:weight|10]]
[[Property:uuid|eb11a237-0c75-0427-452a-303d4f276b97]]
This document contains details of modifications and bug fixes to the Vision2 library listed by the release version of EiffelStudio. All bug fixes and modifications are relative to the previously released version.
This document contains details of modifications and bug fixes to the EiffelVision 2 library listed by the release version of EiffelStudio. All bug fixes and modifications are relative to the previously released version.
==EiffelStudio 6.2==
@@ -54,7 +54,7 @@ This document contains details of modifications and bug fixes to the Vision2 lib
* '''EV_PICK_AND_DROPABLE''' - Added context menu capabilities with 'set_configurable_target_menu_mode', 'set_configurable_target_menu_handler' and 'show_configurable_target_menu' that can be used to override the existing Pick and Drop mechanism.
* '''EV_ACTION_SEQUENCE''' - Now event_data is defined with named tuples for easier reading of the action sequence parameters.
* '''EV_APPLICATION_ACTION_SEQUENCES'''
** Added 'file_drop_actions' for OS based file drag and drop from exterior applications to a Vision2 application.
** Added 'file_drop_actions' for OS based file drag and drop from exterior applications to a EiffelVision 2 application.
** Made 'idle_actions' obsolete as it is not thread-safe
** Now a full garbage collection occurs if the application has been idle for 30 seconds
@@ -101,7 +101,7 @@ This document contains details of modifications and bug fixes to the Vision2 lib
* '''STRING_GENERAL''' - All string operations now take STRING_GENERAL instead of STRING, this allows for mixing and matching of 8 and 32-bit string objects and allows for 32bit Unicode values, the return value is always STRING_32
* '''EV_APPLICATION'''
** Added action sequences for querying global user events such as pointer clicks and motion
** Vision2 is now thread-aware with the addition of thread-safe 'add_idle_action' and 'do_once_on_idle' that allow threads to add agents to update the main GUI thread in a safe manner
** EiffelVision 2 is now thread-aware with the addition of thread-safe 'add_idle_action' and 'do_once_on_idle' that allow threads to add agents to update the main GUI thread in a safe manner
* '''EV_POINTER_STYLE''' - Added new pointer style class for setting the style of the mouse pointer, EV_CURSOR will be made obsolete, in the future animated cursors and transparency will be available
* '''EV_PIXEL_BUFFER''' - New class for loading/querying and setting RGBA values from disk
@@ -130,7 +130,7 @@ This document contains details of modifications and bug fixes to the Vision2 lib
* '''EV_GRID_ROW''' - Added `insert_subrows' for the quick addition of multiple subrows at once.
* '''EV_WINDOW''' - Added `is_border_enabled', `enable_border' and `disable_border'. This lets you turn on/off the border as required.
* '''EV_HEADER_ITEM''' - Added `user_can_resize' which enables you to prevent a user from resizing the item. Also added `minimum_width' and `maximum_width' which permit you to restrict the resizing of the item within a particular range.
* '''EV_MESSAGE_DIALOG''' - All message dialogs now use their associated message icon as the icon pixmap displayed in the title bar, instead of the standard EiffelVision2 icon.
* '''EV_MESSAGE_DIALOG''' - All message dialogs now use their associated message icon as the icon pixmap displayed in the title bar, instead of the standard EiffelVision 2 icon.
* '''EV_DYNAMIC_TREE_ITEM''' - The `subtree_function' is now only executed when you expand the item. In the previous version, querying the contents of the item caused the subtree function to be executed, filling the children.
* '''EV_COMBO_BOX''' - Added `is_list_shown', `list_hidden_actions' and renamed `drop_down_actions' to `list_shown_actions'.
* '''EV_APPLICATION''' - Added `pointer_motion_actions', `pointer_button_press_actions', `pointer_button_release_actions', `pointer_double_press_actions', `mouse_wheel_actions', `key_press_actions', `key_press_string_actions' and `key_release_actions'. Each of these action sequences pass the applicable widget as part of the event data.
@@ -291,7 +291,7 @@ This document contains details of modifications and bug fixes to the Vision2 lib
*** Fixed crash when removing nodes from parent nodes not present in a tree widget
** '''EV_RICH_TEXT'''
*** Now `paste' uses the Vision2 clipboard directly and so all clipboard assertions are fulfilled
*** Now `paste' uses the EiffelVision 2 clipboard directly and so all clipboard assertions are fulfilled
*** Fixed `buffered_format' to not wipe out the text buffer of the widget and therefore stop other EV_TEXT features from functioning correctly
*** Now `buffered_append' doesn't wipe out the screen contents of the rich text control
@@ -302,7 +302,7 @@ This document contains details of modifications and bug fixes to the Vision2 lib
** '''EV_PIXMAP''' - Improved pixmap 'stretch' for smaller images
** '''EV_WIDGET'''
*** Optimized motion event handling so that current motion events only get requested when the previous one has been processed
*** Fixed theme managed handling in all widgets so that fonts when changed outside of the application by the theme manager get reflected in the Vision2 application
*** Fixed theme managed handling in all widgets so that fonts when changed outside of the application by the theme manager get reflected in the EiffelVision 2 application
** '''EV_DIALOG'''
*** Fixed bug where modal and modeless dialogs were not centered to parent
@@ -412,7 +412,7 @@ This document contains details of modifications and bug fixes to the Vision2 lib
* '''EV_FIGURE_EQUILATERAL''' - First point generated is now based upon 'point_b'
'''Breaking changes'''
* '''EV_TREE_NODE_CONTAINER''' - This class is no longer used in EiffelVision2, and if you were relying on it, you should use EV_TREE_NODE_LIST instead. The type of `parent' for tree nodes has been changed from EV_TREE_NODE_CONTAINER to EV_TREE_NODE_LIST, so if you retrieve the `parent' and then attempt to iterate, you may have declared an instance of EV_TREE_NODE_CONTAINER. In this situation, you should simply change the definition to EV_TREE_NODE_LIST instead.
* '''EV_TREE_NODE_CONTAINER''' - This class is no longer used in EiffelVision 2, and if you were relying on it, you should use EV_TREE_NODE_LIST instead. The type of `parent' for tree nodes has been changed from EV_TREE_NODE_CONTAINER to EV_TREE_NODE_LIST, so if you retrieve the `parent' and then attempt to iterate, you may have declared an instance of EV_TREE_NODE_CONTAINER. In this situation, you should simply change the definition to EV_TREE_NODE_LIST instead.
'''Bug fixes'''
* '''Platform independent'''
@@ -599,7 +599,7 @@ The following list details some of the breaking changes, and how to fix them:
** redefined `prunable' to `True' and implemented `prune'.
** Added the following features - `set_item_span', `set_item_position', `set_item_span_and_position', `area_clear_excluding_widget', `item_row_span', `item_column_span', `item_row_position' and `item_column_position'.
* '''EV_WIDGET''' - Changed type of `focus_in_actions' and `focus_out_actions' from EV_FOCUS_ACTION_SEQUENCE to EV_NOTIFY_ACTION_SEQUENCE. `is_parent_recursive' is no longer available. It has been moved to EV_CONTAINER. This was necessary to fix a catcall encountered using vision2 under .NET. The problem manifested with widgets that held items.
* '''EV_WIDGET''' - Changed type of `focus_in_actions' and `focus_out_actions' from EV_FOCUS_ACTION_SEQUENCE to EV_NOTIFY_ACTION_SEQUENCE. `is_parent_recursive' is no longer available. It has been moved to EV_CONTAINER. This was necessary to fix a catcall encountered using EiffelVision 2 under .NET. The problem manifested with widgets that held items.
* '''EV_FIGURE''' - `proximity_in_actions' and `proximity_out_actions' are now obsolete.
* '''EV_FONTABLE''' - `set_font' now sets a copy of the font internally.
* '''EV_TREE''' - `ensure_item_visible' and `has_recursively' now take an EV_TREE_NODE as arguments, instead of an EV_TREE_ITEM.
@@ -753,7 +753,7 @@ The following list details some of the breaking changes, and how to fix them:
** '''EV_BUTTON''' - The result of `text_alignment' after default_create was incorrect.
* '''Gtk'''
** Gtk version of Studio released (including Vision2), so no fixes from 5.0
** Gtk version of Studio released (including EiffelVision 2), so no fixes from 5.0