In C/C++ I often use the preprocessor to define procedures that are based on common base procedure (yes, I know, functions in C).
For example (the names, types, and values are hypothetical):
// in some .h file
void some_base_procedure(int a, char c);
#define proc1(a) some_base_procedure(a, 'd')
#define proc2(a) some_base_procedure(a, 'e')
#define proc3(a) some_base_procedure(a, 'f')
I've looked at generics in Ada and have used them for packages, but for subprograms I'm not sure how to cleanly do something akin to the above C example.
I did come up with this however:
-- in some .ads file
procedure some_base(a:integer; c: character);
procedure proc1(a:integer; b: character := 'd') with
Import => True,
Address => some_base'Address;
procedure proc2(a:integer; b: character := 'e') with
Import => True,
Address => some_base'Address;
procedure proc3(a:integer; b: character := 'f') with
Import => True,
Address => some_base'Address;
This actually works fairly well, I only have to implement one body for some_base in the related .adb file, and I don't have to implement proc1, proc2, proc3 subprogram bodies that just call some_base with the correct parameter values. In some of my use cases though I have some more aspects then just Import and Address, so that might not scale well.
For lack of a better term I'll will refer to these as parameterized subprogram aliases.
A few problems with the above approach:
So my question is in regard to the last point above.
Is there some way of putting Import => True, Address => some_base'Address;
into some sort of aspect set, and then reusing it for each parameterized subprogram alias?
So that it would be something like this (aspect_set, using some_base_set, ... made up for this example):
-- in some .ads file
procedure some_base(a:integer; c: character);
aspect_set some_base_set is Import => True, Address => some_base'Address;
procedure proc1(a:integer; b: character := 'd') using some_base_set;
procedure proc2(a:integer; b: character := 'e') using some_base_set;
procedure proc3(a:integer; b: character := 'f') using some_base_set;
Even if there is not, I consider my above approach good enough unless someone convincingly points out why it is a very bad approach, and that there is a more expressive Ada like way of doing something like this.
What's the problem you're having with generics?
generic
C : Character;
procedure Some_Base(A : Integer);
procedure Some_Base(A : Integer) is
begin
-- do something with A and B;
end Some_Base;
procedure Proc_1 is new Some_Base('d');
procedure Proc_2 is new Some_Base('e');
procedure Proc_3 is new Some_Base('f');