OSDN Git Service

2006-06-07 Paolo Bonzini <bonzini@gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / ada / a-cgcaso.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT LIBRARY COMPONENTS                          --
4 --                                                                          --
5 --                      A D A . C O N T A I N E R S .                       --
6 --       G E N E R I C _ C O N S T R A I N E D _ A R R A Y _ S O R T        --
7 --                                                                          --
8 --                                 B o d y                                  --
9 --                                                                          --
10 --          Copyright (C) 2004-2006, Free Software Foundation, Inc.         --
11 --                                                                          --
12 -- This specification is derived from the Ada Reference Manual for use with --
13 -- GNAT. The copyright notice above, and the license provisions that follow --
14 -- apply solely to the  contents of the part following the private keyword. --
15 --                                                                          --
16 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
17 -- terms of the  GNU General Public License as published  by the Free Soft- --
18 -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
19 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
20 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
21 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
22 -- for  more details.  You should have  received  a copy of the GNU General --
23 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
24 -- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
25 -- Boston, MA 02110-1301, USA.                                              --
26 --                                                                          --
27 -- As a special exception,  if other files  instantiate  generics from this --
28 -- unit, or you link  this unit with other files  to produce an executable, --
29 -- this  unit  does not  by itself cause  the resulting  executable  to  be --
30 -- covered  by the  GNU  General  Public  License.  This exception does not --
31 -- however invalidate  any other reasons why  the executable file  might be --
32 -- covered by the  GNU Public License.                                      --
33 --                                                                          --
34 -- This unit has originally being developed by Matthew J Heaney.            --
35 ------------------------------------------------------------------------------
36
37 --  This algorithm was adapted from GNAT.Heap_Sort_G (see g-hesorg.ad[sb]).
38
39 with System;
40
41 procedure Ada.Containers.Generic_Constrained_Array_Sort
42   (Container : in out Array_Type)
43 is
44    type T is range System.Min_Int .. System.Max_Int;
45
46    function To_Index (J : T) return Index_Type;
47    pragma Inline (To_Index);
48
49    procedure Sift (S : T);
50
51    A : Array_Type renames Container;
52
53    --------------
54    -- To_Index --
55    --------------
56
57    function To_Index (J : T) return Index_Type is
58       K : constant T'Base := Index_Type'Pos (A'First) + J - T'(1);
59    begin
60       return Index_Type'Val (K);
61    end To_Index;
62
63    Max  : T := A'Length;
64    Temp : Element_Type;
65
66    ----------
67    -- Sift --
68    ----------
69
70    procedure Sift (S : T) is
71       C   : T := S;
72       Son : T;
73
74    begin
75       loop
76          Son := 2 * C;
77
78          exit when Son > Max;
79
80          declare
81             Son_Index : Index_Type := To_Index (Son);
82
83          begin
84             if Son < Max then
85                if A (Son_Index) < A (Index_Type'Succ (Son_Index)) then
86                   Son := Son + 1;
87                   Son_Index := Index_Type'Succ (Son_Index);
88                end if;
89             end if;
90
91             A (To_Index (C)) := A (Son_Index);  -- Move (Son, C);
92          end;
93
94          C := Son;
95       end loop;
96
97       while C /= S loop
98          declare
99             Father      : constant T := C / 2;
100             Father_Elem : Element_Type renames A (To_Index (Father));
101
102          begin
103             if Father_Elem < Temp then           -- Lt (Father, 0)
104                A (To_Index (C)) := Father_Elem;  -- Move (Father, C)
105                C := Father;
106
107             else
108                exit;
109             end if;
110          end;
111       end loop;
112
113       A (To_Index (C)) := Temp; -- Move (0, C);
114    end Sift;
115
116 --  Start of processing for Generic_Constrained_Array_Sort
117
118 begin
119    for J in reverse 1 .. Max / 2 loop
120       Temp := Container (To_Index (J)); --  Move (J, 0);
121       Sift (J);
122    end loop;
123
124    while Max > 1 loop
125       declare
126          Max_Elem : Element_Type renames A (To_Index (Max));
127       begin
128          Temp := Max_Elem;         --  Move (Max, 0);
129          Max_Elem := A (A'First);  --  Move (1, Max);
130       end;
131
132       Max := Max - 1;
133       Sift (1);
134    end loop;
135 end Ada.Containers.Generic_Constrained_Array_Sort;