Contents Index Search Previous Next
4.5.2 Relational Operators and Membership Tests
1
The
equality operators = (equals) and /= (not equals) are predefined
for nonlimited types.
The other
relational_operators are the
ordering
operators < (less than), <= (less than or equal), > (greater
than), and >= (greater than or equal).
The
ordering operators are predefined for scalar types, and for
discrete
array types, that is, one-dimensional array types whose components
are of a discrete type.
2
A
membership test, using
in or
not in, determines
whether or not a value belongs to a given subtype or range, or has a
tag that identifies a type that is covered by a given type. Membership
tests are allowed for all types.
Name Resolution Rules
3
The
tested
type of a membership test is the type of the
range
or the type determined by the
subtype_mark.
If the tested type is tagged, then the
simple_expression
shall resolve to be of a type that covers or is covered by the tested
type; if untagged, the expected type for the
simple_expression
is the tested type.
Legality Rules
4
For a membership test, if the simple_expression
is of a tagged class-wide type, then the tested type shall be (visibly)
tagged.
Static Semantics
5
The result type of a membership test is the predefined
type Boolean.
6
The equality operators
are predefined for every specific type T that is not limited,
and not an anonymous access type, with the following specifications:
7
function "=" (Left, Right : T) return Boolean
function "/="(Left, Right : T) return Boolean
8
The ordering operators
are predefined for every specific scalar type T, and for every
discrete array type T, with the following specifications:
9
function "<" (Left, Right : T) return Boolean
function "<="(Left, Right : T) return Boolean
function ">" (Left, Right : T) return Boolean
function ">="(Left, Right : T) return Boolean
Dynamic Semantics
10
For discrete types, the predefined relational
operators are defined in terms of corresponding mathematical operations
on the position numbers of the values of the operands.
11
For real types, the predefined relational operators
are defined in terms of the corresponding mathematical operations on
the values of the operands, subject to the accuracy of the type.
12
Two access-to-object values are equal if they
designate the same object, or if both are equal to the null value of
the access type.
13
Two access-to-subprogram values are equal if
they are the result of the same evaluation of an Access
attribute_reference,
or if both are equal to the null value of the access type. Two access-to-subprogram
values are unequal if they designate different subprograms.
It
is unspecified whether two access values that designate the same subprogram
but are the result of distinct evaluations of Access
attribute_references
are equal or unequal.
14
For a type extension, predefined
equality is defined in terms of the primitive (possibly user-defined)
equals operator of the parent type and of any tagged components of the
extension part, and predefined equality for any other components not
inherited from the parent type.
15
For a private type, if its full type is tagged,
predefined equality is defined in terms of the primitive equals operator
of the full type; if the full type is untagged, predefined equality for
the private type is that of its full type.
16
For
other composite types, the predefined equality operators (and certain
other predefined operations on composite types -- see
4.5.1
and
4.6) are defined in terms of the corresponding
operation on
matching components, defined as follows:
17
- For two composite objects or values
of the same non-array type, matching components are those that correspond
to the same component_declaration
or discriminant_specification;
18
- For two one-dimensional arrays of
the same type, matching components are those (if any) whose index values
match in the following sense: the lower bounds of the index ranges are
defined to match, and the successors of matching indices are defined
to match;
19
- For two multidimensional arrays of
the same type, matching components are those whose index values match
in successive index positions.
20
The analogous definitions apply if the types
of the two objects or values are convertible, rather than being the same.
21
Given the above
definition of matching components, the result of the predefined equals
operator for composite types (other than for those composite types covered
earlier) is defined as follows:
22
- If there are no components, the result
is defined to be True;
23
- If there are unmatched components,
the result is defined to be False;
24
- Otherwise, the result is defined in
terms of the primitive equals operator for any matching tagged components,
and the predefined equals for any matching untagged components.
24.1/1
For any composite type, the order in which
"=" is called for components is unspecified. Furthermore, if
the result can be determined before calling "=" on some components,
it is unspecified whether "=" is called on those components.
25
The predefined "/=" operator gives
the complementary result to the predefined "=" operator.
26
For a discrete array type,
the predefined ordering operators correspond to
lexicographic order
using the predefined order relation of the component type: A null array
is lexicographically less than any array having at least one component.
In the case of nonnull arrays, the left operand is lexicographically
less than the right operand if the first component of the left operand
is less than that of the right; otherwise the left operand is lexicographically
less than the right operand only if their first components are equal
and the tail of the left operand is lexicographically less than that
of the right (the
tail consists of the remaining components beyond
the first and can be null).
27
For the evaluation of a membership
test, the
simple_expression and
the
range (if any) are evaluated
in an arbitrary order.
28
A membership test
using in yields the result True if:
29
- The tested type is scalar, and the
value of the simple_expression belongs
to the given range, or the range
of the named subtype; or
30
- The tested type is not scalar, and
the value of the simple_expression
satisfies any constraints of the named subtype, and, if the type of the
simple_expression is class-wide,
the value has a tag that identifies a type covered by the tested type.
31
Otherwise the test yields the result False.
32
A membership test using not in gives the
complementary result to the corresponding membership test using in.
Implementation Requirements
32.1/1
For all nonlimited types declared in language-defined
packages, the "=" and "/=" operators of the type
shall behave as if they were the predefined equality operators for the
purposes of the equality of composite types and generic formal types.
33
13 No exception is ever
raised by a membership test, by a predefined ordering operator, or by
a predefined equality operator for an elementary type, but an exception
can be raised by the evaluation of the operands. A predefined equality
operator for a composite type can only raise an exception if the type
has a tagged part whose primitive equals operator propagates an exception.
34
14 If a composite type
has components that depend on discriminants, two values of this type
have matching components if and only if their discriminants are equal.
Two nonnull arrays have matching components if and only if the length
of each dimension is the same for both.
Examples
35
Examples of
expressions involving relational operators and membership tests:
36
X /= Y
37
"" < "A" and "A" < "Aa" -- True
"Aa" < "B" and "A" < "A " -- True
38
My_Car = null -- true if My_Car has been set to null (see 3.10.1)
My_Car = Your_Car -- true if we both share the same car
My_Car.all = Your_Car.all -- true if the two cars are identical
39
N not in 1 .. 10 -- range membership test
Today in Mon .. Fri -- range membership test
Today in Weekday -- subtype membership test (see 3.5.1)
Archive in Disk_Unit -- subtype membership test (see 3.8.1)
Tree.all in Addition'Class -- class membership test (see 3.9.1)
Contents Index Search Previous Next Legal