http://www.adaconcept.com/programs/mutatok_hasznalata/mutatok_hasznalata.adb
-- Rotter Gyorgy
-- a bemutatasra kerulo program meglehetosen osszetett, ezert figyelmesen tanulmanyozzuk a forraskodot,
-- es a program kimenetet


with Ada.Text_IO;
with System.Address_Image;
with System.Address_To_Access_Conversions;  -- ilyen is letezik

procedure mutatok_hasznalata is

   -- az egyszerubb hasznalat erdekeben sok esetben hasznalunk mutato tipust olyan esetekben,
   -- amikor a gyujtotipus merete valtozhat (indefinit tipus)

   -- Ada 2005:
   --
   --    null exclusion :
   --       mivel a null -ertek minden mutato tipus tipusertek halmazaban szerepel,
   --       az Ada 2005 elotti szabvanyaiban gyakran kellett olyan elagazasokat irnunk,
   --       amelyek nem engedik a null erteket felvevo mutato tipusu valtozot dereferalni
   --       (azaz nem engedik meg az altaluk mutatott ertekre torteno hivatkozast)
   --       az ilyen jellegu ellenorzesek tobb szempontbol nem kivanatosak
   --       ezert az Ada 2005 -ben bevezettek a kovetkezo format:
   --
   --           type Biztosan_Nem_Null_Mutato_Tipus is not null access integer;
   --
   --       ha egy ilyen tipusu valtozo null erteket venne fel (CONSTRAINT_ERROR) kivetelt kapunk
   --       a not null akar egy formalis parameter listaban, vagy fuggveny visszateresi ertekenel is szerepelhet
   --
   --
   --   nevtelen mutato tipusok :
   --          a : access integer;
   --
   --       vagy akar (lancolt listak keszitesekor)
   --
   --          type Lista_Elem_Tipus is record
   --             Adat      : Integer;
   --             Kovetkezo : access Lista_Elem_Tipus;
   --          end record;
   --



begin
   Ada.Text_IO.Put_Line("Program indul");

   String_Mutatok:
   declare

      Megszoritatlan_String : aliased String       := (1..10 => ' ');                                                                                                    -- "megszoritatlan"
      Megszoritott_String   : aliased String(1..5) := (others => ' ');                                                                                                   -- "megszoritott"

      type Megszoritatlan_Altalanos_String_Mutato_Tipus is access all String;                                                                                            -- altalanos (megszoritatlan) mutato tipus (az all miatt nem csak a dinamikus memoriateruletre mutathat)
      type Megszoritott_Altalanos_String_Mutato_Tipus   is access all String(1..5);                                                                                      -- altalanos (megszoritott) mutato tipus

      Megszoritatlan_String_Mutato : Megszoritatlan_Altalanos_String_Mutato_Tipus := Megszoritatlan_String'Access;                                                       --| nem mutathatnak egymasra
      Megszoritott_String_Mutato   : Megszoritott_Altalanos_String_Mutato_Tipus   := Megszoritott_String'Access;                                                         --|

   begin
      Ada.Text_IO.Put_Line("a Megszoritott_String cime :                   " & System.Address_Image(Megszoritott_String'Address));
      Ada.Text_IO.Put_Line("a Megszoritott_String elso karakterenek cime : " & System.Address_Image(Megszoritott_String(Megszoritott_String'First)'Address));            -- egy T tomb tipusu valtozo eseten T'Address = T(T'First)'Address
   end String_Mutatok;






   Eljaras_Es_Fuggveny_Mutatok:
   declare

      -- "specialis ketvaltozos-egyerteku elemenkenti feldolgozas"
      procedure Stringbe_Masol(Mibe : in out String; Mit : String) is
         c1, c2 : Positive;
      begin
         c1 := Mibe'First;
         c2 := Mit'First;
         while c1 <= Mibe'Last and c2 <= Mit'Last loop
            Mibe(c1) := Mit(c2);

            c1 := Positive'Succ(c1);
            c2 := Positive'Succ(c2);
         end loop;
      end Stringbe_Masol;



      S1 : String       := "12345"; -- ('1', '2', '3', '4', '5');                                                                                                        --| mindket irasmod helyes
      S2 : String(3..5) := "345";   -- ('3', '4', '5');                                                                                                                  --|


      type Eljaras_Mutato_Tipus is access procedure(A : in out String; B : String);                                                                                      -- fuggveny mutato tipust hasonloan keszithetunk

      Masolas : Eljaras_Mutato_Tipus := Stringbe_Masol'Access;

   begin
      Masolas(A => S1, B => S2);                                                                                                                                         -- figyeljuk meg az argumentumok neveit

      Ada.Text_IO.Put_Line("S1 erteke a masolas utan : " & S1);

      declare

         -- Vegyuk eszre, hogy a Modositva_Kiir eljaras deklaraciojanal/definiciojanal meg nem letezik az Megszoritatlan_Altalanos_String_Mutato_Tipus.

         procedure Modositva_Kiir(Mit : access String) is                                                                                                                -- nevtelen formalis mutatotipusu parameter nem lehet in modu sem :)                                                                                                              -- nevtelen string mutato tipus mint formalis parameter, nagyon fontos lesz a kesobbiekben!!!
         begin
            Masolas(Mit.all, " :)");                                                                                                                                     -- figyeljuk meg, hogy megvaltozik a mutatott ertek
            Ada.Text_IO.Put_Line(Mit.all);
         end Modositva_Kiir;

         -- innentol mar letezik az Megszoritatlan_Altalanos_String_Mutato_Tipus...
         type Megszoritatlan_Altalanos_String_Mutato_Tipus is access all String;

         S : aliased String := S2;
         S_Mutato : Megszoritatlan_Altalanos_String_Mutato_Tipus := S'Access;


      begin
         Ada.Text_IO.Put_Line("A kiirasok : ");
         Modositva_Kiir(S'Access);                                                                                                                                       --| figyeljuk meg, hogy mindket hivas helyes
         Modositva_Kiir(S_Mutato);                                                                                                                                       --|
         Ada.Text_IO.Put_Line(S);
      end;


   end Eljaras_Es_Fuggveny_Mutatok;


   Ada.Text_IO.Put_Line(String'(1..10 => '-'));                                                                                                                          -- ilyet is lehet


   Konstans_Es_Megszoritott_Mutatok:
   declare

      type Konstans_Integer_Mutato is access constant Integer;                                                                                                           -- az ilyen tipusunak deklaralt valtozon keresztul nem valtoztathatjuk meg a mutatott erteket (hasznos pl. eljarasok es fuggvenyek formalis parameterenek tipusakent is)

      I : aliased Integer := 3;

      K : constant Konstans_Integer_Mutato := I'Access;                                                                                                                  -- K nem kaphat mas erteket (konstans)

      -- ----------

      type Megszoritott_Altalanos_Integer_Mutato is access all Integer range 1..5;

      -- M : Megszoritott_Altalanos_Integer_Mutato := new Integer'(7);  -- CONSTRAINT_ERROR!

   begin

      Ada.Text_IO.Put_Line(Integer'Image(K.all));

   end Konstans_Es_Megszoritott_Mutatok;


   Ada.Text_IO.Put_Line(String'(1..10 => '-'));


   Elettartam_Es_Lathatosag:
   declare

       -- amikor nem teljesul, hogy a mutatott típus/valtozo elettartama legalabb olyan hosszu mint a mutato tipus elettartama

       type Altalanos_Integer_Mutato is access all Integer;


       procedure Kiir(Mit : Altalanos_Integer_Mutato) is
       begin
          Ada.Text_IO.Put_Line(Integer'Image(Mit.all));
       end Kiir;


   begin
      declare

         I : aliased Integer := 5;

      begin

         Kiir(I'Unchecked_Access);                                                                                                                                       -- 'Unrestricted_Access eljaras vagy fuggveny mutato eseten

      end;
   end Elettartam_Es_Lathatosag;


   Ada.Text_IO.Put_Line("Program vege");
end mutatok_hasznalata;