update dev300-m58
[ooovba.git] / sal / cpprt / operators_new_delete.cxx
blob6cb8b2581336e8654492b269ca9f08148c689ff3
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: operators_new_delete.cxx,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sal.hxx"
34 #ifdef WNT /* avoid 'std::bad_alloc' unresolved externals */
35 #define _CRTIMP
36 #define _NTSDK
37 #endif /* WNT */
39 #ifndef INCLUDED_ALGORITHM
40 #include <algorithm>
41 #define INCLUDED_ALGORITHM
42 #endif
44 #ifndef INCLUDED_NEW
45 #include <new>
46 #define INCLUDED_NEW
47 #endif
49 #ifndef INCLUDED_STRING_H
50 #include <string.h>
51 #define INCLUDED_STRING_H
52 #endif
53 #include <osl/diagnose.h>
54 #include <rtl/alloc.h>
56 using std::nothrow_t;
58 // =======================================================================
59 // AllocatorTraits
60 // =======================================================================
62 namespace
65 struct AllocatorTraits
67 typedef char const signature_type[8];
68 const signature_type & m_signature;
70 explicit AllocatorTraits (signature_type const & s) SAL_THROW(())
71 : m_signature (s)
74 std::size_t size (std::size_t n) const SAL_THROW(())
76 n = std::max(n, std::size_t(1));
77 #if OSL_DEBUG_LEVEL > 0
78 n += sizeof(signature_type);
79 #endif /* OSL_DEBUG_LEVEL */
80 return n;
83 void* init (void * p) const SAL_THROW(())
85 #if OSL_DEBUG_LEVEL > 0
86 memcpy (p, m_signature, sizeof(signature_type));
87 p = static_cast<char*>(p) + sizeof(signature_type);
88 #endif /* OSL_DEBUG_LEVEL */
89 return p;
92 void* fini (void * p) const SAL_THROW(())
94 #if OSL_DEBUG_LEVEL > 0
95 p = static_cast<char*>(p) - sizeof(signature_type);
96 if (memcmp (p, m_signature, sizeof(signature_type)) != 0)
98 OSL_ENSURE(0, "operator delete mismatch");
100 #endif /* OSL_DEBUG_LEVEL */
101 return p;
105 // =======================================================================
107 struct VectorTraits : public AllocatorTraits
109 static const signature_type g_signature;
111 VectorTraits() SAL_THROW(())
112 : AllocatorTraits (g_signature)
116 struct ScalarTraits : public AllocatorTraits
118 static const signature_type g_signature;
120 ScalarTraits() SAL_THROW(())
121 : AllocatorTraits (g_signature)
125 const AllocatorTraits::signature_type VectorTraits::g_signature = "new[]()";
126 const AllocatorTraits::signature_type ScalarTraits::g_signature = "new() ";
128 } // anonymous namespace
130 // =======================================================================
131 // Allocator
132 // =======================================================================
134 static void default_handler (void)
136 // Multithreading race in 'std::set_new_handler()' call sequence below.
137 throw std::bad_alloc();
140 // =======================================================================
142 static void* allocate (
143 std::size_t n, AllocatorTraits const & rTraits)
144 SAL_THROW((std::bad_alloc))
146 n = rTraits.size (n);
147 for (;;)
149 void * p = rtl_allocateMemory (sal_Size(n));
150 if (p != 0)
151 return rTraits.init (p);
153 std::new_handler d = default_handler, f = std::set_new_handler (d);
154 if (f != d)
155 std::set_new_handler (f);
157 if (f == 0)
158 throw std::bad_alloc();
159 (*f)();
163 // =======================================================================
165 static void* allocate (
166 std::size_t n, AllocatorTraits const & rTraits, std::nothrow_t const &)
167 SAL_THROW(())
171 return allocate (n, rTraits);
173 catch (std::bad_alloc const &)
175 return (0);
179 // =======================================================================
181 static void deallocate (void * p, AllocatorTraits const & rTraits)
182 SAL_THROW(())
184 if (p)
186 rtl_freeMemory (rTraits.fini(p));
190 // =======================================================================
191 // T * p = new T; delete p;
192 // =======================================================================
194 void* SAL_CALL operator new (std::size_t n) throw (std::bad_alloc)
196 return allocate (n, ScalarTraits());
199 // =======================================================================
201 void SAL_CALL operator delete (void * p) throw ()
203 deallocate (p, ScalarTraits());
206 // =======================================================================
207 // T * p = new(nothrow) T; delete(nothrow) p;
208 // =======================================================================
210 void* SAL_CALL operator new (std::size_t n, std::nothrow_t const &) throw ()
212 return allocate (n, ScalarTraits(), nothrow_t());
215 // =======================================================================
217 void SAL_CALL operator delete (void * p, std::nothrow_t const &) throw ()
219 deallocate (p, ScalarTraits());
222 // =======================================================================
223 // T * p = new T[n]; delete[] p;
224 // =======================================================================
226 void* SAL_CALL operator new[] (std::size_t n) throw (std::bad_alloc)
228 return allocate (n, VectorTraits());
231 // =======================================================================
233 void SAL_CALL operator delete[] (void * p) throw ()
235 deallocate (p, VectorTraits());
238 // =======================================================================
239 // T * p = new(nothrow) T[n]; delete(nothrow)[] p;
240 // =======================================================================
242 void* SAL_CALL operator new[] (std::size_t n, std::nothrow_t const &) throw ()
244 return allocate (n, VectorTraits(), nothrow_t());
247 // =======================================================================
249 void SAL_CALL operator delete[] (void * p, std::nothrow_t const &) throw ()
251 deallocate (p, VectorTraits());
254 // =======================================================================