OSDN Git Service

* gcc-interface/trans.c (add_decl_expr): At toplevel, mark the
[pf3gnuchains/gcc-fork.git] / gcc / ada / a-cgaaso.adb
index cd4cfab..abb8631 100644 (file)
 --                                                                          --
 --                         GNAT LIBRARY COMPONENTS                          --
 --                                                                          --
---                      A D A . C O N T A I N E R S .                       --
---        G E N E R I C _ A N O N Y M O U S _ A R R A Y _ S O R T           --
+--              ADA.CONTAINERS.GENERIC_ANONYMOUS_ARRAY_SORT                 --
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 2004-2005, Free Software Foundation, Inc.         --
---                                                                          --
--- This specification is derived from the Ada Reference Manual for use with --
--- GNAT. The copyright notice above, and the license provisions that follow --
--- apply solely to the  contents of the part following the private keyword. --
+--          Copyright (C) 2004-2009, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
--- ware  Foundation;  either version 2,  or (at your option) any later ver- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
--- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
--- for  more details.  You should have  received  a copy of the GNU General --
--- Public License  distributed with GNAT;  see file COPYING.  If not, write --
--- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
--- Boston, MA 02110-1301, USA.                                              --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
+--                                                                          --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
 --                                                                          --
--- As a special exception,  if other files  instantiate  generics from this --
--- unit, or you link  this unit with other files  to produce an executable, --
--- this  unit  does not  by itself cause  the resulting  executable  to  be --
--- covered  by the  GNU  General  Public  License.  This exception does not --
--- however invalidate  any other reasons why  the executable file  might be --
--- covered by the  GNU Public License.                                      --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
 --                                                                          --
 -- This unit was originally developed by Matthew J Heaney.                  --
 ------------------------------------------------------------------------------
 
+--  This algorithm was adapted from GNAT.Heap_Sort (see g-heasor.ad[sb])
+
+with System;
+
 procedure Ada.Containers.Generic_Anonymous_Array_Sort
   (First, Last : Index_Type'Base)
 is
-   Pivot, Lo, Mid, Hi : Index_Type;
+   type T is range System.Min_Int .. System.Max_Int;
 
-begin
-   if Last <= First then
-      return;
-   end if;
-
-   Lo := First;
-   Hi := Last;
-
-   if Last = Index_Type'Succ (First) then
-      if not Less (Lo, Hi) then
-         Swap (Lo, Hi);
-      end if;
-
-      return;
-   end if;
-
-   Mid := Index_Type'Val
-     (Index_Type'Pos (Lo) +
-      (Index_Type'Pos (Hi) - Index_Type'Pos (Lo)) / 2);
-
-   --  We need to figure out which case we have:
-   --  x < y < z
-   --  x < z < y
-   --  z < x < y
-   --  y < x < z
-   --  y < z < x
-   --  z < y < x
-
-   if Less (Lo, Mid) then
-      if Less (Lo, Hi) then
-         if Less (Mid, Hi) then
-            Swap (Lo, Mid);
+   function To_Index (J : T) return Index_Type;
+   pragma Inline (To_Index);
 
-         else
-            Swap (Lo, Hi);
+   function Lt (J, K : T) return Boolean;
+   pragma Inline (Lt);
 
-         end if;
+   procedure Xchg (J, K : T);
+   pragma Inline (Xchg);
+
+   procedure Sift (S : T);
+
+   --------------
+   -- To_Index --
+   --------------
 
-      else
-         null;  --  lo is median
-      end if;
+   function To_Index (J : T) return Index_Type is
+      K : constant T'Base := Index_Type'Pos (First) + J - T'(1);
+   begin
+      return Index_Type'Val (K);
+   end To_Index;
 
-   elsif Less (Lo, Hi) then
-      null; --  lo is median
+   --------
+   -- Lt --
+   --------
 
-   elsif Less (Mid, Hi) then
-      Swap (Lo, Hi);
+   function Lt (J, K : T) return Boolean is
+   begin
+      return Less (To_Index (J), To_Index (K));
+   end Lt;
 
-   else
-      Swap (Lo, Mid);
-   end if;
+   ----------
+   -- Xchg --
+   ----------
 
-   Pivot := Lo;
-   Outer : loop
+   procedure Xchg (J, K : T) is
+   begin
+      Swap (To_Index (J), To_Index (K));
+   end Xchg;
+
+   Max : T := Index_Type'Pos (Last) - Index_Type'Pos (First) + T'(1);
+
+   ----------
+   -- Sift --
+   ----------
+
+   procedure Sift (S : T) is
+      C      : T := S;
+      Son    : T;
+      Father : T;
+
+   begin
       loop
-         exit Outer when not (Pivot < Hi);
+         Son := C + C;
 
-         if Less (Hi, Pivot) then
-            Swap (Hi, Pivot);
-            Pivot := Hi;
-            Lo := Index_Type'Succ (Lo);
+         if Son < Max then
+            if Lt (Son, Son + 1) then
+               Son := Son + 1;
+            end if;
+         elsif Son > Max then
             exit;
-         else
-            Hi := Index_Type'Pred (Hi);
          end if;
+
+         Xchg (Son, C);
+         C := Son;
       end loop;
 
-      loop
-         exit Outer when not (Lo < Pivot);
+      while C /= S loop
+         Father := C / 2;
 
-         if Less (Lo, Pivot) then
-            Lo := Index_Type'Succ (Lo);
+         if Lt (Father, C) then
+            Xchg (Father, C);
+            C := Father;
          else
-            Swap (Lo, Pivot);
-            Pivot := Lo;
-            Hi := Index_Type'Pred (Hi);
             exit;
          end if;
       end loop;
-   end loop Outer;
+   end Sift;
 
-   Generic_Anonymous_Array_Sort (First, Index_Type'Pred (Pivot));
-   Generic_Anonymous_Array_Sort (Index_Type'Succ (Pivot), Last);
+--  Start of processing for Generic_Anonymous_Array_Sort
 
+begin
+   for J in reverse 1 .. Max / 2 loop
+      Sift (J);
+   end loop;
+
+   while Max > 1 loop
+      Xchg (1, Max);
+      Max := Max - 1;
+      Sift (1);
+   end loop;
 end Ada.Containers.Generic_Anonymous_Array_Sort;