File : a-cgcaso.adb


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                         GNAT LIBRARY COMPONENTS                          --
   4 --                                                                          --
   5 --              ADA.CONTAINERS.GENERIC_CONSTRAINED_ARRAY_SORT               --
   6 --                                                                          --
   7 --                                 B o d y                                  --
   8 --                                                                          --
   9 --          Copyright (C) 2004-2009, Free Software Foundation, Inc.         --
  10 --                                                                          --
  11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  12 -- terms of the  GNU General Public License as published  by the Free Soft- --
  13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
  14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  16 -- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
  17 --                                                                          --
  18 --                                                                          --
  19 --                                                                          --
  20 --                                                                          --
  21 --                                                                          --
  22 -- You should have received a copy of the GNU General Public License and    --
  23 -- a copy of the GCC Runtime Library Exception along with this program;     --
  24 -- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
  25 -- <http://www.gnu.org/licenses/>.                                          --
  26 --                                                                          --
  27 -- This unit was originally developed by Matthew J Heaney.                  --
  28 ------------------------------------------------------------------------------
  29 
  30 --  This algorithm was adapted from GNAT.Heap_Sort_G (see g-hesorg.ad[sb])
  31 
  32 with System;
  33 
  34 procedure Ada.Containers.Generic_Constrained_Array_Sort
  35   (Container : in out Array_Type)
  36 is
  37    type T is range System.Min_Int .. System.Max_Int;
  38 
  39    function To_Index (J : T) return Index_Type;
  40    pragma Inline (To_Index);
  41 
  42    procedure Sift (S : T);
  43 
  44    A : Array_Type renames Container;
  45 
  46    --------------
  47    -- To_Index --
  48    --------------
  49 
  50    function To_Index (J : T) return Index_Type is
  51       K : constant T'Base := Index_Type'Pos (A'First) + J - T'(1);
  52    begin
  53       return Index_Type'Val (K);
  54    end To_Index;
  55 
  56    Max  : T := A'Length;
  57    Temp : Element_Type;
  58 
  59    ----------
  60    -- Sift --
  61    ----------
  62 
  63    procedure Sift (S : T) is
  64       C   : T := S;
  65       Son : T;
  66 
  67    begin
  68       loop
  69          Son := 2 * C;
  70 
  71          exit when Son > Max;
  72 
  73          declare
  74             Son_Index : Index_Type := To_Index (Son);
  75 
  76          begin
  77             if Son < Max then
  78                if A (Son_Index) < A (Index_Type'Succ (Son_Index)) then
  79                   Son := Son + 1;
  80                   Son_Index := Index_Type'Succ (Son_Index);
  81                end if;
  82             end if;
  83 
  84             A (To_Index (C)) := A (Son_Index);  -- Move (Son, C);
  85          end;
  86 
  87          C := Son;
  88       end loop;
  89 
  90       while C /= S loop
  91          declare
  92             Father : constant T := C / 2;
  93          begin
  94             if A (To_Index (Father)) < Temp then           -- Lt (Father, 0)
  95                A (To_Index (C)) := A (To_Index (Father));  -- Move (Father, C)
  96                C := Father;
  97             else
  98                exit;
  99             end if;
 100          end;
 101       end loop;
 102 
 103       A (To_Index (C)) := Temp; -- Move (0, C);
 104    end Sift;
 105 
 106 --  Start of processing for Generic_Constrained_Array_Sort
 107 
 108 begin
 109    for J in reverse 1 .. Max / 2 loop
 110       Temp := Container (To_Index (J)); --  Move (J, 0);
 111       Sift (J);
 112    end loop;
 113 
 114    while Max > 1 loop
 115       Temp := A (To_Index (Max));         --  Move (Max, 0);
 116       A (To_Index (Max)) := A (A'First);  --  Move (1, Max);
 117 
 118       Max := Max - 1;
 119       Sift (1);
 120    end loop;
 121 end Ada.Containers.Generic_Constrained_Array_Sort;