Generic units in Ada provide a powerful mechanism for creating reusable and flexible code components. They allow you to define templates for procedures, functions, packages, and other constructs that can be instantiated with different types or values. This feature is particularly useful for creating data structures and algorithms that work with any data type.
Key Concepts
- Generic Declaration: Defines a template with placeholders (generic parameters) that can be replaced with actual types or values when the generic unit is instantiated.
- Generic Instantiation: Creates a specific instance of a generic unit by providing actual parameters for the placeholders defined in the generic declaration.
- Generic Parameters: Can be types, subprograms, or values. They are specified in the generic declaration and replaced during instantiation.
Generic Procedures and Functions
Generic Procedure Example
Let's start with a simple example of a generic procedure that swaps two elements of any type.
- Generic Declaration: The
generickeyword introduces the generic unit. - Generic Parameter:
Element_Typeis a placeholder for any type.
Implementation
procedure Swap(X, Y : in out Element_Type) is Temp : Element_Type; begin Temp := X; X := Y; Y := Temp; end Swap;
Instantiation
To use the generic procedure, you need to instantiate it with a specific type.
Now, you can use Swap_Integer to swap two integers.
Generic Packages
Generic packages allow you to create reusable and flexible packages. Here’s an example of a generic package for a stack data structure.
Generic Package Declaration
generic type Element_Type is private; Max_Size : Positive; package Generic_Stack is procedure Push(Item : in Element_Type); procedure Pop(Item : out Element_Type); function Is_Empty return Boolean; function Is_Full return Boolean; end Generic_Stack;
Implementation
package body Generic_Stack is
type Stack_Array is array (1 .. Max_Size) of Element_Type;
Stack : Stack_Array;
Top : Integer := 0;
procedure Push(Item : in Element_Type) is
begin
if Top < Max_Size then
Top := Top + 1;
Stack(Top) := Item;
else
raise Constraint_Error with "Stack Overflow";
end if;
end Push;
procedure Pop(Item : out Element_Type) is
begin
if Top > 0 then
Item := Stack(Top);
Top := Top - 1;
else
raise Constraint_Error with "Stack Underflow";
end if;
end Pop;
function Is_Empty return Boolean is
begin
return Top = 0;
end Is_Empty;
function Is_Full return Boolean is
begin
return Top = Max_Size;
end Is_Full;
end Generic_Stack;Instantiation
To use the generic stack package, instantiate it with a specific type and size.
Now, you can use Integer_Stack to create and manipulate stacks of integers.
declare Stack : Integer_Stack.Stack_Array; Item : Integer; begin Integer_Stack.Push(Stack, 10); Integer_Stack.Push(Stack, 20); Integer_Stack.Pop(Stack, Item); -- Item is now 20 end;
Practical Exercises
Exercise 1: Generic Sorting Procedure
Create a generic procedure for sorting an array of any type.
Solution
generic
type Element_Type is private;
type Array_Type is array (Positive range <>) of Element_Type;
with function "<" (Left, Right : Element_Type) return Boolean;
procedure Generic_Sort(A : in out Array_Type);
procedure Generic_Sort(A : in out Array_Type) is
begin
for I in A'First .. A'Last - 1 loop
for J in I + 1 .. A'Last loop
if A(J) < A(I) then
declare
Temp : Element_Type := A(I);
begin
A(I) := A(J);
A(J) := Temp;
end;
end if;
end loop;
end loop;
end Generic_Sort;Exercise 2: Instantiate and Use the Generic Sorting Procedure
Instantiate the generic sorting procedure for an array of integers and sort an array.
Solution
procedure Sort_Integer_Array is new Generic_Sort(Integer, Integer_Array, "<"); declare A : Integer_Array(1 .. 5) := (5, 3, 4, 1, 2); begin Sort_Integer_Array(A); -- A is now (1, 2, 3, 4, 5) end;
Summary
In this section, you learned about generic units in Ada, including generic procedures, functions, and packages. You saw how to declare, implement, and instantiate generic units, and you practiced creating and using a generic sorting procedure. Understanding generics is crucial for writing reusable and flexible code in Ada, and it prepares you for more advanced topics in the language.
Ada Programming Course
Module 1: Introduction to Ada
Module 2: Basic Concepts
- Variables and Data Types
- Operators and Expressions
- Control Structures
- Loops in Ada
- Subprograms: Procedures and Functions
Module 3: Advanced Data Types
Module 4: Modular Programming
Module 5: Concurrency and Real-Time Programming
Module 6: Advanced Topics
Module 7: Best Practices and Optimization
- Code Style and Best Practices
- Debugging and Testing
- Performance Optimization
- Security Considerations
