3.5.5 Operations of Discrete Types
Static Semantics
For every discrete 
subtype S, the following attributes are defined: 
S'Pos
S'Pos denotes a function with 
the following specification: 
 
function S'Pos(Arg : S'Base)
  return universal_integer
This function returns the position number 
of the value of Arg, as a value of type universal_integer.
S'Val
S'Val denotes a function with 
the following specification: 
 
function S'Val(Arg : universal_integer)
  return S'Base
This 
function returns a value of the type of S whose position number equals 
the value of 
Arg. 
For 
the evaluation of a call on S'Val, if there is no value in the base range 
of its type with the given position number, Constraint_Error is raised. 
 
  For every static 
discrete subtype S for which there exists at least one value belonging 
to S that satisfies the predicates of S, the following attributes are 
defined:
  S'First_Valid
S'First_Valid denotes the smallest 
value that belongs to S and satisfies the predicates of S. The value 
of this attribute is of the type of S.
 
  S'Last_Valid
S'Last_Valid denotes the largest 
value that belongs to S and satisfies the predicates of S. The value 
of this attribute is of the type of S. 
 
  First_Valid and Last_Valid 
attribute_references 
are always static expressions. Any explicit predicate of S can only have 
been specified by a Static_Predicate aspect.
 
Implementation Advice
For the evaluation of a call on S'Pos for an enumeration 
subtype, if the value of the operand does not correspond to the internal 
code for any enumeration literal of its type (perhaps due to an uninitialized 
variable), then the implementation should raise Program_Error. 
This 
is particularly important for enumeration types with noncontiguous internal 
codes specified by an 
enumeration_representation_clause. 
 
36  Indexing and loop iteration use values 
of discrete types.
37  
The predefined operations 
of a discrete type include the assignment operation, qualification, the 
membership tests, and the relational operators; for a boolean type they 
include the short-circuit control forms and the logical operators; for 
an integer type they include type conversion to and from other numeric 
types, as well as the binary and unary adding operators – and +, 
the multiplying operators, the unary operator 
abs, and the exponentiation 
operator. The assignment operation is described in 
5.2. 
The other predefined operations are described in Clause 
4.
 
38  As for all types, objects of a discrete 
type have Size and Address attributes (see 
13.3).
 
39  For a 
subtype of a discrete type, the result delivered by the attribute Val 
might not belong to the subtype; similarly, the actual parameter of the 
attribute Pos need not belong to the subtype. The following relations 
are satisfied (in the absence of an exception) by these attributes: 
   S'Val(S'Pos(X)) = X
   S'Pos(S'Val(N)) = N
Examples
Examples of attributes 
of discrete subtypes: 
--
  For the types and subtypes declared in subclause 3.5.1 the following hold:  
--  Color'First   = White,   Color'Last   = Black
--  Rainbow'First = Red,     Rainbow'Last = Blue
--  Color'Succ(Blue) = Rainbow'Succ(Blue) = Brown
--  Color'Pos(Blue)  = Rainbow'Pos(Blue)  = 4
--  Color'Val(0)     = Rainbow'Val(0)     = White
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe