One option is to use a ref counted access type (similar to shared_ptr). You can then just do a vector of those. Doing vectors of limited types directly is really tough since limited types cannot be copied, and vectors require copying to work (not impossible, but tough to do out of the box).
I have a ref counted access type that supports limited types here: bullfrog/src/bullfrog-access_types-smart_access.ads at 0420184ead40fe6ce418d14d738887d9fc779807 · jere-software/bullfrog · GitHub
you can then do something like:
package Task_Holders is new Bullfrog.Access_Types.Smart_Access(My_Task_Type);
subtype Shared_Access is Task_Holders.Shared_Access;
use type Shared_Access; -- to get operators visible
package Task_Vectors is new Ada.Containers.Vectors(Positive, Shared_Access);
subtype Task_Vector is Task_Vectors.Vector;
Tasks : Task_Vector;
and later:
Tasks.Append(Task_Holders.Make.Shared_Access(new My_Task_Type);
and access with:
-- First task in the list's entry. Reference is an operation
-- from Smart_Access that dereferences the Shared_Access object into your task.
-- It's a bit different from Shared_Ptr, but Ada has different constraints to do this
-- kind of thing.
Task(1).Reference.Some_Task_Entry;
NOTE: all of that is hand typed out, so may contain syntax errors. Did it quickly.
You can roll your own ref counted access types as well.
This can be tricky. You’ll either have to force the task to end early using a protected object (or entry, depends on what works for your task design), and then you want to wait until the task is terminated all before you deallocate it. You can try wrapping your task in a limited_controlled type and have you overrriding finalize procedure handle all of that. Even then, I’m no expert here, but there may be more to it when deallocating a task. You can also for terminate a task before deallocating it, but that is really risky depending on the task.
Finalization intro: Ada95 Lovelace Tutorial Section 7.7 - User-Controlled Initialization, Finalization, and Assignment
Finalization package spec: gnatprove_14.1.1_f6ca6f8c/libexec/spark/lib/gcc/x86_64-pc-linux-gnu/14.1.0/adainclude/a-finali.ads - Ada Code Search
Side note, where you declare your container also can have impacts. Task and object finalization can be impacted differently based on if it is declared at library level or in you main procedure. I always try to declare task related stuff at library level when I can.