Reputation: 1403
I am new to Ada and I'm trying to make a generic quicksort package that can take an integer array of n numbers. The integers in the array must within 1 to 1000.
When I compile the following code, it told me
main.adb:: "Quicksort" is not visible
main.adb:: non-visible declaration at quick_sort.ads:6
main.adb:: "sort" is undefined
However, I cannot find the reason why it is like so and it just seems to be the same feeling that I can find on generic tutorial. I really appreciate that if someone can help me clear my mind why this is happening and how I can use generic correctly.
I wrote the following generic package declaration and body.
quick_sort.ads file
package quick_sort is
generic
type element_type is private;
type array_type is array(Natural range <>) of element_type;
procedure Quicksort(arr: in out array_type);
end quick_sort;
quick_sort.adb file(snippet)
package body quick_sort is
procedure Quicksort(arr: in out array_type) is
left: integer := arr'First;
right: integer := arr'Last;
procedure partition is
....
begin
pivot := find_pivot(arr(left), arr((left+right)/2), arr(right));
-- do the partition for the array
while left <= right loop
while arr(left) < pivot loop
left := left + 1;
end loop;
while arr(right) > pivot loop
right := right - 1;
end loop;
if left <= right then
swap(arr(left), arr(right));
left := left + 1;
right := right - 1;
end if;
end loop;
end partition;
begin
if arr'Length > 1 then
partition;
Quicksort(arr(arr'First..right));
Quicksort(arr(left..arr'Last));
end if;
end Quicksort;
end quick_sort;
main.adb
with quick_sort;
procedure main is
subtype item is integer range 1..1000;
arr: array(1..3) of item;
input: item;
package sort is new Quicksort(element_type => item);
begin
for i in 1..3 loop
get(input);
arr(i) := input;
end loop;
sort(arr);
end main;
Edit:
I tried with/without the "use quick_sort" clause. Either way, the compiler will give me the following 2 errors
a generic package is not allowed in a use clause
"Quicksort" is not the name of a generic package
I cannot figure out if I used some wrong declarator. Any thought on it? Thanks!!!!!
Upvotes: 1
Views: 3282
Reputation: 25501
Your Main
begins with Quick_Sort;
. This means that Main
’s code has direct access to Quick_Sort
but not to its contents - you have to qualify them by saying Quick_Sort.<whatever>
.
You can either begin Main
with
with Quick_Sort; use Quick_Sort;
or instantiate the generic with
package sort is new Quick_Sort.Quicksort(element_type => item);
That resolves the "Quicksort" is not visible
problem. However as you report, the compiler now says "Quicksort" is not the name of a generic package
; which is true, because it’s the name of a generic procedure.
Of course that last line above should read
procedure sort is new Quick_Sort.Quicksort(element_type => item);
which leads to the new error
missing actual "Array_Type"
in instantiation of "Quicksort" declared at yeelan.ada:6
instantiation abandoned
which means that instead of
arr: array(1..3) of item;
you need to write something like
type Item_Array is array (Natural range <>) of Item;
Arr : Item_Array (1 .. 3);
and then
procedure Sort is new Quicksort(Element_Type => Item,
Array_Type => Item_Array);
You’ll then get an error about Get being undefined, but the reason for that would be the answer to another question.
Upvotes: 1