File: mallocallocator.hh

package info (click to toggle)
dune-common 2.11.0-1~exp2
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 6,056 kB
  • sloc: cpp: 54,404; python: 4,136; sh: 1,657; makefile: 17
file content (116 lines) | stat: -rw-r--r-- 2,936 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
#ifndef DUNE_MALLOC_ALLOCATOR_HH
#define DUNE_MALLOC_ALLOCATOR_HH

#include <exception>
#include <cstdlib>
#include <new>
#include <utility>

/**
 * @file
 * @brief Allocators that use malloc/free.
 */
namespace Dune
{
  /**
     @ingroup Allocators
     @brief Allocators implementation which simply calls malloc/free
   */
  template <class T>
  class MallocAllocator {
  public:
    typedef std::size_t size_type;
    typedef std::ptrdiff_t difference_type;
    typedef T* pointer;
    typedef const T* const_pointer;
    typedef T& reference;
    typedef const T& const_reference;
    typedef T value_type;
    template <class U> struct rebind {
      typedef MallocAllocator<U> other;
    };

    //! create a new MallocAllocator
    MallocAllocator() noexcept {}
    //! copy construct from an other MallocAllocator, possibly for a different result type
    template <class U>
    MallocAllocator(const MallocAllocator<U>&) noexcept {}
    //! cleanup this allocator
    ~MallocAllocator() noexcept {}

    pointer address(reference x) const
    {
      return &x;
    }
    const_pointer address(const_reference x) const
    {
      return &x;
    }

    //! allocate n objects of type T
    pointer allocate(size_type n,
                     [[maybe_unused]] const void* hint = 0)
    {
      if (n > this->max_size())
        throw std::bad_alloc();

      pointer ret = static_cast<pointer>(std::malloc(n * sizeof(T)));
      if (!ret)
        throw std::bad_alloc();
      return ret;
    }

    //! deallocate n objects of type T at address p
    void deallocate(pointer p, [[maybe_unused]] size_type n)
    {
      std::free(p);
    }

    //! max size for allocate
    size_type max_size() const noexcept
    {
      return size_type(-1) / sizeof(T);
    }

    //! copy-construct an object of type T (i.e. make a placement new on p)
    void construct(pointer p, const T& val)
    {
      ::new((void*)p)T(val);
    }

    //! construct an object of type T from variadic parameters
    template<typename ... Args>
    void construct(pointer p, Args&&... args)
    {
      ::new((void *)p)T(std::forward<Args>(args) ...);
    }

    //! destroy an object of type T (i.e. call the destructor)
    void destroy(pointer p)
    {
      p->~T();
    }
  };

  //! check whether allocators are equivalent
  template<class T>
  constexpr bool
  operator==(const MallocAllocator<T> &, const MallocAllocator<T> &)
  {
    return true;
  }

  //! check whether allocators are not equivalent
  template<class T>
  constexpr bool
  operator!=(const MallocAllocator<T> &, const MallocAllocator<T> &)
  {
    return false;
  }
}

#endif // DUNE_MALLOC_ALLOCATOR_HH