(root)/
gcc-13.2.0/
libstdc++-v3/
testsuite/
util/
replacement_memory_operators.h
       1  //
       2  // Copyright (C) 2007-2023 Free Software Foundation, Inc.
       3  //
       4  // This file is part of the GNU ISO C++ Library.  This library is free
       5  // software; you can redistribute it and/or modify it under the
       6  // terms of the GNU General Public License as published by the
       7  // Free Software Foundation; either version 3, or (at your option)
       8  // any later version.
       9  //
      10  // This library is distributed in the hope that it will be useful,
      11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
      12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13  // GNU General Public License for more details.
      14  //
      15  // You should have received a copy of the GNU General Public License along
      16  // with this library; see the file COPYING3.  If not see
      17  // <http://www.gnu.org/licenses/>.
      18  
      19  #include <exception>
      20  #include <stdexcept>
      21  #include <cstdlib>
      22  #include <cstdio>
      23  #include <testsuite_hooks.h>
      24  
      25  namespace __gnu_test
      26  {
      27    struct counter_error : public std::exception { };
      28  
      29    struct counter
      30    {
      31      std::size_t _M_count;
      32      std::size_t _M_increments, _M_decrements;
      33      bool	_M_throw;
      34  
      35      counter() : _M_count(0), _M_throw(true) { }
      36  
      37      ~counter() THROW (counter_error)
      38      {
      39        if (_M_throw && _M_count != 0)
      40  	throw counter_error();
      41      }
      42  
      43      static void
      44      increment()
      45      {
      46        counter& cntr = get();
      47        cntr._M_count++;
      48        cntr._M_increments++;
      49      }
      50  
      51      static void
      52      decrement()
      53      {
      54        counter& cntr = get();
      55        cntr._M_count--;
      56        cntr._M_decrements++;
      57      }
      58  
      59      static counter&
      60      get()
      61      {
      62        static counter g;
      63        return g;
      64      }
      65  
      66      static std::size_t
      67      count() { return get()._M_count; }
      68  
      69      static void
      70      exceptions(bool __b) { get()._M_throw = __b; }
      71  
      72      static void
      73      reset()
      74      {
      75        counter& cntr = get();
      76        cntr._M_increments = cntr._M_decrements = 0;
      77      }
      78    };
      79  
      80    template<typename Alloc, bool uses_global_new>
      81      bool
      82      check_new(Alloc a = Alloc())
      83      {
      84        __gnu_test::counter::exceptions(false);
      85        (void) a.allocate(10);
      86        const bool __b((__gnu_test::counter::count() > 0) == uses_global_new);
      87        if (!__b)
      88  	throw std::logic_error("counter not incremented");
      89        return __b;
      90      }
      91  
      92    template<typename Alloc, bool uses_global_delete>
      93      bool
      94      check_delete(Alloc a = Alloc())
      95      {
      96        __gnu_test::counter::exceptions(false);
      97  #if __cplusplus >= 201103L
      98        auto p = a.allocate(10);
      99  #else
     100        typename Alloc::pointer p = a.allocate(10);
     101  #endif
     102        const std::size_t count1 = __gnu_test::counter::count();
     103        a.deallocate(p, 10);
     104        const std::size_t count2 = __gnu_test::counter::count();
     105        const bool __b((count2 < count1) == uses_global_delete);
     106        if (!__b)
     107  	throw std::logic_error("counter not decremented");
     108        return __b;
     109      }
     110  } // namespace __gnu_test
     111  
     112  void* operator new(std::size_t size) THROW(std::bad_alloc)
     113  {
     114    std::printf("operator new is called \n");
     115    void* p = std::malloc(size);
     116    if (!p)
     117      throw std::bad_alloc();
     118    __gnu_test::counter::increment();
     119    return p;
     120  }
     121  
     122  void operator delete(void* p) throw()
     123  {
     124    std::printf("operator delete is called \n");
     125    if (p)
     126      {
     127        std::free(p);
     128        __gnu_test::counter::decrement();
     129  
     130        std::size_t count = __gnu_test::counter::count();
     131        if (count == 0)
     132  	std::printf("All memory released \n");
     133        else
     134  	std::printf("%lu allocations to be released \n", (unsigned long)count);
     135      }
     136  }
     137  
     138  #if __cpp_sized_deallocation
     139  void operator delete(void* p, std::size_t) throw() { ::operator delete(p); }
     140  #endif