LCOV - code coverage report
Current view: top level - /usr/include/c++/14/bits - new_allocator.h (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 40.0 % 5 2
Test Date: 2026-02-27 05:14:50 Functions: 4.8 % 21 1
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Allocator that wraps operator new -*- C++ -*-
       2              : 
       3              : // Copyright (C) 2001-2024 Free Software Foundation, Inc.
       4              : //
       5              : // This file is part of the GNU ISO C++ Library.  This library is free
       6              : // software; you can redistribute it and/or modify it under the
       7              : // terms of the GNU General Public License as published by the
       8              : // Free Software Foundation; either version 3, or (at your option)
       9              : // any later version.
      10              : 
      11              : // This library is distributed in the hope that it will be useful,
      12              : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13              : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14              : // GNU General Public License for more details.
      15              : 
      16              : // Under Section 7 of GPL version 3, you are granted additional
      17              : // permissions described in the GCC Runtime Library Exception, version
      18              : // 3.1, as published by the Free Software Foundation.
      19              : 
      20              : // You should have received a copy of the GNU General Public License and
      21              : // a copy of the GCC Runtime Library Exception along with this program;
      22              : // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23              : // <http://www.gnu.org/licenses/>.
      24              : 
      25              : /** @file bits/new_allocator.h
      26              :  *  This is an internal header file, included by other library headers.
      27              :  *  Do not attempt to use it directly. @headername{memory}
      28              :  */
      29              : 
      30              : #ifndef _STD_NEW_ALLOCATOR_H
      31              : #define _STD_NEW_ALLOCATOR_H 1
      32              : 
      33              : #include <bits/c++config.h>
      34              : #include <new>
      35              : #include <bits/functexcept.h>
      36              : #include <bits/move.h>
      37              : #if __cplusplus >= 201103L
      38              : #include <type_traits>
      39              : #endif
      40              : 
      41              : namespace std _GLIBCXX_VISIBILITY(default)
      42              : {
      43              : _GLIBCXX_BEGIN_NAMESPACE_VERSION
      44              : 
      45              :   /**
      46              :    * @brief  An allocator that uses global `new`, as per C++03 [20.4.1].
      47              :    * @ingroup allocators
      48              :    *
      49              :    * This is precisely the allocator defined in the C++ Standard.
      50              :    *   - all allocation calls `operator new`
      51              :    *   - all deallocation calls `operator delete`
      52              :    *
      53              :    * This is the default base-class implementation of `std::allocator`,
      54              :    * and is also the base-class of the `__gnu_cxx::new_allocator` extension.
      55              :    * You should use either `std::allocator` or `__gnu_cxx::new_allocator`
      56              :    * instead of using this directly.
      57              :    *
      58              :    * @tparam  _Tp  Type of allocated object.
      59              :    *
      60              :    * @headerfile memory
      61              :    */
      62              :   template<typename _Tp>
      63              :     class __new_allocator
      64              :     {
      65              :     public:
      66              :       typedef _Tp        value_type;
      67              :       typedef std::size_t     size_type;
      68              :       typedef std::ptrdiff_t  difference_type;
      69              : #if __cplusplus <= 201703L
      70              :       typedef _Tp*       pointer;
      71              :       typedef const _Tp* const_pointer;
      72              :       typedef _Tp&       reference;
      73              :       typedef const _Tp& const_reference;
      74              : 
      75              :       template<typename _Tp1>
      76              :     struct rebind
      77              :     { typedef __new_allocator<_Tp1> other; };
      78              : #endif
      79              : 
      80              : #if __cplusplus >= 201103L
      81              :       // _GLIBCXX_RESOLVE_LIB_DEFECTS
      82              :       // 2103. propagate_on_container_move_assignment
      83              :       typedef std::true_type propagate_on_container_move_assignment;
      84              : #endif
      85              : 
      86              :       __attribute__((__always_inline__))
      87              :       _GLIBCXX20_CONSTEXPR
      88           90 :       __new_allocator() _GLIBCXX_USE_NOEXCEPT { }
      89              : 
      90              :       __attribute__((__always_inline__))
      91              :       _GLIBCXX20_CONSTEXPR
      92              :       __new_allocator(const __new_allocator&) _GLIBCXX_USE_NOEXCEPT { }
      93              : 
      94              :       template<typename _Tp1>
      95              :     __attribute__((__always_inline__))
      96              :     _GLIBCXX20_CONSTEXPR
      97              :     __new_allocator(const __new_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { }
      98              : 
      99              : #if __cplusplus >= 201103L
     100              :       __new_allocator& operator=(const __new_allocator&) = default;
     101              : #endif
     102              : 
     103              : #if __cplusplus <= 201703L
     104           90 :       ~__new_allocator() _GLIBCXX_USE_NOEXCEPT { }
     105              : 
     106              :       pointer
     107              :       address(reference __x) const _GLIBCXX_NOEXCEPT
     108              :       { return std::__addressof(__x); }
     109              : 
     110              :       const_pointer
     111              :       address(const_reference __x) const _GLIBCXX_NOEXCEPT
     112              :       { return std::__addressof(__x); }
     113              : #endif
     114              : 
     115              : #if __has_builtin(__builtin_operator_new) >= 201802L
     116              : # define _GLIBCXX_OPERATOR_NEW __builtin_operator_new
     117              : # define _GLIBCXX_OPERATOR_DELETE __builtin_operator_delete
     118              : #else
     119              : # define _GLIBCXX_OPERATOR_NEW ::operator new
     120              : # define _GLIBCXX_OPERATOR_DELETE ::operator delete
     121              : #endif
     122              : 
     123              :       // NB: __n is permitted to be 0.  The C++ standard says nothing
     124              :       // about what the return value is when __n == 0.
     125              :       _GLIBCXX_NODISCARD _Tp*
     126              :       allocate(size_type __n, const void* = static_cast<const void*>(0))
     127              :       {
     128              : #if __cplusplus >= 201103L
     129              :     // _GLIBCXX_RESOLVE_LIB_DEFECTS
     130              :     // 3308. std::allocator<void>().allocate(n)
     131              :     static_assert(sizeof(_Tp) != 0, "cannot allocate incomplete types");
     132              : #endif
     133              : 
     134              :     if (__builtin_expect(__n > this->_M_max_size(), false))
     135              :       {
     136              :         // _GLIBCXX_RESOLVE_LIB_DEFECTS
     137              :         // 3190. allocator::allocate sometimes returns too little storage
     138              :         if (__n > (std::size_t(-1) / sizeof(_Tp)))
     139              :           std::__throw_bad_array_new_length();
     140              :         std::__throw_bad_alloc();
     141              :       }
     142              : 
     143              : #if __cpp_aligned_new && __cplusplus >= 201103L
     144              :     if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
     145              :       {
     146              :         std::align_val_t __al = std::align_val_t(alignof(_Tp));
     147              :         return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n * sizeof(_Tp),
     148              :                                __al));
     149              :       }
     150              : #endif
     151              :     return static_cast<_Tp*>(_GLIBCXX_OPERATOR_NEW(__n * sizeof(_Tp)));
     152              :       }
     153              : 
     154              :       // __p is not permitted to be a null pointer.
     155              :       void
     156            0 :       deallocate(_Tp* __p, size_type __n __attribute__ ((__unused__)))
     157              :       {
     158              : #if __cpp_sized_deallocation
     159              : # define _GLIBCXX_SIZED_DEALLOC(p, n) (p), (n) * sizeof(_Tp)
     160              : #else
     161              : # define _GLIBCXX_SIZED_DEALLOC(p, n) (p)
     162              : #endif
     163              : 
     164              : #if __cpp_aligned_new && __cplusplus >= 201103L
     165              :     if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
     166              :       {
     167              :         _GLIBCXX_OPERATOR_DELETE(_GLIBCXX_SIZED_DEALLOC(__p, __n),
     168              :                      std::align_val_t(alignof(_Tp)));
     169              :         return;
     170              :       }
     171              : #endif
     172            0 :     _GLIBCXX_OPERATOR_DELETE(_GLIBCXX_SIZED_DEALLOC(__p, __n));
     173              :       }
     174              : 
     175              : #undef _GLIBCXX_SIZED_DEALLOC
     176              : #undef _GLIBCXX_OPERATOR_DELETE
     177              : #undef _GLIBCXX_OPERATOR_NEW
     178              : 
     179              : #if __cplusplus <= 201703L
     180              :       __attribute__((__always_inline__))
     181              :       size_type
     182              :       max_size() const _GLIBCXX_USE_NOEXCEPT
     183              :       { return _M_max_size(); }
     184              : 
     185              : #if __cplusplus >= 201103L
     186              :       template<typename _Up, typename... _Args>
     187              :     __attribute__((__always_inline__))
     188              :     void
     189              :     construct(_Up* __p, _Args&&... __args)
     190              :     noexcept(__is_nothrow_new_constructible<_Up, _Args...>)
     191              :     { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
     192              : 
     193              :       template<typename _Up>
     194              :     __attribute__((__always_inline__))
     195              :     void
     196              :     destroy(_Up* __p)
     197              :     noexcept(std::is_nothrow_destructible<_Up>::value)
     198            0 :     { __p->~_Up(); }
     199              : #else
     200              :       // _GLIBCXX_RESOLVE_LIB_DEFECTS
     201              :       // 402. wrong new expression in [some_] allocator::construct
     202              :       __attribute__((__always_inline__))
     203              :       void
     204              :       construct(pointer __p, const _Tp& __val)
     205              :       { ::new((void *)__p) _Tp(__val); }
     206              : 
     207              :       __attribute__((__always_inline__))
     208              :       void
     209              :       destroy(pointer __p) { __p->~_Tp(); }
     210              : #endif
     211              : #endif // ! C++20
     212              : 
     213              :       template<typename _Up>
     214              :     friend __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR bool
     215              :     operator==(const __new_allocator&, const __new_allocator<_Up>&)
     216              :     _GLIBCXX_NOTHROW
     217              :     { return true; }
     218              : 
     219              : #if __cpp_impl_three_way_comparison < 201907L
     220              :       template<typename _Up>
     221              :     friend __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR bool
     222              :     operator!=(const __new_allocator&, const __new_allocator<_Up>&)
     223              :     _GLIBCXX_NOTHROW
     224              :     { return false; }
     225              : #endif
     226              : 
     227              :     private:
     228              :       __attribute__((__always_inline__))
     229              :       _GLIBCXX_CONSTEXPR size_type
     230              :       _M_max_size() const _GLIBCXX_USE_NOEXCEPT
     231              :       {
     232              : #if __PTRDIFF_MAX__ < __SIZE_MAX__
     233              :     return std::size_t(__PTRDIFF_MAX__) / sizeof(_Tp);
     234              : #else
     235              :     return std::size_t(-1) / sizeof(_Tp);
     236              : #endif
     237              :       }
     238              :     };
     239              : 
     240              : _GLIBCXX_END_NAMESPACE_VERSION
     241              : } // namespace
     242              : 
     243              : #endif
        

Generated by: LCOV version 2.0-1