1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
  
     | 
    
      ------------------------------------------------------------------------------
--                                                                          --
--                         GNAT LIBRARY COMPONENTS                          --
--                                                                          --
--               A D A . C O N T A I N E R S . H E L P E R S                --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--           Copyright (C) 2015-2016, Free Software Foundation, Inc.        --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
--                                                                          --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception,   --
-- version 3.1, as published by the Free Software Foundation.               --
--                                                                          --
-- You should have received a copy of the GNU General Public License and    --
-- a copy of the GCC Runtime Library Exception along with this program;     --
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
-- <http://www.gnu.org/licenses/>.                                          --
------------------------------------------------------------------------------
package body Ada.Containers.Helpers is
   package body Generic_Implementation is
      use type SAC.Atomic_Unsigned;
      ------------
      -- Adjust --
      ------------
      procedure Adjust (Control : in out Reference_Control_Type) is
      begin
         if Control.T_Counts /= null then
            Lock (Control.T_Counts.all);
         end if;
      end Adjust;
      ----------
      -- Busy --
      ----------
      procedure Busy (T_Counts : in out Tamper_Counts) is
      begin
         if T_Check then
            SAC.Increment (T_Counts.Busy);
         end if;
      end Busy;
      --------------
      -- Finalize --
      --------------
      procedure Finalize (Control : in out Reference_Control_Type) is
      begin
         if Control.T_Counts /= null then
            Unlock (Control.T_Counts.all);
            Control.T_Counts := null;
         end if;
      end Finalize;
      --  No need to protect against double Finalize here, because these types
      --  are limited.
      procedure Finalize (Busy : in out With_Busy) is
         pragma Warnings (Off);
         pragma Assert (T_Check); -- not called if check suppressed
         pragma Warnings (On);
      begin
         Unbusy (Busy.T_Counts.all);
      end Finalize;
      procedure Finalize (Lock : in out With_Lock) is
         pragma Warnings (Off);
         pragma Assert (T_Check); -- not called if check suppressed
         pragma Warnings (On);
      begin
         Unlock (Lock.T_Counts.all);
      end Finalize;
      ----------------
      -- Initialize --
      ----------------
      procedure Initialize (Busy : in out With_Busy) is
         pragma Warnings (Off);
         pragma Assert (T_Check); -- not called if check suppressed
         pragma Warnings (On);
      begin
         Generic_Implementation.Busy (Busy.T_Counts.all);
      end Initialize;
      procedure Initialize (Lock : in out With_Lock) is
         pragma Warnings (Off);
         pragma Assert (T_Check); -- not called if check suppressed
         pragma Warnings (On);
      begin
         Generic_Implementation.Lock (Lock.T_Counts.all);
      end Initialize;
      ----------
      -- Lock --
      ----------
      procedure Lock (T_Counts : in out Tamper_Counts) is
      begin
         if T_Check then
            SAC.Increment (T_Counts.Lock);
            SAC.Increment (T_Counts.Busy);
         end if;
      end Lock;
      --------------
      -- TC_Check --
      --------------
      procedure TC_Check (T_Counts : Tamper_Counts) is
      begin
         if T_Check and then T_Counts.Busy > 0 then
            raise Program_Error with
              "attempt to tamper with cursors";
         end if;
         --  The lock status (which monitors "element tampering") always
         --  implies that the busy status (which monitors "cursor tampering")
         --  is set too; this is a representation invariant. Thus if the busy
         --  bit is not set, then the lock bit must not be set either.
         pragma Assert (T_Counts.Lock = 0);
      end TC_Check;
      --------------
      -- TE_Check --
      --------------
      procedure TE_Check (T_Counts : Tamper_Counts) is
      begin
         if T_Check and then T_Counts.Lock > 0 then
            raise Program_Error with
              "attempt to tamper with elements";
         end if;
      end TE_Check;
      ------------
      -- Unbusy --
      ------------
      procedure Unbusy (T_Counts : in out Tamper_Counts) is
      begin
         if T_Check then
            SAC.Decrement (T_Counts.Busy);
         end if;
      end Unbusy;
      ------------
      -- Unlock --
      ------------
      procedure Unlock (T_Counts : in out Tamper_Counts) is
      begin
         if T_Check then
            SAC.Decrement (T_Counts.Lock);
            SAC.Decrement (T_Counts.Busy);
         end if;
      end Unlock;
      -----------------
      -- Zero_Counts --
      -----------------
      procedure Zero_Counts (T_Counts : out Tamper_Counts) is
      begin
         if T_Check then
            T_Counts := (others => <>);
         end if;
      end Zero_Counts;
   end Generic_Implementation;
end Ada.Containers.Helpers;
 
     |