1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<TITLE>AARM95 - Relational Operators and Membership Tests</TITLE>
<META NAME="Author" CONTENT="JTC1/SC22/WG9/ARG, by Randall Brukardt, ARG Editor">
<META NAME="GENERATOR" CONTENT="Arm_Form.Exe, Ada Reference Manual generator">
<STYLE type="text/css">
DIV.paranum {position: absolute; font-family: Arial, Helvetica, sans-serif; left: 0.5 em; top: auto}
TT {font-family: "Courier New", monospace}
DT {display: compact}
DIV.Normal {font-family: "Times New Roman", Times, serif; margin-bottom: 0.6em}
DIV.Wide {font-family: "Times New Roman", Times, serif; margin-top: 0.6em; margin-bottom: 0.6em}
DIV.Annotations {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-bottom: 0.6em}
DIV.WideAnnotations {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-top: 0.6em; margin-bottom: 0.6em}
DIV.Index {font-family: "Times New Roman", Times, serif}
DIV.SyntaxSummary {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-bottom: 0.4em}
DIV.Notes {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-bottom: 0.6em}
DIV.NotesHeader {font-family: "Times New Roman", Times, serif; margin-left: 2.0em}
DIV.SyntaxIndented {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-bottom: 0.4em}
DIV.Indented {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-bottom: 0.6em}
DIV.CodeIndented {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-bottom: 0.6em}
DIV.SmallIndented {font-family: "Times New Roman", Times, serif; margin-left: 10.0em; margin-bottom: 0.6em}
DIV.SmallCodeIndented {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-bottom: 0.6em}
DIV.Examples {font-family: "Courier New", monospace; margin-left: 2.0em; margin-bottom: 0.6em}
DIV.SmallExamples {font-family: "Courier New", monospace; font-size: 80%; margin-left: 7.5em; margin-bottom: 0.6em}
DIV.IndentedExamples {font-family: "Courier New", monospace; margin-left: 8.0em; margin-bottom: 0.6em}
DIV.SmallIndentedExamples {font-family: "Courier New", monospace; font-size: 80%; margin-left: 15.0em; margin-bottom: 0.6em}
UL.Bulleted {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-right: 2.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.SmallBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.NestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.SmallNestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-right: 8.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.IndentedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-right: 8.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.CodeIndentedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.CodeIndentedNestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-right: 8.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.SyntaxIndentedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.NotesBulleted {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.NotesNestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
DL.Hanging {font-family: "Times New Roman", Times, serif; margin-top: 0em; margin-bottom: 0.6em}
DD.Hanging {margin-left: 6.0em}
DL.IndentedHanging {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-top: 0em; margin-bottom: 0.6em}
DD.IndentedHanging {margin-left: 2.0em}
DL.HangingInBulleted {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-right: 2.0em; margin-top: 0em; margin-bottom: 0.5em}
DD.HangingInBulleted {margin-left: 4.0em}
DL.SmallHanging {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-top: 0em; margin-bottom: 0.6em}
DD.SmallHanging {margin-left: 7.5em}
DL.SmallIndentedHanging {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-top: 0em; margin-bottom: 0.6em}
DD.SmallIndentedHanging {margin-left: 2.0em}
DL.SmallHangingInBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
DD.SmallHangingInBulleted {margin-left: 5.0em}
DL.Enumerated {font-family: "Times New Roman", Times, serif; margin-right: 0.0em; margin-top: 0em; margin-bottom: 0.5em}
DD.Enumerated {margin-left: 2.0em}
DL.SmallEnumerated {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
DD.SmallEnumerated {margin-left: 2.5em}
DL.NestedEnumerated {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-right: 2.0em; margin-top: 0em; margin-bottom: 0.5em}
DL.SmallNestedEnumerated {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
</STYLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFF0" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
<P><A HREF="AA-TOC.html">Contents</A> <A HREF="AA-0-29.html">Index</A> <A HREF="AA-4-5-1.html">Previous</A> <A HREF="AA-4-5-3.html">Next</A></P>
<HR>
<H1> 4.5.2 Relational Operators and Membership Tests</H1>
<DIV Class="Paranum"><FONT SIZE=-2>1</FONT></DIV>
<DIV Class="Normal"> [<A NAME="I2595"></A><A NAME="I2596"></A> <A NAME="I2597"></A><A NAME="I2598"></A><A NAME="I2599"></A>The
<I>equality operators</I> = (equals) and /= (not equals) are predefined
for nonlimited types. <A NAME="I2600"></A><A NAME="I2601"></A>The other
<FONT FACE="Arial, Helvetica">relational_operator</FONT>s are the <I>ordering
operators</I> < (less than), <= (less than or equal), > (greater
than), and >= (greater than or equal). <A NAME="I2602"></A><A NAME="I2603"></A><A NAME="I2604"></A><A NAME="I2605"></A><A NAME="I2606"></A><A NAME="I2607"></A><A NAME="I2608"></A><A NAME="I2609"></A><A NAME="I2610"></A><A NAME="I2611"></A><A NAME="I2612"></A><A NAME="I2613"></A><A NAME="I2614"></A><A NAME="I2615"></A><A NAME="I2616"></A><A NAME="I2617"></A><A NAME="I2618"></A><A NAME="I2619"></A><A NAME="I2620"></A><A NAME="I2621"></A><A NAME="I2622"></A><A NAME="I2623"></A><A NAME="I2624"></A><A NAME="I2625"></A><A NAME="I2626"></A>The
ordering operators are predefined for scalar types, and for <I>discrete
array types</I>, that is, one-dimensional array types whose components
are of a discrete type. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>1.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>The equality
operators are not defined for <I>every</I> nonlimited type -- see below
for the exact rule. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>2</FONT></DIV>
<DIV Class="Normal"> <A NAME="I2627"></A><A NAME="I2628"></A><A NAME="I2629"></A>A
<I>membership test</I>, using <B>in</B> or <B>not in</B>, 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.]</DIV>
<H4 ALIGN=CENTER>Name Resolution Rules</H4>
<DIV Class="Paranum"><FONT SIZE=-2>3</FONT></DIV>
<DIV Class="Normal"> <A NAME="I2630"></A><A NAME="I2631"></A>The <I>tested
type</I> of a membership test is the type of the <FONT FACE="Arial, Helvetica">range</FONT>
or the type determined by the <FONT FACE="Arial, Helvetica">subtype_mark</FONT>.
If the tested type is tagged, then the <FONT FACE="Arial, Helvetica">simple_expression</FONT>
shall resolve to be of a type that covers or is covered by the tested
type; if untagged, the expected type for the <FONT FACE="Arial, Helvetica">simple_expression</FONT>
is the tested type. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>3.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Reason: </B>The part of the
rule for untagged types is stated in a way that ensures that operands
like <B>null</B> are still legal as operands of a membership test.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>3.b</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>The significance of ``covers or
is covered by'' is that we allow the <FONT FACE="Arial, Helvetica">simple_expression</FONT>
to be of any class-wide type that covers the tested type, not just the
one rooted at the tested type. </FONT></DIV>
<H4 ALIGN=CENTER>Legality Rules</H4>
<DIV Class="Paranum"><FONT SIZE=-2>4</FONT></DIV>
<DIV Class="Normal"> For a membership test, if the <FONT FACE="Arial, Helvetica">simple_expression</FONT>
is of a tagged class-wide type, then the tested type shall be (visibly)
tagged. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>4.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>Untagged
types covered by the tagged class-wide type are not permitted. Such types
can exist if they are descendants of a private type whose full type is
tagged. This rule is intended to avoid confusion since such derivatives
don't have their ``own'' tag, and hence are indistinguishable from one
another at run time once converted to a covering class-wide type. </FONT></DIV>
<H4 ALIGN=CENTER>Static Semantics</H4>
<DIV Class="Paranum"><FONT SIZE=-2>5</FONT></DIV>
<DIV Class="Normal"> The result type of a membership test is the predefined
type Boolean.</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>6</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em"> The equality operators
are predefined for every specific type <I>T</I> that is not limited,
and not an anonymous access type, with the following specifications:
</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>7</FONT></DIV>
<DIV Class="Examples"><TT><B>function</B> "=" (Left, Right : <I>T</I>) <B>return</B> Boolean<BR>
<B>function</B> "/="(Left, Right : <I>T</I>) <B>return</B> Boolean</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>8</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em"> The ordering operators
are predefined for every specific scalar type <I>T</I>, and for every
discrete array type <I>T</I>, with the following specifications: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>9</FONT></DIV>
<DIV Class="Examples"><TT><B>function</B> "<" (Left, Right : <I>T</I>) <B>return</B> Boolean<BR>
<B>function</B> "<="(Left, Right : <I>T</I>) <B>return</B> Boolean<BR>
<B>function</B> ">" (Left, Right : <I>T</I>) <B>return</B> Boolean<BR>
<B>function</B> ">="(Left, Right : <I>T</I>) <B>return</B> Boolean</TT></DIV>
<H4 ALIGN=CENTER>Dynamic Semantics</H4>
<DIV Class="Paranum"><FONT SIZE=-2>10</FONT></DIV>
<DIV Class="Normal"> 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.</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>11</FONT></DIV>
<DIV Class="Normal"> 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. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>11.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>For floating
point types, the results of comparing <I>nearly</I> equal values depends
on the accuracy of the implementation (see <A HREF="AA-G-2-1.html">G.2.1</A>,
``<A HREF="AA-G-2-1.html">Model of Floating Point Arithmetic</A>'' for
implementations that support the Numerics Annex). </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>11.b</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Implementation Note: </B>On
a machine with signed zeros, if the generated code generates both plus
zero and minus zero, plus and minus zero must be equal by the predefined
equality operators. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>12</FONT></DIV>
<DIV Class="Normal"> 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.</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>13</FONT></DIV>
<DIV Class="Normal"> Two access-to-subprogram values are equal if
they are the result of the same evaluation of an Access <FONT FACE="Arial, Helvetica">attribute_reference</FONT>,
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. <A NAME="I2632"></A>[It
is unspecified whether two access values that designate the same subprogram
but are the result of distinct evaluations of Access <FONT FACE="Arial, Helvetica">attribute_reference</FONT>s
are equal or unequal.] </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>13.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Reason: </B>This allows each
Access <FONT FACE="Arial, Helvetica">attribute_reference</FONT> for a
subprogram to designate a distinct ``wrapper'' subprogram if necessary
to support an indirect call. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>14</FONT></DIV>
<DIV Class="Normal"> <A NAME="I2633"></A>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. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>14.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>Two values
of a type extension are not equal if there is a <FONT FACE="Arial, Helvetica">variant_part</FONT>
in the extension part and the two values have different <FONT FACE="Arial, Helvetica">variant</FONT>s
present. This is a ramification of the requirement that a discriminant
governing such a <FONT FACE="Arial, Helvetica">variant_part</FONT> has
to be a ``new'' discriminant, and so has to be equal in the two values
for the values to be equal. Note that <FONT FACE="Arial, Helvetica">variant_part</FONT>s
in the parent part need not match if the primitive equals operator for
the parent type considers them equal. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>15</FONT></DIV>
<DIV Class="Normal"> 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.</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>16</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em"> <A NAME="I2634"></A>For
other composite types, the predefined equality operators [(and certain
other predefined operations on composite types -- see <A HREF="AA-4-5-1.html">4.5.1</A>
and <A HREF="AA-4-6.html">4.6</A>)] are defined in terms of the corresponding
operation on <I>matching components</I>, defined as follows: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>17</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>For two composite objects or values of the same non-array
type, matching components are those that correspond to the same <FONT FACE="Arial, Helvetica">component_declaration</FONT>
or <FONT FACE="Arial, Helvetica">discriminant_specification</FONT>;</LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>18</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>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;</LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>19</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>For two multidimensional arrays of the same type, matching
components are those whose index values match in successive index positions.
</LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>20</FONT></DIV>
<DIV Class="Normal"> The analogous definitions apply if the types
of the two objects or values are convertible, rather than being the same.
</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>20.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Discussion: </B>Ada 83 seems
to omit this part of the definition, though it is used in array type
conversions. See <A HREF="AA-4-6.html">4.6</A>. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>21</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em"> 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: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>22</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>If there are no components, the result is defined to be
True;</LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>23</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>If there are unmatched components, the result is defined
to be False;</LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>24</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>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. </LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>24.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Reason: </B>This asymmetry
between tagged and untagged components is necessary to preserve upward
compatibility and corresponds with the corresponding situation with generics,
where the predefined operations ``reemerge'' in a generic for untagged
types, but do not for tagged types. Also, only tagged types support user-defined
assignment (see <A HREF="AA-7-6.html">7.6</A>), so only tagged types
can fully handle levels of indirection in the implementation of the type.
For untagged types, one reason for a user-defined equals operator might
be to allow values with different bounds or discriminants to compare
equal in certain cases. When such values are matching components, the
bounds or discriminants will necessarily match anyway if the discriminants
of the enclosing values match. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>24.b</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>Two null
arrays of the same type are always equal; two null records of the same
type are always equal.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>24.c</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>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.
</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>24.1/1</FONT></DIV>
<DIV Class="Normal"> {<I><A HREF="defect1.html#8652/0016">8652/0016</A></I>}
<U>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.<A NAME="I2635"></A></U></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>25</FONT></DIV>
<DIV Class="Normal"> The predefined "/=" operator gives
the complementary result to the predefined "=" operator. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>25.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>Furthermore,
if the user defines an "=" operator that returns Boolean, then
a "/=" operator is implicitly declared in terms of the user-defined
"=" operator so as to give the complementary result. See <A HREF="AA-6-6.html">6.6</A>.
</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>26</FONT></DIV>
<DIV Class="Normal"> <A NAME="I2636"></A>For a discrete array type,
the predefined ordering operators correspond to <I>lexicographic order</I>
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 <I>tail</I> consists of the remaining components beyond
the first and can be null).</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>27</FONT></DIV>
<DIV Class="Normal"> <A NAME="I2637"></A>For the evaluation of a membership
test, the <FONT FACE="Arial, Helvetica">simple_expression</FONT> and
the <FONT FACE="Arial, Helvetica">range</FONT> (if any) are evaluated
in an arbitrary order.</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>28</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em"> A membership test
using <B>in</B> yields the result True if: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>29</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>The tested type is scalar, and the value of the <FONT FACE="Arial, Helvetica">simple_expression</FONT>
belongs to the given <FONT FACE="Arial, Helvetica">range</FONT>, or the
range of the named subtype; or </LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>29.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>The scalar
membership test only does a range check. It does not perform any other
check, such as whether a value falls in a ``hole'' of a ``holey'' enumeration
type. The Pos attribute function can be used for that purpose.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>29.b</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>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. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>30</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>The tested type is not scalar, and the value of the <FONT FACE="Arial, Helvetica">simple_expression</FONT>
satisfies any constraints of the named subtype, and, if the type of the
<FONT FACE="Arial, Helvetica">simple_expression</FONT> is class-wide,
the value has a tag that identifies a type covered by the tested type.
</LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>30.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>Note that
the tag is not checked if the <FONT FACE="Arial, Helvetica">simple_expression</FONT>
is of a specific type. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>31</FONT></DIV>
<DIV Class="Normal"> Otherwise the test yields the result False.</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>32</FONT></DIV>
<DIV Class="Normal"> A membership test using <B>not in</B> gives the
complementary result to the corresponding membership test using <B>in</B>.
</DIV>
<H4 ALIGN=CENTER>Implementation Requirements</H4>
<DIV Class="Paranum"><FONT SIZE=-2>32.1/1</FONT></DIV>
<DIV Class="Normal"> {<I><A HREF="defect1.html#8652/0016">8652/0016</A></I>}
<U>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.</U> </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>32.a.1/1</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B><U>If any
language-defined types are implemented with a user-defined "="
operator, then either the full type must be tagged, or the compiler must
use ``magic'' to implement equality for this type. A normal user-defined
"=" operator for an untagged type does <I>not</I> meet this
requirement.</U> </FONT></DIV>
<DIV Class="NotesHeader"><FONT SIZE=-1>NOTES</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>33</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>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.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>34</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>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. </FONT></DIV>
<H4 ALIGN=CENTER>Examples</H4>
<DIV Class="Paranum"><FONT SIZE=-2>35</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em"> <I>Examples of
expressions involving relational operators and membership tests:</I>
</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>36</FONT></DIV>
<DIV Class="Examples"><TT>X /= Y</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>37</FONT></DIV>
<DIV Class="Examples"><TT>"" < "A" <B>and</B> "A" < "Aa" <I>-- True</I><BR>
"Aa" < "B" <B>and</B> "A" < "A " <I>-- True</I></TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>38</FONT></DIV>
<DIV Class="Examples"><TT>My_Car = <B>null</B> <I>-- true if My_Car has been set to null (see <A HREF="AA-3-10-1.html">3.10.1</A>)</I><BR>
My_Car = Your_Car <I>-- true if we both share the same car</I><BR>
My_Car.<B>all</B> = Your_Car.<B>all</B> <I>-- true if the two cars are identical</I></TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>39</FONT></DIV>
<DIV Class="Examples"><TT>N <B>not</B> <B>in</B> 1 .. 10 <I>-- range membership test</I><BR>
Today <B>in</B> Mon .. Fri <I>-- range membership test</I><BR>
Today <B>in</B> Weekday <I>-- subtype membership test (see <A HREF="AA-3-5-1.html">3.5.1</A>)</I><BR>
Archive <B>in</B> Disk_Unit <I>-- subtype membership test (see <A HREF="AA-3-8-1.html">3.8.1</A>)</I><BR>
Tree.<B>all</B> <B>in</B> Addition'Class <I>-- class membership test (see <A HREF="AA-3-9-1.html">3.9.1</A>)</I></TT></DIV>
<H4 ALIGN=CENTER>Extensions to Ada 83</H4>
<DIV Class="Paranum"><FONT SIZE=-2>39.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><A NAME="I2638"></A>Membership
tests can be used to test the tag of a class-wide value.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>39.b</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>Predefined equality for a composite
type is defined in terms of the primitive equals operator for tagged
components or the parent part. </FONT></DIV>
<H4 ALIGN=CENTER>Wording Changes from Ada 83</H4>
<DIV Class="Paranum"><FONT SIZE=-2>39.c</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>The term ``membership test'' refers
to the <FONT FACE="Arial, Helvetica">relation</FONT> "X in S"
rather to simply the reserved word <B>in</B> or <B>not in</B>.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>39.d</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>We use the term ``equality operator''
to refer to both the = (equals) and /= (not equals) operators. Ada 83
referred to = as <I>the</I> 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 /=.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>39.e</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>We have changed the term ``catenate''
to ``concatenate''. </FONT></DIV>
<HR>
<P><A HREF="AA-TOC.html">Contents</A> <A HREF="AA-0-29.html">Index</A> <A HREF="AA-4-5-1.html">Previous</A> <A HREF="AA-4-5-3.html">Next</A> <A HREF="AA-TTL.html">Legal</A></P>
</BODY>
</HTML>
|