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 name_not_empty: a_nm /= Void and then not a_nm.is_empty
offset_valid: a_offset >= -12 and a_offset <= 12 offset_valid: a_offset >= -12 and a_offset <= 12
do do
name := clone (a_nm) name := a_nm.twin
utcoffset := a_offset utcoffset := a_offset
ensure ensure
name_initialized: name.is_equal (a_nm) 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: [[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>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: * <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: * <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>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>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/> * <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>. 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. 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,33 +42,45 @@ 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. * <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. 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== ==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 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/> 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 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: 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 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 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> 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]] : 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: 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: The flat-short form of [[ref:/libraries/base/reference/bilinear_chart|BILINEAR]] shows the complete reconstructed invariant:
<code> <code>
@@ -86,7 +104,7 @@ loop
lin.forth lin.forth
end</code> 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/> 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>. 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,19 +116,23 @@ For every one of the structures under discussion there is a notion of current po
* <eiffel>finish</eiffel>, <eiffel>back</eiffel>, <eiffel>before</eiffel>. * <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: 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) <code>
after = (index = count + 1)
before = (index = 0)</code> 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: 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)) <code>
after = (is_empty or (index = count + 1))
before = (is_empty or (index = 0))</code> 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 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 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: 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 <code>
0 <= index
index <= count + 1 index <= count + 1
before = (index = 0) before = (index = 0)
after = (index = count + 1) after = (index = count + 1)
@@ -137,13 +159,13 @@ 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.) * 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: 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>. * <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: Other procedures work on the current position:
* <code>s.</code><eiffel>remove</eiffel> removes the item at 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.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/> 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: Yet another group of features are based on the first occurrence of a certain item, or on all occurrences:
@@ -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.) * 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>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>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. 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> <code>not after</code>
Similarly, the precondition for back is 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]] : 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. For a non-empty circular chain, then, you can circle forever around the items, using forth or back.
@@ -199,7 +223,8 @@ 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/> 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/> 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 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 <code>
forth
-- Move cursor to next item, cyclically. -- Move cursor to next item, cyclically.
do do
standard_forth standard_forth
@@ -214,7 +239,8 @@ In such cases the circular chain classes have features called <eiffel>standard_f
==Traversing a list or circular chain== ==Traversing a list or circular chain==
The properties of <eiffel>forth</eiffel> for circular chains imply that a traversal loop written as The properties of <eiffel>forth</eiffel> for circular chains imply that a traversal loop written as
<code>from <code>
from
lin.start lin.start
until until
lin.off lin.off
@@ -225,9 +251,9 @@ 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 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 <code>
from
lin.start lin.start
some_optional_initializing_operation (lin) some_optional_initializing_operation (lin)
until until
lin.exhausted lin.exhausted
@@ -268,7 +294,11 @@ An arrayed implementation uses an array to represent a linear structure. If the
==Linked structures== ==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. 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 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>
@@ -276,12 +306,16 @@ will have as its run-time value (if not void) a reference to such an object, whi
Clearly, a header of type <code>LINKED_LIST [SOME_TYPE]</code> will be associated with cells of type <code>LINKABLE [SOME_TYPE]</code>. <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/> 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. 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== ==Linked cells==
The classes describing list cells are descendants of a deferred class called [[ref:/libraries/base/reference/cell_chart|CELL]] , whose features are: 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>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/> 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. 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,7 +323,8 @@ 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. }} {{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 It may be implemented as
<code>item: G is <code>
item: G
-- Current item -- Current item
do do
Result := active.item Result := active.item
@@ -328,7 +363,8 @@ divided into a number of blocks. Each block is an array, but the successive arra
=Sorted Linear Structures= =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 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 <code>
deferred class
COMPARABLE_STRUCT [G -> COMPARABLE] COMPARABLE_STRUCT [G -> COMPARABLE]
inherit inherit
BILINEAR BILINEAR
@@ -342,7 +378,8 @@ 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/> 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/> 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 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 <code>
deferred class
PART_SORTED_LIST [G -> COMPARABLE]...</code> 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/> 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/>

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. 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== ==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. 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> <code>
until_do is until_do
-- Apply action to every item of target, -- Apply action to every item of target,
-- up to but excluding first one satisfying test. -- up to but excluding first one satisfying test.
-- (Apply to full list if no item satisfies 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/> 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>: 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> <code>
test: BOOLEAN is test: BOOLEAN
-- Test to be applied to item at current position in -- Test to be applied to item at current position in
-- target (default: value of item_test on item) -- target (default: value of item_test on item)
require require
@@ -128,7 +131,7 @@ inherit
feature feature
resize_paragraphs (t: TEXT) is resize_paragraphs (t: TEXT)
-- Resize all the paragraphs of t up to but excluding -- Resize all the paragraphs of t up to but excluding
-- the first one that has been modified. -- the first one that has been modified.
do do
@@ -138,13 +141,13 @@ feature
feature {NONE} feature {NONE}
item_test (p PARAGRAPH): BOOLEAN is item_test (p PARAGRAPH): BOOLEAN
-- Has p been modified? -- Has p been modified?
do do
Result := p.modified Result := p.modified
end end
item_action (p: PARAGRAPH) is item_action (p: PARAGRAPH)
-- Resize p. -- Resize p.
do do
p.resize p.resize
@@ -195,7 +198,7 @@ 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]] ). 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== ==General iteration facilities==
@@ -205,7 +208,7 @@ An iterator will always apply to a certain target structure. The target is intro
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: 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> <code>
set (s: like target) is set (s: like target)
-- Make s the new target of iterations. -- Make s the new target of iterations.
require require
s /= Void 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: 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> <code>
action is action
-- Action to be applied to item at current position in -- Action to be applied to item at current position in
-- target. -- target.
-- (default: item_action on item at current position.) -- (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 invariant_satisfied: invariant_value
end end
test: BOOLEAN is test: BOOLEAN
-- Test to be applied to item at current position in -- Test to be applied to item at current position in
-- target (default: value of item_test on item) -- target (default: value of item_test on item)
require 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/> [[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>: 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> <code>
do_if is do_if
-- Apply action to every item of target satisfying -- Apply action to every item of target satisfying
-- test. -- test.
do do
from from
target.start target.start
invariant invariant
invariant_value 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 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> <code>
off: BOOLEAN is off: BOOLEAN
-- Is position of target off? -- Is position of target off?
require require
traversable_exists: target /= Void traversable_exists: target /= Void
@@ -363,13 +367,13 @@ feature -- Status report
feature -- Cursor movement feature -- Cursor movement
finish is finish
-- Move cursor of target to last position. -- Move cursor of target to last position.
do do
target.finish target.finish
end end
back is back
-- Move cursor of target backward one position. -- Move cursor of target backward one position.
do do
target.back 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/> 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: [[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>pre_do_all</eiffel>, <eiffel>pre_until</eiffel>, and so on.
* <eiffel>post_do_all</eiffel>, <eiffel>post_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>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= =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== ==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/> 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 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. The next two techniques will remove this limitation.
@@ -431,38 +435,38 @@ inherit
feature feature
action1 is action1
-- Action for the first scheme -- Action for the first scheme
do do
... ...
end end
test1: BOOLEAN is test1: BOOLEAN
-- Test for the first scheme -- Test for the first scheme
do do
... ...
end end
action2 is action2
-- Action for the second scheme -- Action for the second scheme
do do
... ...
end end
test2: BOOLEAN is test2: BOOLEAN
-- Test for the second scheme -- Test for the second scheme
do do
... ...
end end
iterate1 is iterate1
-- Execute iteration of first kind. -- Execute iteration of first kind.
do do
set (...) set (...)
do_if1 do_if1
end end
iterate2 is iterate2
-- Execute iteration of second kind. -- Execute iteration of second kind.
do do
set (...) 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/> 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 We can use loops for that purpose, for example
<code> <code>
display is display
-- Recursively display all components of the complex -- Recursively display all components of the complex
-- figure -- figure
do do
@@ -548,7 +552,7 @@ create
feature feature
item_action (f: FIGURE) is item_action (f: FIGURE)
-- Action to be applied to each figure: display -- Action to be applied to each figure: display
-- it. -- it.
do 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: 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> <code>
display is display
-- Recursively display all components of the complex -- Recursively display all components of the complex
-- figure -- figure
local local

View File

@@ -26,7 +26,7 @@ The deferred class [[ref:libraries/base/reference/comparable_set_chart|COMPARABL
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/> 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/> 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

@@ -22,7 +22,8 @@ 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. * 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 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) <code>
h.put (x, k)
h := a.item (k)</code> 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/> 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/>
@@ -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/> 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 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 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. * 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== ==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. 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. 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. 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=== ===Basic binary trees===
Class [[ref:libraries/base/reference/binary_tree_chart|BINARY_TREE]] describes binary trees. <br/> Class [[ref:libraries/base/reference/binary_tree_chart|BINARY_TREE]] describes binary trees.
<br/>
[[Image:binary-tree|binary_tree]] <br/>
<br/> [[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). 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=== ===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 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): 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''. * 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''. * 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''. * 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

@@ -55,6 +55,13 @@ feature
end end
</code> </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 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> <code>
x := out x := out
@@ -66,9 +73,9 @@ The first call yields a printable representation of the current object; the seco
==Input and output features== ==Input and output features==
Some of the features of [[ref:/libraries/base/reference/any_chart|ANY]] cover common input and output needs. <br/> 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/> 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 </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/> 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 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. 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== ==Copy and comparison routines==
@@ -77,15 +84,20 @@ Procedure copy copies the fields of an object onto those of another. It is used
target.copy (source) target.copy (source)
</code> </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> <code>
target := clone (source) target := source.twin
</code> </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 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/> 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 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/> 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>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 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== ==Type information==
@@ -155,6 +167,8 @@ until
index = some_final_index index = some_final_index
loop loop
... ...
x := direct_access.item (index) x := direct_access.item (index)
... ...
direct_access.put (some_value, index) direct_access.put (some_value, index)
@@ -286,10 +300,10 @@ The object attached at run-time to an entity such declared of type [[ref:/librar
As a result, four assignment or assignment-like operations are possible: As a result, four assignment or assignment-like operations are possible:
* '''A1''' <code>s1 := s</code> * '''A1''' <code>s1 := s</code>
* '''A2''' <code>s2.share (s)</code> * '''A2''' <code>s2.share (s)</code>
* '''A3''' <code> s3 := clone (s) </code> * '''A3''' <code>s3 := s.twin</code>
* '''A4''' <code>s4.copy (s)</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]] [[Image:strings]]
fig. 1: Effect of string assignment and copy operations fig. 1: Effect of string assignment and copy operations

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==== ====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==== ====Measurement====
@@ -46,7 +46,7 @@ The origin is 01/01/1600.
====Comparison==== ====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==== ====Measurement====
@@ -59,9 +59,9 @@ Much information may be gotten from functions written in this part. Most of them
====Operations==== ====Operations====
<eiffel>DATE</eiffel> operations looks like <eiffel>TIME</eiffel> 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. * 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) * 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)). * 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. * 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. 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==== ====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==== ====Measurement====

View File

@@ -3,9 +3,9 @@
[[Property:uuid|64672bd0-b696-0c39-1e30-5ac64aae4a99]] [[Property:uuid|64672bd0-b696-0c39-1e30-5ac64aae4a99]]
<eiffel>TIME_DURATION</eiffel>, <eiffel>DATE_DURATION</eiffel>, and <eiffel>DATE_TIME_DURATION</eiffel> <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. 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==== ====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==== ====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==== ====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==== ====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==== ====Operations====
* Adding hours, minutes and seconds with features hour_add, minute_add and second_add. * 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 +, infix and prefix - are available to compose instances of each other. * <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==== ====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: 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, minute and second less than 60. * 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, 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. * 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== ==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. 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 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. 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 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. * 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==== ====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==== ====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==== ====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==== ====Operation====
* Add years, months and days with features year_add, month_add and day_add. * 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 +, infix and prefix - are available to compose instances of each other. * <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==== ====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. * <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.
* 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_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== ==DATE_TIME_DURATION==
@@ -98,29 +100,29 @@ There are, as in <eiffel>DATE_DURATION</eiffel>, definite and non definite durat
====Creation==== ====Creation====
There are still several ways to create an instance: 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 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> (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 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> (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 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==== ====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==== ====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==== ====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==== ====Operation====
* <eiffel>DATE_TIME_DURATION</eiffel> inherits from GROUP_ELEMENT. infix and prefix +, infix and prefix - are available to compose instances to each other. * <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 day_add is present. To add only one element, features from <eiffel>TIME_DURATION</eiffel> or <eiffel>DATE_DURATION</eiffel> have to be used. * 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==== ====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. * <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.
* 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>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

@@ -56,7 +56,7 @@ 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: 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> <code>
modify_button_text: STRING is modify_button_text: STRING
-- `Result' is STRING constant named modify_button_text. -- `Result' is STRING constant named modify_button_text.
once once
Result := "Modify" Result := "Modify"
@@ -68,7 +68,7 @@ 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: 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> <code>
medium_padding: INTEGER is medium_padding: INTEGER
-- `Result' is INTEGER constant named medium_padding. -- `Result' is INTEGER constant named medium_padding.
once once
Result := 8 Result := 8
@@ -78,7 +78,7 @@ A Integer constant represents an Eiffel INTEGER, and may be any valid INTEGER va
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: 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> <code>
pixmap_location: STRING is pixmap_location: STRING
-- `Result' is DIRECTORY constant named pixmap_location. -- `Result' is DIRECTORY constant named pixmap_location.
once once
Result := "C:\pixmaps" Result := "C:\pixmaps"
@@ -90,7 +90,7 @@ 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: 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: * '''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> <code>
main_pixmap: EV_PIXMAP is main_pixmap: EV_PIXMAP
-- `Result' is PIXMAP constant named main_pixmap. -- `Result' is PIXMAP constant named main_pixmap.
local local
a_file_name: FILE_NAME a_file_name: FILE_NAME
@@ -103,7 +103,7 @@ A pixmap constant is a representation of a pixmap image, and two types are avail
* '''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: * '''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> <code>
main_pixmap: EV_PIXMAP is main_pixmap: EV_PIXMAP
-- `Result' is PIXMAP constant named main_pixmap. -- `Result' is PIXMAP constant named main_pixmap.
local local
a_file_name: FILE_NAME a_file_name: FILE_NAME
@@ -121,7 +121,8 @@ Where `pixmap_location' is the name of the Directory constant to which the pixma
==Font constant== ==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: 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 <code>
times_new_roman: EV_FONT
-- `Result' is EV_FONT constant named `times_new_roman'. -- `Result' is EV_FONT constant named `times_new_roman'.
once once
create Result create Result
@@ -135,7 +136,8 @@ A Font constant represents an EV_FONT. For example, in the generated constants f
==Color constant== ==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: 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 <code>
red: EV_COLOR
-- `Result' is EV_COLOR constant named `red'. -- `Result' is EV_COLOR constant named `red'.
once once
Result := create {EV_COLOR}.make_with_8_bit_rgb (255, 0, 0) Result := create {EV_COLOR}.make_with_8_bit_rgb (255, 0, 0)

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: 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: * '''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]] [[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. 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: * '''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]] [[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: 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. ** '''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. ** '''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== ==Main window with externally docked tools==
The following screenshot illustrates the appearance of the main window with all dockable tools external: The following screenshot illustrates the appearance of the main window with all dockable tools external:
[[Image:main-window-with-docked-tools]] [[Image:main-window-with-docked-tools]]

View File

@@ -31,7 +31,7 @@ When an object editor is targeted to an [[EiffelBuild Notation|object]] , you wi
* 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. * 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|EiffelVision 2]] 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. }} {{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,7 +1,7 @@
[[Property:title|Type selector]] [[Property:title|Type selector]]
[[Property:weight|4]] [[Property:weight|4]]
[[Property:uuid|893343c2-417f-90c5-147e-941bc232fe43]] [[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]] [[Image:type-selector]]

View File

@@ -1,7 +1,7 @@
[[Property:title|EiffelVision 2 Samples]] [[Property:title|EiffelVision 2 Samples]]
[[Property:weight|3]] [[Property:weight|3]]
[[Property:uuid|79c05bf8-367e-001d-0c13-f668e34fa5b0]] [[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. * [[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. 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== ==Under the Hood==

View File

@@ -1,23 +1,27 @@
[[Property:title|EiffelVision Introduction]] [[Property:title|EiffelVision Introduction]]
[[Property:weight|0]] [[Property:weight|0]]
[[Property:uuid|f964651a-e36d-4e9e-00ea-37803a26373a]] [[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== ==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== ==Architecture==
EiffelVision relies on a two-tiered architecture illustrated by the following figure. EiffelVision 2 relies on a two-tiered architecture illustrated by the following figure.
[[Image:vision2--figure1]] [[Image:vision2--figure1]]
The two tiers play complementary roles: 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. * 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'''. 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== ==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. 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== ==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. 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> <code>
text: STRING text: STRING
set_text (a_text: STRING) is ...
set_text (a_text: STRING)
...
do
...
end
</code> </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'. 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> <code>
is_sensitive: BOOLEAN is_sensitive: BOOLEAN
enable_sensitive is ...
disable_sensitive is ... enable_sensitive
...
do
...
end
disable_sensitive
...
do
...
end
</code> </code>
==Implementation== ==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:title|Events]]
[[Property:weight|4]] [[Property:weight|4]]
[[Property:uuid|fc32d1b5-72d6-2955-18fd-bce988ed8323]] [[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?== ==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?== ==How do I connect to an event?==
@@ -16,7 +16,7 @@ An example of adding an agent to an action_sequence is as follows.
button.select_actions.extend (agent print ("Button Clicked!%N")) button.select_actions.extend (agent print ("Button Clicked!%N"))
</code> </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. 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:title|Figures]]
[[Property:weight|7]] [[Property:weight|7]]
[[Property:uuid|c12fee6e-5e99-ae59-8ac5-f57abb4c1878]] [[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. * 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. * 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. * 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 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]] . 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=== ===Points===

View File

@@ -1,7 +1,7 @@
[[Property:title|Items]] [[Property:title|Items]]
[[Property:weight|3]] [[Property:weight|3]]
[[Property:uuid|3143511c-28bd-cc5c-c710-700796778982]] [[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?== ==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_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_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_chart|EV_MULTI_COLUMN_LIST]] accepts items of type:
** [[ref:libraries/vision2/reference/ev_multi_column_list_row_chart|EV_MULTI_COLUMN_LIST_ROW]] ** [[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:title|Properties]]
[[Property:weight|5]] [[Property:weight|5]]
[[Property:uuid|0d46c1eb-bce4-2d67-0272-da4aa5950c65]] [[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: EV_WIDGET inherits the following properties:
* [[ref:libraries/vision2/reference/ev_pick_and_dropable_chart|EV_PICK_AND_DROPABLE]] * [[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]] . ** For an overview of the Pick and Drop mechanism, click [[EiffelVision Pick and Drop|here]] .
* [[ref:libraries/vision2/reference/ev_sensitive_chart|EV_SENSITIVE]] * [[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. 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]] * [[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_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. Use <eiffel>set_default_colors</eiffel> to restore the colors to their defaults.
* [[ref:libraries/vision2/reference/ev_help_contextable_chart|EV_HELP_CONTEXTABLE]] * [[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]] * [[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>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>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. Use <eiffel>minimum_width</eiffel> and <eiffel>minimum_height</eiffel> to find its size.
* [[ref:libraries/vision2/reference/ev_containable_chart|EV_CONTAINABLE]] * [[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_deselectable_chart|EV_DESELECTABLE]]
* [[ref:libraries/vision2/reference/ev_drawable_chart|EV_DRAWABLE]] * [[ref:libraries/vision2/reference/ev_drawable_chart|EV_DRAWABLE]]
* [[ref:libraries/vision2/reference/ev_fontable_chart|EV_FONTABLE]] * [[ref:libraries/vision2/reference/ev_fontable_chart|EV_FONTABLE]]

View File

@@ -1,7 +1,7 @@
[[Property:title|Revisions and Bug Fixes]] [[Property:title|Revisions and Bug Fixes]]
[[Property:weight|10]] [[Property:weight|10]]
[[Property:uuid|eb11a237-0c75-0427-452a-303d4f276b97]] [[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== ==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_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_ACTION_SEQUENCE''' - Now event_data is defined with named tuples for easier reading of the action sequence parameters.
* '''EV_APPLICATION_ACTION_SEQUENCES''' * '''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 ** 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 ** 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 * '''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''' * '''EV_APPLICATION'''
** Added action sequences for querying global user events such as pointer clicks and motion ** 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_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 * '''EV_PIXEL_BUFFER''' - New class for loading/querying and setting RGBA values from disk
@@ -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 *** Fixed crash when removing nodes from parent nodes not present in a tree widget
** '''EV_RICH_TEXT''' ** '''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 *** 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 *** 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_PIXMAP''' - Improved pixmap 'stretch' for smaller images
** '''EV_WIDGET''' ** '''EV_WIDGET'''
*** Optimized motion event handling so that current motion events only get requested when the previous one has been processed *** 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''' ** '''EV_DIALOG'''
*** Fixed bug where modal and modeless dialogs were not centered to parent *** Fixed bug where modal and modeless dialogs were not centered to parent
@@ -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'. ** 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'. ** 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_FIGURE''' - `proximity_in_actions' and `proximity_out_actions' are now obsolete.
* '''EV_FONTABLE''' - `set_font' now sets a copy of the font internally. * '''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. * '''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. ** '''EV_BUTTON''' - The result of `text_alignment' after default_create was incorrect.
* '''Gtk''' * '''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