1132720Skan// Allocator that wraps "C" malloc -*- C++ -*-
2132720Skan
3169691Skan// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4132720Skan//
5132720Skan// This file is part of the GNU ISO C++ Library.  This library is free
6132720Skan// software; you can redistribute it and/or modify it under the
7132720Skan// terms of the GNU General Public License as published by the
8132720Skan// Free Software Foundation; either version 2, or (at your option)
9132720Skan// any later version.
10132720Skan
11132720Skan// This library is distributed in the hope that it will be useful,
12132720Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of
13132720Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14132720Skan// GNU General Public License for more details.
15132720Skan
16132720Skan// You should have received a copy of the GNU General Public License along
17132720Skan// with this library; see the file COPYING.  If not, write to the Free
18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19132720Skan// USA.
20132720Skan
21132720Skan// As a special exception, you may use this file as part of a free software
22132720Skan// library without restriction.  Specifically, if other files instantiate
23132720Skan// templates or use macros or inline functions from this file, or you compile
24132720Skan// this file and link it with other files to produce an executable, this
25132720Skan// file does not by itself cause the resulting executable to be covered by
26132720Skan// the GNU General Public License.  This exception does not however
27132720Skan// invalidate any other reasons why the executable file might be covered by
28132720Skan// the GNU General Public License.
29132720Skan
30169691Skan/** @file ext/malloc_allocator.h
31169691Skan *  This file is a GNU extension to the Standard C++ Library.
32169691Skan */
33169691Skan
34132720Skan#ifndef _MALLOC_ALLOCATOR_H
35132720Skan#define _MALLOC_ALLOCATOR_H 1
36132720Skan
37169691Skan#include <cstdlib>
38132720Skan#include <new>
39169691Skan#include <bits/functexcept.h>
40132720Skan
41169691Skan_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
42169691Skan
43169691Skan  using std::size_t;
44169691Skan  using std::ptrdiff_t;
45169691Skan
46132720Skan  /**
47169691Skan   *  @brief  An allocator that uses malloc.
48132720Skan   *
49132720Skan   *  This is precisely the allocator defined in the C++ Standard.
50132720Skan   *    - all allocation calls malloc
51132720Skan   *    - all deallocation calls free
52132720Skan   */
53132720Skan  template<typename _Tp>
54132720Skan    class malloc_allocator
55132720Skan    {
56132720Skan    public:
57132720Skan      typedef size_t     size_type;
58132720Skan      typedef ptrdiff_t  difference_type;
59132720Skan      typedef _Tp*       pointer;
60132720Skan      typedef const _Tp* const_pointer;
61132720Skan      typedef _Tp&       reference;
62132720Skan      typedef const _Tp& const_reference;
63132720Skan      typedef _Tp        value_type;
64132720Skan
65132720Skan      template<typename _Tp1>
66132720Skan        struct rebind
67132720Skan        { typedef malloc_allocator<_Tp1> other; };
68132720Skan
69132720Skan      malloc_allocator() throw() { }
70132720Skan
71132720Skan      malloc_allocator(const malloc_allocator&) throw() { }
72132720Skan
73132720Skan      template<typename _Tp1>
74132720Skan        malloc_allocator(const malloc_allocator<_Tp1>&) throw() { }
75132720Skan
76132720Skan      ~malloc_allocator() throw() { }
77132720Skan
78132720Skan      pointer
79132720Skan      address(reference __x) const { return &__x; }
80132720Skan
81132720Skan      const_pointer
82132720Skan      address(const_reference __x) const { return &__x; }
83132720Skan
84132720Skan      // NB: __n is permitted to be 0.  The C++ standard says nothing
85132720Skan      // about what the return value is when __n == 0.
86132720Skan      pointer
87132720Skan      allocate(size_type __n, const void* = 0)
88132720Skan      {
89169691Skan	if (__builtin_expect(__n > this->max_size(), false))
90169691Skan	  std::__throw_bad_alloc();
91169691Skan
92132720Skan	pointer __ret = static_cast<_Tp*>(malloc(__n * sizeof(_Tp)));
93132720Skan	if (!__ret)
94169691Skan	  std::__throw_bad_alloc();
95132720Skan	return __ret;
96132720Skan      }
97132720Skan
98132720Skan      // __p is not permitted to be a null pointer.
99132720Skan      void
100132720Skan      deallocate(pointer __p, size_type)
101132720Skan      { free(static_cast<void*>(__p)); }
102132720Skan
103132720Skan      size_type
104132720Skan      max_size() const throw()
105132720Skan      { return size_t(-1) / sizeof(_Tp); }
106132720Skan
107132720Skan      // _GLIBCXX_RESOLVE_LIB_DEFECTS
108132720Skan      // 402. wrong new expression in [some_] allocator::construct
109132720Skan      void
110132720Skan      construct(pointer __p, const _Tp& __val)
111132720Skan      { ::new(__p) value_type(__val); }
112132720Skan
113132720Skan      void
114132720Skan      destroy(pointer __p) { __p->~_Tp(); }
115132720Skan    };
116132720Skan
117132720Skan  template<typename _Tp>
118132720Skan    inline bool
119132720Skan    operator==(const malloc_allocator<_Tp>&, const malloc_allocator<_Tp>&)
120132720Skan    { return true; }
121132720Skan
122132720Skan  template<typename _Tp>
123132720Skan    inline bool
124132720Skan    operator!=(const malloc_allocator<_Tp>&, const malloc_allocator<_Tp>&)
125132720Skan    { return false; }
126132720Skan
127169691Skan_GLIBCXX_END_NAMESPACE
128169691Skan
129132720Skan#endif
130