* arm.md (push_multi): Revert unintended change.
[official-gcc.git] / libstdc++ / vec.cc
blob966feb486de49a7f124dd1b9263d6e60e7681454
1 // new abi support -*- C++ -*-
2 // Copyright (C) 2000
3 // Free Software Foundation, Inc.
4 // Written by Nathan Sidwell, Codesourcery LLC, <nathan@codesourcery.com>
5 //
6 // GNU CC is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2, or (at your option)
9 // any later version.
11 // GNU CC is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with GNU CC; see the file COPYING. If not, write to
18 // the Free Software Foundation, 59 Temple Place - Suite 330,
19 // Boston, MA 02111-1307, USA.
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
30 #if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
31 #include <cxxabi.h>
32 #include <new>
33 #include <exception>
35 // Exception handling hook, to mark current exception as not caught --
36 // generally because we're about to rethrow it after some cleanup.
37 extern "C" void __uncatch_exception (void);
39 namespace __cxxabiv1
42 /* allocate and construct array */
43 extern "C" void *
44 __cxa_vec_new (size_t element_count,
45 size_t element_size,
46 size_t padding_size,
47 void (*constructor) (void *),
48 void (*destructor) (void *))
50 return __cxa_vec_new2 (element_count, element_size, padding_size,
51 constructor, destructor,
52 &operator new[], &operator delete []);
55 extern "C" void *
56 __cxa_vec_new2 (size_t element_count,
57 size_t element_size,
58 size_t padding_size,
59 void (*constructor) (void *),
60 void (*destructor) (void *),
61 void *(*alloc) (size_t),
62 void (*dealloc) (void *))
64 size_t size = element_count * element_size + padding_size;
65 char *base = static_cast <char *> (alloc (size));
67 if (padding_size)
69 base += padding_size;
70 reinterpret_cast <size_t *> (base)[-1] = element_count;
72 try
74 __cxa_vec_ctor (base, element_count, element_size,
75 constructor, destructor);
77 catch (...)
79 __uncatch_exception ();
80 dealloc (base - padding_size);
81 throw;
83 return base;
86 extern "C" void *
87 __cxa_vec_new3 (size_t element_count,
88 size_t element_size,
89 size_t padding_size,
90 void (*constructor) (void *),
91 void (*destructor) (void *),
92 void *(*alloc) (size_t),
93 void (*dealloc) (void *, size_t))
95 size_t size = element_count * element_size + padding_size;
96 char *base = static_cast <char *> (alloc (size));
98 if (padding_size)
100 base += padding_size;
101 reinterpret_cast <size_t *> (base)[-1] = element_count;
105 __cxa_vec_ctor (base, element_count, element_size,
106 constructor, destructor);
108 catch (...)
110 __uncatch_exception ();
111 dealloc (base - padding_size, size);
112 throw;
114 return base;
117 /* construct array */
118 extern "C" void
119 __cxa_vec_ctor (void *array_address,
120 size_t element_count,
121 size_t element_size,
122 void (*constructor) (void *),
123 void (*destructor) (void *))
125 size_t ix = 0;
126 char *ptr = static_cast <char *> (array_address);
130 if (constructor)
131 for (; ix != element_count; ix++, ptr += element_size)
132 constructor (ptr);
134 catch (...)
136 __uncatch_exception ();
137 __cxa_vec_dtor (array_address, ix, element_size, destructor);
138 throw;
142 /* construct an array by copying */
144 extern "C" void
145 __cxa_vec_cctor (void *dest_array,
146 void *src_array,
147 size_t element_count,
148 size_t element_size,
149 void (*constructor) (void *, void *),
150 void (*destructor) (void *))
152 size_t ix = 0;
153 char *dest_ptr = static_cast <char *> (dest_array);
154 char *src_ptr = static_cast <char *> (src_array);
158 if (constructor)
159 for (; ix != element_count;
160 ix++, src_ptr += element_size, dest_ptr += element_size)
161 constructor (dest_ptr, src_ptr);
163 catch (...)
165 __uncatch_exception ();
166 __cxa_vec_dtor (dest_array, ix, element_size, destructor);
167 throw;
171 /* destruct array */
172 extern "C" void
173 __cxa_vec_dtor (void *array_address,
174 size_t element_count,
175 size_t element_size,
176 void (*destructor) (void *))
178 if (destructor)
180 char *ptr = static_cast <char *> (array_address);
181 size_t ix = element_count;
182 bool unwinding = std::uncaught_exception ();
184 ptr += element_count * element_size;
188 while (ix--)
190 ptr -= element_size;
191 destructor (ptr);
194 catch (...)
196 if (unwinding)
197 // [except.ctor]/3 If a destructor called during stack unwinding
198 // exits with an exception, terminate is called.
199 std::terminate ();
200 __uncatch_exception ();
201 __cxa_vec_dtor (array_address, ix, element_size, destructor);
202 throw;
207 /* destruct and release array */
208 extern "C" void
209 __cxa_vec_delete (void *array_address,
210 size_t element_size,
211 size_t padding_size,
212 void (*destructor) (void *))
214 __cxa_vec_delete2 (array_address, element_size, padding_size,
215 destructor,
216 &operator delete []);
219 extern "C" void
220 __cxa_vec_delete2 (void *array_address,
221 size_t element_size,
222 size_t padding_size,
223 void (*destructor) (void *),
224 void (*dealloc) (void *))
226 char *base = static_cast <char *> (array_address);
228 if (padding_size)
230 size_t element_count = reinterpret_cast <size_t *> (base)[-1];
231 base -= padding_size;
234 __cxa_vec_dtor (array_address, element_count, element_size,
235 destructor);
237 catch (...)
239 __uncatch_exception ();
240 dealloc (base);
241 throw;
244 dealloc (base);
247 extern "C" void
248 __cxa_vec_delete3 (void *array_address,
249 size_t element_size,
250 size_t padding_size,
251 void (*destructor) (void *),
252 void (*dealloc) (void *, size_t))
254 char *base = static_cast <char *> (array_address);
255 size_t size = 0;
257 if (padding_size)
259 size_t element_count = reinterpret_cast <size_t *> (base)[-1];
260 base -= padding_size;
261 size = element_count * element_size + padding_size;
264 __cxa_vec_dtor (array_address, element_count, element_size,
265 destructor);
267 catch (...)
269 __uncatch_exception ();
270 dealloc (base, size);
271 throw;
274 dealloc (base, size);
277 } // namespace __cxxabiv1
279 #endif // defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100