private with Ada.Synchronous_Task_Control; generic type T is private; package Task_Coroutines.Generator with Preelaborate is type Inner_Control is tagged limited private; procedure Yield (This : in out Inner_Control; Val : T); type Instance is tagged limited private with Iterable => (First => First, Next => Next, Has_Element => Has_Element, Element => Element); type Generator_Proc is access procedure (Ctrl : in out Inner_Control'Class); procedure Start (This : aliased in out Instance; Proc : not null Generator_Proc); procedure Stop (This : in out Instance); function Done (This : Instance) return Boolean; -- Iterable -- type Cursor_Type is null record; function Has_Next (This : in out Instance) return Boolean; function Next (This : in out Instance) return T; function First (This : Instance) return Cursor_Type; function Next (This : in out Instance; C : Cursor_Type) return Cursor_Type; function Has_Element (This : in out Instance; C : Cursor_Type) return Boolean; function Element (This : in out Instance; C : Cursor_Type) return T; private type Inner_Acc is access all Inner_Control'Class; type Outer_Acc is access all Instance'Class; task type Coro_Task is entry Start (Inner : not null Inner_Acc; Proc : not null Generator_Proc); end Coro_Task; type State_Type is (Waiting, Yielding, Done); type Instance is tagged limited record T : Coro_Task; Suspend : Ada.Synchronous_Task_Control.Suspension_Object; Inner : aliased Inner_Control; end record; type Inner_Control is tagged limited record Outer : Outer_Acc; State : State_Type := Waiting; Val : T; Suspend : Ada.Synchronous_Task_Control.Suspension_Object; end record; end Task_Coroutines.Generator;