diff --git a/courses/fundamentals_of_ada/030_basic_types/11-subtypes_full_picture.rst b/courses/fundamentals_of_ada/030_basic_types/11-subtypes_full_picture.rst index 47547ccaf..316742196 100644 --- a/courses/fundamentals_of_ada/030_basic_types/11-subtypes_full_picture.rst +++ b/courses/fundamentals_of_ada/030_basic_types/11-subtypes_full_picture.rst @@ -181,6 +181,35 @@ Attributes Reflect the Underlying Type Shade : Color range Red .. Blue := Brown; -- run-time error Hue : Rainbow := Rainbow'Succ (Blue); -- run-time error +--------------- +Valid attribute +--------------- + +* :ada:`The_Type'Valid` is a :ada:`Boolean` +* :ada:`True` |rightarrow| the current representation for the given scalar is valid + +.. code:: Ada + + procedure Main is + subtype Small_T is Integer range 1 .. 3; + Big : aliased Integer := 0; + Small : Small_T with Address => Big'Address; + begin + for V in 0 .. 5 loop + Big := V; + Put_Line (Big'Image & " => " & Boolean'Image (Small'Valid)); + end loop; + end Main; + +.. code:: + + 0 => FALSE + 1 => TRUE + 2 => TRUE + 3 => TRUE + 4 => FALSE + 5 => FALSE + ------------------------ Idiom: Extended Ranges ------------------------ diff --git a/courses/fundamentals_of_ada/140_access_types-in_depth.rst b/courses/fundamentals_of_ada/140_access_types-in_depth.rst index 87b5de62b..221cb911d 100644 --- a/courses/fundamentals_of_ada/140_access_types-in_depth.rst +++ b/courses/fundamentals_of_ada/140_access_types-in_depth.rst @@ -57,5 +57,6 @@ Access Types In Depth .. include:: 140_access_types/08-memory_management.rst .. include:: 140_access_types/09-memory_debugging.rst .. include:: 140_access_types/10-memory_control.rst +.. include:: 140_access_types/11-type_safe_idioms.rst .. include:: labs/140_access_types-in_depth.lab.rst .. include:: 140_access_types/99-summary_with_pools.rst diff --git a/courses/fundamentals_of_ada/140_access_types/10-memory_control.rst b/courses/fundamentals_of_ada/140_access_types/10-memory_control.rst index 3172da19f..5baff8343 100644 --- a/courses/fundamentals_of_ada/140_access_types/10-memory_control.rst +++ b/courses/fundamentals_of_ada/140_access_types/10-memory_control.rst @@ -123,4 +123,3 @@ System.Storage_Pools Example (Partial) end if; end loop; end Deallocate; - diff --git a/courses/fundamentals_of_ada/140_access_types/11-type_safe_idioms.rst b/courses/fundamentals_of_ada/140_access_types/11-type_safe_idioms.rst new file mode 100644 index 000000000..970edf979 --- /dev/null +++ b/courses/fundamentals_of_ada/140_access_types/11-type_safe_idioms.rst @@ -0,0 +1,98 @@ +=========================== +Advanced Access Type Safety +=========================== + +----------------------------------- +Elaboration-Only Dynamic Allocation +----------------------------------- + +* Common in critical contexts +* Rationale: + + 1. We (might) need dynamically allocated date + + - e.g. loading configuration data of unknown size + + 2. Deallocations can cause leaks, corruption + + - |rightarrow| **Disallow** them entirely + + 3. A dynamically allocated object will need deallocation + + - |rightarrow| Unless it never goes out of **scope** + +* |rightarrow| Allow only allocation onto globals + +.. tip:: + + And restrict allocations to program elaboration + +-------------------------- +Prevent Heap Deallocations +-------------------------- + +* :ada:`Ada.Unchecked_Deallocation` cannot be used anymore +* No heap deallocation is possible + + - The total number of allocations should be bounded + - e.g. elaboration-only allocations + +.. code:: Ada + + pragma Restrictions + (No_Dependence => Unchecked_Deallocation); + +-------------------------------- +Constant Access at Library Level +-------------------------------- + +.. code:: Ada + + type Acc is access T; + procedure Free is new Ada.Unchecked_Deallocation (T, Acc); + + A : constant Acc := new T; + +* :ada:`A` is :ada:`constant` + + * Cannot be deallocated + +------------------------------- +Constant Access as Discriminant +------------------------------- + +.. code:: Ada + + type R (A : access T) is limited record + +* :ada:`A` is :ada:`constant` + + * Cannot be deallocated + +* :ada:`R` is :ada:`limited` + + * Cannot be copied + +------------------------ +Idiom: Access to Subtype +------------------------ + +.. tip:: + + :ada:`subtype` improves access-related code safety + +* Subtype constraints still apply through the access type + +.. code:: Ada + + type Values_T is array (Positive range <>) of Integer; + subtype Two_Values_T is Values_T (1 .. 2); + type Two_Values_A is access all Two_Values_T; + + function Get return Values_T is (1 => 10); + + -- O : aliased Two_Values_T := Get; + -- Runtime FAIL: Constraint check + O : aliased Values_T := Get; -- Single value, bounds are 1 .. 1 + -- P : Two_Values_A := O'Access; + -- Compile-time FAIL: Bounds must statically match diff --git a/courses/fundamentals_of_ada/230_interfacing_with_c/10-example_refcount_wrap.rst b/courses/fundamentals_of_ada/230_interfacing_with_c/10-example_refcount_wrap.rst new file mode 100644 index 000000000..d710aa783 --- /dev/null +++ b/courses/fundamentals_of_ada/230_interfacing_with_c/10-example_refcount_wrap.rst @@ -0,0 +1,151 @@ +========================================== +Refcounting Wrapper for External C Objects +========================================== + +------- +Context +------- + +* From :url:`https://blog.adacore.com/the-road-to-a-thick-opengl-binding-for-ada-part-2` +* OpenGL API create various objects like textures or vertex buffers +* Creating them gives us an ID + + - Can then be used to refer to the object + +* Simple approach: Manually reclaiming them + + - Could cause leaks + +* Refcount approach: automatic ID management + + - From an Ada wrapper + - Automatic reclaim once the last reference vanishes + +----------------- +Wrapper Interface +----------------- + +* :ada:`type GL_Object is abstract tagged private` + + - Implements smart pointer logic + +.. code:: Ada + + procedure Initialize_Id (Object : in out GL_Object); + + procedure Clear (Object : in out GL_Object); + + function Initialized (Object : GL_Object) return Boolean; + +* Derived by the **actual** object types + +.. code:: Ada + + procedure Internal_Create_Id + (Object : GL_Object; Id : out UInt) is abstract; + + procedure Internal_Release_Id + (Object : GL_Object; Id : UInt) is abstract; + +* Example usage + +.. code:: Ada + + type Shader (Kind : Shader_Type) is new GL_Object with null record; + +------------------------------------ +Wrapper Implementation: Private part +------------------------------------ + +* Object ID's holder: :ada:`GL_Object_Reference` + + - All derived types have a handle to this + +.. code:: Ada + + type GL_Object_Reference; + type GL_Object_Reference_Access is access all GL_Object_Reference; + + type GL_Object is abstract new Ada.Finalization.Controlled + with record + Reference : GL_Object_Reference_Access := null; + end record; + +* Controlled type implementing **ref-counting** + +.. code:: Ada + + overriding procedure Adjust (Object : in out GL_Object); + -- Increases reference count. + + overriding procedure Finalize (Object : in out GL_Object); + -- Decreases reference count. + -- Destroys underlying resource when it reaches zero. + +------------------------------------ +Wrapper Implementation: Full Picture +------------------------------------ + +.. image:: controlled_gl_object.svg + +.. code:: Ada + + type GL_Object_Reference is record + GL_Id : UInt; + Reference_Count : Natural; + Is_Owner : Boolean; + end record; + +------------------------ +:ada:`Adjust` Completion +------------------------ + +* :ada:`Adjust` is called every time a new reference is **created** +* Increments the ref-counter + +.. code:: Ada + + overriding procedure Adjust (Object : in out GL_Object) is + begin + if Object.Reference /= null then + Object.Reference.Reference_Count := @ + 1; + end if; + end Adjust; + +-------------------------- +:ada:`Finalize` Completion +-------------------------- + +.. note:: + + * :ada:`Finalize` should always be :dfn:`idempotent` + + - Compiler might call it multiple times on the same object + - In particular when **exceptions** occur + +.. code:: Ada + + overriding procedure Finalize (Object : in out GL_Object) is + Ref : GL_Object_Reference_Access + renames Object.Reference; + begin + + +.. warning:: + + Do **not** decrement the reference counter for every call + + * A given object will own **only one** reference + +.. code:: Ada + + -- Idempotence: the next call to Finalize will have no effect + Ref := null; + + if Ref /= null then + Ref.Reference_Count := @ - 1; + if Ref.Reference_Count = 0 then + Free (Ref.all); -- Call to user-defined primitive + Unchecked_Free (Ref); + end if; + end if; diff --git a/courses/fundamentals_of_ada/240_tasking/05-task_types_in_depth.rst b/courses/fundamentals_of_ada/240_tasking/05-task_types_in_depth.rst index 0a9c6c062..2dbff7131 100644 --- a/courses/fundamentals_of_ada/240_tasking/05-task_types_in_depth.rst +++ b/courses/fundamentals_of_ada/240_tasking/05-task_types_in_depth.rst @@ -158,6 +158,40 @@ Protected Object Entries ... end Object; +------------------------------------- +Discriminated Protected or Task types +------------------------------------- + +* Discriminant can be an :ada:`access` or discrete type +* Resulting type is indefinite + + - Unless mutable + +* Example: counter shared between tasks + +.. code:: Ada + + protected type Counter_T is + procedure Increment; + end Counter_T + + task type My_Task (Counter : not null access Counter_T) is [...] + + task body My_Task is + begin + Counter.Increment; + [...] + +---------------------------------------- +Using discriminant for Real-Time aspects +---------------------------------------- + +.. code:: Ada + + protected type Protected_With_Priority (Prio : System.Priority) + with Priority => Prio + is + ------------------------------------------ Example: Protected Objects - Declaration ------------------------------------------ diff --git a/courses/fundamentals_of_ada/240_tasking/21-gnat_semaphores.rst b/courses/fundamentals_of_ada/240_tasking/21-gnat_semaphores.rst new file mode 100644 index 000000000..187345819 --- /dev/null +++ b/courses/fundamentals_of_ada/240_tasking/21-gnat_semaphores.rst @@ -0,0 +1,85 @@ +=============== +GNAT Semaphores +=============== + +---------- +Semaphores +---------- + +* Shared counters +* Multitask-safe + + - Support priorities from "Real-time Systems" LRM Annex D + +* :ada:`Counting_Semaphore` and :ada:`Binary_Semaphore` + + - :ada:`protected` types + - Counting holds an Integer + - Binary holds a Boolean + +* Priority ceiling (LRM D.3) + + - For :ada:`pragma Locking_Policy (Ceiling_Locking)` + - Protects against priority inversions + + +--------- +Interface +--------- + +.. code:: Ada + + protected type Counting_Semaphore + (Initial_Value : Natural; + [...] + + entry Seize; + -- Blocks caller until/unless the semaphore's internal counter is + -- greater than zero. Decrements the semaphore's internal counter when + -- executed. + + procedure Release; + -- Increments the semaphore's internal counter + +.. code:: Ada + + protected type Binary_Semaphore + (Initially_Available : Boolean; + +.. code:: Ada + + subtype Mutual_Exclusion is Binary_Semaphore + (Initially_Available => True, + Ceiling => Default_Ceiling); + +------------------ +Idiom: Scope Locks +------------------ + +* Automatic release + +.. code:: Ada + + type Scope_Lock (Lock : access Mutual_Exclusion) is + new Ada.Finalization.Limited_Controlled with null record; + + procedure Initialize (This : in out Scope_Lock) is + begin + This.Lock.Seize; + end Initialize; + + procedure Finalize (This : in out Scope_Lock) is + begin + This.Lock.Release; + end Finalize; + + Mutex : aliased Mutual_Exclusion; + + State : Integer := 0; + + procedure Operation_1 is + S : Scope_Lock (Mutex’Access); + begin + State := State + 1; -- for example... + Put_Line ("State is now" & State'Img); + end Operation_1; diff --git a/courses/fundamentals_of_ada/240_tasking/22-task_safe_interfaces.rst b/courses/fundamentals_of_ada/240_tasking/22-task_safe_interfaces.rst new file mode 100644 index 000000000..6af1d2586 --- /dev/null +++ b/courses/fundamentals_of_ada/240_tasking/22-task_safe_interfaces.rst @@ -0,0 +1,147 @@ +==================== +Task Safe Interfaces +==================== + +----------------- +Problem Statement +----------------- + +* Designing task-safe code requires using dedicated constructs +* How to reuse the components? +* How to refactor task-unsafe code into task-safe version? + +---------------- +Access Protected +---------------- + +* Access to :ada:`protected` objects' subprograms +* :ada:`type P is access protected procedure (args...)` +* :ada:`type F is access protected function (args...) return ...` + +.. code:: Ada + + type Work_Id is tagged limited private; + + type Work_Handler is + access protected procedure (T : Work_Id); + +---------------------- +Synchronized Interface +---------------------- + +* :ada:`synchronized interface` can be inherited by :ada:`task`/:ada:`protected` types + +.. code:: Ada + + type Counter_I is synchronized interface; + procedure Increment (Counter : in out Counter_I) is abstract; + + task type Counter_Task_T is new Counter_I with + -- Always implemented as an entry for tasks + entry Increment; + end task; + + protected type Counter_Prot_T is new Counter_I with + procedure Increment; + end Counter_Prot_T; + +* Also present: + + - :ada:`task interface` meant for tasks only + - :ada:`protected interface` meant for protected types only + +.. warning:: + + Only available in **full-tasking** runtimes + +--------------------------------- +Standard Library Queues Interface +--------------------------------- + +* In :ada:`Ada.Containers` +* :ada:`Synchronized_Queue_Interfaces` interface + +.. tip:: + + Provides a portable interface + +.. code:: Ada + + generic + type Element_Type is private; + package Ada.Containers.Synchronized_Queue_Interfaces is + type Queue is synchronized interface; + +--------------------------------------- +Standard Library Queues Implementations +--------------------------------------- + +* Four implementations + +.. tip:: + + Recommended over rolling-out one's own queue implementation + +* Synchronized implementations + + - :ada:`Unbounded_Synchronized_Queues` + - :ada:`Bounded_Synchronized_Queues` + - As :ada:`protected` types + - With priority ceiling + +* Priority implementations + + - :ada:`Unbounded_Priority_Queues` + - :ada:`Bounded_Priotiry_Queues` + - As :ada:`protected` types + - Elements provide :ada:`Get_Priority` + + + Used for sorting elements + +---------------------------- +Example: Scheduler Interface +---------------------------- + +.. code:: Ada + + type Scheduler_I; + type Maybe_Work_Item_I is access protected procedure; + type Work_Item_I is not null access protected procedure; + + type Scheduler_I is synchronized interface; + procedure Queue (S : in out Scheduler_I; W : Work_Item_I) is abstract; + procedure Execute_Next (S : in out Scheduler_I) is abstract; + + type Work_Items_Array is array (Positive range <>) + of Maybe_Work_Item_I; + + protected type Scheduler_T (Size : Positive) is new Scheduler_I with + procedure Queue (W : Work_Item_I); + entry Execute_Next; + private + Number_Of_Items : Natural := 0; + Items : Work_Items_Array (1 .. Size); + end Scheduler_T; + +------------------------- +Example: Scheduler (Body) +------------------------- + +.. code:: Ada + + protected body Scheduler_T is + procedure Queue (W : Work_Item_I) is + begin + Number_Of_Items := Number_Of_Items + 1; + Items (Number_Of_Items) := Maybe_Work_Item_I (W); + end Queue; + + entry Execute_Next + when Number_Of_Items > 0 + is + W : Work_Item_I := Work_Item_I (Items (Number_Of_Items)); + begin + Number_Of_Items := Number_Of_Items - 1; + W.all; + end Execute_Next; + end Scheduler_T; diff --git a/courses/fundamentals_of_ada/260_controlled_types/10-idiom_refcounting.rst b/courses/fundamentals_of_ada/260_controlled_types/10-idiom_refcounting.rst new file mode 100644 index 000000000..d30b0ad66 --- /dev/null +++ b/courses/fundamentals_of_ada/260_controlled_types/10-idiom_refcounting.rst @@ -0,0 +1,91 @@ +========================================= +Reference Counting Using Controlled Types +========================================= + +--------------- +Global Overview +--------------- + +* Idiom for counting object references + + - Safe deallocation + - No memory leak + - Efficient + - All :ada:`access` must then be using it + +* Any refcounted type **must** derive from :ada:`Refcounted` + + - Tagged + - Get a :ada:`Ref` through :ada:`Set` + - Turn a :ada:`Ref` into an :ada:`access` through :ada:`Get` + +.. code:: Ada + + package Ref_Counter is + type Refcounted is abstract tagged private; + procedure Free (Self : in out Refcounted) is null; + + type Refcounted_Access is access all Refcounted'Class; + type Ref is tagged private; + + procedure Set (Self : in out Ref; Data : Refcounted'Class); + function Get (Self : Ref) return Refcounted_Access; + procedure Finalize (P : in out Ref); + procedure Adjust (P : in out Ref); + private + type Refcounted is abstract tagged record + Refcount : Integer := 0; + end record; + + type Ref is new Ada.Finalization.Controlled with record + Data : Refcounted_Access; + end record; + +---------------------- +Implementation Details +---------------------- + +.. code:: Ada + + procedure Set (Self : in out Ref; Data : Refcounted'Class) + +.. tip:: + + This procedure is safe + + - :ada:`Ref` default value is :ada:`null` + - Clears up any previously used :ada:`Ref` + +.. code:: Ada + + is + D : constant Refcounted_Access := new Refcounted'Class'(Data); + begin + if Self.Data /= null then + Finalize (Self); -- decrement old reference count + end if; + + Self.Data := D; + Adjust (Self); -- increment reference count (set to 1) + end Set; + +.. code:: Ada + + overriding procedure Adjust (P : in out Ref) + +.. note:: + + Called for all new references + +.. warning:: + + :ada:`Data` might be :ada:`null` + +.. code:: Ada + + is + begin + if P.Data /= null then + P.Data.Refcount := P.Data.Refcount + 1; + end if; + end Adjust; diff --git a/courses/fundamentals_of_ada/260_controlled_types/11-example_logger.rst b/courses/fundamentals_of_ada/260_controlled_types/11-example_logger.rst new file mode 100644 index 000000000..d0f762c44 --- /dev/null +++ b/courses/fundamentals_of_ada/260_controlled_types/11-example_logger.rst @@ -0,0 +1,79 @@ +====== +Logger +====== + +---------------- +Public Interface +---------------- + +* :ada:`Logger` uses a file for writing +* :ada:`limited` cannot be copied, or compared +* :ada:`procedure Put_Line` for logging + +.. code:: Ada + + type Logger (Filename : not null access constant String) + is tagged limited private; + + procedure Put_Line + (L : Logger; S : String); + +---------------------------- +Implementation: Private part +---------------------------- + +.. code:: Ada + + type Logger (Filename : not null access constant String) + is new Ada.Finalization.Limited_Controlled with + +.. note:: + + * :ada:`Limited_Controlled` + * Maintains a handle to the log file + +.. code:: Ada + + record + Logfile : Ada.Text_IO.File_Type; + end record; + + procedure Initialize (L : in out Logger); + -- opens the file + procedure Finalize (L : in out Logger); + -- closes the file + +-------------------- +Implementation: Body +-------------------- + +* Trivial + +.. tip:: + + Once the hard part of designing the interface is done, implementation is trivial. + +.. code:: Ada + + with Ada.Text_IO; use Ada.Text_IO; + + package body Loggers is + procedure Initialize (L : in out Logger) is + begin + Create (L.Logfile, Out_File, L.Filename.all); + Put_Line (L, "Starting"); + end Initialize; + + procedure Put_Line (L : Logger; S : String) is + begin + Put_Line ("Logger: " & S); + Put_Line (L.Logfile, S); + end Put_Line; + + procedure Finalize + (L : in out Logger) is + begin + Put_Line (L, "Closing"); + Close (L.Logfile); + end Finalize; + end Loggers; diff --git a/courses/fundamentals_of_ada/290_advanced_data_hiding/04-indefinite_private.rst b/courses/fundamentals_of_ada/290_advanced_data_hiding/04-indefinite_private.rst new file mode 100644 index 000000000..bcfa5697d --- /dev/null +++ b/courses/fundamentals_of_ada/290_advanced_data_hiding/04-indefinite_private.rst @@ -0,0 +1,165 @@ +================== +Indefinite Private +================== + +--------------- +Limited Private +--------------- + +.. code:: Ada + + type T is limited private; + +* Same interface as private + + - Removes :ada:`=` and :ada:`/=` + - Removes assignments + - Removes copies + +.. note:: + + Private type is a **view** + + - Completion should provide **at least** the same set of features + - Completion can be a :ada:`limited record` + - ... but doesn't **have** to + +--------------- +Limited Private +--------------- + +* No assignment: user cannot duplicate a key +* No equality: user cannot check two keys are the same +* Private type: user cannot access or change the issued date + +.. code:: Ada + + package Key_Stuff is + type Key is limited private; + function Make_Key ( ... ) return Key; + ... + + package body Key_Stuff is + function Make_Key ( ... ) return Key is + begin + return New_Key: Key do + New_Key.Issued := Today; + ... + end return; + end Make_Key; + +.. warning:: + + * Definite type + * User **doesn't** have to call :ada:`Make_Key` + +------------------ +Indefinite Private +------------------ + +* Indefinite: user **must** use the constructors +* Delegated :ada:`constant` objects are static constructors + +.. code:: Ada + + package Binary_Trees is + type Tree_T (<>) is private; + + Empty_Tree : constant Tree_T; + + type Nodes_T is ... + type Edges_T is ... + procedure Make (Nodes : Nodes_T; Edges : Edges_T); + ... + private + type Tree_T is record + ... + + Empty_Tree : constant Tree_T := ...; + + end Binary_Trees; + +.. tip:: + + Type completion **can** be definite + +--------------- +Opaque Pointers +--------------- + +* User can instantiate +* Completion is an :ada:`access` +* Concrete type being pointed to is **incomplete** +* Implementation is done entirely within the body + +.. code:: Ada + + package Black_Boxes is + type Box_T is private; + procedure Foo (B : Box_T); + private + type Internal_Box_T; -- incomplete + type Box_T is access all Internal_Box_T; + end Black_Boxes; + +------------------------------ +Example: A String Holder (1/2) +------------------------------ + +* Implementation not discussed here + +.. code:: Ada + + package String_Holders is + type Info is limited private; + + function Contains (Obj : Info; Str : String) return Boolean + with Ghost; + function Equals (Left, Right : Info) return Boolean + with Ghost; + +.. tip:: + + These are only used for contracts, hence the :ada:`Ghost` aspect + +.. code:: Ada + + function To_Info (Str : String) return Info + with Post => Contains (To_Info'Result, S); + + function To_String (Obj : Info) + return String + with Post => Contains (Obj, To_String'Result); + + procedure Copy (To : in out Info; + From : Info) + with Post => Equals (To, From); + + procedure Append (Obj : in out Info; + Str : String) + with Post => Contains (Obj, To_String (Obj)'Old & S); + + procedure Destroy (Obj : in out Info); + +------------------------------ +Example: A String Holder (2/2) +------------------------------ + +.. code:: Ada + + private + type Info is access String; + + function To_String_Internal (Obj : Info) return String + is (if Obj = null then "" else Obj.all); +.. tip:: + + This can be used by contracts implementation below, and child packages + +.. code:: Ada + + function Contains (Obj : Info; Str : String) return Boolean + is (Obj /= null and then Obj.all = Str); + function Equals (Left, Right : Info) return Boolean + is (To_String_Internal (Left) + = To_String_Internal (Right)); diff --git a/courses/fundamentals_of_ada/700_expert_resource_management.rst b/courses/fundamentals_of_ada/700_expert_resource_management.rst new file mode 100644 index 000000000..74f6610b0 --- /dev/null +++ b/courses/fundamentals_of_ada/700_expert_resource_management.rst @@ -0,0 +1,44 @@ +************************** +Expert Resource Management +************************** + +.. container:: PRELUDE BEGIN + +.. container:: PRELUDE ROLES + +.. role:: ada(code) + :language: Ada + +.. role:: C(code) + :language: C + +.. role:: cpp(code) + :language: C++ + +.. role:: rust(code) + :language: Rust + +.. container:: PRELUDE SYMBOLS + +.. |rightarrow| replace:: :math:`\rightarrow` +.. |forall| replace:: :math:`\forall` +.. |exists| replace:: :math:`\exists` +.. |equivalent| replace:: :math:`\iff` +.. |le| replace:: :math:`\le` +.. |ge| replace:: :math:`\ge` +.. |lt| replace:: :math:`<` +.. |gt| replace:: :math:`>` +.. |checkmark| replace:: :math:`\checkmark` + +.. container:: PRELUDE REQUIRES + +.. container:: PRELUDE PROVIDES + +.. container:: PRELUDE END + +.. include:: 290_advanced_data_hiding/04-indefinite_private.rst +.. include:: 260_controlled_types/10-idiom_refcounting.rst +.. include:: 260_controlled_types/11-example_logger.rst +.. include:: 230_interfacing_with_c/10-example_refcount_wrap.rst +.. include:: 240_tasking/21-gnat_semaphores.rst +.. include:: 240_tasking/22-task_safe_interfaces.rst diff --git a/images/controlled_gl_object.svg b/images/controlled_gl_object.svg new file mode 100755 index 000000000..c890081e3 --- /dev/null +++ b/images/controlled_gl_object.svg @@ -0,0 +1,276 @@ + + + + + + + + + + + + + + + + + + + + + GL_Object + GL_Object_Reference + GL_Object_Reference_Access + + Reference: GL_Object_Reference_Access + + GL_Id: Uint+ Reference_Count: Natural+ Is_Owner: Boolean + + + Shader + + + abstract + + .... + inherits + contains + accesses + +