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-2021, 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-- As a special exception under Section 7 of GPL version 3, you are granted -- 19-- additional permissions described in the GCC Runtime Library Exception, -- 20-- version 3.1, as published by the Free Software Foundation. -- 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 32procedure Ada.Containers.Generic_Constrained_Array_Sort 33 (Container : in out Array_Type) 34is 35 subtype T is Long_Long_Integer; 36 37 function To_Index (J : T) return Index_Type; 38 pragma Inline (To_Index); 39 40 procedure Sift (S : T); 41 42 A : Array_Type renames Container; 43 44 -------------- 45 -- To_Index -- 46 -------------- 47 48 function To_Index (J : T) return Index_Type is 49 K : constant T'Base := Index_Type'Pos (A'First) + J - T'(1); 50 begin 51 return Index_Type'Val (K); 52 end To_Index; 53 54 Max : T := A'Length; 55 Temp : Element_Type; 56 57 ---------- 58 -- Sift -- 59 ---------- 60 61 procedure Sift (S : T) is 62 C : T := S; 63 Son : T; 64 65 begin 66 loop 67 Son := 2 * C; 68 69 exit when Son > Max; 70 71 declare 72 Son_Index : Index_Type := To_Index (Son); 73 74 begin 75 if Son < Max then 76 if A (Son_Index) < A (Index_Type'Succ (Son_Index)) then 77 Son := Son + 1; 78 Son_Index := Index_Type'Succ (Son_Index); 79 end if; 80 end if; 81 82 A (To_Index (C)) := A (Son_Index); -- Move (Son, C); 83 end; 84 85 C := Son; 86 end loop; 87 88 while C /= S loop 89 declare 90 Father : constant T := C / 2; 91 begin 92 if A (To_Index (Father)) < Temp then -- Lt (Father, 0) 93 A (To_Index (C)) := A (To_Index (Father)); -- Move (Father, C) 94 C := Father; 95 else 96 exit; 97 end if; 98 end; 99 end loop; 100 101 A (To_Index (C)) := Temp; -- Move (0, C); 102 end Sift; 103 104-- Start of processing for Generic_Constrained_Array_Sort 105 106begin 107 for J in reverse 1 .. Max / 2 loop 108 Temp := Container (To_Index (J)); -- Move (J, 0); 109 Sift (J); 110 end loop; 111 112 while Max > 1 loop 113 Temp := A (To_Index (Max)); -- Move (Max, 0); 114 A (To_Index (Max)) := A (A'First); -- Move (1, Max); 115 116 Max := Max - 1; 117 Sift (1); 118 end loop; 119end Ada.Containers.Generic_Constrained_Array_Sort; 120