1ffeaf689SAlexander Kabaev // Allocators -*- C++ -*- 2ffeaf689SAlexander Kabaev 3*f8a1b7d9SAlexander Kabaev // Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 4ffeaf689SAlexander Kabaev // 5ffeaf689SAlexander Kabaev // This file is part of the GNU ISO C++ Library. This library is free 6ffeaf689SAlexander Kabaev // software; you can redistribute it and/or modify it under the 7ffeaf689SAlexander Kabaev // terms of the GNU General Public License as published by the 8ffeaf689SAlexander Kabaev // Free Software Foundation; either version 2, or (at your option) 9ffeaf689SAlexander Kabaev // any later version. 10ffeaf689SAlexander Kabaev 11ffeaf689SAlexander Kabaev // This library is distributed in the hope that it will be useful, 12ffeaf689SAlexander Kabaev // but WITHOUT ANY WARRANTY; without even the implied warranty of 13ffeaf689SAlexander Kabaev // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14ffeaf689SAlexander Kabaev // GNU General Public License for more details. 15ffeaf689SAlexander Kabaev 16ffeaf689SAlexander Kabaev // You should have received a copy of the GNU General Public License along 17ffeaf689SAlexander Kabaev // with this library; see the file COPYING. If not, write to the Free 18*f8a1b7d9SAlexander Kabaev // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19ffeaf689SAlexander Kabaev // USA. 20ffeaf689SAlexander Kabaev 21ffeaf689SAlexander Kabaev // As a special exception, you may use this file as part of a free software 22ffeaf689SAlexander Kabaev // library without restriction. Specifically, if other files instantiate 23ffeaf689SAlexander Kabaev // templates or use macros or inline functions from this file, or you compile 24ffeaf689SAlexander Kabaev // this file and link it with other files to produce an executable, this 25ffeaf689SAlexander Kabaev // file does not by itself cause the resulting executable to be covered by 26ffeaf689SAlexander Kabaev // the GNU General Public License. This exception does not however 27ffeaf689SAlexander Kabaev // invalidate any other reasons why the executable file might be covered by 28ffeaf689SAlexander Kabaev // the GNU General Public License. 29ffeaf689SAlexander Kabaev 30ffeaf689SAlexander Kabaev /* 31ffeaf689SAlexander Kabaev * Copyright (c) 1996-1997 32ffeaf689SAlexander Kabaev * Silicon Graphics Computer Systems, Inc. 33ffeaf689SAlexander Kabaev * 34ffeaf689SAlexander Kabaev * Permission to use, copy, modify, distribute and sell this software 35ffeaf689SAlexander Kabaev * and its documentation for any purpose is hereby granted without fee, 36ffeaf689SAlexander Kabaev * provided that the above copyright notice appear in all copies and 37ffeaf689SAlexander Kabaev * that both that copyright notice and this permission notice appear 38ffeaf689SAlexander Kabaev * in supporting documentation. Silicon Graphics makes no 39ffeaf689SAlexander Kabaev * representations about the suitability of this software for any 40ffeaf689SAlexander Kabaev * purpose. It is provided "as is" without express or implied warranty. 41ffeaf689SAlexander Kabaev */ 42ffeaf689SAlexander Kabaev 43ffeaf689SAlexander Kabaev /** @file ext/debug_allocator.h 44ffeaf689SAlexander Kabaev * This file is a GNU extension to the Standard C++ Library. 45ffeaf689SAlexander Kabaev * You should only include this header if you are using GCC 3 or later. 46ffeaf689SAlexander Kabaev */ 47ffeaf689SAlexander Kabaev 48ffeaf689SAlexander Kabaev #ifndef _DEBUG_ALLOCATOR_H 49ffeaf689SAlexander Kabaev #define _DEBUG_ALLOCATOR_H 1 50ffeaf689SAlexander Kabaev 51*f8a1b7d9SAlexander Kabaev #include <stdexcept> 52ffeaf689SAlexander Kabaev 53*f8a1b7d9SAlexander Kabaev _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 54*f8a1b7d9SAlexander Kabaev 55*f8a1b7d9SAlexander Kabaev using std::size_t; 56*f8a1b7d9SAlexander Kabaev 57ffeaf689SAlexander Kabaev /** 58ffeaf689SAlexander Kabaev * @brief A meta-allocator with debugging bits, as per [20.4]. 59ffeaf689SAlexander Kabaev * 60ffeaf689SAlexander Kabaev * This is precisely the allocator defined in the C++ Standard. 61ffeaf689SAlexander Kabaev * - all allocation calls operator new 62ffeaf689SAlexander Kabaev * - all deallocation calls operator delete 63ffeaf689SAlexander Kabaev */ 64ffeaf689SAlexander Kabaev template<typename _Alloc> 65ffeaf689SAlexander Kabaev class debug_allocator 66ffeaf689SAlexander Kabaev { 67ffeaf689SAlexander Kabaev public: 68ffeaf689SAlexander Kabaev typedef typename _Alloc::size_type size_type; 69ffeaf689SAlexander Kabaev typedef typename _Alloc::difference_type difference_type; 70ffeaf689SAlexander Kabaev typedef typename _Alloc::pointer pointer; 71ffeaf689SAlexander Kabaev typedef typename _Alloc::const_pointer const_pointer; 72ffeaf689SAlexander Kabaev typedef typename _Alloc::reference reference; 73ffeaf689SAlexander Kabaev typedef typename _Alloc::const_reference const_reference; 74ffeaf689SAlexander Kabaev typedef typename _Alloc::value_type value_type; 75ffeaf689SAlexander Kabaev 76ffeaf689SAlexander Kabaev private: 77ffeaf689SAlexander Kabaev // _M_extra is the number of objects that correspond to the 78ffeaf689SAlexander Kabaev // extra space where debug information is stored. 79ffeaf689SAlexander Kabaev size_type _M_extra; 80ffeaf689SAlexander Kabaev 81ffeaf689SAlexander Kabaev _Alloc _M_allocator; 82ffeaf689SAlexander Kabaev 83ffeaf689SAlexander Kabaev public: debug_allocator()84ffeaf689SAlexander Kabaev debug_allocator() 85ffeaf689SAlexander Kabaev { 86ffeaf689SAlexander Kabaev const size_t __obj_size = sizeof(value_type); 87ffeaf689SAlexander Kabaev _M_extra = (sizeof(size_type) + __obj_size - 1) / __obj_size; 88ffeaf689SAlexander Kabaev } 89ffeaf689SAlexander Kabaev 90ffeaf689SAlexander Kabaev pointer allocate(size_type __n)91ffeaf689SAlexander Kabaev allocate(size_type __n) 92ffeaf689SAlexander Kabaev { 93ffeaf689SAlexander Kabaev pointer __res = _M_allocator.allocate(__n + _M_extra); 94ffeaf689SAlexander Kabaev size_type* __ps = reinterpret_cast<size_type*>(__res); 95ffeaf689SAlexander Kabaev *__ps = __n; 96ffeaf689SAlexander Kabaev return __res + _M_extra; 97ffeaf689SAlexander Kabaev } 98ffeaf689SAlexander Kabaev 99ffeaf689SAlexander Kabaev pointer allocate(size_type __n,const void * __hint)100ffeaf689SAlexander Kabaev allocate(size_type __n, const void* __hint) 101ffeaf689SAlexander Kabaev { 102ffeaf689SAlexander Kabaev pointer __res = _M_allocator.allocate(__n + _M_extra, __hint); 103ffeaf689SAlexander Kabaev size_type* __ps = reinterpret_cast<size_type*>(__res); 104ffeaf689SAlexander Kabaev *__ps = __n; 105ffeaf689SAlexander Kabaev return __res + _M_extra; 106ffeaf689SAlexander Kabaev } 107ffeaf689SAlexander Kabaev 108ffeaf689SAlexander Kabaev void deallocate(pointer __p,size_type __n)109ffeaf689SAlexander Kabaev deallocate(pointer __p, size_type __n) 110ffeaf689SAlexander Kabaev { 111*f8a1b7d9SAlexander Kabaev if (__p) 112*f8a1b7d9SAlexander Kabaev { 113ffeaf689SAlexander Kabaev pointer __real_p = __p - _M_extra; 114ffeaf689SAlexander Kabaev if (*reinterpret_cast<size_type*>(__real_p) != __n) 115*f8a1b7d9SAlexander Kabaev { 116*f8a1b7d9SAlexander Kabaev throw std::runtime_error("debug_allocator::deallocate" 117*f8a1b7d9SAlexander Kabaev " wrong size"); 118*f8a1b7d9SAlexander Kabaev } 119ffeaf689SAlexander Kabaev _M_allocator.deallocate(__real_p, __n + _M_extra); 120ffeaf689SAlexander Kabaev } 121*f8a1b7d9SAlexander Kabaev else 122*f8a1b7d9SAlexander Kabaev throw std::runtime_error("debug_allocator::deallocate null pointer"); 123*f8a1b7d9SAlexander Kabaev } 124ffeaf689SAlexander Kabaev }; 125*f8a1b7d9SAlexander Kabaev 126*f8a1b7d9SAlexander Kabaev _GLIBCXX_END_NAMESPACE 127ffeaf689SAlexander Kabaev 128ffeaf689SAlexander Kabaev #endif 129