// -*- C++ -*-
// Testing allocator for the C++ library testsuite.
//
// Copyright (C) 2002-2025 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3.  If not see
// <http://www.gnu.org/licenses/>.
//

// This file provides an test instrumentation allocator that can be
// used to verify allocation functionality of standard library
// containers.  2002.11.25 smw

#ifndef _GLIBCXX_TESTSUITE_ALLOCATOR_H
#define _GLIBCXX_TESTSUITE_ALLOCATOR_H

#include <bits/move.h>
#include <ext/pointer.h>
#include <ext/alloc_traits.h>
#include <testsuite_hooks.h>
#if __cplusplus >= 201703L
# include <memory_resource>
# include <new>
#endif

#if __cplusplus >= 201103L
# include <unordered_map>
namespace unord = std;
#else
# include <tr1/unordered_map>
namespace unord = std::tr1;
#endif

namespace __gnu_test
{
  // A common API for calling max_size() on an allocator in any -std mode.
  template<typename A>
    typename A::size_type
    max_size(const A& a)
    {
#if __cplusplus >= 201103L
      return std::allocator_traits<A>::max_size(a);
#else
      return a.max_size();
#endif
    }

  class tracker_allocator_counter
  {
  public:
    typedef std::size_t    size_type;

    static void
    allocate(size_type blocksize)
    { allocationCount_ += blocksize; }

    static void
    construct() { ++constructCount_; }

    static void
    destroy() { ++destructCount_; }

    static void
    deallocate(size_type blocksize)
    { deallocationCount_ += blocksize; }

    static size_type
    get_allocation_count() { return allocationCount_; }

    static size_type
    get_deallocation_count() { return deallocationCount_; }

    static int
    get_construct_count() { return constructCount_; }

    static int
    get_destruct_count() { return destructCount_; }

    static void
    reset()
    {
      allocationCount_ = 0;
      deallocationCount_ = 0;
      constructCount_ = 0;
      destructCount_ = 0;
    }

 private:
    static size_type  allocationCount_;
    static size_type  deallocationCount_;
    static int        constructCount_;
    static int        destructCount_;
  };

  // Helper to detect inconsistency between type used to instantiate an
  // allocator and the underlying allocator value_type.
  template<typename T, typename Alloc,
	   typename = typename Alloc::value_type>
    struct check_consistent_alloc_value_type;

  template<typename T, typename Alloc>
    struct check_consistent_alloc_value_type<T, Alloc, T>
    { typedef T value_type; };

  // An allocator facade that intercepts allocate/deallocate/construct/destroy
  // calls and track them through the tracker_allocator_counter class. This
  // class is templated on the target object type, but tracker isn't.
  template<typename T, typename Alloc = std::allocator<T> >
    class tracker_allocator : public Alloc
    {
    private:
      typedef tracker_allocator_counter counter_type;

      typedef __gnu_cxx::__alloc_traits<Alloc> AllocTraits;

    public:
      typedef typename
      check_consistent_alloc_value_type<T, Alloc>::value_type value_type;
      typedef typename AllocTraits::pointer pointer;
      typedef typename AllocTraits::size_type size_type;

      template<class U>
	struct rebind
	{
	  typedef tracker_allocator<U,
		typename AllocTraits::template rebind<U>::other> other;
	};

#if __cplusplus >= 201103L
      tracker_allocator() = default;
      tracker_allocator(const tracker_allocator&) = default;
      tracker_allocator(tracker_allocator&&) = default;
      tracker_allocator& operator=(const tracker_allocator&) = default;
      tracker_allocator& operator=(tracker_allocator&&) = default;

      // Perfect forwarding constructor.
      template<typename... _Args>
	tracker_allocator(_Args&&... __args)
	  : Alloc(std::forward<_Args>(__args)...)
	{ }
#else
      tracker_allocator()
      { }

      tracker_allocator(const tracker_allocator& a) : Alloc(a)
      { }

      ~tracker_allocator()
      { }
#endif

      template<class U>
	tracker_allocator(const tracker_allocator<U,
	  typename AllocTraits::template rebind<U>::other>& alloc)
	    _GLIBCXX_USE_NOEXCEPT
	  : Alloc(alloc)
	{ }

      pointer
      allocate(size_type n, const void* = 0)
      {
	pointer p = AllocTraits::allocate(*this, n);
	counter_type::allocate(n * sizeof(T));
	return p;
      }

#if __cplusplus >= 201103L
      template<typename U, typename... Args>
	void
	construct(U* p, Args&&... args)
	{
	  AllocTraits::construct(*this, p, std::forward<Args>(args)...);
	  counter_type::construct();
	}

      template<typename U>
	void
	destroy(U* p)
	{
	  AllocTraits::destroy(*this, p);
	  counter_type::destroy();
	}
#else
      void
      construct(pointer p, const T& value)
      {
	AllocTraits::construct(*this, p, value);
	counter_type::construct();
      }

      void
      destroy(pointer p)
      {
	AllocTraits::destroy(*this, p);
	counter_type::destroy();
      }
#endif

      void
      deallocate(pointer p, size_type num)
      {
	counter_type::deallocate(num * sizeof(T));
	AllocTraits::deallocate(*this, p, num);
      }

      // Implement swap for underlying allocators that might need it.
      friend inline void
      swap(tracker_allocator& a, tracker_allocator& b)
      {
	using std::swap;

	Alloc& aa = a;
	Alloc& ab = b;
	swap(aa, ab);
      }
    };

  template<class T1, class Alloc1, class T2, class Alloc2>
    bool
    operator==(const tracker_allocator<T1, Alloc1>& lhs,
	       const tracker_allocator<T2, Alloc2>& rhs) throw()
    {
      const Alloc1& alloc1 = lhs;
      const Alloc2& alloc2 = rhs;
      return alloc1 == alloc2;
    }

  template<class T1, class Alloc1, class T2, class Alloc2>
    bool
    operator!=(const tracker_allocator<T1, Alloc1>& lhs,
	       const tracker_allocator<T2, Alloc2>& rhs) throw()
    { return !(lhs == rhs); }

  bool
  check_construct_destroy(const char* tag, int expected_c, int expected_d);

  template<typename Alloc>
    bool
    check_deallocate_null()
    {
      // Let's not core here...
      Alloc a;
      a.deallocate(0, 1);
      a.deallocate(0, 10);
      return true;
    }

#if __cpp_exceptions
  template<typename Alloc>
    bool
    check_allocate_max_size()
    {
      Alloc a;
      try
	{
	  (void) a.allocate(__gnu_test::max_size(a) + 1);
	}
      catch(std::bad_alloc&)
	{
	  return true;
	}
      catch(...)
	{
	  throw;
	}
      throw;
    }
#endif

  // A simple allocator which can be constructed endowed of a given
  // "personality" (an integer), queried in operator== to simulate the
  // behavior of realworld "unequal" allocators (i.e., not exploiting
  // the provision in 20.1.5/4, first bullet).  A global unordered_map,
  // filled at allocation time with (pointer, personality) pairs, is
  // then consulted to enforce the requirements in Table 32 about
  // deallocation vs allocator equality.  Note that this allocator is
  // swappable, not copy assignable, consistently with Option 3 of DR 431
  // (see N1599).
  struct uneq_allocator_base
  {
    typedef unord::unordered_map<void*, int>   map_type;

    // Avoid static initialization troubles and/or bad interactions
    // with tests linking testsuite_allocator.o and playing globally
    // with operator new/delete.
    static map_type&
    get_map()
    {
      static map_type alloc_map;
      return alloc_map;
    }
  };

  template<typename Tp, typename Alloc = std::allocator<Tp> >
    class uneq_allocator
    : private uneq_allocator_base,
      public Alloc
    {
      typedef __gnu_cxx::__alloc_traits<Alloc> AllocTraits;

      Alloc& base() { return *this; }
      const Alloc& base() const  { return *this; }
      void swap_base(Alloc& b) { using std::swap; swap(b, this->base()); }

    public:
      typedef typename check_consistent_alloc_value_type<Tp, Alloc>::value_type
	value_type;
      typedef typename AllocTraits::size_type	size_type;
      typedef typename AllocTraits::pointer	pointer;

#if __cplusplus >= 201103L
      typedef std::true_type			propagate_on_container_swap;
      typedef std::false_type			is_always_equal;
#endif

      template<typename Tp1>
	struct rebind
	{
	  typedef uneq_allocator<Tp1,
		typename AllocTraits::template rebind<Tp1>::other> other;
	};

      uneq_allocator() _GLIBCXX_USE_NOEXCEPT
      : personality(0) { }

      uneq_allocator(int person) _GLIBCXX_USE_NOEXCEPT
      : personality(person) { }

#if __cplusplus >= 201103L
      uneq_allocator(const uneq_allocator&) = default;
      uneq_allocator(uneq_allocator&&) = default;
#endif

      template<typename Tp1>
	uneq_allocator(const uneq_allocator<Tp1,
		       typename AllocTraits::template rebind<Tp1>::other>& b)
	_GLIBCXX_USE_NOEXCEPT
	: personality(b.get_personality()) { }

      ~uneq_allocator() _GLIBCXX_USE_NOEXCEPT
      { }

      int get_personality() const { return personality; }

      pointer
      allocate(size_type n, const void* = 0)
      {
	pointer p = AllocTraits::allocate(*this, n);

	try
	  {
	    get_map().insert(map_type::value_type(reinterpret_cast<void*>(p),
						  personality));
	  }
	catch(...)
	  {
	    AllocTraits::deallocate(*this, p, n);
	    __throw_exception_again;
	  }

	return p;
      }

      void
      deallocate(pointer p, size_type n)
      {
	VERIFY( p );

	map_type::iterator it = get_map().find(reinterpret_cast<void*>(p));
	VERIFY( it != get_map().end() );

	// Enforce requirements in Table 32 about deallocation vs
	// allocator equality.
	VERIFY( it->second == personality );

	get_map().erase(it);
	AllocTraits::deallocate(*this, p, n);
      }

#if __cplusplus >= 201103L
      // Not copy assignable...
      uneq_allocator&
      operator=(const uneq_allocator&) = delete;

      // ... but still moveable if base allocator is.
      uneq_allocator&
      operator=(uneq_allocator&&) = default;
#else
    private:
      // Not assignable...
      uneq_allocator&
      operator=(const uneq_allocator&);
#endif

    private:
      // ... yet swappable!
      friend inline void
      swap(uneq_allocator& a, uneq_allocator& b)
      {
	std::swap(a.personality, b.personality);
	a.swap_base(b);
      }

      template<typename Tp1>
	friend inline bool
	operator==(const uneq_allocator& a,
		   const uneq_allocator<Tp1,
		   typename AllocTraits::template rebind<Tp1>::other>& b)
	{ return a.personality == b.get_personality(); }

      template<typename Tp1>
	friend inline bool
	operator!=(const uneq_allocator& a,
		   const uneq_allocator<Tp1,
		   typename AllocTraits::template rebind<Tp1>::other>& b)
	{ return !(a == b); }

      int personality;
    };

#if __cplusplus >= 201103L
  // An uneq_allocator which can be used to test allocator propagation.
  template<typename Tp, bool Propagate, typename Alloc = std::allocator<Tp>>
    class propagating_allocator : public uneq_allocator<Tp, Alloc>
    {
      typedef __gnu_cxx::__alloc_traits<Alloc> AllocTraits;

      typedef uneq_allocator<Tp, Alloc> base_alloc;
      base_alloc& base() { return *this; }
      const base_alloc& base() const  { return *this; }
      void swap_base(base_alloc& b) { swap(b, this->base()); }

      typedef std::integral_constant<bool, Propagate> trait_type;

    public:
      // default allocator_traits::rebind_alloc would select
      // uneq_allocator::rebind so we must define rebind here
      template<typename Up>
	struct rebind
	{
	  typedef propagating_allocator<Up, Propagate,
		typename AllocTraits::template rebind<Up>::other> other;
	};

      propagating_allocator(int i) noexcept
      : base_alloc(i)
      { }

      template<typename Up>
	propagating_allocator(const propagating_allocator<Up, Propagate,
			      typename AllocTraits::template rebind<Up>::other>& a)
	noexcept
	: base_alloc(a)
	{ }

      propagating_allocator() noexcept = default;

      propagating_allocator(const propagating_allocator&) noexcept = default;

      propagating_allocator&
      operator=(const propagating_allocator& a) noexcept
      {
	static_assert(Propagate, "assigning propagating_allocator<T, true>");
	propagating_allocator(a).swap_base(*this);
	return *this;
      }

      template<bool P2>
	propagating_allocator&
	operator=(const propagating_allocator<Tp, P2, Alloc>& a) noexcept
  	{
	  static_assert(P2, "assigning propagating_allocator<T, true>");
	  propagating_allocator(a).swap_base(*this);
	  return *this;
  	}

      // postcondition: LWG2593 a.get_personality() un-changed.
      propagating_allocator(propagating_allocator&& a) noexcept
      : base_alloc(std::move(a.base()))
      { }

      // postcondition: LWG2593 a.get_personality() un-changed
      propagating_allocator&
      operator=(propagating_allocator&& a) noexcept
      {
	propagating_allocator(std::move(a)).swap_base(*this);
	return *this;
      }

      typedef trait_type propagate_on_container_copy_assignment;
      typedef trait_type propagate_on_container_move_assignment;
      typedef trait_type propagate_on_container_swap;

      propagating_allocator select_on_container_copy_construction() const
      { return Propagate ? *this : propagating_allocator(); }
    };

  // Class template supporting the minimal interface that satisfies the
  // Allocator requirements, from example in [allocator.requirements]
  template <class Tp>
    struct SimpleAllocator
    {
      typedef Tp value_type;

      constexpr SimpleAllocator() noexcept { }

      template <class T>
        SimpleAllocator(const SimpleAllocator<T>&) { }

      Tp *allocate(std::size_t n)
      { return std::allocator<Tp>().allocate(n); }

      void deallocate(Tp *p, std::size_t n)
      { std::allocator<Tp>().deallocate(p, n); }
    };

  template <class T, class U>
    bool operator==(const SimpleAllocator<T>&, const SimpleAllocator<U>&)
    { return true; }
  template <class T, class U>
    bool operator!=(const SimpleAllocator<T>&, const SimpleAllocator<U>&)
    { return false; }

  template<typename T>
    struct default_init_allocator
    {
      using value_type = T;

      default_init_allocator() = default;

      template<typename U>
        default_init_allocator(const default_init_allocator<U>& a)
	  : state(a.state)
        { }

      T*
      allocate(std::size_t n)
      { return std::allocator<T>().allocate(n); }

      void
      deallocate(T* p, std::size_t n)
      { std::allocator<T>().deallocate(p, n); }

      int state;
    };

  template<typename T, typename U>
    bool operator==(const default_init_allocator<T>& t,
		    const default_init_allocator<U>& u)
    { return t.state == u.state; }

  template<typename T, typename U>
    bool operator!=(const default_init_allocator<T>& t,
		    const default_init_allocator<U>& u)
    { return !(t == u); }
#endif

  template<typename Tp>
    struct ExplicitConsAlloc : std::allocator<Tp>
    {
      ExplicitConsAlloc() { }

      template<typename Up>
        explicit
        ExplicitConsAlloc(const ExplicitConsAlloc<Up>&) { }

      template<typename Up>
        struct rebind
        { typedef ExplicitConsAlloc<Up> other; };
    };

#if __cplusplus >= 201103L
  template<typename Tp>
    class CustomPointerAlloc : public std::allocator<Tp>
    {
      template<typename Up, typename Sp = __gnu_cxx::_Std_pointer_impl<Up>>
	using Ptr =  __gnu_cxx::_Pointer_adapter<Sp>;

    public:
      CustomPointerAlloc() = default;

      template<typename Up>
        CustomPointerAlloc(const CustomPointerAlloc<Up>&) { }

      template<typename Up>
        struct rebind
        { typedef CustomPointerAlloc<Up> other; };

      typedef Ptr<Tp> 		pointer;
      typedef Ptr<const Tp>	const_pointer;
      typedef Ptr<void>		void_pointer;
      typedef Ptr<const void>	const_void_pointer;

      pointer allocate(std::size_t n, const_void_pointer = {})
      { return pointer(std::allocator<Tp>::allocate(n)); }

      void deallocate(pointer p, std::size_t n)
      { std::allocator<Tp>::deallocate(std::addressof(*p), n); }
    };

  // A class type meeting *only* the Cpp17NullablePointer requirements.
  // Can be used as a base class for fancy pointers (like PointerBase, below)
  // or to wrap a built-in pointer type to remove operations not required
  // by the Cpp17NullablePointer requirements (dereference, increment etc.)
  template<typename Ptr>
    struct NullablePointer
    {
      // N.B. default constructor does not initialize value
      NullablePointer() = default;
      NullablePointer(std::nullptr_t) noexcept : value() { }

      explicit operator bool() const noexcept { return value != nullptr; }

      friend inline bool
      operator==(NullablePointer lhs, NullablePointer rhs) noexcept
      { return lhs.value == rhs.value; }

      friend inline bool
      operator!=(NullablePointer lhs, NullablePointer rhs) noexcept
      { return lhs.value != rhs.value; }

    protected:
      explicit NullablePointer(Ptr p) noexcept : value(p) { }
      Ptr value;
    };

  // NullablePointer<void> is an empty type that models Cpp17NullablePointer.
  template<>
    struct NullablePointer<void>
    {
      NullablePointer() = default;
      NullablePointer(std::nullptr_t) noexcept { }
      explicit NullablePointer(const volatile void*) noexcept { }

      explicit operator bool() const noexcept { return false; }

      friend inline bool
      operator==(NullablePointer, NullablePointer) noexcept
      { return true; }

      friend inline bool
      operator!=(NullablePointer, NullablePointer) noexcept
      { return false; }
    };

  // Utility for use as CRTP base class of custom pointer types
  template<typename Derived, typename T>
    struct PointerBase : NullablePointer<T*>
    {
      typedef T element_type;

      // typedefs for iterator_traits
      typedef T value_type;
      typedef std::ptrdiff_t difference_type;
      typedef std::random_access_iterator_tag iterator_category;
      typedef Derived pointer;
      typedef T& reference;

      using NullablePointer<T*>::NullablePointer;

      // Public (but explicit) constructor from raw pointer:
      explicit PointerBase(T* p) noexcept : NullablePointer<T*>(p) { }

      template<typename D, typename U,
	       typename = decltype(static_cast<T*>(std::declval<U*>()))>
	PointerBase(const PointerBase<D, U>& p)
	: NullablePointer<T*>(p.operator->()) { }

      T& operator*() const { return *this->value; }
      T* operator->() const { return this->value; }
      T& operator[](difference_type n) const { return this->value[n]; }

      Derived& operator++() { ++this->value; return derived(); }
      Derived& operator--() { --this->value; return derived(); }

      Derived operator++(int) { return Derived(this->value++); }

      Derived operator--(int) { return Derived(this->value--); }

      Derived& operator+=(difference_type n)
      {
	this->value += n;
	return derived();
      }

      Derived& operator-=(difference_type n)
      {
	this->value -= n;
	return derived();
      }

      Derived
      operator+(difference_type n) const
      {
	Derived p(derived());
	return p += n;
      }

      Derived
      operator-(difference_type n) const
      {
	Derived p(derived());
	return p -= n;
      }

    private:
      friend std::ptrdiff_t operator-(PointerBase l, PointerBase r)
      { return l.value - r.value; }

      friend bool operator<(PointerBase l, PointerBase r)
      { return l.value < r.value; }
      friend bool operator>(PointerBase l, PointerBase r)
      { return l.value > r.value; }
      friend bool operator<=(PointerBase l, PointerBase r)
      { return l.value <= r.value; }
      friend bool operator>=(PointerBase l, PointerBase r)
      { return l.value >= r.value; }

      Derived&
      derived() { return static_cast<Derived&>(*this); }

      const Derived&
      derived() const { return static_cast<const Derived&>(*this); }
    };

  // implementation for pointer-to-void specializations
  template<typename T>
    struct PointerBase_void : NullablePointer<T*>
    {
      typedef T element_type;

      // typedefs for iterator_traits
      typedef T value_type;
      typedef std::ptrdiff_t difference_type;
      typedef std::random_access_iterator_tag iterator_category;

      using NullablePointer<T*>::NullablePointer;

      T* operator->() const { return this->value; }

      template<typename D, typename U,
	       typename = decltype(static_cast<T*>(std::declval<U*>()))>
	PointerBase_void(const PointerBase<D, U>& p)
	: NullablePointer<T*>(p.operator->()) { }
    };

  template<typename Derived>
    struct PointerBase<Derived, void> : PointerBase_void<void>
    {
      using PointerBase_void::PointerBase_void;
      typedef Derived pointer;
    };

  template<typename Derived>
    struct PointerBase<Derived, const void> : PointerBase_void<const void>
    {
      using PointerBase_void::PointerBase_void;
      typedef Derived pointer;
    };
#endif // C++11

#if __cplusplus >= 201703L
#if __cpp_aligned_new
  // A concrete memory_resource, with error checking.
  class memory_resource : public std::pmr::memory_resource
  {
  public:
    memory_resource()
    : lists(new allocation_lists)
    { }

    memory_resource(const memory_resource& r) noexcept
    : lists(r.lists)
    { lists->refcount++; }

    memory_resource& operator=(const memory_resource&) = delete;

    ~memory_resource()
    {
      if (lists->refcount-- == 1)
	delete lists;  // last one out turns out the lights
    }

    struct bad_size { };
    struct bad_alignment { };
    struct bad_address { };

    // Deallocate everything (moving the tracking info to the freed list)
    void
    deallocate_everything()
    {
      while (lists->active)
	{
	  auto a = lists->active;
	  // Intentionally virtual dispatch, to inform derived classes:
	  this->do_deallocate(a->p, a->bytes, a->alignment);
	}
    }

    // Clear the freed list
    void
    forget_freed_allocations()
    { lists->forget_allocations(lists->freed); }

    // Count how many allocations have been done and not freed.
    std::size_t
    number_of_active_allocations() const noexcept
    {
      std::size_t n = 0;
      for (auto a = lists->active; a != nullptr; a = a->next)
	++n;
      return n;
    }

  protected:
    void*
    do_allocate(std::size_t bytes, std::size_t alignment) override
    {
      // TODO perform a single allocation and put the allocation struct
      // in the buffer using placement new? It means deallocation won't
      // actually return memory to the OS, as it will stay in lists->freed.
      //
      // TODO adjust the returned pointer to be minimally aligned?
      // e.g. if alignment==1 don't return something aligned to 2 bytes.
      // Maybe not worth it, at least monotonic_buffer_resource will
      // never ask upstream for anything with small alignment.
      void* p = ::operator new(bytes, std::align_val_t(alignment));
      lists->active = new allocation{p, bytes, alignment, lists->active};
      return p;
    }

    void
    do_deallocate(void* p, std::size_t bytes, std::size_t alignment) override
    {
      allocation** aptr = &lists->active;
      while (*aptr)
	{
	  allocation* a = *aptr;
	  if (p == a->p)
	    {
	      if (bytes != a->bytes)
		_S_throw<bad_size>();
	      if (alignment != a->alignment)
		_S_throw<bad_alignment>();
#if __cpp_sized_deallocation
	      ::operator delete(p, bytes, std::align_val_t(alignment));
#else
	      ::operator delete(p, std::align_val_t(alignment));
#endif
	      *aptr = a->next;
	      a->next = lists->freed;
	      lists->freed = a;
	      return;
	    }
	  aptr = &a->next;
	}
      _S_throw<bad_address>();
    }

    bool
    do_is_equal(const std::pmr::memory_resource& r) const noexcept override
    {
#if __cpp_rtti
      // Equality is determined by sharing the same allocation_lists object.
      if (auto p = dynamic_cast<const memory_resource*>(&r))
	return p->lists == lists;
#else
      if (this == &r) // Is this the best we can do without RTTI?
	return true;
#endif
      return false;
    }

  private:
    template<typename E>
      static void
      _S_throw()
      {
#if __cpp_exceptions
	throw E();
#else
	__builtin_abort();
#endif
      }

    struct allocation
    {
      void* p;
      std::size_t bytes;
      std::size_t alignment;
      allocation* next;
    };

    // Maintain list of allocated blocks and list of freed blocks.
    // Copies of this memory_resource share the same ref-counted lists.
    struct allocation_lists
    {
      unsigned refcount = 1;
      allocation* active = nullptr;
      allocation* freed = nullptr;

      void forget_allocations(allocation*& list)
      {
	while (list)
	  {
	    auto p = list;
	    list = list->next;
	    delete p;
	  }
      }

      ~allocation_lists()
      {
	forget_allocations(active); // Anything in this list is a leak!
	forget_allocations(freed);
      }
    };

    allocation_lists* lists;
  };
#endif // aligned-new

  // Set the default resource, and restore the previous one on destruction.
  struct default_resource_mgr
  {
    explicit default_resource_mgr(std::pmr::memory_resource* r)
    : prev(std::pmr::set_default_resource(r))
    { }

    ~default_resource_mgr()
    { std::pmr::set_default_resource(prev); }

    std::pmr::memory_resource* prev;
  };

#endif // C++17

} // namespace __gnu_test

#endif // _GLIBCXX_TESTSUITE_ALLOCATOR_H
