File: gal-sorting.ads

package info (click to toggle)
adabrowse 4.0.3-5
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 2,364 kB
  • sloc: ada: 29,770; makefile: 137; ansic: 4
file content (139 lines) | stat: -rw-r--r-- 6,088 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
-------------------------------------------------------------------------------
--
-- <STRONG>Copyright (c) 1999 - 2002 by Thomas Wolf.</STRONG>
-- <BLOCKQUOTE>
--    AdaBrowse is free software; you can redistribute it and/or modify it
--    under the terms of the  GNU General Public License as published by the
--    Free Software  Foundation; either version 2, or (at your option) any
--    later version. AdaBrowse is distributed in the hope that it will be
--    useful, but <EM>without any warranty</EM>; without even the implied
--    warranty of <EM>merchantability or fitness for a particular purpose.</EM>
--    See the GNU General Public License for  more details. You should have
--    received a copy of the GNU General Public License with this distribution,
--    see file "<A HREF="GPL.txt">GPL.txt</A>". If not, write to the Free
--    Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
--    USA.
-- </BLOCKQUOTE>
-- <BLOCKQUOTE>
--   As a special exception from the GPL, 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 GPL. This exception does not however invalidate any
--   other reasons why the executable file might be covered by the GPL.
-- </BLOCKQUOTE>
--
-- <DL><DT><STRONG>
-- Author:</STRONG><DD>
--   Thomas Wolf  (TW)
--   <ADDRESS><A HREF="mailto:twolf@acm.org">twolf@acm.org</A></ADDRESS></DL>
--
-- <DL><DT><STRONG>
-- Purpose:</STRONG><DD>
--   Speed and space optimized quicksort. Actually, an <EM>introspective
--   quicksort</EM> with a <STRONG>worst-case</STRONG> runtime complexity of
--   <CODE>O (N * log2 (N))</CODE>.</DL>
--
-- <DL><DT><STRONG>
-- Literature:</STRONG><DD>
--   Musser, D.R.: "Introspective Sorting and Selection Algorithms",
--      <EM>Software -- Practice & Experience (8):983-993</EM>; 1997.</DL>
--
-- <DL><DT><STRONG>
-- Tasking semantics:</STRONG><DD>
--   N/A. Not abortion-safe.</DL>
--
-- <DL><DT><STRONG>
-- Storage semantics:</STRONG><DD>
--   No dynamic storage allocation. Stack space used is
--   <CODE>O (log2 (N))</CODE>.</DL>
--
-- <!--
-- Revision History
--
--   21-JAN-1999   TW  Initial version as package TW_Sorting.
--   26-NOV-2001   TW  Changed into GAL.Sorting, added 'Sort_Slice_G'.
-- -->
-------------------------------------------------------------------------------

pragma License (Modified_GPL);

package GAL.Sorting is

   pragma Elaborate_Body;

   ----------------------------------------------------------------------------
   --  A sort with a classic interface:

   generic
      type Index_Type   is (<>);
      type Element_Type is private;
      type Array_Type   is array (Index_Type range <>) of Element_Type;
      with function "<" (Left, Right : in Element_Type) return Boolean is <>;
   procedure Sort_G
     (To_Sort : in out Array_Type);
   --  Sorts the array into ascending order according to the given function
   --  "<". This is an introspective quicksort with average *and* worst-case
   --  performance complexity of O(log2(N)). Stack space usage is bounded by
   --  log2(N).
   --     If To_Sort'Length >= System.Max_Int, Constraint_Error may be raised.
   --  (I didn't test that!) However, System.Max_Int is typically >= 2**31-1,
   --  and sorting arrays of 2 Gigabytes or more is not exactly a common case.

   ----------------------------------------------------------------------------
   --  The same with an access parameter and range bounds.

   generic
      type Index_Type   is (<>);
      type Element_Type is private;
      type Array_Type   is array (Index_Type range <>) of Element_Type;
      with function "<" (Left, Right : in Element_Type) return Boolean is <>;
   procedure Sort_Slice_G
     (To_Sort  : access Array_Type;
      From, To : in     Index_Type);
   --  A no-op if To_Sort'Length <= 1 or To < From. In both cases, it is
   --  irrelevant whether or not 'To' and 'From' are within To_Sort'Range.
   --  If both To_Sort'Length > 1 and From <= To, a check is made to ensure
   --  that both 'From' and 'To' are within To_Sort'Range, and Constraint_Error
   --  will be raised without modifying the array if not. Otherwise, the given
   --  slice To_Sort (From .. To) is sorted into ascending order according to
   --  '<'.

   ----------------------------------------------------------------------------
   --  A very general sort that can be used to sort whatever you like. As
   --  long as you can provide random access in constant time, this will
   --  be a logarithmic sort. (It's an introspective quicksort, too.)

   generic
      with function  Is_Smaller (Left, Right : in Integer) return Boolean;
      --  Shall return True if the element at index 'Left' is smaller than
      --  the element at index 'Right' and Fasle otherwise.
      with procedure Copy       (To, From    : in Integer);
      --  Shall copy the element at index 'From' to position 'To'.
   procedure Sort_Indexed_G
     (Left, Right : in Natural);
   --  Sorts range Left .. Right of your data by calling 'Is_Smaller' for
   --  comparisons and 'Move' to move elements around. Both 'Is_Smaller'
   --  and 'Move' must be prepared to receive indices -1 and -2, which denote
   --  two single (and different) temporary locations. Both routines are never
   --  called with both indices negative, one index at least is always
   --  in the (Left .. Right).

   ----------------------------------------------------------------------------
   --  Same as above, but using access-to-subroutines.

   type Comparator is access
     function (Left, Right : in Integer) return Boolean;

   type Copier is access
     procedure (To, From : in Integer);

   procedure Sort
     (Left, Right : in Natural;
      Is_Smaller  : in Comparator;
      Copy        : in Copier);
   --  Of course, both 'Is_Smaller' and 'Copy' must not be null or this will
   --  raise Constraint_Error!

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

end GAL.Sorting;