From d79da98c2ba8d96bb26377479eb6fd34b765f76d Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 5 Oct 2024 13:35:16 +0200 Subject: [PATCH 1/9] Editorial change: remove todo item --- .../advanced-ada/parts/data_types/records.rst | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/content/courses/advanced-ada/parts/data_types/records.rst b/content/courses/advanced-ada/parts/data_types/records.rst index 35cc80179..931d91023 100644 --- a/content/courses/advanced-ada/parts/data_types/records.rst +++ b/content/courses/advanced-ada/parts/data_types/records.rst @@ -2108,20 +2108,15 @@ value set for the parent type :ada:`T`. Instead of using :ada:`<>`, we have to repeat the value explicitly. -.. - TO BE DONE: +Discriminant constraints and operations +--------------------------------------- - Discriminant constraints and operations - --------------------------------------- - .. admonition:: In the Ada Reference Manual +.. admonition:: In the Ada Reference Manual - - :arm:`3.7.1 Discriminant Constraints <3-7-1>` + - :arm:`3.7.1 Discriminant Constraints <3-7-1>` - .. todo:: - - Discriminant constraint - - (MOVE: Constrained Attribute) .. From 979074d8d1816970eb4624c51800a69a9acbe200 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 5 Oct 2024 13:37:06 +0200 Subject: [PATCH 2/9] Editorial change: adding anchor --- content/courses/advanced-ada/parts/data_types/records.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/content/courses/advanced-ada/parts/data_types/records.rst b/content/courses/advanced-ada/parts/data_types/records.rst index 931d91023..9ccfb03b7 100644 --- a/content/courses/advanced-ada/parts/data_types/records.rst +++ b/content/courses/advanced-ada/parts/data_types/records.rst @@ -2108,6 +2108,8 @@ value set for the parent type :ada:`T`. Instead of using :ada:`<>`, we have to repeat the value explicitly. +.. _Adv_Ada_Record_Discriminant_Constraints_Operations: + Discriminant constraints and operations --------------------------------------- From 79ad760d8bd89d4f446dffef0312dca1d824bc89 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 5 Oct 2024 13:37:35 +0200 Subject: [PATCH 3/9] Adding small introduction --- content/courses/advanced-ada/parts/data_types/records.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/content/courses/advanced-ada/parts/data_types/records.rst b/content/courses/advanced-ada/parts/data_types/records.rst index 9ccfb03b7..bf4abcd2b 100644 --- a/content/courses/advanced-ada/parts/data_types/records.rst +++ b/content/courses/advanced-ada/parts/data_types/records.rst @@ -2113,6 +2113,9 @@ value set for the parent type :ada:`T`. Discriminant constraints and operations --------------------------------------- +In this section, we discuss some details about discriminant constraints and +operations related to discriminants |mdash| more specifically, the +:ada:`Constrained` attribute. .. admonition:: In the Ada Reference Manual From d69bc011eef124ba296350059d442d6f9b3636a6 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 5 Oct 2024 13:39:44 +0200 Subject: [PATCH 4/9] Editorial change: moving section --- .../advanced-ada/parts/data_types/records.rst | 160 +++++++++++++++++ .../advanced-ada/parts/data_types/types.rst | 163 +----------------- 2 files changed, 161 insertions(+), 162 deletions(-) diff --git a/content/courses/advanced-ada/parts/data_types/records.rst b/content/courses/advanced-ada/parts/data_types/records.rst index bf4abcd2b..e87281e6b 100644 --- a/content/courses/advanced-ada/parts/data_types/records.rst +++ b/content/courses/advanced-ada/parts/data_types/records.rst @@ -2122,6 +2122,166 @@ operations related to discriminants |mdash| more specifically, the - :arm:`3.7.1 Discriminant Constraints <3-7-1>` +Constrained Attribute +~~~~~~~~~~~~~~~~~~~~~ + +We can use the :ada:`Constrained` attribute to verify whether an object of +discriminated type is constrained or not. Let's start our discussion by reusing +the :ada:`Simple_Record` type from previous examples. In this version of the +:ada:`Unconstrained_Types` package, we're adding a :ada:`Reset` procedure for +the discriminated record type: + +.. code:: ada compile_button project=Courses.Advanced_Ada.Data_Types.Types.Definite_Indefinite_Subtypes.Constrained_Attribute + + package Unconstrained_Types is + + type Simple_Record + (Extended : Boolean := False) is + record + V : Integer; + case Extended is + when False => + null; + when True => + V_Float : Float; + end case; + end record; + + procedure Reset (R : in out Simple_Record); + + end Unconstrained_Types; + + with Ada.Text_IO; use Ada.Text_IO; + + package body Unconstrained_Types is + + procedure Reset (R : in out Simple_Record) is + Zero_Not_Extended : constant + Simple_Record := (Extended => False, + V => 0); + + Zero_Extended : constant + Simple_Record := (Extended => True, + V => 0, + V_Float => 0.0); + begin + Put_Line ("---- Reset: R'Constrained => " + & R'Constrained'Image); + + if not R'Constrained then + R := Zero_Extended; + else + if R.Extended then + R := Zero_Extended; + else + R := Zero_Not_Extended; + end if; + end if; + end Reset; + + end Unconstrained_Types; + +As the name indicates, the :ada:`Reset` procedure initializes all record +components with zero. Note that we use the :ada:`Constrained` attribute to +verify whether objects are constrained before assigning to them. For objects +that are not constrained, we can simply assign another object to it |mdash| as +we do with the :ada:`R := Zero_Extended` statement. When an object is +constrained, however, the discriminants must match. If we assign an object to +:ada:`R`, the discriminant of that object must match the discriminant of +:ada:`R`. This is the kind of verification that we do in the :ada:`else` part +of that procedure: we check the state of the :ada:`Extended` discriminant +before assigning an object to the :ada:`R` parameter. + +The :ada:`Using_Constrained_Attribute` procedure below declares two objects of +:ada:`Simple_Record` type: :ada:`R1` and :ada:`R2`. Because the +:ada:`Simple_Record` type has a default value for its discriminant, we can +declare objects of this type without specifying a value for the discriminant. +This is exactly what we do in the declaration of :ada:`R1`. Here, we don't +specify any constraints, so that it takes the default value +(:ada:`Extended => False`). In the declaration of :ada:`R2`, however, we +explicitly set :ada:`Extended` to :ada:`False`: + +.. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Types.Definite_Indefinite_Subtypes.Constrained_Attribute + + with Ada.Text_IO; use Ada.Text_IO; + + with Unconstrained_Types; use Unconstrained_Types; + + procedure Using_Constrained_Attribute is + R1 : Simple_Record; + R2 : Simple_Record (Extended => False); + + procedure Show_Rs is + begin + Put_Line ("R1'Constrained => " + & R1'Constrained'Image); + Put_Line ("R1.Extended => " + & R1.Extended'Image); + Put_Line ("--"); + Put_Line ("R2'Constrained => " + & R2'Constrained'Image); + Put_Line ("R2.Extended => " + & R2.Extended'Image); + Put_Line ("----------------"); + end Show_Rs; + begin + Show_Rs; + + Reset (R1); + Reset (R2); + Put_Line ("----------------"); + + Show_Rs; + end Using_Constrained_Attribute; + +When we run this code, the user messages from :ada:`Show_Rs` indicate to us +that :ada:`R1` is not constrained, while :ada:`R2` is constrained. +Because we declare :ada:`R1` without specifying a value for the :ada:`Extended` +discriminant, :ada:`R1` is not constrained. In the declaration of +:ada:`R2`, on the other hand, the explicit value for the :ada:`Extended` +discriminant makes this object constrained. Note that, for both :ada:`R1` and +:ada:`R2`, the value of :ada:`Extended` is :ada:`False` in the declarations. + +As we were just discussing, the :ada:`Reset` procedure includes checks to avoid +mismatches in discriminants. When we don't have those checks, we might get +exceptions at runtime. We can force this situation by replacing the +implementation of the :ada:`Reset` procedure with the following lines: + +.. code-block:: ada + + -- [...] + begin + Put_Line ("---- Reset: R'Constrained => " + & R'Constrained'Image); + R := Zero_Extended; + end Reset; + +Running the code now generates a runtime exception: + +:: + + raised CONSTRAINT_ERROR : unconstrained_types.adb:12 discriminant check failed + +This exception is raised during the call to :ada:`Reset (R2)`. As see in the +code, :ada:`R2` is constrained. Also, its :ada:`Extended` discriminant is set +to :ada:`False`, which means that it doesn't have the :ada:`V_Float` +component. Therefore, :ada:`R2` is not compatible with the constant +:ada:`Zero_Extended` object, so we cannot assign :ada:`Zero_Extended` to +:ada:`R2`. Also, because :ada:`R2` is constrained, its :ada:`Extended` +discriminant cannot be modified. + +The behavior is different for the call to :ada:`Reset (R1)`, which works fine. +Here, when we pass :ada:`R1` as an argument to the :ada:`Reset` procedure, its +:ada:`Extended` discriminant is :ada:`False` by default. Thus, :ada:`R1` is +also not compatible with the :ada:`Zero_Extended` object. However, because +:ada:`R1` is not constrained, the assignment modifies :ada:`R1` (by changing +the value of the :ada:`Extended` discriminant). Therefore, with the call to +:ada:`Reset`, the :ada:`Extended` discriminant of :ada:`R1` changes from +:ada:`False` to :ada:`True`. + +.. admonition:: In the Ada Reference Manual + + - :arm22:`3.7.2 Operations of Discriminated Types <3-7-2>` .. diff --git a/content/courses/advanced-ada/parts/data_types/types.rst b/content/courses/advanced-ada/parts/data_types/types.rst index fa093074b..9dc9a16fa 100644 --- a/content/courses/advanced-ada/parts/data_types/types.rst +++ b/content/courses/advanced-ada/parts/data_types/types.rst @@ -1194,167 +1194,6 @@ We'll see later how definite and indefinite types apply to - :arm22:`3.3 Objects and Named Numbers <3-3>` -Constrained Attribute -~~~~~~~~~~~~~~~~~~~~~ - -We can use the :ada:`Constrained` attribute to verify whether an object of -discriminated type is constrained or not. Let's start our discussion by reusing -the :ada:`Simple_Record` type from previous examples. In this version of the -:ada:`Unconstrained_Types` package, we're adding a :ada:`Reset` procedure for -the discriminated record type: - -.. code:: ada compile_button project=Courses.Advanced_Ada.Data_Types.Types.Definite_Indefinite_Subtypes.Constrained_Attribute - - package Unconstrained_Types is - - type Simple_Record - (Extended : Boolean := False) is - record - V : Integer; - case Extended is - when False => - null; - when True => - V_Float : Float; - end case; - end record; - - procedure Reset (R : in out Simple_Record); - - end Unconstrained_Types; - - with Ada.Text_IO; use Ada.Text_IO; - - package body Unconstrained_Types is - - procedure Reset (R : in out Simple_Record) is - Zero_Not_Extended : constant - Simple_Record := (Extended => False, - V => 0); - - Zero_Extended : constant - Simple_Record := (Extended => True, - V => 0, - V_Float => 0.0); - begin - Put_Line ("---- Reset: R'Constrained => " - & R'Constrained'Image); - - if not R'Constrained then - R := Zero_Extended; - else - if R.Extended then - R := Zero_Extended; - else - R := Zero_Not_Extended; - end if; - end if; - end Reset; - - end Unconstrained_Types; - -As the name indicates, the :ada:`Reset` procedure initializes all record -components with zero. Note that we use the :ada:`Constrained` attribute to -verify whether objects are constrained before assigning to them. For objects -that are not constrained, we can simply assign another object to it |mdash| as -we do with the :ada:`R := Zero_Extended` statement. When an object is -constrained, however, the discriminants must match. If we assign an object to -:ada:`R`, the discriminant of that object must match the discriminant of -:ada:`R`. This is the kind of verification that we do in the :ada:`else` part -of that procedure: we check the state of the :ada:`Extended` discriminant -before assigning an object to the :ada:`R` parameter. - -The :ada:`Using_Constrained_Attribute` procedure below declares two objects of -:ada:`Simple_Record` type: :ada:`R1` and :ada:`R2`. Because the -:ada:`Simple_Record` type has a default value for its discriminant, we can -declare objects of this type without specifying a value for the discriminant. -This is exactly what we do in the declaration of :ada:`R1`. Here, we don't -specify any constraints, so that it takes the default value -(:ada:`Extended => False`). In the declaration of :ada:`R2`, however, we -explicitly set :ada:`Extended` to :ada:`False`: - -.. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Types.Definite_Indefinite_Subtypes.Constrained_Attribute - - with Ada.Text_IO; use Ada.Text_IO; - - with Unconstrained_Types; use Unconstrained_Types; - - procedure Using_Constrained_Attribute is - R1 : Simple_Record; - R2 : Simple_Record (Extended => False); - - procedure Show_Rs is - begin - Put_Line ("R1'Constrained => " - & R1'Constrained'Image); - Put_Line ("R1.Extended => " - & R1.Extended'Image); - Put_Line ("--"); - Put_Line ("R2'Constrained => " - & R2'Constrained'Image); - Put_Line ("R2.Extended => " - & R2.Extended'Image); - Put_Line ("----------------"); - end Show_Rs; - begin - Show_Rs; - - Reset (R1); - Reset (R2); - Put_Line ("----------------"); - - Show_Rs; - end Using_Constrained_Attribute; - -When we run this code, the user messages from :ada:`Show_Rs` indicate to us -that :ada:`R1` is not constrained, while :ada:`R2` is constrained. -Because we declare :ada:`R1` without specifying a value for the :ada:`Extended` -discriminant, :ada:`R1` is not constrained. In the declaration of -:ada:`R2`, on the other hand, the explicit value for the :ada:`Extended` -discriminant makes this object constrained. Note that, for both :ada:`R1` and -:ada:`R2`, the value of :ada:`Extended` is :ada:`False` in the declarations. - -As we were just discussing, the :ada:`Reset` procedure includes checks to avoid -mismatches in discriminants. When we don't have those checks, we might get -exceptions at runtime. We can force this situation by replacing the -implementation of the :ada:`Reset` procedure with the following lines: - -.. code-block:: ada - - -- [...] - begin - Put_Line ("---- Reset: R'Constrained => " - & R'Constrained'Image); - R := Zero_Extended; - end Reset; - -Running the code now generates a runtime exception: - -:: - - raised CONSTRAINT_ERROR : unconstrained_types.adb:12 discriminant check failed - -This exception is raised during the call to :ada:`Reset (R2)`. As see in the -code, :ada:`R2` is constrained. Also, its :ada:`Extended` discriminant is set -to :ada:`False`, which means that it doesn't have the :ada:`V_Float` -component. Therefore, :ada:`R2` is not compatible with the constant -:ada:`Zero_Extended` object, so we cannot assign :ada:`Zero_Extended` to -:ada:`R2`. Also, because :ada:`R2` is constrained, its :ada:`Extended` -discriminant cannot be modified. - -The behavior is different for the call to :ada:`Reset (R1)`, which works fine. -Here, when we pass :ada:`R1` as an argument to the :ada:`Reset` procedure, its -:ada:`Extended` discriminant is :ada:`False` by default. Thus, :ada:`R1` is -also not compatible with the :ada:`Zero_Extended` object. However, because -:ada:`R1` is not constrained, the assignment modifies :ada:`R1` (by changing -the value of the :ada:`Extended` discriminant). Therefore, with the call to -:ada:`Reset`, the :ada:`Extended` discriminant of :ada:`R1` changes from -:ada:`False` to :ada:`True`. - -.. admonition:: In the Ada Reference Manual - - - :arm22:`3.7.2 Operations of Discriminated Types <3-7-2>` - .. _Adv_Ada_Incomplete_Types: @@ -2489,7 +2328,7 @@ subtype :ada:`S` related to the :ada:`T` type. For example: In this example, we declare the :ada:`Int` type and the :ada:`Sub_Int_1` and :ada:`Sub_Int_2` subtypes: -- the :ada:`Int` type is derived from the :ada:`Integer` type, +- the :ada:`Int` type is derived from the :ada:`Integer` type, - :ada:`Sub_Int_1` is a subtype of the :ada:`Integer` type, and From 9660eb7a0774646ee4d8222f04a6c4fe8bd69856 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 5 Oct 2024 13:40:26 +0200 Subject: [PATCH 5/9] Editorial change: adding anchor --- content/courses/advanced-ada/parts/data_types/records.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/content/courses/advanced-ada/parts/data_types/records.rst b/content/courses/advanced-ada/parts/data_types/records.rst index e87281e6b..b09660c66 100644 --- a/content/courses/advanced-ada/parts/data_types/records.rst +++ b/content/courses/advanced-ada/parts/data_types/records.rst @@ -2122,6 +2122,8 @@ operations related to discriminants |mdash| more specifically, the - :arm:`3.7.1 Discriminant Constraints <3-7-1>` +.. _Adv_Ada_Constrained_Attribute: + Constrained Attribute ~~~~~~~~~~~~~~~~~~~~~ From c1f875423c6576321a7b748f3ad4a6451d0f3feb Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 5 Oct 2024 13:42:12 +0200 Subject: [PATCH 6/9] Editorial change: adapting project name --- content/courses/advanced-ada/parts/data_types/records.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/courses/advanced-ada/parts/data_types/records.rst b/content/courses/advanced-ada/parts/data_types/records.rst index b09660c66..90c19fe8b 100644 --- a/content/courses/advanced-ada/parts/data_types/records.rst +++ b/content/courses/advanced-ada/parts/data_types/records.rst @@ -2133,7 +2133,7 @@ the :ada:`Simple_Record` type from previous examples. In this version of the :ada:`Unconstrained_Types` package, we're adding a :ada:`Reset` procedure for the discriminated record type: -.. code:: ada compile_button project=Courses.Advanced_Ada.Data_Types.Types.Definite_Indefinite_Subtypes.Constrained_Attribute +.. code:: ada compile_button project=Courses.Advanced_Ada.Data_Types.Records.Discriminants_Constraints_Operations.Constrained_Attribute package Unconstrained_Types is @@ -2203,7 +2203,7 @@ specify any constraints, so that it takes the default value (:ada:`Extended => False`). In the declaration of :ada:`R2`, however, we explicitly set :ada:`Extended` to :ada:`False`: -.. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Types.Definite_Indefinite_Subtypes.Constrained_Attribute +.. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Records.Discriminants_Constraints_Operations.Constrained_Attribute with Ada.Text_IO; use Ada.Text_IO; From 2290833ac9091e86f1917ba9ecfcf426b08461e4 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 5 Oct 2024 13:58:42 +0200 Subject: [PATCH 7/9] Adding simple example for Constrained attribute --- .../advanced-ada/parts/data_types/records.rst | 44 +++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/content/courses/advanced-ada/parts/data_types/records.rst b/content/courses/advanced-ada/parts/data_types/records.rst index 90c19fe8b..c4b6f3dae 100644 --- a/content/courses/advanced-ada/parts/data_types/records.rst +++ b/content/courses/advanced-ada/parts/data_types/records.rst @@ -2128,10 +2128,46 @@ Constrained Attribute ~~~~~~~~~~~~~~~~~~~~~ We can use the :ada:`Constrained` attribute to verify whether an object of -discriminated type is constrained or not. Let's start our discussion by reusing -the :ada:`Simple_Record` type from previous examples. In this version of the -:ada:`Unconstrained_Types` package, we're adding a :ada:`Reset` procedure for -the discriminated record type: +discriminated type is constrained or not. Let's look at a simple example: + +.. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Records.Discriminants_Constraints_Operations.Simple_Constrained_Attribute + + package Recs is + + type T (L : Positive := 1) is + null record; + + end Recs; + + with Ada.Text_IO; use Ada.Text_IO; + + with Recs; use Recs; + + procedure Show_Constrained_Attribute is + Constr : T (L => 5); + -- ^^^^^^ constrained. + Unconstr : T; + -- ^ unconstrained; + -- using defaults. + begin + Put_Line ("Constr'Constrained: " + & Constr'Constrained'Image); + Put_Line ("Unconstr'Constrained: " + & Unconstr'Constrained'Image); + end Show_Constrained_Attribute; + +As the :ada:`Constrained` attribute indicates, the :ada:`Constr` object is +constrained (by the :ada:`L => 5` discriminant constraint), while the +:ada:`Unconstr` object is unconstrained. Note that, even though :ada:`Unconstr` +is using the default value for :ada:`L` |mdash| which would correspond to the +discriminant constraint :ada:`L => 1` |mdash| the object itself hasn't been +constraint at its declaration. + +Let's continue our discussion with a more complex example by reusing +the :ada:`Unconstrained_Types` package that we declared in a +:ref:`previous section `. In this +version of the package, we're adding a :ada:`Reset` procedure for the +discriminated record type :ada:`Simple_Record`: .. code:: ada compile_button project=Courses.Advanced_Ada.Data_Types.Records.Discriminants_Constraints_Operations.Constrained_Attribute From 6fa888e93338e85723d01b436ebbe687a7891a70 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 5 Oct 2024 14:02:58 +0200 Subject: [PATCH 8/9] Adding section on discriminant constraints --- .../advanced-ada/parts/data_types/records.rst | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/content/courses/advanced-ada/parts/data_types/records.rst b/content/courses/advanced-ada/parts/data_types/records.rst index c4b6f3dae..79e4b0dd3 100644 --- a/content/courses/advanced-ada/parts/data_types/records.rst +++ b/content/courses/advanced-ada/parts/data_types/records.rst @@ -1071,11 +1071,15 @@ component :ada:`Arr`. Note that the same discriminant part must appear in both :ref:`the partial and the full view ` of type :ada:`T`. +.. _Adv_Ada_Record_Discriminants_Object_Declaration: + Object declaration ~~~~~~~~~~~~~~~~~~ As we've already seen, we declare objects of a type :ada:`T` with a discriminant :ada:`D` by specifying the actual value of discriminant :ada:`D`. +This is called a +:ref:`discriminant constraint `. For example: .. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Records.Discriminants.Objects_Discriminants @@ -2122,6 +2126,94 @@ operations related to discriminants |mdash| more specifically, the - :arm:`3.7.1 Discriminant Constraints <3-7-1>` +.. _Adv_Ada_Record_Discriminant_Constraints: + +Discriminant constraints +~~~~~~~~~~~~~~~~~~~~~~~~ + +As we discussed before, when +:ref:`declaring an object with a discriminant `, +we have to specify the values of the all discriminants |mdash| unless, of +course, those discriminants have a +:ref:`default value `. The values +we specify for the discriminants are called discriminant constraints. + +Let's revisit the code example we've seen earlier on: + +.. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Records.Discriminants_Constraints_Operations.Discriminant_Constraint + + package Recs is + + type T (L : Positive; + M : Positive) is + null record; + + end Recs; + + with Recs; use Recs; + + procedure Show_Object_Declaration is + A : T (L => 5, M => 6); + B : T (7, 8); + C : T (7, M => 8); + begin + null; + end Show_Object_Declaration; + +Here, :ada:`L => 5, M => 6` (for object :ada:`A`) are named constraints, while +:ada:`7, 8` (for object :ada:`B`) are positional constraints. + +It's possible to use both positional and named constraints, as we do for object +:ada:`C`: :ada:`7, M => 8`. In this case, the positional associations must +precede the named associations. + +In the case of named constraints, we can use multiple selector names: + +.. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Records.Discriminants_Constraints_Operations.Discriminant_Constraint + + with Recs; use Recs; + + procedure Show_Object_Declaration is + A : T (L | M => 5); + -- ^^^^^ + -- multiple selector names + begin + null; + end Show_Object_Declaration; + +This is only possible, however, if those named discriminants are all of the +same type. (In this case, :ada:`L` and :ada:`M` are both of :ada:`Positive` +subtype.) + +.. admonition:: In the Ada Reference Manual + + - :arm22:`3.7.1 Discriminant Constraints <3-7-1>` + + +Discriminant constraint in subtypes +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +We can use discriminant constraints in the declaration of subtypes. For +example: + +.. code:: ada run_button project=Courses.Advanced_Ada.Data_Types.Records.Discriminants_Constraints_Operations.Discriminant_Constraint + + with Recs; use Recs; + + procedure Show_Object_Declaration is + subtype T_5_6 is T (L => 5, M => 6); + -- ^^^^^^^^^^^^^^ + -- discriminant constraints for subtype + + A : T_5_6; + begin + null; + end Show_Object_Declaration; + +In this example, we use the named discriminant constraints +:ada:`L => 5, M => 6` in the declaration of the subtype :ada:`T_5_6`. + + .. _Adv_Ada_Constrained_Attribute: Constrained Attribute @@ -2322,6 +2414,7 @@ the value of the :ada:`Extended` discriminant). Therefore, with the call to - :arm22:`3.7.2 Operations of Discriminated Types <3-7-2>` + .. TO BE DONE: From f90f1feb88c3c27069f9656af5b179270e75752d Mon Sep 17 00:00:00 2001 From: gusthoff Date: Fri, 11 Oct 2024 22:30:01 +0200 Subject: [PATCH 9/9] Editorial change: missing word --- content/courses/advanced-ada/parts/data_types/records.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/courses/advanced-ada/parts/data_types/records.rst b/content/courses/advanced-ada/parts/data_types/records.rst index 79e4b0dd3..35a9dae6f 100644 --- a/content/courses/advanced-ada/parts/data_types/records.rst +++ b/content/courses/advanced-ada/parts/data_types/records.rst @@ -2392,7 +2392,7 @@ Running the code now generates a runtime exception: raised CONSTRAINT_ERROR : unconstrained_types.adb:12 discriminant check failed -This exception is raised during the call to :ada:`Reset (R2)`. As see in the +This exception is raised during the call to :ada:`Reset (R2)`. As we see in the code, :ada:`R2` is constrained. Also, its :ada:`Extended` discriminant is set to :ada:`False`, which means that it doesn't have the :ada:`V_Float` component. Therefore, :ada:`R2` is not compatible with the constant