1f8a1b7d9SAlexander Kabaev // -*- C++ -*-
2f8a1b7d9SAlexander Kabaev
3f8a1b7d9SAlexander Kabaev // Copyright (C) 2005, 2006 Free Software Foundation, Inc.
4f8a1b7d9SAlexander Kabaev //
5f8a1b7d9SAlexander Kabaev // This file is part of the GNU ISO C++ Library. This library is free
6f8a1b7d9SAlexander Kabaev // software; you can redistribute it and/or modify it under the terms
7f8a1b7d9SAlexander Kabaev // of the GNU General Public License as published by the Free Software
8f8a1b7d9SAlexander Kabaev // Foundation; either version 2, or (at your option) any later
9f8a1b7d9SAlexander Kabaev // version.
10f8a1b7d9SAlexander Kabaev
11f8a1b7d9SAlexander Kabaev // This library is distributed in the hope that it will be useful, but
12f8a1b7d9SAlexander Kabaev // WITHOUT ANY WARRANTY; without even the implied warranty of
13f8a1b7d9SAlexander Kabaev // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14f8a1b7d9SAlexander Kabaev // General Public License for more details.
15f8a1b7d9SAlexander Kabaev
16f8a1b7d9SAlexander Kabaev // You should have received a copy of the GNU General Public License
17f8a1b7d9SAlexander Kabaev // along with this library; see the file COPYING. If not, write to
18f8a1b7d9SAlexander Kabaev // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
19f8a1b7d9SAlexander Kabaev // MA 02111-1307, USA.
20f8a1b7d9SAlexander Kabaev
21f8a1b7d9SAlexander Kabaev // As a special exception, you may use this file as part of a free
22f8a1b7d9SAlexander Kabaev // software library without restriction. Specifically, if other files
23f8a1b7d9SAlexander Kabaev // instantiate templates or use macros or inline functions from this
24f8a1b7d9SAlexander Kabaev // file, or you compile this file and link it with other files to
25f8a1b7d9SAlexander Kabaev // produce an executable, this file does not by itself cause the
26f8a1b7d9SAlexander Kabaev // resulting executable to be covered by the GNU General Public
27f8a1b7d9SAlexander Kabaev // License. This exception does not however invalidate any other
28f8a1b7d9SAlexander Kabaev // reasons why the executable file might be covered by the GNU General
29f8a1b7d9SAlexander Kabaev // Public License.
30f8a1b7d9SAlexander Kabaev
31f8a1b7d9SAlexander Kabaev // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
32f8a1b7d9SAlexander Kabaev
33f8a1b7d9SAlexander Kabaev // Permission to use, copy, modify, sell, and distribute this software
34f8a1b7d9SAlexander Kabaev // is hereby granted without fee, provided that the above copyright
35f8a1b7d9SAlexander Kabaev // notice appears in all copies, and that both that copyright notice
36f8a1b7d9SAlexander Kabaev // and this permission notice appear in supporting documentation. None
37f8a1b7d9SAlexander Kabaev // of the above authors, nor IBM Haifa Research Laboratories, make any
38f8a1b7d9SAlexander Kabaev // representation about the suitability of this software for any
39f8a1b7d9SAlexander Kabaev // purpose. It is provided "as is" without express or implied
40f8a1b7d9SAlexander Kabaev // warranty.
41f8a1b7d9SAlexander Kabaev
42f8a1b7d9SAlexander Kabaev /** @file ext/vstring.h
43f8a1b7d9SAlexander Kabaev * This file is a GNU extension to the Standard C++ Library.
44f8a1b7d9SAlexander Kabaev *
45f8a1b7d9SAlexander Kabaev * Contains an exception-throwing allocator, useful for testing
46f8a1b7d9SAlexander Kabaev * exception safety. In addition, allocation addresses are stored and
47f8a1b7d9SAlexander Kabaev * sanity checked.
48f8a1b7d9SAlexander Kabaev */
49f8a1b7d9SAlexander Kabaev
50f8a1b7d9SAlexander Kabaev /**
51f8a1b7d9SAlexander Kabaev * @file throw_allocator.h
52f8a1b7d9SAlexander Kabaev */
53f8a1b7d9SAlexander Kabaev
54f8a1b7d9SAlexander Kabaev #ifndef _THROW_ALLOCATOR_H
55f8a1b7d9SAlexander Kabaev #define _THROW_ALLOCATOR_H 1
56f8a1b7d9SAlexander Kabaev
57f8a1b7d9SAlexander Kabaev #include <cmath>
58f8a1b7d9SAlexander Kabaev #include <map>
59f8a1b7d9SAlexander Kabaev #include <set>
60f8a1b7d9SAlexander Kabaev #include <string>
61f8a1b7d9SAlexander Kabaev #include <ostream>
62f8a1b7d9SAlexander Kabaev #include <stdexcept>
63f8a1b7d9SAlexander Kabaev #include <utility>
64f8a1b7d9SAlexander Kabaev #include <tr1/random>
650995a43fSAlexander Kabaev #include <bits/functexcept.h>
66f8a1b7d9SAlexander Kabaev
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)67f8a1b7d9SAlexander Kabaev _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
68f8a1b7d9SAlexander Kabaev
69f8a1b7d9SAlexander Kabaev class twister_rand_gen
70f8a1b7d9SAlexander Kabaev {
71f8a1b7d9SAlexander Kabaev public:
72f8a1b7d9SAlexander Kabaev twister_rand_gen(unsigned int seed =
73f8a1b7d9SAlexander Kabaev static_cast<unsigned int>(std::time(0)));
74f8a1b7d9SAlexander Kabaev
75f8a1b7d9SAlexander Kabaev void
76f8a1b7d9SAlexander Kabaev init(unsigned int);
77f8a1b7d9SAlexander Kabaev
78f8a1b7d9SAlexander Kabaev double
79f8a1b7d9SAlexander Kabaev get_prob();
80f8a1b7d9SAlexander Kabaev
81f8a1b7d9SAlexander Kabaev private:
82f8a1b7d9SAlexander Kabaev std::tr1::mt19937 _M_generator;
83f8a1b7d9SAlexander Kabaev };
84f8a1b7d9SAlexander Kabaev
85f8a1b7d9SAlexander Kabaev struct forced_exception_error : public std::exception
86f8a1b7d9SAlexander Kabaev { };
87f8a1b7d9SAlexander Kabaev
880995a43fSAlexander Kabaev // Substitute for concurrence_error object in the case of -fno-exceptions.
890995a43fSAlexander Kabaev inline void
__throw_forced_exception_error()900995a43fSAlexander Kabaev __throw_forced_exception_error()
910995a43fSAlexander Kabaev {
920995a43fSAlexander Kabaev #if __EXCEPTIONS
930995a43fSAlexander Kabaev throw forced_exception_error();
940995a43fSAlexander Kabaev #else
950995a43fSAlexander Kabaev __builtin_abort();
960995a43fSAlexander Kabaev #endif
970995a43fSAlexander Kabaev }
980995a43fSAlexander Kabaev
99f8a1b7d9SAlexander Kabaev class throw_allocator_base
100f8a1b7d9SAlexander Kabaev {
101f8a1b7d9SAlexander Kabaev public:
102f8a1b7d9SAlexander Kabaev void
103f8a1b7d9SAlexander Kabaev init(unsigned long seed);
104f8a1b7d9SAlexander Kabaev
105f8a1b7d9SAlexander Kabaev static void
106f8a1b7d9SAlexander Kabaev set_throw_prob(double throw_prob);
107f8a1b7d9SAlexander Kabaev
108f8a1b7d9SAlexander Kabaev static double
109f8a1b7d9SAlexander Kabaev get_throw_prob();
110f8a1b7d9SAlexander Kabaev
111f8a1b7d9SAlexander Kabaev static void
112f8a1b7d9SAlexander Kabaev set_label(size_t l);
113f8a1b7d9SAlexander Kabaev
114f8a1b7d9SAlexander Kabaev static bool
115f8a1b7d9SAlexander Kabaev empty();
116f8a1b7d9SAlexander Kabaev
117f8a1b7d9SAlexander Kabaev struct group_throw_prob_adjustor
118f8a1b7d9SAlexander Kabaev {
group_throw_prob_adjustorgroup_throw_prob_adjustor119f8a1b7d9SAlexander Kabaev group_throw_prob_adjustor(size_t size)
120f8a1b7d9SAlexander Kabaev : _M_throw_prob_orig(_S_throw_prob)
121f8a1b7d9SAlexander Kabaev {
122f8a1b7d9SAlexander Kabaev _S_throw_prob =
123f8a1b7d9SAlexander Kabaev 1 - ::pow(double(1 - _S_throw_prob), double(0.5 / (size + 1)));
124f8a1b7d9SAlexander Kabaev }
125f8a1b7d9SAlexander Kabaev
~group_throw_prob_adjustorgroup_throw_prob_adjustor126f8a1b7d9SAlexander Kabaev ~group_throw_prob_adjustor()
127f8a1b7d9SAlexander Kabaev { _S_throw_prob = _M_throw_prob_orig; }
128f8a1b7d9SAlexander Kabaev
129f8a1b7d9SAlexander Kabaev private:
130f8a1b7d9SAlexander Kabaev const double _M_throw_prob_orig;
131f8a1b7d9SAlexander Kabaev };
132f8a1b7d9SAlexander Kabaev
133f8a1b7d9SAlexander Kabaev struct zero_throw_prob_adjustor
134f8a1b7d9SAlexander Kabaev {
zero_throw_prob_adjustorzero_throw_prob_adjustor135f8a1b7d9SAlexander Kabaev zero_throw_prob_adjustor() : _M_throw_prob_orig(_S_throw_prob)
136f8a1b7d9SAlexander Kabaev { _S_throw_prob = 0; }
137f8a1b7d9SAlexander Kabaev
~zero_throw_prob_adjustorzero_throw_prob_adjustor138f8a1b7d9SAlexander Kabaev ~zero_throw_prob_adjustor()
139f8a1b7d9SAlexander Kabaev { _S_throw_prob = _M_throw_prob_orig; }
140f8a1b7d9SAlexander Kabaev
141f8a1b7d9SAlexander Kabaev private:
142f8a1b7d9SAlexander Kabaev const double _M_throw_prob_orig;
143f8a1b7d9SAlexander Kabaev };
144f8a1b7d9SAlexander Kabaev
145f8a1b7d9SAlexander Kabaev protected:
146f8a1b7d9SAlexander Kabaev static void
147f8a1b7d9SAlexander Kabaev insert(void*, size_t);
148f8a1b7d9SAlexander Kabaev
149f8a1b7d9SAlexander Kabaev static void
150f8a1b7d9SAlexander Kabaev erase(void*, size_t);
151f8a1b7d9SAlexander Kabaev
152f8a1b7d9SAlexander Kabaev static void
153f8a1b7d9SAlexander Kabaev throw_conditionally();
154f8a1b7d9SAlexander Kabaev
155f8a1b7d9SAlexander Kabaev // See if a particular address and size has been allocated by this
156f8a1b7d9SAlexander Kabaev // allocator.
157f8a1b7d9SAlexander Kabaev static void
158f8a1b7d9SAlexander Kabaev check_allocated(void*, size_t);
159f8a1b7d9SAlexander Kabaev
160f8a1b7d9SAlexander Kabaev // See if a given label has been allocated by this allocator.
161f8a1b7d9SAlexander Kabaev static void
162f8a1b7d9SAlexander Kabaev check_allocated(size_t);
163f8a1b7d9SAlexander Kabaev
164f8a1b7d9SAlexander Kabaev private:
165f8a1b7d9SAlexander Kabaev typedef std::pair<size_t, size_t> alloc_data_type;
166f8a1b7d9SAlexander Kabaev typedef std::map<void*, alloc_data_type> map_type;
167f8a1b7d9SAlexander Kabaev typedef map_type::value_type entry_type;
168f8a1b7d9SAlexander Kabaev typedef map_type::const_iterator const_iterator;
169f8a1b7d9SAlexander Kabaev typedef map_type::const_reference const_reference;
170f8a1b7d9SAlexander Kabaev
171f8a1b7d9SAlexander Kabaev friend std::ostream&
172f8a1b7d9SAlexander Kabaev operator<<(std::ostream&, const throw_allocator_base&);
173f8a1b7d9SAlexander Kabaev
174f8a1b7d9SAlexander Kabaev static entry_type
175f8a1b7d9SAlexander Kabaev make_entry(void*, size_t);
176f8a1b7d9SAlexander Kabaev
177f8a1b7d9SAlexander Kabaev static void
178f8a1b7d9SAlexander Kabaev print_to_string(std::string&);
179f8a1b7d9SAlexander Kabaev
180f8a1b7d9SAlexander Kabaev static void
181f8a1b7d9SAlexander Kabaev print_to_string(std::string&, const_reference);
182f8a1b7d9SAlexander Kabaev
183f8a1b7d9SAlexander Kabaev static twister_rand_gen _S_g;
184f8a1b7d9SAlexander Kabaev static map_type _S_map;
185f8a1b7d9SAlexander Kabaev static double _S_throw_prob;
186f8a1b7d9SAlexander Kabaev static size_t _S_label;
187f8a1b7d9SAlexander Kabaev };
188f8a1b7d9SAlexander Kabaev
189f8a1b7d9SAlexander Kabaev
190f8a1b7d9SAlexander Kabaev template<typename T>
191f8a1b7d9SAlexander Kabaev class throw_allocator : public throw_allocator_base
192f8a1b7d9SAlexander Kabaev {
193f8a1b7d9SAlexander Kabaev public:
194f8a1b7d9SAlexander Kabaev typedef size_t size_type;
195f8a1b7d9SAlexander Kabaev typedef ptrdiff_t difference_type;
196f8a1b7d9SAlexander Kabaev typedef T value_type;
197f8a1b7d9SAlexander Kabaev typedef value_type* pointer;
198f8a1b7d9SAlexander Kabaev typedef const value_type* const_pointer;
199f8a1b7d9SAlexander Kabaev typedef value_type& reference;
200f8a1b7d9SAlexander Kabaev typedef const value_type& const_reference;
201f8a1b7d9SAlexander Kabaev
202f8a1b7d9SAlexander Kabaev
203f8a1b7d9SAlexander Kabaev template<typename U>
204f8a1b7d9SAlexander Kabaev struct rebind
205f8a1b7d9SAlexander Kabaev {
206f8a1b7d9SAlexander Kabaev typedef throw_allocator<U> other;
207f8a1b7d9SAlexander Kabaev };
208f8a1b7d9SAlexander Kabaev
throw()209f8a1b7d9SAlexander Kabaev throw_allocator() throw() { }
210f8a1b7d9SAlexander Kabaev
throw()211f8a1b7d9SAlexander Kabaev throw_allocator(const throw_allocator&) throw() { }
212f8a1b7d9SAlexander Kabaev
213f8a1b7d9SAlexander Kabaev template<typename U>
throw_allocator(const throw_allocator<U> &)214f8a1b7d9SAlexander Kabaev throw_allocator(const throw_allocator<U>&) throw() { }
215f8a1b7d9SAlexander Kabaev
throw()216f8a1b7d9SAlexander Kabaev ~throw_allocator() throw() { }
217f8a1b7d9SAlexander Kabaev
218f8a1b7d9SAlexander Kabaev size_type
max_size()219f8a1b7d9SAlexander Kabaev max_size() const throw()
220f8a1b7d9SAlexander Kabaev { return std::allocator<value_type>().max_size(); }
221f8a1b7d9SAlexander Kabaev
222f8a1b7d9SAlexander Kabaev pointer
223f8a1b7d9SAlexander Kabaev allocate(size_type num, std::allocator<void>::const_pointer hint = 0)
224f8a1b7d9SAlexander Kabaev {
225f8a1b7d9SAlexander Kabaev throw_conditionally();
226f8a1b7d9SAlexander Kabaev value_type* const a = std::allocator<value_type>().allocate(num, hint);
227f8a1b7d9SAlexander Kabaev insert(a, sizeof(value_type) * num);
228f8a1b7d9SAlexander Kabaev return a;
229f8a1b7d9SAlexander Kabaev }
230f8a1b7d9SAlexander Kabaev
231f8a1b7d9SAlexander Kabaev void
construct(pointer p,const T & val)232f8a1b7d9SAlexander Kabaev construct(pointer p, const T& val)
233f8a1b7d9SAlexander Kabaev { return std::allocator<value_type>().construct(p, val); }
234f8a1b7d9SAlexander Kabaev
235f8a1b7d9SAlexander Kabaev void
destroy(pointer p)236f8a1b7d9SAlexander Kabaev destroy(pointer p)
237f8a1b7d9SAlexander Kabaev { std::allocator<value_type>().destroy(p); }
238f8a1b7d9SAlexander Kabaev
239f8a1b7d9SAlexander Kabaev void
deallocate(pointer p,size_type num)240f8a1b7d9SAlexander Kabaev deallocate(pointer p, size_type num)
241f8a1b7d9SAlexander Kabaev {
242f8a1b7d9SAlexander Kabaev erase(p, sizeof(value_type) * num);
243f8a1b7d9SAlexander Kabaev std::allocator<value_type>().deallocate(p, num);
244f8a1b7d9SAlexander Kabaev }
245f8a1b7d9SAlexander Kabaev
246f8a1b7d9SAlexander Kabaev void
check_allocated(pointer p,size_type num)247f8a1b7d9SAlexander Kabaev check_allocated(pointer p, size_type num)
248f8a1b7d9SAlexander Kabaev { throw_allocator_base::check_allocated(p, sizeof(value_type) * num); }
249f8a1b7d9SAlexander Kabaev
250f8a1b7d9SAlexander Kabaev void
check_allocated(size_type label)251f8a1b7d9SAlexander Kabaev check_allocated(size_type label)
252f8a1b7d9SAlexander Kabaev { throw_allocator_base::check_allocated(label); }
253f8a1b7d9SAlexander Kabaev };
254f8a1b7d9SAlexander Kabaev
255f8a1b7d9SAlexander Kabaev template<typename T>
256f8a1b7d9SAlexander Kabaev inline bool
257f8a1b7d9SAlexander Kabaev operator==(const throw_allocator<T>&, const throw_allocator<T>&)
258f8a1b7d9SAlexander Kabaev { return true; }
259f8a1b7d9SAlexander Kabaev
260f8a1b7d9SAlexander Kabaev template<typename T>
261f8a1b7d9SAlexander Kabaev inline bool
262f8a1b7d9SAlexander Kabaev operator!=(const throw_allocator<T>&, const throw_allocator<T>&)
263f8a1b7d9SAlexander Kabaev { return false; }
264f8a1b7d9SAlexander Kabaev
265f8a1b7d9SAlexander Kabaev std::ostream&
266f8a1b7d9SAlexander Kabaev operator<<(std::ostream& os, const throw_allocator_base& alloc)
267f8a1b7d9SAlexander Kabaev {
268f8a1b7d9SAlexander Kabaev std::string error;
269f8a1b7d9SAlexander Kabaev throw_allocator_base::print_to_string(error);
270f8a1b7d9SAlexander Kabaev os << error;
271f8a1b7d9SAlexander Kabaev return os;
272f8a1b7d9SAlexander Kabaev }
273f8a1b7d9SAlexander Kabaev
274f8a1b7d9SAlexander Kabaev // XXX Should be in .cc.
275f8a1b7d9SAlexander Kabaev twister_rand_gen::
twister_rand_gen(unsigned int seed)276f8a1b7d9SAlexander Kabaev twister_rand_gen(unsigned int seed) : _M_generator(seed) { }
277f8a1b7d9SAlexander Kabaev
278f8a1b7d9SAlexander Kabaev void
279f8a1b7d9SAlexander Kabaev twister_rand_gen::
init(unsigned int seed)280f8a1b7d9SAlexander Kabaev init(unsigned int seed)
281f8a1b7d9SAlexander Kabaev { _M_generator.seed(seed); }
282f8a1b7d9SAlexander Kabaev
283f8a1b7d9SAlexander Kabaev double
284f8a1b7d9SAlexander Kabaev twister_rand_gen::
get_prob()285f8a1b7d9SAlexander Kabaev get_prob()
286f8a1b7d9SAlexander Kabaev {
287f8a1b7d9SAlexander Kabaev const double eng_min = _M_generator.min();
288f8a1b7d9SAlexander Kabaev const double eng_range =
289f8a1b7d9SAlexander Kabaev static_cast<const double>(_M_generator.max() - eng_min);
290f8a1b7d9SAlexander Kabaev
291f8a1b7d9SAlexander Kabaev const double eng_res =
292f8a1b7d9SAlexander Kabaev static_cast<const double>(_M_generator() - eng_min);
293f8a1b7d9SAlexander Kabaev
294f8a1b7d9SAlexander Kabaev const double ret = eng_res / eng_range;
295f8a1b7d9SAlexander Kabaev _GLIBCXX_DEBUG_ASSERT(ret >= 0 && ret <= 1);
296f8a1b7d9SAlexander Kabaev return ret;
297f8a1b7d9SAlexander Kabaev }
298f8a1b7d9SAlexander Kabaev
299f8a1b7d9SAlexander Kabaev twister_rand_gen throw_allocator_base::_S_g;
300f8a1b7d9SAlexander Kabaev
301f8a1b7d9SAlexander Kabaev throw_allocator_base::map_type
302f8a1b7d9SAlexander Kabaev throw_allocator_base::_S_map;
303f8a1b7d9SAlexander Kabaev
304f8a1b7d9SAlexander Kabaev double throw_allocator_base::_S_throw_prob;
305f8a1b7d9SAlexander Kabaev
306f8a1b7d9SAlexander Kabaev size_t throw_allocator_base::_S_label = 0;
307f8a1b7d9SAlexander Kabaev
308f8a1b7d9SAlexander Kabaev throw_allocator_base::entry_type
make_entry(void * p,size_t size)309f8a1b7d9SAlexander Kabaev throw_allocator_base::make_entry(void* p, size_t size)
310f8a1b7d9SAlexander Kabaev { return std::make_pair(p, alloc_data_type(_S_label, size)); }
311f8a1b7d9SAlexander Kabaev
312f8a1b7d9SAlexander Kabaev void
init(unsigned long seed)313f8a1b7d9SAlexander Kabaev throw_allocator_base::init(unsigned long seed)
314f8a1b7d9SAlexander Kabaev { _S_g.init(seed); }
315f8a1b7d9SAlexander Kabaev
316f8a1b7d9SAlexander Kabaev void
set_throw_prob(double throw_prob)317f8a1b7d9SAlexander Kabaev throw_allocator_base::set_throw_prob(double throw_prob)
318f8a1b7d9SAlexander Kabaev { _S_throw_prob = throw_prob; }
319f8a1b7d9SAlexander Kabaev
320f8a1b7d9SAlexander Kabaev double
get_throw_prob()321f8a1b7d9SAlexander Kabaev throw_allocator_base::get_throw_prob()
322f8a1b7d9SAlexander Kabaev { return _S_throw_prob; }
323f8a1b7d9SAlexander Kabaev
324f8a1b7d9SAlexander Kabaev void
set_label(size_t l)325f8a1b7d9SAlexander Kabaev throw_allocator_base::set_label(size_t l)
326f8a1b7d9SAlexander Kabaev { _S_label = l; }
327f8a1b7d9SAlexander Kabaev
328f8a1b7d9SAlexander Kabaev void
insert(void * p,size_t size)329f8a1b7d9SAlexander Kabaev throw_allocator_base::insert(void* p, size_t size)
330f8a1b7d9SAlexander Kabaev {
331f8a1b7d9SAlexander Kabaev const_iterator found_it = _S_map.find(p);
332f8a1b7d9SAlexander Kabaev if (found_it != _S_map.end())
333f8a1b7d9SAlexander Kabaev {
334f8a1b7d9SAlexander Kabaev std::string error("throw_allocator_base::insert");
335f8a1b7d9SAlexander Kabaev error += "double insert!";
336f8a1b7d9SAlexander Kabaev error += '\n';
337f8a1b7d9SAlexander Kabaev print_to_string(error, make_entry(p, size));
338f8a1b7d9SAlexander Kabaev print_to_string(error, *found_it);
3390995a43fSAlexander Kabaev std::__throw_logic_error(error.c_str());
340f8a1b7d9SAlexander Kabaev }
341f8a1b7d9SAlexander Kabaev _S_map.insert(make_entry(p, size));
342f8a1b7d9SAlexander Kabaev }
343f8a1b7d9SAlexander Kabaev
344f8a1b7d9SAlexander Kabaev bool
empty()345f8a1b7d9SAlexander Kabaev throw_allocator_base::empty()
346f8a1b7d9SAlexander Kabaev { return _S_map.empty(); }
347f8a1b7d9SAlexander Kabaev
348f8a1b7d9SAlexander Kabaev void
erase(void * p,size_t size)349f8a1b7d9SAlexander Kabaev throw_allocator_base::erase(void* p, size_t size)
350f8a1b7d9SAlexander Kabaev {
351f8a1b7d9SAlexander Kabaev check_allocated(p, size);
352f8a1b7d9SAlexander Kabaev _S_map.erase(p);
353f8a1b7d9SAlexander Kabaev }
354f8a1b7d9SAlexander Kabaev
355f8a1b7d9SAlexander Kabaev void
check_allocated(void * p,size_t size)356f8a1b7d9SAlexander Kabaev throw_allocator_base::check_allocated(void* p, size_t size)
357f8a1b7d9SAlexander Kabaev {
358f8a1b7d9SAlexander Kabaev const_iterator found_it = _S_map.find(p);
359f8a1b7d9SAlexander Kabaev if (found_it == _S_map.end())
360f8a1b7d9SAlexander Kabaev {
361f8a1b7d9SAlexander Kabaev std::string error("throw_allocator_base::check_allocated by value ");
362f8a1b7d9SAlexander Kabaev error += "null erase!";
363f8a1b7d9SAlexander Kabaev error += '\n';
364f8a1b7d9SAlexander Kabaev print_to_string(error, make_entry(p, size));
3650995a43fSAlexander Kabaev std::__throw_logic_error(error.c_str());
366f8a1b7d9SAlexander Kabaev }
367f8a1b7d9SAlexander Kabaev
368f8a1b7d9SAlexander Kabaev if (found_it->second.second != size)
369f8a1b7d9SAlexander Kabaev {
370f8a1b7d9SAlexander Kabaev std::string error("throw_allocator_base::check_allocated by value ");
371f8a1b7d9SAlexander Kabaev error += "wrong-size erase!";
372f8a1b7d9SAlexander Kabaev error += '\n';
373f8a1b7d9SAlexander Kabaev print_to_string(error, make_entry(p, size));
374f8a1b7d9SAlexander Kabaev print_to_string(error, *found_it);
3750995a43fSAlexander Kabaev std::__throw_logic_error(error.c_str());
376f8a1b7d9SAlexander Kabaev }
377f8a1b7d9SAlexander Kabaev }
378f8a1b7d9SAlexander Kabaev
379f8a1b7d9SAlexander Kabaev void
check_allocated(size_t label)380f8a1b7d9SAlexander Kabaev throw_allocator_base::check_allocated(size_t label)
381f8a1b7d9SAlexander Kabaev {
382f8a1b7d9SAlexander Kabaev std::string found;
383f8a1b7d9SAlexander Kabaev const_iterator it = _S_map.begin();
384f8a1b7d9SAlexander Kabaev while (it != _S_map.end())
385f8a1b7d9SAlexander Kabaev {
386f8a1b7d9SAlexander Kabaev if (it->second.first == label)
387f8a1b7d9SAlexander Kabaev print_to_string(found, *it);
388f8a1b7d9SAlexander Kabaev ++it;
389f8a1b7d9SAlexander Kabaev }
390f8a1b7d9SAlexander Kabaev
391f8a1b7d9SAlexander Kabaev if (!found.empty())
392f8a1b7d9SAlexander Kabaev {
393f8a1b7d9SAlexander Kabaev std::string error("throw_allocator_base::check_allocated by label ");
394f8a1b7d9SAlexander Kabaev error += '\n';
395f8a1b7d9SAlexander Kabaev error += found;
3960995a43fSAlexander Kabaev std::__throw_logic_error(error.c_str());
397f8a1b7d9SAlexander Kabaev }
398f8a1b7d9SAlexander Kabaev }
399f8a1b7d9SAlexander Kabaev
400f8a1b7d9SAlexander Kabaev void
throw_conditionally()401f8a1b7d9SAlexander Kabaev throw_allocator_base::throw_conditionally()
402f8a1b7d9SAlexander Kabaev {
403f8a1b7d9SAlexander Kabaev if (_S_g.get_prob() < _S_throw_prob)
4040995a43fSAlexander Kabaev __throw_forced_exception_error();
405f8a1b7d9SAlexander Kabaev }
406f8a1b7d9SAlexander Kabaev
407f8a1b7d9SAlexander Kabaev void
print_to_string(std::string & s)408f8a1b7d9SAlexander Kabaev throw_allocator_base::print_to_string(std::string& s)
409f8a1b7d9SAlexander Kabaev {
410f8a1b7d9SAlexander Kabaev const_iterator begin = throw_allocator_base::_S_map.begin();
411f8a1b7d9SAlexander Kabaev const_iterator end = throw_allocator_base::_S_map.end();
412f8a1b7d9SAlexander Kabaev for (; begin != end; ++begin)
413f8a1b7d9SAlexander Kabaev print_to_string(s, *begin);
414f8a1b7d9SAlexander Kabaev }
415f8a1b7d9SAlexander Kabaev
416f8a1b7d9SAlexander Kabaev void
print_to_string(std::string & s,const_reference ref)417f8a1b7d9SAlexander Kabaev throw_allocator_base::print_to_string(std::string& s, const_reference ref)
418f8a1b7d9SAlexander Kabaev {
419f8a1b7d9SAlexander Kabaev char buf[40];
420f8a1b7d9SAlexander Kabaev const char tab('\t');
421f8a1b7d9SAlexander Kabaev s += "address: ";
422f8a1b7d9SAlexander Kabaev sprintf(buf, "%p", ref.first);
423f8a1b7d9SAlexander Kabaev s += buf;
424f8a1b7d9SAlexander Kabaev s += tab;
425f8a1b7d9SAlexander Kabaev s += "label: ";
426*096464d3SPedro F. Giffuni sprintf(buf, "%lu", ref.second.first);
427f8a1b7d9SAlexander Kabaev s += buf;
428f8a1b7d9SAlexander Kabaev s += tab;
429f8a1b7d9SAlexander Kabaev s += "size: ";
430*096464d3SPedro F. Giffuni sprintf(buf, "%lu", ref.second.second);
431f8a1b7d9SAlexander Kabaev s += buf;
432f8a1b7d9SAlexander Kabaev s += '\n';
433f8a1b7d9SAlexander Kabaev }
434f8a1b7d9SAlexander Kabaev
435f8a1b7d9SAlexander Kabaev _GLIBCXX_END_NAMESPACE
436f8a1b7d9SAlexander Kabaev
437f8a1b7d9SAlexander Kabaev #endif
438