1

[{*relational operator*}
{*operator (relational)*}
{*comparison operator:
See relational operator*} {*equality
operator*} {*operator
(equality)*} The *equality operators*
= (equals) and /= (not equals) are predefined for nonlimited types. {*ordering
operator*} {*operator
(ordering)*} The other relational_operators
are the *ordering operators* < (less than), <= (less than
or equal), > (greater than), and >= (greater than or equal). {*=
operator*} {*operator
(=)*} {*equal
operator*} {*operator
(equal)*} {*/=
operator*} {*operator
(/=)*} {*not
equal operator*} {*operator
(not equal)*} {*<
operator*} {*operator
(<)*} {*less
than operator*} {*operator
(less than)*} {*<=
operator*} {*operator
(<=)*} {*less
than or equal operator*} {*operator
(less than or equal)*} {*>
operator*} {*operator
(>)*} {*greater
than operator*} {*operator
(greater than)*} {*>=
operator*} {*operator
(>=)*} {*greater
than or equal operator*} {*operator
(greater than or equal)*} {*discrete
array type*} 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.

1.a

2

{*membership test*}
{*in (membership test)*}
{*not in (membership
test)*} 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.]

3/2

{*AI95-00251-01*}
{*expected type (membership test simple_expression)*
[partial]} {*tested
type (of a membership test)*} 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 is convertible
(see 4.6) to covers
or is covered by the tested type; if untagged, the expected type
for the simple_expression is the tested type.

3.a/2

3.b/2

{*AI95-00251-01*}
The significance of “is convertible to covers
or is covered by” is that we allow the simple_expression
to be of any class-wide type that could be converted
to covers the tested type, not just
the one rooted at the tested type. This includes
any class-wide type that covers the tested type, along with class-wide
interfaces in some cases.

4

For a membership test, if the simple_expression
is of a tagged class-wide type, then the tested type shall be (visibly)
tagged.

4.a

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

7.1/2

{*AI95-00230-01*}
The following additional equality operators for
the *universal_access* type are declared in package Standard for
use with anonymous access types:

7.2/2

8

The ordering operators
are predefined for every specific scalar type *T*, and for every
discrete array type *T*, with the following specifications:

9

9.1/2

{*AI95-00230-01*}
{*AI95-00420-01*}
At least one of the operands of an equality operator
for *universal_access* shall be of a specific anonymous access type.
Unless the predefined equality operator is identified using an expanded
name with prefix denoting the package Standard,
neither operand shall be of an access-to-object type whose designated
type is *D* or *D*'Class, where *D* has a user-defined
primitive equality operator such that:

9.2/2

- its result type is Boolean;

9.3/2

- it is declared
immediately within the same declaration list as
*D*; and

9.4/2

- at least one
of its operands is an access parameter with designated type
*D*.

9.a/2

9.b/2

The rest of the rule makes
it possible to call (including a dispatching call) user-defined "="
operators for anonymous access-to-object types (they'd be hidden otherwise),
and to write user-defined "=" operations for anonymous access
types (by making it possible to see the universal operator using the
Standard prefix).

9.c/2

9.5/2

{*AI95-00230-01*}
At least one of the operands of the equality operators
for *universal_access* shall be of type *universal_access*,
or both shall be of access-to-object types, or both shall be of access-to-subprogram
types. Further:

9.6/2

- When both are of access-to-object types, the designated types shall be the same or one shall cover the other, and if the designated types are elementary or array types, then the designated subtypes shall statically match;

9.7/2

- When both are of access-to-subprogram types, the designated profiles shall be subtype conformant.

9.d/2

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.

11.a

11.b

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. {*unspecified*
[partial]} [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.]

13.a

14

{*equality operator
(special inheritance rule for tagged types)*} 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.

14.a

14.b/2

{*AI95-00349-01*}
The full type extension's operation is used for
a private extension. This follows as only full types have parent types;
the type specified in a private extension is an ancestor, but not necessarily
the parent type. For instance, in:

14.c/2

14.d/2

the parent type is Pak1.Typ2,
not Pak1.Typ1, and the equality operator of Pak1.Typ2 is used to create
predefined equality for Typ3.

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

{*matching
components*} 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.

20.a

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.a

24.b

24.c

Note that if a composite object has a component
of a floating point type, and the floating point type has both a plus
and minus zero, which are considered equal by the predefined equality,
then a block compare cannot be used for the predefined composite equality.
Of course, with user-defined equals operators for tagged components,
a block compare breaks down anyway, so this is not the only special case
that requires component-by-component comparisons. On a one's complement
machine, a similar situation might occur for integer types, since one's
complement machines typically have both a plus and minus (integer) zero.

24.d/2

24.e/2

For a component with a
tagged type *T*, “the primitive equals operator” is
the one with two parameters of *T* which returns Boolean. We're
not talking about some random other primitive function named "=".

24.1/1

{*8652/0016*}
{*AI95-00123-01*}
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.{*Unspecified*
[partial]}

25

The predefined "/=" operator gives the
complementary result to the predefined "=" operator.

25.a

26

{*lexicographic order*}
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

{*evaluation (membership
test)* [partial]} 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

29.a

29.b

Even though Standard.Float is an unconstrained
subtype, the test “X in Float” will still return False (presuming
the evaluation of X does not raise Constraint_Error) when X is outside
Float'Range.

30/2

- {
*AI95-00231-01*} 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.

30.1/2

- {
*AI95-00231-01*} if the type of the simple_expression is class-wide, the value has a tag that identifies a type covered by the tested type;

30.a

30.2/2

- {
*AI95-00231-01*} if the tested type is an access type and the named subtype excludes null, the value of the simple_expression is not null.

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**.

32.1/1

{*8652/0016*}
{*AI95-00123-01*}
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.

32.a.1/1

NOTES

33/2

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.

35

36

X /= Y

37

"" < "A" **and** "A" < "Aa" --* True*

"Aa" < "B"**and** "A" < "A " --* True*

"Aa" < "B"

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*

My_Car = Your_Car --

My_Car.

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)*

Today

Today

Archive

Tree.

39.a

39.b

Predefined equality for a composite type is
defined in terms of the primitive equals operator for tagged components
or the parent part.

39.c

The term “membership test” refers
to the relation "X in S" rather
to simply the reserved word **in** or **not in**.

39.d

We use the term “equality operator”
to refer to both the = (equals) and /= (not equals) operators. Ada 83
referred to = as *the* equality operator, and /= as the inequality
operator. The new wording is more consistent with the ISO 10646 name
for "=" (equals sign) and provides a category similar to “ordering
operator” to refer to both = and /=.

39.e

We have changed the term “catenate”
to “concatenate”.

39.f/2

{*AI95-00230-01*}
{*AI95-00420-01*}
{*extensions to Ada 95*} The
*universal_access* equality operators are new. They provide equality
operations (most importantly, testing against **null**) for anonymous
access types.

39.g/2

{*8652/0016*}
{*AI95-00123-01*}
**Corrigendum:** Wording was added to clarify
that the order of calls (and whether the calls are made at all) on "="
for components is unspecified. Also clarified that "=" must
compose properly for language-defined types.

39.h/2

{*AI95-00251-01*}
Memberships were adjusted to allow interfaces which
don't cover the tested type, in order to be consistent with type conversions.

Sponsored by **Ada-Europe**