// <experimental/memory_resource> -*- C++ -*-
-// Copyright (C) 2015-2021 Free Software Foundation, Inc.
+// Copyright (C) 2015-2024 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
#pragma GCC system_header
+#include <bits/requires_hosted.h> // experimental is currently omitted
+
#if __cplusplus >= 201402L
#include <memory> // align, uses_allocator, __uses_alloc
#include <bits/new_allocator.h>
#include <debug/assertions.h>
-/// @cond
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp> class malloc_allocator;
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace __gnu_cxx
-/// @endcond
namespace std {
_GLIBCXX_BEGIN_NAMESPACE_VERSION
allocator_type get_allocator() const noexcept { return _M_alloc; }
protected:
+#if (defined __sun__ || defined __VXWORKS__) && defined __i386__
+// Cannot use max_align_t on 32-bit Solaris x86, see PR libstdc++/77691
+# define _GLIBCXX_MAX_ALIGN_MATCHES_MALLOC 0
+#elif defined __hpux__ && defined __hppa__ && defined __LP64__
+// Ignore inconsistent long double and malloc alignment (libstdc++/77691)
+# define _GLIBCXX_MAX_ALIGN_MATCHES_MALLOC 0
+#else
+# define _GLIBCXX_MAX_ALIGN_MATCHES_MALLOC 1
+#endif
+
virtual void*
do_allocate(size_t __bytes, size_t __alignment) override
{
- // Cannot use max_align_t on 32-bit Solaris x86, see PR libstdc++/77691
-#if ! ((defined __sun__ || defined __VXWORKS__) && defined __i386__)
+#if _GLIBCXX_MAX_ALIGN_MATCHES_MALLOC
if (__alignment == alignof(max_align_t))
return _M_allocate<alignof(max_align_t)>(__bytes);
#endif
do_deallocate(void* __ptr, size_t __bytes, size_t __alignment) noexcept
override
{
-#if ! ((defined __sun__ || defined __VXWORKS__) && defined __i386__)
+#if _GLIBCXX_MAX_ALIGN_MATCHES_MALLOC
if (__alignment == alignof(max_align_t))
return (void) _M_deallocate<alignof(max_align_t)>(__ptr, __bytes);
#endif
virtual bool
do_is_equal(const memory_resource& __other) const noexcept override
{
+#if __cpp_rtti
if (auto __p = dynamic_cast<const __resource_adaptor_imp*>(&__other))
return _M_alloc == __p->_M_alloc;
+#else
+ if (this == &__other) // Need RTTI to do better than this.
+ return true;
+#endif
return false;
}
// The default memory resource
/// @cond undocumented
- inline std::atomic<memory_resource*>&
+ inline auto&
__get_default_resource()
{
+#ifndef _GLIBCXX_HAS_GTHREADS
+ struct type {
+ using value_type = memory_resource*;
+ explicit type(value_type __r) : _M_r(__r) { }
+ value_type _M_r;
+ value_type load() const { return _M_r; }
+ value_type exchange(value_type __r) { return std::__exchange(_M_r, __r); }
+ };
+#else
using type = atomic<memory_resource*>;
+#endif
alignas(type) static unsigned char __buf[sizeof(type)];
static type* __r = new(__buf) type(new_delete_resource());
return *__r;