Add initial version of C++17 <memory_resource> header
This is missing the synchronized_pool_resource and unsynchronized_pool_resource classes but is otherwise complete. This is a new implementation, not based on the existing code in <experimental/memory_resource>, but memory_resource and polymorphic_allocator ended up looking almost the same anyway. The constant_init kluge in src/c++17/memory_resource.cc is apparently due to Richard Smith and ensures that the objects are constructed during constant initialiation phase and not destroyed (because the constant_init destructor doesn't destroy the union member and the storage is not reused). * config/abi/pre/gnu.ver: Export new symbols. * configure: Regenerate. * include/Makefile.am: Add new <memory_resource> header. * include/Makefile.in: Regenerate. * include/precompiled/stdc++.h: Include <memory_resource> for C++17. * include/std/memory_resource: New header. (memory_resource, polymorphic_allocator, new_delete_resource) (null_memory_resource, set_default_resource, get_default_resource) (pool_options, monotonic_buffer_resource): Define. * src/Makefile.am: Add c++17 directory. * src/Makefile.in: Regenerate. * src/c++11/Makefile.am: Fix comment. * src/c++17/Makefile.am: Add makefile for new sub-directory. * src/c++17/Makefile.in: Generate. * src/c++17/memory_resource.cc: New. (newdel_res_t, null_res_t, constant_init, newdel_res, null_res) (default_res, new_delete_resource, null_memory_resource) (set_default_resource, get_default_resource): Define. * testsuite/20_util/memory_resource/1.cc: New test. * testsuite/20_util/memory_resource/2.cc: New test. * testsuite/20_util/monotonic_buffer_resource/1.cc: New test. * testsuite/20_util/monotonic_buffer_resource/allocate.cc: New test. * testsuite/20_util/monotonic_buffer_resource/deallocate.cc: New test. * testsuite/20_util/monotonic_buffer_resource/release.cc: New test. * testsuite/20_util/monotonic_buffer_resource/upstream_resource.cc: New test. * testsuite/20_util/polymorphic_allocator/1.cc: New test. * testsuite/20_util/polymorphic_allocator/resource.cc: New test. * testsuite/20_util/polymorphic_allocator/select.cc: New test. * testsuite/util/testsuite_allocator.h (__gnu_test::memory_resource): Define concrete memory resource for testing. (__gnu_test::default_resource_mgr): Define RAII helper for changing default resource. From-SVN: r262953
This commit is contained in:
parent
e874029dd9
commit
dfaa3c47cc
|
@ -1,5 +1,39 @@
|
|||
2018-07-24 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
* config/abi/pre/gnu.ver: Export new symbols.
|
||||
* configure: Regenerate.
|
||||
* include/Makefile.am: Add new <memory_resource> header.
|
||||
* include/Makefile.in: Regenerate.
|
||||
* include/precompiled/stdc++.h: Include <memory_resource> for C++17.
|
||||
* include/std/memory_resource: New header.
|
||||
(memory_resource, polymorphic_allocator, new_delete_resource)
|
||||
(null_memory_resource, set_default_resource, get_default_resource)
|
||||
(pool_options, monotonic_buffer_resource): Define.
|
||||
* src/Makefile.am: Add c++17 directory.
|
||||
* src/Makefile.in: Regenerate.
|
||||
* src/c++11/Makefile.am: Fix comment.
|
||||
* src/c++17/Makefile.am: Add makefile for new sub-directory.
|
||||
* src/c++17/Makefile.in: Generate.
|
||||
* src/c++17/memory_resource.cc: New.
|
||||
(newdel_res_t, null_res_t, constant_init, newdel_res, null_res)
|
||||
(default_res, new_delete_resource, null_memory_resource)
|
||||
(set_default_resource, get_default_resource): Define.
|
||||
* testsuite/20_util/memory_resource/1.cc: New test.
|
||||
* testsuite/20_util/memory_resource/2.cc: New test.
|
||||
* testsuite/20_util/monotonic_buffer_resource/1.cc: New test.
|
||||
* testsuite/20_util/monotonic_buffer_resource/allocate.cc: New test.
|
||||
* testsuite/20_util/monotonic_buffer_resource/deallocate.cc: New test.
|
||||
* testsuite/20_util/monotonic_buffer_resource/release.cc: New test.
|
||||
* testsuite/20_util/monotonic_buffer_resource/upstream_resource.cc:
|
||||
New test.
|
||||
* testsuite/20_util/polymorphic_allocator/1.cc: New test.
|
||||
* testsuite/20_util/polymorphic_allocator/resource.cc: New test.
|
||||
* testsuite/20_util/polymorphic_allocator/select.cc: New test.
|
||||
* testsuite/util/testsuite_allocator.h (__gnu_test::memory_resource):
|
||||
Define concrete memory resource for testing.
|
||||
(__gnu_test::default_resource_mgr): Define RAII helper for changing
|
||||
default resource.
|
||||
|
||||
PR libstdc++/86658
|
||||
* include/bits/stl_algobase.h (__niter_wrap<_Iterator>): Pass unused
|
||||
parameter by reference, to avoid copying invalid iterators.
|
||||
|
|
|
@ -2039,6 +2039,11 @@ GLIBCXX_3.4.26 {
|
|||
_ZNSt7__cxx1118basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]Ev;
|
||||
_ZNSt7__cxx1119basic_[io]stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]Ev;
|
||||
|
||||
_ZNSt3pmr19new_delete_resourceEv;
|
||||
_ZNSt3pmr20null_memory_resourceEv;
|
||||
_ZNSt3pmr20get_default_resourceEv;
|
||||
_ZNSt3pmr20set_default_resourceEPNS_15memory_resourceE;
|
||||
|
||||
} GLIBCXX_3.4.25;
|
||||
|
||||
# Symbols in the support library (libsupc++) have their own tag.
|
||||
|
|
|
@ -4965,7 +4965,7 @@ $as_echo "$ac_cv_path_EGREP" >&6; }
|
|||
# expandable list at autoconf time; the second provides an expandable list
|
||||
# (i.e., shell variable) at configure time.
|
||||
|
||||
SUBDIRS='include libsupc++ src src/c++98 src/c++11 src/filesystem doc po testsuite python'
|
||||
SUBDIRS='include libsupc++ src src/c++98 src/c++11 src/c++17 src/filesystem doc po testsuite python'
|
||||
|
||||
# These need to be absolute paths, yet at the same time need to
|
||||
# canonicalize only relative paths, because then amd will not unmount
|
||||
|
@ -81841,7 +81841,7 @@ ac_config_files="$ac_config_files doc/xsl/customization.xsl"
|
|||
# append it here. Only modify Makefiles that have just been created.
|
||||
#
|
||||
# Also, get rid of this simulated-VPATH thing that automake does.
|
||||
ac_config_files="$ac_config_files include/Makefile libsupc++/Makefile src/Makefile src/c++98/Makefile src/c++11/Makefile src/filesystem/Makefile doc/Makefile po/Makefile testsuite/Makefile python/Makefile"
|
||||
ac_config_files="$ac_config_files include/Makefile libsupc++/Makefile src/Makefile src/c++98/Makefile src/c++11/Makefile src/c++17/Makefile src/filesystem/Makefile doc/Makefile po/Makefile testsuite/Makefile python/Makefile"
|
||||
|
||||
|
||||
ac_config_commands="$ac_config_commands generate-headers"
|
||||
|
@ -83076,6 +83076,7 @@ do
|
|||
"src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
|
||||
"src/c++98/Makefile") CONFIG_FILES="$CONFIG_FILES src/c++98/Makefile" ;;
|
||||
"src/c++11/Makefile") CONFIG_FILES="$CONFIG_FILES src/c++11/Makefile" ;;
|
||||
"src/c++17/Makefile") CONFIG_FILES="$CONFIG_FILES src/c++17/Makefile" ;;
|
||||
"src/filesystem/Makefile") CONFIG_FILES="$CONFIG_FILES src/filesystem/Makefile" ;;
|
||||
"doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
|
||||
"po/Makefile") CONFIG_FILES="$CONFIG_FILES po/Makefile" ;;
|
||||
|
@ -84904,6 +84905,17 @@ _EOF
|
|||
;;
|
||||
"src/c++11/Makefile":F) cat > vpsed$$ << \_EOF
|
||||
s!`test -f '$<' || echo '$(srcdir)/'`!!
|
||||
_EOF
|
||||
sed -f vpsed$$ $ac_file > tmp$$
|
||||
mv tmp$$ $ac_file
|
||||
rm vpsed$$
|
||||
echo 'MULTISUBDIR =' >> $ac_file
|
||||
ml_norecursion=yes
|
||||
. ${multi_basedir}/config-ml.in
|
||||
{ ml_norecursion=; unset ml_norecursion;}
|
||||
;;
|
||||
"src/c++17/Makefile":F) cat > vpsed$$ << \_EOF
|
||||
s!`test -f '$<' || echo '$(srcdir)/'`!!
|
||||
_EOF
|
||||
sed -f vpsed$$ $ac_file > tmp$$
|
||||
mv tmp$$ $ac_file
|
||||
|
|
|
@ -54,6 +54,7 @@ std_headers = \
|
|||
${std_srcdir}/locale \
|
||||
${std_srcdir}/map \
|
||||
${std_srcdir}/memory \
|
||||
${std_srcdir}/memory_resource \
|
||||
${std_srcdir}/mutex \
|
||||
${std_srcdir}/numeric \
|
||||
${std_srcdir}/optional \
|
||||
|
|
|
@ -347,6 +347,7 @@ std_headers = \
|
|||
${std_srcdir}/locale \
|
||||
${std_srcdir}/map \
|
||||
${std_srcdir}/memory \
|
||||
${std_srcdir}/memory_resource \
|
||||
${std_srcdir}/mutex \
|
||||
${std_srcdir}/numeric \
|
||||
${std_srcdir}/optional \
|
||||
|
|
|
@ -128,7 +128,7 @@
|
|||
// #include <execution>
|
||||
#include <filesystem>
|
||||
#include <optional>
|
||||
// #include <memory_resource>
|
||||
#include <memory_resource>
|
||||
#include <string_view>
|
||||
#include <variant>
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,510 @@
|
|||
// <memory_resource> -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2018 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file include/memory_resource
|
||||
* This is a Standard C++ Library header.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_MEMORY_RESOURCE
|
||||
#define _GLIBCXX_MEMORY_RESOURCE 1
|
||||
|
||||
#pragma GCC system_header
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
|
||||
#include <bit> // __ceil2, __log2p1
|
||||
#include <memory> // align, allocator_arg_t, __uses_alloc
|
||||
#include <utility> // pair, index_sequence
|
||||
#include <cstddef> // size_t, max_align_t
|
||||
#include <debug/assertions.h>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
namespace pmr
|
||||
{
|
||||
// #define __cpp_lib_memory_resource 201603
|
||||
|
||||
class memory_resource;
|
||||
|
||||
template<typename _Tp>
|
||||
class polymorphic_allocator;
|
||||
|
||||
// Global memory resources
|
||||
memory_resource* new_delete_resource() noexcept;
|
||||
memory_resource* null_memory_resource() noexcept;
|
||||
memory_resource* set_default_resource(memory_resource* __r) noexcept;
|
||||
memory_resource* get_default_resource() noexcept
|
||||
__attribute__((__returns_nonnull__));
|
||||
|
||||
// Pool resource classes
|
||||
struct pool_options;
|
||||
class synchronized_pool_resource;
|
||||
class unsynchronized_pool_resource;
|
||||
class monotonic_buffer_resource;
|
||||
|
||||
/// Class memory_resource
|
||||
class memory_resource
|
||||
{
|
||||
static constexpr size_t _S_max_align = alignof(max_align_t);
|
||||
|
||||
public:
|
||||
memory_resource() = default;
|
||||
memory_resource(const memory_resource&) = default;
|
||||
virtual ~memory_resource() = default;
|
||||
|
||||
memory_resource& operator=(const memory_resource&) = default;
|
||||
|
||||
[[nodiscard]]
|
||||
void*
|
||||
allocate(size_t __bytes, size_t __alignment = _S_max_align)
|
||||
__attribute__((__returns_nonnull__,__alloc_size__(2),__alloc_align__(3)))
|
||||
{ return do_allocate(__bytes, __alignment); }
|
||||
|
||||
void
|
||||
deallocate(void* __p, size_t __bytes, size_t __alignment = _S_max_align)
|
||||
__attribute__((__nonnull__))
|
||||
{ return do_deallocate(__p, __bytes, __alignment); }
|
||||
|
||||
bool
|
||||
is_equal(const memory_resource& __other) const noexcept
|
||||
{ return do_is_equal(__other); }
|
||||
|
||||
private:
|
||||
virtual void*
|
||||
do_allocate(size_t __bytes, size_t __alignment) = 0;
|
||||
|
||||
virtual void
|
||||
do_deallocate(void* __p, size_t __bytes, size_t __alignment) = 0;
|
||||
|
||||
virtual bool
|
||||
do_is_equal(const memory_resource& __other) const noexcept = 0;
|
||||
};
|
||||
|
||||
inline bool
|
||||
operator==(const memory_resource& __a, const memory_resource& __b) noexcept
|
||||
{ return &__a == &__b || __a.is_equal(__b); }
|
||||
|
||||
inline bool
|
||||
operator!=(const memory_resource& __a, const memory_resource& __b) noexcept
|
||||
{ return !(__a == __b); }
|
||||
|
||||
|
||||
// C++17 23.12.3 Class template polymorphic_allocator
|
||||
template<typename _Tp>
|
||||
class polymorphic_allocator
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 2975. Missing case for pair construction in polymorphic allocators
|
||||
template<typename _Up>
|
||||
struct __not_pair { using type = void; };
|
||||
|
||||
template<typename _Up1, typename _Up2>
|
||||
struct __not_pair<pair<_Up1, _Up2>> { };
|
||||
|
||||
public:
|
||||
using value_type = _Tp;
|
||||
|
||||
polymorphic_allocator() noexcept
|
||||
: _M_resource(get_default_resource())
|
||||
{ }
|
||||
|
||||
polymorphic_allocator(memory_resource* __r) noexcept
|
||||
__attribute__((__nonnull__))
|
||||
: _M_resource(__r)
|
||||
{ _GLIBCXX_DEBUG_ASSERT(__r); }
|
||||
|
||||
polymorphic_allocator(const polymorphic_allocator& __other) = default;
|
||||
|
||||
template<typename _Up>
|
||||
polymorphic_allocator(const polymorphic_allocator<_Up>& __x) noexcept
|
||||
: _M_resource(__x.resource())
|
||||
{ }
|
||||
|
||||
polymorphic_allocator&
|
||||
operator=(const polymorphic_allocator&) = delete;
|
||||
|
||||
[[nodiscard]]
|
||||
_Tp*
|
||||
allocate(size_t __n)
|
||||
__attribute__((__returns_nonnull__))
|
||||
{
|
||||
if (__n > (numeric_limits<size_t>::max() / sizeof(_Tp)))
|
||||
std::__throw_bad_alloc();
|
||||
return static_cast<_Tp*>(_M_resource->allocate(__n * sizeof(_Tp),
|
||||
alignof(_Tp)));
|
||||
}
|
||||
|
||||
void
|
||||
deallocate(_Tp* __p, size_t __n) noexcept
|
||||
__attribute__((__nonnull__))
|
||||
{ _M_resource->deallocate(__p, __n * sizeof(_Tp), alignof(_Tp)); }
|
||||
|
||||
template<typename _Tp1, typename... _Args>
|
||||
__attribute__((__nonnull__))
|
||||
typename __not_pair<_Tp>::type
|
||||
construct(_Tp1* __p, _Args&&... __args)
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 2969. polymorphic_allocator::construct() shouldn't pass resource()
|
||||
auto __use_tag
|
||||
= __use_alloc<_Tp1, polymorphic_allocator, _Args...>(*this);
|
||||
_S_construct(__use_tag, __p, std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
template<typename _Tp1, typename _Tp2,
|
||||
typename... _Args1, typename... _Args2>
|
||||
__attribute__((__nonnull__))
|
||||
void
|
||||
construct(pair<_Tp1, _Tp2>* __p, piecewise_construct_t,
|
||||
tuple<_Args1...> __x, tuple<_Args2...> __y)
|
||||
{
|
||||
auto __x_tag =
|
||||
__use_alloc<_Tp1, polymorphic_allocator, _Args1...>(*this);
|
||||
auto __y_tag =
|
||||
__use_alloc<_Tp2, polymorphic_allocator, _Args2...>(*this);
|
||||
index_sequence_for<_Args1...> __x_i;
|
||||
index_sequence_for<_Args2...> __y_i;
|
||||
|
||||
::new(__p) pair<_Tp1, _Tp2>(piecewise_construct,
|
||||
_S_construct_p(__x_tag, __x, __x_i),
|
||||
_S_construct_p(__y_tag, __y, __y_i));
|
||||
}
|
||||
|
||||
template<typename _Tp1, typename _Tp2>
|
||||
__attribute__((__nonnull__))
|
||||
void
|
||||
construct(pair<_Tp1, _Tp2>* __p)
|
||||
{ this->construct(__p, piecewise_construct, tuple<>(), tuple<>()); }
|
||||
|
||||
template<typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
|
||||
__attribute__((__nonnull__))
|
||||
void
|
||||
construct(pair<_Tp1, _Tp2>* __p, _Up&& __x, _Vp&& __y)
|
||||
{
|
||||
this->construct(__p, piecewise_construct,
|
||||
forward_as_tuple(std::forward<_Up>(__x)),
|
||||
forward_as_tuple(std::forward<_Vp>(__y)));
|
||||
}
|
||||
|
||||
template <typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
|
||||
__attribute__((__nonnull__))
|
||||
void
|
||||
construct(pair<_Tp1, _Tp2>* __p, const std::pair<_Up, _Vp>& __pr)
|
||||
{
|
||||
this->construct(__p, piecewise_construct,
|
||||
forward_as_tuple(__pr.first),
|
||||
forward_as_tuple(__pr.second));
|
||||
}
|
||||
|
||||
template<typename _Tp1, typename _Tp2, typename _Up, typename _Vp>
|
||||
__attribute__((__nonnull__))
|
||||
void
|
||||
construct(pair<_Tp1, _Tp2>* __p, pair<_Up, _Vp>&& __pr)
|
||||
{
|
||||
this->construct(__p, piecewise_construct,
|
||||
forward_as_tuple(std::forward<_Up>(__pr.first)),
|
||||
forward_as_tuple(std::forward<_Vp>(__pr.second)));
|
||||
}
|
||||
|
||||
template<typename _Up>
|
||||
__attribute__((__nonnull__))
|
||||
void
|
||||
destroy(_Up* __p)
|
||||
{ __p->~_Up(); }
|
||||
|
||||
polymorphic_allocator
|
||||
select_on_container_copy_construction() const noexcept
|
||||
{ return polymorphic_allocator(); }
|
||||
|
||||
memory_resource*
|
||||
resource() const noexcept
|
||||
__attribute__((__returns_nonnull__))
|
||||
{ return _M_resource; }
|
||||
|
||||
private:
|
||||
using __uses_alloc1_ = __uses_alloc1<polymorphic_allocator>;
|
||||
using __uses_alloc2_ = __uses_alloc2<polymorphic_allocator>;
|
||||
|
||||
template<typename _Tp1, typename... _Args>
|
||||
static void
|
||||
_S_construct(__uses_alloc0, _Tp1* __p, _Args&&... __args)
|
||||
{ ::new(__p) _Tp1(std::forward<_Args>(__args)...); }
|
||||
|
||||
template<typename _Tp1, typename... _Args>
|
||||
static void
|
||||
_S_construct(__uses_alloc1_ __ua, _Tp1* __p, _Args&&... __args)
|
||||
{
|
||||
::new(__p) _Tp1(allocator_arg, *__ua._M_a,
|
||||
std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
template<typename _Tp1, typename... _Args>
|
||||
static void
|
||||
_S_construct(__uses_alloc2_ __ua, _Tp1* __p, _Args&&... __args)
|
||||
{ ::new(__p) _Tp1(std::forward<_Args>(__args)..., *__ua._M_a); }
|
||||
|
||||
template<typename _Ind, typename... _Args>
|
||||
static tuple<_Args&&...>
|
||||
_S_construct_p(__uses_alloc0, _Ind, tuple<_Args...>& __t)
|
||||
{ return std::move(__t); }
|
||||
|
||||
template<size_t... _Ind, typename... _Args>
|
||||
static tuple<allocator_arg_t, polymorphic_allocator&, _Args&&...>
|
||||
_S_construct_p(__uses_alloc1_ __ua, index_sequence<_Ind...>,
|
||||
tuple<_Args...>& __t)
|
||||
{
|
||||
return {
|
||||
allocator_arg, *__ua._M_a, std::get<_Ind>(std::move(__t))...
|
||||
};
|
||||
}
|
||||
|
||||
template<size_t... _Ind, typename... _Args>
|
||||
static tuple<_Args&&..., polymorphic_allocator&>
|
||||
_S_construct_p(__uses_alloc2_ __ua, index_sequence<_Ind...>,
|
||||
tuple<_Args...>& __t)
|
||||
{ return { std::get<_Ind>(std::move(__t))..., *__ua._M_a }; }
|
||||
|
||||
memory_resource* _M_resource;
|
||||
};
|
||||
|
||||
template<typename _Tp1, typename _Tp2>
|
||||
inline bool
|
||||
operator==(const polymorphic_allocator<_Tp1>& __a,
|
||||
const polymorphic_allocator<_Tp2>& __b) noexcept
|
||||
{ return *__a.resource() == *__b.resource(); }
|
||||
|
||||
template<typename _Tp1, typename _Tp2>
|
||||
inline bool
|
||||
operator!=(const polymorphic_allocator<_Tp1>& __a,
|
||||
const polymorphic_allocator<_Tp2>& __b) noexcept
|
||||
{ return !(__a == __b); }
|
||||
|
||||
|
||||
struct pool_options
|
||||
{
|
||||
size_t max_blocks_per_chunk = 0;
|
||||
size_t largest_required_pool_block = 0;
|
||||
};
|
||||
|
||||
// TODO class synchronized_pool_resource;
|
||||
// TODO class unsynchronized_pool_resource;
|
||||
|
||||
class monotonic_buffer_resource : public memory_resource
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
monotonic_buffer_resource(memory_resource* __upstream) noexcept
|
||||
__attribute__((__nonnull__))
|
||||
: _M_upstream(__upstream)
|
||||
{ _GLIBCXX_DEBUG_ASSERT(__upstream != nullptr); }
|
||||
|
||||
monotonic_buffer_resource(size_t __initial_size,
|
||||
memory_resource* __upstream) noexcept
|
||||
__attribute__((__nonnull__))
|
||||
: _M_next_bufsiz(__initial_size),
|
||||
_M_upstream(__upstream)
|
||||
{
|
||||
_GLIBCXX_DEBUG_ASSERT(__upstream != nullptr);
|
||||
_GLIBCXX_DEBUG_ASSERT(__initial_size > 0);
|
||||
}
|
||||
|
||||
monotonic_buffer_resource(void* __buffer, size_t __buffer_size,
|
||||
memory_resource* __upstream) noexcept
|
||||
__attribute__((__nonnull__(4)))
|
||||
: _M_current_buf(__buffer), _M_avail(__buffer_size),
|
||||
_M_next_bufsiz(_S_next_bufsize(__buffer_size)),
|
||||
_M_upstream(__upstream),
|
||||
_M_orig_buf(__buffer), _M_orig_size(__buffer_size)
|
||||
{
|
||||
_GLIBCXX_DEBUG_ASSERT(__upstream != nullptr);
|
||||
_GLIBCXX_DEBUG_ASSERT(__buffer != nullptr || __buffer_size == 0);
|
||||
}
|
||||
|
||||
monotonic_buffer_resource() noexcept
|
||||
: monotonic_buffer_resource(get_default_resource())
|
||||
{ }
|
||||
|
||||
explicit
|
||||
monotonic_buffer_resource(size_t __initial_size) noexcept
|
||||
: monotonic_buffer_resource(__initial_size, get_default_resource())
|
||||
{ }
|
||||
|
||||
monotonic_buffer_resource(void* __buffer, size_t __buffer_size) noexcept
|
||||
: monotonic_buffer_resource(__buffer, __buffer_size, get_default_resource())
|
||||
{ }
|
||||
|
||||
monotonic_buffer_resource(const monotonic_buffer_resource&) = delete;
|
||||
|
||||
virtual ~monotonic_buffer_resource() { release(); }
|
||||
|
||||
monotonic_buffer_resource&
|
||||
operator=(const monotonic_buffer_resource&) = delete;
|
||||
|
||||
void
|
||||
release() noexcept
|
||||
{
|
||||
_Chunk::release(_M_head, _M_upstream);
|
||||
|
||||
// reset to initial state at contruction:
|
||||
if ((_M_current_buf = _M_orig_buf))
|
||||
{
|
||||
_M_avail = _M_orig_size;
|
||||
_M_next_bufsiz = _S_next_bufsize(_M_orig_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
_M_avail = 0;
|
||||
_M_next_bufsiz = _M_orig_size;
|
||||
}
|
||||
}
|
||||
|
||||
memory_resource*
|
||||
upstream_resource() const noexcept
|
||||
__attribute__((__returns_nonnull__))
|
||||
{ return _M_upstream; }
|
||||
|
||||
protected:
|
||||
void*
|
||||
do_allocate(size_t __bytes, size_t __alignment) override
|
||||
{
|
||||
if (__bytes == 0)
|
||||
__bytes = 1; // Ensures we don't return the same pointer twice.
|
||||
|
||||
if (auto __p = std::align(__alignment, __bytes, _M_current_buf, _M_avail))
|
||||
{
|
||||
_M_current_buf = (char*)_M_current_buf + __bytes;
|
||||
_M_avail -= __bytes;
|
||||
return __p;
|
||||
}
|
||||
|
||||
const size_t __n = std::max(__bytes, _M_next_bufsiz);
|
||||
const size_t __m = std::max(__alignment, alignof(std::max_align_t));
|
||||
auto [__p, __size] = _Chunk::allocate(_M_upstream, __n, __m, _M_head);
|
||||
_M_current_buf = (char*)__p + __bytes;
|
||||
_M_avail = __size - __bytes;
|
||||
_M_next_bufsiz *= _S_growth_factor;
|
||||
return __p;
|
||||
}
|
||||
|
||||
void
|
||||
do_deallocate(void*, size_t, size_t) override
|
||||
{ }
|
||||
|
||||
bool
|
||||
do_is_equal(const memory_resource& __other) const noexcept override
|
||||
{ return this == &__other; }
|
||||
|
||||
private:
|
||||
static size_t
|
||||
_S_next_bufsize(size_t __buffer_size) noexcept
|
||||
{
|
||||
if (__buffer_size == 0)
|
||||
__buffer_size = 1;
|
||||
return __buffer_size * _S_growth_factor;
|
||||
}
|
||||
|
||||
static constexpr size_t _S_init_bufsize = 128 * sizeof(void*);
|
||||
static constexpr float _S_growth_factor = 1.5;
|
||||
|
||||
void* _M_current_buf = nullptr;
|
||||
size_t _M_avail = 0;
|
||||
size_t _M_next_bufsiz = _S_init_bufsize;
|
||||
|
||||
// Initial values set at construction and reused by release():
|
||||
memory_resource* const _M_upstream;
|
||||
void* const _M_orig_buf = nullptr;
|
||||
size_t const _M_orig_size = _M_next_bufsiz;
|
||||
|
||||
// Memory allocated by the upstream resource is managed in a linked list
|
||||
// of _Chunk objects. A _Chunk object recording the size and alignment of
|
||||
// the allocated block and a pointer to the previous chunk is placed
|
||||
// at end of the block.
|
||||
class _Chunk
|
||||
{
|
||||
public:
|
||||
// Return the address and size of a block of memory allocated from __r,
|
||||
// of at least __size bytes and aligned to __align.
|
||||
// Add a new _Chunk to the front of the linked list at __head.
|
||||
static pair<void*, size_t>
|
||||
allocate(memory_resource* __r, size_t __size, size_t __align,
|
||||
_Chunk*& __head)
|
||||
{
|
||||
__size = std::__ceil2(__size + sizeof(_Chunk));
|
||||
void* __p = __r->allocate(__size, __align);
|
||||
// Add a chunk defined by (__p, __size, __align) to linked list __head.
|
||||
void* const __back = (char*)__p + __size - sizeof(_Chunk);
|
||||
__head = ::new(__back) _Chunk(__size, __align, __head);
|
||||
return { __p, __size - sizeof(_Chunk) };
|
||||
}
|
||||
|
||||
// Return every chunk in linked list __head to resource __r.
|
||||
static void
|
||||
release(_Chunk*& __head, memory_resource* __r) noexcept
|
||||
{
|
||||
_Chunk* __next = __head;
|
||||
__head = nullptr;
|
||||
while (__next)
|
||||
{
|
||||
_Chunk* __ch = __next;
|
||||
__builtin_memcpy(&__next, __ch->_M_next, sizeof(_Chunk*));
|
||||
|
||||
__glibcxx_assert(__ch->_M_canary != 0);
|
||||
__glibcxx_assert(__ch->_M_canary == (__ch->_M_size|__ch->_M_align));
|
||||
|
||||
if (__ch->_M_canary != (__ch->_M_size | __ch->_M_align))
|
||||
return; // buffer overflow detected!
|
||||
|
||||
size_t __size = (1u << __ch->_M_size);
|
||||
size_t __align = (1u << __ch->_M_align);
|
||||
void* __start = (char*)(__ch + 1) - __size;
|
||||
__r->deallocate(__start, __size, __align);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
_Chunk(size_t __size, size_t __align, _Chunk* __next) noexcept
|
||||
: _M_size(std::__log2p1(__size) - 1),
|
||||
_M_align(std::__log2p1(__align) - 1)
|
||||
{
|
||||
__builtin_memcpy(_M_next, &__next, sizeof(__next));
|
||||
_M_canary = _M_size | _M_align;
|
||||
}
|
||||
|
||||
unsigned char _M_canary;
|
||||
unsigned char _M_size;
|
||||
unsigned char _M_align;
|
||||
unsigned char _M_next[sizeof(_Chunk*)];
|
||||
};
|
||||
static_assert(alignof(_Chunk) == 1);
|
||||
|
||||
_Chunk* _M_head = nullptr;
|
||||
};
|
||||
|
||||
} // namespace pmr
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
|
||||
#endif // C++17
|
||||
#endif // _GLIBCXX_MEMORY_RESOURCE
|
|
@ -28,7 +28,7 @@ else
|
|||
filesystem_dir =
|
||||
endif
|
||||
|
||||
SUBDIRS = c++98 c++11 $(filesystem_dir)
|
||||
SUBDIRS = c++98 c++11 c++17 $(filesystem_dir)
|
||||
|
||||
# Cross compiler support.
|
||||
if VTV_CYGMIN
|
||||
|
@ -58,6 +58,7 @@ endif
|
|||
|
||||
vpath % $(top_srcdir)/src/c++98
|
||||
vpath % $(top_srcdir)/src/c++11
|
||||
vpath % $(top_srcdir)/src/c++17
|
||||
if ENABLE_FILESYSTEM_TS
|
||||
vpath % $(top_srcdir)/src/filesystem
|
||||
endif
|
||||
|
@ -92,13 +93,15 @@ libstdc___la_LIBADD = \
|
|||
$(GLIBCXX_LIBS) \
|
||||
$(top_builddir)/libsupc++/libsupc++convenience.la \
|
||||
$(top_builddir)/src/c++98/libc++98convenience.la \
|
||||
$(top_builddir)/src/c++11/libc++11convenience.la
|
||||
$(top_builddir)/src/c++11/libc++11convenience.la \
|
||||
$(top_builddir)/src/c++17/libc++17convenience.la
|
||||
|
||||
libstdc___la_DEPENDENCIES = \
|
||||
${version_dep} \
|
||||
$(top_builddir)/libsupc++/libsupc++convenience.la \
|
||||
$(top_builddir)/src/c++98/libc++98convenience.la \
|
||||
$(top_builddir)/src/c++11/libc++11convenience.la
|
||||
$(top_builddir)/src/c++11/libc++11convenience.la \
|
||||
$(top_builddir)/src/c++17/libc++17convenience.la
|
||||
|
||||
libstdc___la_LDFLAGS = \
|
||||
-version-info $(libtool_VERSION) ${version_arg} -lm
|
||||
|
@ -148,8 +151,8 @@ compatibility-condvar.o: compatibility-condvar.cc
|
|||
# Thus, the shared libs have more compat symbols, which can be found
|
||||
# segregated in the sources with -D_GLIBCXX_SHARED.
|
||||
#
|
||||
# In the sub-directories of libsupc++, src/c++98, src/c++11, only
|
||||
# -prefer-pic objects are generated for the convenience libraries.
|
||||
# In the sub-directories of libsupc++, src/c++98, src/c++11, src/c++17,
|
||||
# only -prefer-pic objects are generated for the convenience libraries.
|
||||
#
|
||||
# In the main src directory, make shared and static objects just for
|
||||
# the compat libraries. Shared objects are compiled with -prefer-pic
|
||||
|
|
|
@ -152,7 +152,7 @@ AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
|
|||
$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DIST_SUBDIRS = c++98 c++11 filesystem
|
||||
DIST_SUBDIRS = c++98 c++11 c++17 filesystem
|
||||
ABI_TWEAKS_SRCDIR = @ABI_TWEAKS_SRCDIR@
|
||||
ACLOCAL = @ACLOCAL@
|
||||
ALLOCATOR_H = @ALLOCATOR_H@
|
||||
|
@ -379,7 +379,7 @@ WARN_CXXFLAGS = \
|
|||
AM_CPPFLAGS = $(GLIBCXX_INCLUDES) $(CPPFLAGS)
|
||||
@ENABLE_FILESYSTEM_TS_FALSE@filesystem_dir =
|
||||
@ENABLE_FILESYSTEM_TS_TRUE@filesystem_dir = filesystem
|
||||
SUBDIRS = c++98 c++11 $(filesystem_dir)
|
||||
SUBDIRS = c++98 c++11 c++17 $(filesystem_dir)
|
||||
@VTV_CYGMIN_FALSE@toolexeclib_LTLIBRARIES = libstdc++.la
|
||||
|
||||
# Cross compiler support.
|
||||
|
@ -419,13 +419,15 @@ libstdc___la_LIBADD = \
|
|||
$(GLIBCXX_LIBS) \
|
||||
$(top_builddir)/libsupc++/libsupc++convenience.la \
|
||||
$(top_builddir)/src/c++98/libc++98convenience.la \
|
||||
$(top_builddir)/src/c++11/libc++11convenience.la
|
||||
$(top_builddir)/src/c++11/libc++11convenience.la \
|
||||
$(top_builddir)/src/c++17/libc++17convenience.la
|
||||
|
||||
libstdc___la_DEPENDENCIES = \
|
||||
${version_dep} \
|
||||
$(top_builddir)/libsupc++/libsupc++convenience.la \
|
||||
$(top_builddir)/src/c++98/libc++98convenience.la \
|
||||
$(top_builddir)/src/c++11/libc++11convenience.la
|
||||
$(top_builddir)/src/c++11/libc++11convenience.la \
|
||||
$(top_builddir)/src/c++17/libc++17convenience.la
|
||||
|
||||
libstdc___la_LDFLAGS = \
|
||||
-version-info $(libtool_VERSION) ${version_arg} -lm
|
||||
|
@ -440,8 +442,8 @@ libstdc___la_LINK = $(CXXLINK) $(libstdc___la_LDFLAGS)
|
|||
# Thus, the shared libs have more compat symbols, which can be found
|
||||
# segregated in the sources with -D_GLIBCXX_SHARED.
|
||||
#
|
||||
# In the sub-directories of libsupc++, src/c++98, src/c++11, only
|
||||
# -prefer-pic objects are generated for the convenience libraries.
|
||||
# In the sub-directories of libsupc++, src/c++98, src/c++11, src/c++17,
|
||||
# only -prefer-pic objects are generated for the convenience libraries.
|
||||
#
|
||||
# In the main src directory, make shared and static objects just for
|
||||
# the compat libraries. Shared objects are compiled with -prefer-pic
|
||||
|
@ -900,6 +902,7 @@ uninstall-am: uninstall-toolexeclibLTLIBRARIES
|
|||
|
||||
vpath % $(top_srcdir)/src/c++98
|
||||
vpath % $(top_srcdir)/src/c++11
|
||||
vpath % $(top_srcdir)/src/c++17
|
||||
@ENABLE_FILESYSTEM_TS_TRUE@vpath % $(top_srcdir)/src/filesystem
|
||||
|
||||
# Use special rules for compatibility-ldbl.cc compilation, as we need to
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
## Makefile for the C++03 sources of the GNU C++ Standard library.
|
||||
## Makefile for the C++11 sources of the GNU C++ Standard library.
|
||||
##
|
||||
## Copyright (C) 1997-2018 Free Software Foundation, Inc.
|
||||
##
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
## Makefile for the C++17 sources of the GNU C++ Standard library.
|
||||
##
|
||||
## Copyright (C) 1997-2018 Free Software Foundation, Inc.
|
||||
##
|
||||
## This file is part of the libstdc++ version 3 distribution.
|
||||
## Process this file with automake to produce Makefile.in.
|
||||
|
||||
## 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/>.
|
||||
|
||||
include $(top_srcdir)/fragment.am
|
||||
|
||||
# Convenience library for C++17 runtime.
|
||||
noinst_LTLIBRARIES = libc++17convenience.la
|
||||
|
||||
headers =
|
||||
|
||||
sources = \
|
||||
memory_resource.cc
|
||||
|
||||
if ENABLE_DUAL_ABI
|
||||
extra_string_inst_sources =
|
||||
else
|
||||
extra_string_inst_sources =
|
||||
endif
|
||||
|
||||
if ENABLE_EXTERN_TEMPLATE
|
||||
# XTEMPLATE_FLAGS = -fno-implicit-templates
|
||||
inst_sources = \
|
||||
$(extra_string_inst_sources)
|
||||
else
|
||||
# XTEMPLATE_FLAGS =
|
||||
inst_sources =
|
||||
endif
|
||||
|
||||
vpath % $(top_srcdir)/src/c++17
|
||||
|
||||
libc__17convenience_la_SOURCES = $(sources) $(inst_sources)
|
||||
|
||||
# AM_CXXFLAGS needs to be in each subdirectory so that it can be
|
||||
# modified in a per-library or per-sub-library way. Need to manually
|
||||
# set this option because CONFIG_CXXFLAGS has to be after
|
||||
# OPTIMIZE_CXXFLAGS on the compile line so that -O2 can be overridden
|
||||
# as the occasion calls for it.
|
||||
AM_CXXFLAGS = \
|
||||
-std=gnu++17 \
|
||||
$(glibcxx_lt_pic_flag) $(glibcxx_compiler_shared_flag) \
|
||||
$(XTEMPLATE_FLAGS) $(VTV_CXXFLAGS) \
|
||||
$(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS)
|
||||
|
||||
AM_MAKEFLAGS = \
|
||||
"gxx_include_dir=$(gxx_include_dir)"
|
||||
|
||||
# Libtool notes
|
||||
|
||||
# 1) In general, libtool expects an argument such as `--tag=CXX' when
|
||||
# using the C++ compiler, because that will enable the settings
|
||||
# detected when C++ support was being configured. However, when no
|
||||
# such flag is given in the command line, libtool attempts to figure
|
||||
# it out by matching the compiler name in each configuration section
|
||||
# against a prefix of the command line. The problem is that, if the
|
||||
# compiler name and its initial flags stored in the libtool
|
||||
# configuration file don't match those in the command line, libtool
|
||||
# can't decide which configuration to use, and it gives up. The
|
||||
# correct solution is to add `--tag CXX' to LTCXXCOMPILE and maybe
|
||||
# CXXLINK, just after $(LIBTOOL), so that libtool doesn't have to
|
||||
# attempt to infer which configuration to use.
|
||||
#
|
||||
# The second tag argument, `--tag disable-shared` means that libtool
|
||||
# only compiles each source once, for static objects. In actuality,
|
||||
# glibcxx_lt_pic_flag and glibcxx_compiler_shared_flag are added to
|
||||
# the libtool command that is used create the object, which is
|
||||
# suitable for shared libraries. The `--tag disable-shared` must be
|
||||
# placed after --tag CXX lest things CXX undo the affect of
|
||||
# disable-shared.
|
||||
|
||||
# 2) Need to explicitly set LTCXXCOMPILE so that EXTRA_CXX_FLAGS is
|
||||
# last. (That way, things like -O2 passed down from the toplevel can
|
||||
# be overridden by --enable-debug.)
|
||||
LTCXXCOMPILE = \
|
||||
$(LIBTOOL) --tag CXX --tag disable-shared \
|
||||
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(EXTRA_CXX_FLAGS)
|
||||
|
||||
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
|
||||
|
||||
# 3) We'd have a problem when building the shared libstdc++ object if
|
||||
# the rules automake generates would be used. We cannot allow g++ to
|
||||
# be used since this would add -lstdc++ to the link line which of
|
||||
# course is problematic at this point. So, we get the top-level
|
||||
# directory to configure libstdc++-v3 to use gcc as the C++
|
||||
# compilation driver.
|
||||
CXXLINK = \
|
||||
$(LIBTOOL) --tag CXX --tag disable-shared \
|
||||
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=link $(CXX) \
|
||||
$(VTV_CXXLINKFLAGS) \
|
||||
$(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
|
|
@ -0,0 +1,654 @@
|
|||
# Makefile.in generated by automake 1.11.6 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
|
||||
# Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
VPATH = @srcdir@
|
||||
am__make_dryrun = \
|
||||
{ \
|
||||
am__dry=no; \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
|
||||
| grep '^AM OK$$' >/dev/null || am__dry=yes;; \
|
||||
*) \
|
||||
for am__flg in $$MAKEFLAGS; do \
|
||||
case $$am__flg in \
|
||||
*=*|--*) ;; \
|
||||
*n*) am__dry=yes; break;; \
|
||||
esac; \
|
||||
done;; \
|
||||
esac; \
|
||||
test $$am__dry = yes; \
|
||||
}
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
target_triplet = @target@
|
||||
DIST_COMMON = $(top_srcdir)/fragment.am $(srcdir)/Makefile.in \
|
||||
$(srcdir)/Makefile.am
|
||||
subdir = src/c++17
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
|
||||
$(top_srcdir)/../config/enable.m4 \
|
||||
$(top_srcdir)/../config/futex.m4 \
|
||||
$(top_srcdir)/../config/hwcaps.m4 \
|
||||
$(top_srcdir)/../config/iconv.m4 \
|
||||
$(top_srcdir)/../config/lead-dot.m4 \
|
||||
$(top_srcdir)/../config/lib-ld.m4 \
|
||||
$(top_srcdir)/../config/lib-link.m4 \
|
||||
$(top_srcdir)/../config/lib-prefix.m4 \
|
||||
$(top_srcdir)/../config/lthostflags.m4 \
|
||||
$(top_srcdir)/../config/multi.m4 \
|
||||
$(top_srcdir)/../config/no-executables.m4 \
|
||||
$(top_srcdir)/../config/override.m4 \
|
||||
$(top_srcdir)/../config/stdint.m4 \
|
||||
$(top_srcdir)/../config/unwind_ipinfo.m4 \
|
||||
$(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
|
||||
$(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
|
||||
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/crossconfig.m4 \
|
||||
$(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \
|
||||
$(top_srcdir)/../config/gc++filt.m4 \
|
||||
$(top_srcdir)/../config/tls.m4 $(top_srcdir)/../config/gthr.m4 \
|
||||
$(top_srcdir)/../config/cet.m4 $(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
LTLIBRARIES = $(noinst_LTLIBRARIES)
|
||||
libc__17convenience_la_LIBADD =
|
||||
am__objects_1 = memory_resource.lo
|
||||
am__objects_2 =
|
||||
@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_3 = $(am__objects_2)
|
||||
am_libc__17convenience_la_OBJECTS = $(am__objects_1) $(am__objects_3)
|
||||
libc__17convenience_la_OBJECTS = $(am_libc__17convenience_la_OBJECTS)
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
|
||||
depcomp =
|
||||
am__depfiles_maybe =
|
||||
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
CXXLD = $(CXX)
|
||||
SOURCES = $(libc__17convenience_la_SOURCES)
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
ABI_TWEAKS_SRCDIR = @ABI_TWEAKS_SRCDIR@
|
||||
ACLOCAL = @ACLOCAL@
|
||||
ALLOCATOR_H = @ALLOCATOR_H@
|
||||
ALLOCATOR_NAME = @ALLOCATOR_NAME@
|
||||
AMTAR = @AMTAR@
|
||||
AR = @AR@
|
||||
AS = @AS@
|
||||
ATOMICITY_SRCDIR = @ATOMICITY_SRCDIR@
|
||||
ATOMIC_FLAGS = @ATOMIC_FLAGS@
|
||||
ATOMIC_WORD_SRCDIR = @ATOMIC_WORD_SRCDIR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
BASIC_FILE_CC = @BASIC_FILE_CC@
|
||||
BASIC_FILE_H = @BASIC_FILE_H@
|
||||
CC = @CC@
|
||||
CCODECVT_CC = @CCODECVT_CC@
|
||||
CCOLLATE_CC = @CCOLLATE_CC@
|
||||
CCTYPE_CC = @CCTYPE_CC@
|
||||
CFLAGS = @CFLAGS@
|
||||
CLOCALE_CC = @CLOCALE_CC@
|
||||
CLOCALE_H = @CLOCALE_H@
|
||||
CLOCALE_INTERNAL_H = @CLOCALE_INTERNAL_H@
|
||||
CMESSAGES_CC = @CMESSAGES_CC@
|
||||
CMESSAGES_H = @CMESSAGES_H@
|
||||
CMONEY_CC = @CMONEY_CC@
|
||||
CNUMERIC_CC = @CNUMERIC_CC@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CPU_DEFINES_SRCDIR = @CPU_DEFINES_SRCDIR@
|
||||
CPU_OPT_BITS_RANDOM = @CPU_OPT_BITS_RANDOM@
|
||||
CPU_OPT_EXT_RANDOM = @CPU_OPT_EXT_RANDOM@
|
||||
CSTDIO_H = @CSTDIO_H@
|
||||
CTIME_CC = @CTIME_CC@
|
||||
CTIME_H = @CTIME_H@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXFILT = @CXXFILT@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
C_INCLUDE_DIR = @C_INCLUDE_DIR@
|
||||
DBLATEX = @DBLATEX@
|
||||
DEBUG_FLAGS = @DEBUG_FLAGS@
|
||||
DEFS = @DEFS@
|
||||
DOT = @DOT@
|
||||
DOXYGEN = @DOXYGEN@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ERROR_CONSTANTS_SRCDIR = @ERROR_CONSTANTS_SRCDIR@
|
||||
EXEEXT = @EXEEXT@
|
||||
EXTRA_CFLAGS = @EXTRA_CFLAGS@
|
||||
EXTRA_CXX_FLAGS = @EXTRA_CXX_FLAGS@
|
||||
FGREP = @FGREP@
|
||||
GLIBCXX_INCLUDES = @GLIBCXX_INCLUDES@
|
||||
GLIBCXX_LIBS = @GLIBCXX_LIBS@
|
||||
GREP = @GREP@
|
||||
HWCAP_CFLAGS = @HWCAP_CFLAGS@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBICONV = @LIBICONV@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LONG_DOUBLE_COMPAT_FLAGS = @LONG_DOUBLE_COMPAT_FLAGS@
|
||||
LTLIBICONV = @LTLIBICONV@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OPTIMIZE_CXXFLAGS = @OPTIMIZE_CXXFLAGS@
|
||||
OPT_LDFLAGS = @OPT_LDFLAGS@
|
||||
OS_INC_SRCDIR = @OS_INC_SRCDIR@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PDFLATEX = @PDFLATEX@
|
||||
RANLIB = @RANLIB@
|
||||
SECTION_FLAGS = @SECTION_FLAGS@
|
||||
SECTION_LDFLAGS = @SECTION_LDFLAGS@
|
||||
SED = @SED@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STRIP = @STRIP@
|
||||
SYMVER_FILE = @SYMVER_FILE@
|
||||
TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@
|
||||
USE_NLS = @USE_NLS@
|
||||
VERSION = @VERSION@
|
||||
VTV_CXXFLAGS = @VTV_CXXFLAGS@
|
||||
VTV_CXXLINKFLAGS = @VTV_CXXLINKFLAGS@
|
||||
VTV_PCH_CXXFLAGS = @VTV_PCH_CXXFLAGS@
|
||||
WARN_FLAGS = @WARN_FLAGS@
|
||||
WERROR = @WERROR@
|
||||
XMLLINT = @XMLLINT@
|
||||
XSLTPROC = @XSLTPROC@
|
||||
XSL_STYLE_DIR = @XSL_STYLE_DIR@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
baseline_dir = @baseline_dir@
|
||||
baseline_subdir_switch = @baseline_subdir_switch@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
check_msgfmt = @check_msgfmt@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
enable_shared = @enable_shared@
|
||||
enable_static = @enable_static@
|
||||
exec_prefix = @exec_prefix@
|
||||
get_gcc_base_ver = @get_gcc_base_ver@
|
||||
glibcxx_MOFILES = @glibcxx_MOFILES@
|
||||
glibcxx_PCHFLAGS = @glibcxx_PCHFLAGS@
|
||||
glibcxx_POFILES = @glibcxx_POFILES@
|
||||
glibcxx_builddir = @glibcxx_builddir@
|
||||
glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@
|
||||
glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@
|
||||
glibcxx_cxx98_abi = @glibcxx_cxx98_abi@
|
||||
glibcxx_localedir = @glibcxx_localedir@
|
||||
glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@
|
||||
glibcxx_prefixdir = @glibcxx_prefixdir@
|
||||
glibcxx_srcdir = @glibcxx_srcdir@
|
||||
glibcxx_toolexecdir = @glibcxx_toolexecdir@
|
||||
glibcxx_toolexeclibdir = @glibcxx_toolexeclibdir@
|
||||
gxx_include_dir = @gxx_include_dir@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
libtool_VERSION = @libtool_VERSION@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
lt_host_flags = @lt_host_flags@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
multi_basedir = @multi_basedir@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
port_specific_symbol_files = @port_specific_symbol_files@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
python_mod_dir = @python_mod_dir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target = @target@
|
||||
target_alias = @target_alias@
|
||||
target_cpu = @target_cpu@
|
||||
target_os = @target_os@
|
||||
target_vendor = @target_vendor@
|
||||
thread_header = @thread_header@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
toplevel_builddir = @toplevel_builddir@
|
||||
toplevel_srcdir = @toplevel_srcdir@
|
||||
|
||||
# May be used by various substitution variables.
|
||||
gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)
|
||||
MAINT_CHARSET = latin1
|
||||
mkinstalldirs = $(SHELL) $(toplevel_srcdir)/mkinstalldirs
|
||||
PWD_COMMAND = $${PWDCMD-pwd}
|
||||
STAMP = echo timestamp >
|
||||
toolexecdir = $(glibcxx_toolexecdir)
|
||||
toolexeclibdir = $(glibcxx_toolexeclibdir)
|
||||
@ENABLE_WERROR_FALSE@WERROR_FLAG =
|
||||
@ENABLE_WERROR_TRUE@WERROR_FLAG = $(WERROR)
|
||||
@ENABLE_EXTERN_TEMPLATE_FALSE@XTEMPLATE_FLAGS =
|
||||
@ENABLE_EXTERN_TEMPLATE_TRUE@XTEMPLATE_FLAGS = -fno-implicit-templates
|
||||
|
||||
# These bits are all figured out from configure. Look in acinclude.m4
|
||||
# or configure.ac to see how they are set. See GLIBCXX_EXPORT_FLAGS.
|
||||
CONFIG_CXXFLAGS = \
|
||||
$(SECTION_FLAGS) $(HWCAP_CFLAGS) -frandom-seed=$@
|
||||
|
||||
WARN_CXXFLAGS = \
|
||||
$(WARN_FLAGS) $(WERROR_FLAG) -fdiagnostics-show-location=once
|
||||
|
||||
|
||||
# -I/-D flags to pass when compiling.
|
||||
AM_CPPFLAGS = $(GLIBCXX_INCLUDES) $(CPPFLAGS)
|
||||
|
||||
# Convenience library for C++17 runtime.
|
||||
noinst_LTLIBRARIES = libc++17convenience.la
|
||||
headers =
|
||||
sources = \
|
||||
memory_resource.cc
|
||||
|
||||
@ENABLE_DUAL_ABI_FALSE@extra_string_inst_sources =
|
||||
@ENABLE_DUAL_ABI_TRUE@extra_string_inst_sources =
|
||||
# XTEMPLATE_FLAGS =
|
||||
@ENABLE_EXTERN_TEMPLATE_FALSE@inst_sources =
|
||||
|
||||
# XTEMPLATE_FLAGS = -fno-implicit-templates
|
||||
@ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \
|
||||
@ENABLE_EXTERN_TEMPLATE_TRUE@ $(extra_string_inst_sources)
|
||||
|
||||
libc__17convenience_la_SOURCES = $(sources) $(inst_sources)
|
||||
|
||||
# AM_CXXFLAGS needs to be in each subdirectory so that it can be
|
||||
# modified in a per-library or per-sub-library way. Need to manually
|
||||
# set this option because CONFIG_CXXFLAGS has to be after
|
||||
# OPTIMIZE_CXXFLAGS on the compile line so that -O2 can be overridden
|
||||
# as the occasion calls for it.
|
||||
AM_CXXFLAGS = \
|
||||
-std=gnu++17 \
|
||||
$(glibcxx_lt_pic_flag) $(glibcxx_compiler_shared_flag) \
|
||||
$(XTEMPLATE_FLAGS) $(VTV_CXXFLAGS) \
|
||||
$(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS)
|
||||
|
||||
AM_MAKEFLAGS = \
|
||||
"gxx_include_dir=$(gxx_include_dir)"
|
||||
|
||||
|
||||
# Libtool notes
|
||||
|
||||
# 1) In general, libtool expects an argument such as `--tag=CXX' when
|
||||
# using the C++ compiler, because that will enable the settings
|
||||
# detected when C++ support was being configured. However, when no
|
||||
# such flag is given in the command line, libtool attempts to figure
|
||||
# it out by matching the compiler name in each configuration section
|
||||
# against a prefix of the command line. The problem is that, if the
|
||||
# compiler name and its initial flags stored in the libtool
|
||||
# configuration file don't match those in the command line, libtool
|
||||
# can't decide which configuration to use, and it gives up. The
|
||||
# correct solution is to add `--tag CXX' to LTCXXCOMPILE and maybe
|
||||
# CXXLINK, just after $(LIBTOOL), so that libtool doesn't have to
|
||||
# attempt to infer which configuration to use.
|
||||
#
|
||||
# The second tag argument, `--tag disable-shared` means that libtool
|
||||
# only compiles each source once, for static objects. In actuality,
|
||||
# glibcxx_lt_pic_flag and glibcxx_compiler_shared_flag are added to
|
||||
# the libtool command that is used create the object, which is
|
||||
# suitable for shared libraries. The `--tag disable-shared` must be
|
||||
# placed after --tag CXX lest things CXX undo the affect of
|
||||
# disable-shared.
|
||||
|
||||
# 2) Need to explicitly set LTCXXCOMPILE so that EXTRA_CXX_FLAGS is
|
||||
# last. (That way, things like -O2 passed down from the toplevel can
|
||||
# be overridden by --enable-debug.)
|
||||
LTCXXCOMPILE = \
|
||||
$(LIBTOOL) --tag CXX --tag disable-shared \
|
||||
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(EXTRA_CXX_FLAGS)
|
||||
|
||||
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
|
||||
|
||||
# 3) We'd have a problem when building the shared libstdc++ object if
|
||||
# the rules automake generates would be used. We cannot allow g++ to
|
||||
# be used since this would add -lstdc++ to the link line which of
|
||||
# course is problematic at this point. So, we get the top-level
|
||||
# directory to configure libstdc++-v3 to use gcc as the C++
|
||||
# compilation driver.
|
||||
CXXLINK = \
|
||||
$(LIBTOOL) --tag CXX --tag disable-shared \
|
||||
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=link $(CXX) \
|
||||
$(VTV_CXXLINKFLAGS) \
|
||||
$(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
|
||||
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .cc .lo .o .obj
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/fragment.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps src/c++17/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --foreign --ignore-deps src/c++17/Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
$(top_srcdir)/fragment.am:
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
|
||||
clean-noinstLTLIBRARIES:
|
||||
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
|
||||
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
|
||||
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
|
||||
test "$$dir" != "$$p" || dir=.; \
|
||||
echo "rm -f \"$${dir}/so_locations\""; \
|
||||
rm -f "$${dir}/so_locations"; \
|
||||
done
|
||||
libc++17convenience.la: $(libc__17convenience_la_OBJECTS) $(libc__17convenience_la_DEPENDENCIES) $(EXTRA_libc__17convenience_la_DEPENDENCIES)
|
||||
$(CXXLINK) $(libc__17convenience_la_OBJECTS) $(libc__17convenience_la_LIBADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
.cc.o:
|
||||
$(CXXCOMPILE) -c -o $@ $<
|
||||
|
||||
.cc.obj:
|
||||
$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
|
||||
.cc.lo:
|
||||
$(LTCXXCOMPILE) -c -o $@ $<
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
mkid -fID $$unique
|
||||
tags: TAGS
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: CTAGS
|
||||
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(LTLIBRARIES)
|
||||
installdirs:
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
|
||||
mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am:
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am:
|
||||
|
||||
.MAKE: install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
|
||||
clean-libtool clean-noinstLTLIBRARIES ctags distclean \
|
||||
distclean-compile distclean-generic distclean-libtool \
|
||||
distclean-tags dvi dvi-am html html-am info info-am install \
|
||||
install-am install-data install-data-am install-dvi \
|
||||
install-dvi-am install-exec install-exec-am install-html \
|
||||
install-html-am install-info install-info-am install-man \
|
||||
install-pdf install-pdf-am install-ps install-ps-am \
|
||||
install-strip installcheck installcheck-am installdirs \
|
||||
maintainer-clean maintainer-clean-generic mostlyclean \
|
||||
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
|
||||
pdf pdf-am ps ps-am tags uninstall uninstall-am
|
||||
|
||||
|
||||
vpath % $(top_srcdir)/src/c++17
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
|
@ -0,0 +1,111 @@
|
|||
// <memory_resource> implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2018 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.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <memory_resource>
|
||||
#include <atomic>
|
||||
#include <new>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
namespace pmr
|
||||
{
|
||||
namespace
|
||||
{
|
||||
class newdel_res_t final : public memory_resource
|
||||
{
|
||||
void*
|
||||
do_allocate(size_t __bytes, size_t __alignment) override
|
||||
{ return ::operator new(__bytes, std::align_val_t(__alignment)); }
|
||||
|
||||
void
|
||||
do_deallocate(void* __p, size_t __bytes, size_t __alignment) noexcept
|
||||
override
|
||||
{ ::operator delete(__p, __bytes, std::align_val_t(__alignment)); }
|
||||
|
||||
bool
|
||||
do_is_equal(const memory_resource& __other) const noexcept override
|
||||
{ return &__other == this; }
|
||||
};
|
||||
|
||||
class null_res_t final : public memory_resource
|
||||
{
|
||||
void*
|
||||
do_allocate(size_t, size_t) override
|
||||
{ std::__throw_bad_alloc(); }
|
||||
|
||||
void
|
||||
do_deallocate(void*, size_t, size_t) noexcept override
|
||||
{ }
|
||||
|
||||
bool
|
||||
do_is_equal(const memory_resource& __other) const noexcept override
|
||||
{ return &__other == this; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct constant_init
|
||||
{
|
||||
union {
|
||||
unsigned char unused;
|
||||
T obj;
|
||||
};
|
||||
constexpr constant_init() : obj() { }
|
||||
|
||||
template<typename U>
|
||||
explicit constexpr constant_init(U arg) : obj(arg) { }
|
||||
|
||||
~constant_init() { /* do nothing, union member is not destroyed */ }
|
||||
};
|
||||
|
||||
constant_init<newdel_res_t> newdel_res{};
|
||||
constant_init<null_res_t> null_res{};
|
||||
constant_init<atomic<memory_resource*>> default_res{&newdel_res.obj};
|
||||
} // namespace
|
||||
|
||||
memory_resource*
|
||||
new_delete_resource() noexcept
|
||||
{ return &newdel_res.obj; }
|
||||
|
||||
memory_resource*
|
||||
null_memory_resource() noexcept
|
||||
{ return &null_res.obj; }
|
||||
|
||||
memory_resource*
|
||||
set_default_resource(memory_resource* r) noexcept
|
||||
{
|
||||
if (r == nullptr)
|
||||
r = new_delete_resource();
|
||||
return default_res.obj.exchange(r);
|
||||
}
|
||||
|
||||
memory_resource*
|
||||
get_default_resource() noexcept
|
||||
{ return default_res.obj.load(); }
|
||||
|
||||
} // namespace pmr
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do compile { target c++17 } }
|
||||
|
||||
// Copyright (C) 2018 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/>.
|
||||
|
||||
#include <memory_resource>
|
||||
|
||||
static_assert(std::is_abstract_v<std::pmr::memory_resource>);
|
||||
static_assert(std::is_polymorphic_v<std::pmr::memory_resource>);
|
||||
static_assert(!std::is_final_v<std::pmr::memory_resource>);
|
||||
|
||||
struct R0 : std::pmr::memory_resource { };
|
||||
static_assert(std::is_abstract_v<R0>);
|
||||
|
||||
struct R1 : R0 {
|
||||
void* do_allocate(std::size_t, std::size_t) override;
|
||||
};
|
||||
static_assert(std::is_abstract_v<R1>);
|
||||
|
||||
struct R2 : R1 {
|
||||
void do_deallocate(void*, std::size_t, std::size_t) override;
|
||||
};
|
||||
static_assert(std::is_abstract_v<R2>);
|
||||
|
||||
struct R3 : R2 {
|
||||
bool do_is_equal(const std::pmr::memory_resource&) const noexcept override;
|
||||
};
|
||||
static_assert(!std::is_abstract_v<R3>);
|
||||
static_assert(std::is_default_constructible_v<R3>);
|
||||
static_assert(std::is_copy_constructible_v<R3>);
|
||||
static_assert(std::is_copy_assignable_v<R3>);
|
||||
static_assert(std::is_destructible_v<R3>);
|
|
@ -0,0 +1,112 @@
|
|||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do run { target c++17 } }
|
||||
// { dg-skip-if "" { *-*-* } { -fno-aligned-new } }
|
||||
|
||||
// Copyright (C) 2018 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/>.
|
||||
|
||||
#include <memory_resource>
|
||||
#include <testsuite_allocator.h>
|
||||
|
||||
struct R : std::pmr::memory_resource {
|
||||
void* do_allocate(std::size_t, std::size_t) override;
|
||||
void do_deallocate(void*, std::size_t, std::size_t) override;
|
||||
bool do_is_equal(const std::pmr::memory_resource&) const noexcept override;
|
||||
};
|
||||
|
||||
bool called = false;
|
||||
|
||||
void* R::do_allocate(std::size_t bytes, std::size_t a)
|
||||
{
|
||||
called = true;
|
||||
return ::operator new(bytes, std::align_val_t(a));
|
||||
}
|
||||
|
||||
void R::do_deallocate(void* p, std::size_t bytes, std::size_t a)
|
||||
{
|
||||
called = true;
|
||||
::operator delete(p, bytes, std::align_val_t(a));
|
||||
}
|
||||
|
||||
bool R::do_is_equal(const std::pmr::memory_resource& r) const noexcept
|
||||
{
|
||||
called = true;
|
||||
return this == &r;
|
||||
}
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
R res;
|
||||
called = false;
|
||||
auto p = res.allocate(1, 1);
|
||||
VERIFY( called );
|
||||
called = false;
|
||||
res.deallocate(p, 1, 1);
|
||||
VERIFY( called );
|
||||
called = false;
|
||||
VERIFY( res == res );
|
||||
VERIFY( !called );
|
||||
VERIFY( ! (res != res) );
|
||||
VERIFY( !called );
|
||||
|
||||
struct X { int i = 0; };
|
||||
struct MultipleInheritance : X, R { };
|
||||
MultipleInheritance m;
|
||||
VERIFY( m == m );
|
||||
VERIFY( !called );
|
||||
VERIFY( ! (m != m) );
|
||||
VERIFY( !called );
|
||||
VERIFY( m.is_equal(m) );
|
||||
VERIFY( called );
|
||||
called = false;
|
||||
VERIFY( ! (m == res) );
|
||||
VERIFY( called );
|
||||
called = false;
|
||||
VERIFY( m != res );
|
||||
VERIFY( called );
|
||||
called = false;
|
||||
VERIFY( ! (res == m) );
|
||||
VERIFY( called );
|
||||
called = false;
|
||||
VERIFY( res != m );
|
||||
VERIFY( called );
|
||||
called = false;
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
__gnu_test::memory_resource r1, r2;
|
||||
VERIFY( r1 == r1 );
|
||||
VERIFY( ! (r1 != r1) );
|
||||
VERIFY( r1.is_equal(r1) );
|
||||
VERIFY( r2 == r2 );
|
||||
VERIFY( r2.is_equal(r2) );
|
||||
VERIFY( ! (r1 == r2) );
|
||||
VERIFY( r1 != r2 );
|
||||
VERIFY( ! r1.is_equal(r2) );
|
||||
VERIFY( ! (r2 == r1) );
|
||||
VERIFY( r2 != r1 );
|
||||
VERIFY( ! r2.is_equal(r1) );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
// Copyright (C) 2018 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/>.
|
||||
|
||||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do compile { target c++17 } }
|
||||
|
||||
#include <memory_resource>
|
||||
|
||||
using std::pmr::monotonic_buffer_resource;
|
||||
using std::pmr::memory_resource;
|
||||
using std::size_t;
|
||||
|
||||
static_assert(std::is_base_of_v<memory_resource, monotonic_buffer_resource>);
|
||||
static_assert(!std::is_abstract_v<monotonic_buffer_resource>);
|
||||
|
||||
static_assert(std::is_default_constructible_v<monotonic_buffer_resource>);
|
||||
static_assert(std::is_destructible_v<monotonic_buffer_resource>);
|
||||
static_assert(!std::is_copy_constructible_v<monotonic_buffer_resource>);
|
||||
static_assert(!std::is_copy_assignable_v<monotonic_buffer_resource>);
|
||||
static_assert(!std::is_move_constructible_v<monotonic_buffer_resource>);
|
||||
static_assert(!std::is_move_assignable_v<monotonic_buffer_resource>);
|
||||
|
||||
static_assert(std::is_constructible_v<monotonic_buffer_resource,
|
||||
memory_resource*>);
|
||||
static_assert(std::is_constructible_v<monotonic_buffer_resource,
|
||||
size_t, memory_resource*>);
|
||||
static_assert(std::is_constructible_v<monotonic_buffer_resource,
|
||||
void*, size_t, memory_resource*>);
|
||||
|
||||
static_assert(std::is_constructible_v<monotonic_buffer_resource,
|
||||
size_t>);
|
||||
static_assert(std::is_constructible_v<monotonic_buffer_resource,
|
||||
void*, size_t>);
|
||||
|
||||
// Unary constructors are explicit.
|
||||
static_assert(!std::is_convertible_v<memory_resource*,
|
||||
monotonic_buffer_resource>);
|
||||
static_assert(!std::is_convertible_v<size_t,
|
||||
monotonic_buffer_resource>);
|
|
@ -0,0 +1,221 @@
|
|||
// Copyright (C) 2018 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/>.
|
||||
|
||||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do run { target c++17 } }
|
||||
|
||||
#include <memory_resource>
|
||||
#include <testsuite_allocator.h>
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
__gnu_test::memory_resource r;
|
||||
|
||||
// test that it's possible to allocate after each of the constructors
|
||||
{
|
||||
std::pmr::monotonic_buffer_resource mr(&r);
|
||||
auto p = mr.allocate(1024);
|
||||
VERIFY( p != nullptr );
|
||||
auto q = mr.allocate(1024);
|
||||
VERIFY( q != nullptr );
|
||||
VERIFY( p != q );
|
||||
}
|
||||
VERIFY( r.number_of_active_allocations() == 0 );
|
||||
{
|
||||
std::pmr::monotonic_buffer_resource mr(128, &r);
|
||||
auto p = mr.allocate(1024);
|
||||
VERIFY( p != nullptr );
|
||||
auto q = mr.allocate(1024);
|
||||
VERIFY( q != nullptr );
|
||||
VERIFY( p != q );
|
||||
}
|
||||
VERIFY( r.number_of_active_allocations() == 0 );
|
||||
{
|
||||
unsigned char buf[64];
|
||||
std::pmr::monotonic_buffer_resource mr((void*)buf, sizeof(buf), &r);
|
||||
auto p = mr.allocate(1024);
|
||||
VERIFY( p != nullptr );
|
||||
auto q = mr.allocate(1024);
|
||||
VERIFY( q != nullptr );
|
||||
VERIFY( p != q );
|
||||
}
|
||||
VERIFY( r.number_of_active_allocations() == 0 );
|
||||
{
|
||||
std::pmr::monotonic_buffer_resource mr;
|
||||
auto p = mr.allocate(1024);
|
||||
VERIFY( p != nullptr );
|
||||
auto q = mr.allocate(1024);
|
||||
VERIFY( q != nullptr );
|
||||
VERIFY( p != q );
|
||||
}
|
||||
{
|
||||
std::pmr::monotonic_buffer_resource mr(64);
|
||||
auto p = mr.allocate(1024);
|
||||
VERIFY( p != nullptr );
|
||||
auto q = mr.allocate(1024);
|
||||
VERIFY( q != nullptr );
|
||||
VERIFY( p != q );
|
||||
}
|
||||
{
|
||||
unsigned char buf[64];
|
||||
std::pmr::monotonic_buffer_resource mr((void*)buf, sizeof(buf));
|
||||
auto p = mr.allocate(1024);
|
||||
VERIFY( p != nullptr );
|
||||
auto q = mr.allocate(1024);
|
||||
VERIFY( q != nullptr );
|
||||
VERIFY( p != q );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
unsigned char buf[64];
|
||||
std::pmr::monotonic_buffer_resource mr(buf, sizeof(buf));
|
||||
|
||||
auto p = mr.allocate(0);
|
||||
VERIFY( p != nullptr );
|
||||
auto q = mr.allocate(0);
|
||||
VERIFY( q != nullptr );
|
||||
VERIFY( p != q );
|
||||
|
||||
p = mr.allocate(0, 1);
|
||||
VERIFY( p != nullptr );
|
||||
q = mr.allocate(0, 1);
|
||||
VERIFY( q != nullptr );
|
||||
VERIFY( p != q );
|
||||
}
|
||||
|
||||
void
|
||||
test03()
|
||||
{
|
||||
#if __cpp_exceptions
|
||||
{
|
||||
std::pmr::monotonic_buffer_resource mr(std::pmr::null_memory_resource());
|
||||
bool caught = false;
|
||||
try
|
||||
{
|
||||
(void) mr.allocate(1, 1);
|
||||
}
|
||||
catch (const std::bad_alloc&)
|
||||
{
|
||||
caught = true;
|
||||
}
|
||||
VERIFY( caught );
|
||||
}
|
||||
{
|
||||
unsigned char buf[16];
|
||||
std::pmr::monotonic_buffer_resource mr(buf, sizeof(buf),
|
||||
std::pmr::null_memory_resource());
|
||||
(void) mr.allocate(16, 1);
|
||||
bool caught = false;
|
||||
try
|
||||
{
|
||||
(void) mr.allocate(1, 1);
|
||||
}
|
||||
catch (const std::bad_alloc&)
|
||||
{
|
||||
caught = true;
|
||||
}
|
||||
VERIFY( caught );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
test04()
|
||||
{
|
||||
auto buf = new unsigned char[512];
|
||||
std::pmr::monotonic_buffer_resource mr(buf, 512,
|
||||
std::pmr::null_memory_resource());
|
||||
std::size_t prev_size = 1;
|
||||
void* prev_ptr = mr.allocate(prev_size, 1);
|
||||
for (int i = 0; i < 9; ++i)
|
||||
{
|
||||
std::size_t size = 1 << i;
|
||||
void* ptr = mr.allocate(size, 1);
|
||||
VERIFY( ((char*)ptr - (char*)prev_ptr) == prev_size );
|
||||
prev_ptr = ptr;
|
||||
prev_size = size;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test05()
|
||||
{
|
||||
// test that returned pointer is correctly aligned
|
||||
auto is_aligned = [](void* p, size_t alignment) -> bool {
|
||||
return (reinterpret_cast<std::uintptr_t>(p) % alignment) == 0;
|
||||
};
|
||||
|
||||
auto buf = new unsigned char[2048];
|
||||
std::pmr::monotonic_buffer_resource mr(buf+1, 2047);
|
||||
for (int i = 0; i < 9; ++i)
|
||||
{
|
||||
auto p = mr.allocate(1, 1 << i);
|
||||
VERIFY( is_aligned(p, 1 << i) );
|
||||
// Make next available byte misaligned:
|
||||
(void) mr.allocate(1 << i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test06()
|
||||
{
|
||||
// check for geometric progression in buffer sizes from upstream
|
||||
|
||||
struct resource : __gnu_test::memory_resource
|
||||
{
|
||||
bool allocated = false;
|
||||
std::size_t last_size = 0;
|
||||
|
||||
void*
|
||||
do_allocate(size_t bytes, size_t align) override
|
||||
{
|
||||
allocated = true;
|
||||
last_size = bytes;
|
||||
return __gnu_test::memory_resource::do_allocate(bytes, align);
|
||||
}
|
||||
};
|
||||
|
||||
resource r;
|
||||
std::pmr::monotonic_buffer_resource mr(32, &r);
|
||||
std::size_t last_size = 0;
|
||||
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
(void) mr.allocate(16);
|
||||
if (r.allocated)
|
||||
{
|
||||
VERIFY(r.last_size >= last_size);
|
||||
last_size = r.last_size;
|
||||
r.allocated = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
test04();
|
||||
test05();
|
||||
test06();
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
// Copyright (C) 2018 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/>.
|
||||
|
||||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do run { target c++17 } }
|
||||
|
||||
#include <memory_resource>
|
||||
#include <testsuite_allocator.h>
|
||||
|
||||
struct resource : __gnu_test::memory_resource
|
||||
{
|
||||
int allocate_calls = 0;
|
||||
int deallocate_calls = 0;
|
||||
|
||||
void*
|
||||
do_allocate(std::size_t bytes, std::size_t align) override
|
||||
{
|
||||
++allocate_calls;
|
||||
return __gnu_test::memory_resource::do_allocate(bytes, align);
|
||||
}
|
||||
|
||||
void
|
||||
do_deallocate(void* p, std::size_t bytes, std::size_t align) override
|
||||
{
|
||||
++deallocate_calls;
|
||||
__gnu_test::memory_resource::do_deallocate(p, bytes, align);
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
resource r;
|
||||
|
||||
// test that it's possible to deallocate after each of the constructors
|
||||
{
|
||||
std::pmr::monotonic_buffer_resource mr(&r);
|
||||
auto p = mr.allocate(1024);
|
||||
VERIFY( p != nullptr );
|
||||
const std::uintptr_t pi = reinterpret_cast<std::uintptr_t>(p);
|
||||
mr.deallocate(p, 1024);
|
||||
VERIFY( r.deallocate_calls == 0 );
|
||||
auto q = mr.allocate(1024);
|
||||
VERIFY( q != nullptr );
|
||||
VERIFY( pi != reinterpret_cast<std::uintptr_t>(q) );
|
||||
mr.deallocate(q, 1024);
|
||||
VERIFY( r.deallocate_calls == 0 );
|
||||
}
|
||||
VERIFY( r.deallocate_calls == r.allocate_calls );
|
||||
VERIFY( r.number_of_active_allocations() == 0 );
|
||||
{
|
||||
r.deallocate_calls = r.allocate_calls = 0;
|
||||
std::pmr::monotonic_buffer_resource mr(128, &r);
|
||||
auto p = mr.allocate(64);
|
||||
VERIFY( p != nullptr );
|
||||
const std::uintptr_t pi = reinterpret_cast<std::uintptr_t>(p);
|
||||
mr.deallocate(p, 64);
|
||||
auto q = mr.allocate(1024);
|
||||
VERIFY( q != nullptr );
|
||||
VERIFY( p != q );
|
||||
VERIFY( pi != reinterpret_cast<std::uintptr_t>(q) );
|
||||
mr.deallocate(q, 1024);
|
||||
VERIFY( r.deallocate_calls == 0 );
|
||||
}
|
||||
VERIFY( r.number_of_active_allocations() == 0 );
|
||||
{
|
||||
r.deallocate_calls = r.allocate_calls = 0;
|
||||
unsigned char buf[64];
|
||||
std::pmr::monotonic_buffer_resource mr((void*)buf, sizeof(buf), &r);
|
||||
auto p = mr.allocate(64);
|
||||
VERIFY( p != nullptr );
|
||||
const std::uintptr_t pi = reinterpret_cast<std::uintptr_t>(p);
|
||||
mr.deallocate(p, 64);
|
||||
auto q = mr.allocate(1024);
|
||||
VERIFY( q != nullptr );
|
||||
VERIFY( p != q );
|
||||
VERIFY( pi != reinterpret_cast<std::uintptr_t>(q) );
|
||||
mr.deallocate(q, 1024);
|
||||
VERIFY( r.deallocate_calls == 0 );
|
||||
}
|
||||
VERIFY( r.deallocate_calls == r.allocate_calls );
|
||||
VERIFY( r.number_of_active_allocations() == 0 );
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
}
|
|
@ -0,0 +1,172 @@
|
|||
// Copyright (C) 2018 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/>.
|
||||
|
||||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do run { target c++17 } }
|
||||
|
||||
#include <memory_resource>
|
||||
#include <testsuite_allocator.h>
|
||||
|
||||
struct resource : __gnu_test::memory_resource
|
||||
{
|
||||
int allocate_calls = 0;
|
||||
int deallocate_calls = 0;
|
||||
|
||||
void*
|
||||
do_allocate(std::size_t bytes, std::size_t align) override
|
||||
{
|
||||
++allocate_calls;
|
||||
return __gnu_test::memory_resource::do_allocate(bytes, align);
|
||||
}
|
||||
|
||||
void
|
||||
do_deallocate(void* p, std::size_t bytes, std::size_t align) override
|
||||
{
|
||||
++deallocate_calls;
|
||||
__gnu_test::memory_resource::do_deallocate(p, bytes, align);
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
resource r;
|
||||
std::pmr::monotonic_buffer_resource mbr(&r);
|
||||
auto p = mbr.allocate(10, 16);
|
||||
mbr.deallocate(p, 1, 2);
|
||||
VERIFY( r.deallocate_calls == 0 );
|
||||
p = mbr.allocate(10, 16);
|
||||
p = mbr.allocate(10, 16);
|
||||
p = mbr.allocate(10, 16);
|
||||
p = mbr.allocate(1024, 64);
|
||||
p = mbr.allocate(1024, 64);
|
||||
p = mbr.allocate(128, 8);
|
||||
p = mbr.allocate(128, 8);
|
||||
p = mbr.allocate(128, 8);
|
||||
p = mbr.allocate(128, 8);
|
||||
p = mbr.allocate(128, 8);
|
||||
p = mbr.allocate(128, 8);
|
||||
p = mbr.allocate(128, 8);
|
||||
mbr.deallocate(p, 1, 2);
|
||||
p = mbr.allocate(1024, 16);
|
||||
p = mbr.allocate(1024, 16);
|
||||
mbr.deallocate(p, 1, 2);
|
||||
VERIFY( r.deallocate_calls == 0 );
|
||||
mbr.release();
|
||||
VERIFY( r.deallocate_calls != 0 );
|
||||
VERIFY( r.deallocate_calls == r.allocate_calls );
|
||||
VERIFY( mbr.upstream_resource() == &r );
|
||||
VERIFY( r.number_of_active_allocations() == 0 );
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
std::pmr::monotonic_buffer_resource mbr; // uses get_default_resource()
|
||||
auto* const upstream = mbr.upstream_resource();
|
||||
resource r;
|
||||
__gnu_test::default_resource_mgr _(&r); // calls set_default_resource(&r)
|
||||
mbr.release();
|
||||
// release() doesn't change upstream resource:
|
||||
VERIFY( mbr.upstream_resource() == upstream );
|
||||
}
|
||||
|
||||
void
|
||||
test03()
|
||||
{
|
||||
resource r;
|
||||
__gnu_test::default_resource_mgr _(&r);
|
||||
std::pmr::monotonic_buffer_resource mbr(16);
|
||||
for (int i = 0; i < 100; ++i)
|
||||
(void) mbr.allocate(4, 1);
|
||||
const int allocations = r.allocate_calls;
|
||||
VERIFY( allocations != 0 );
|
||||
mbr.release();
|
||||
VERIFY( r.allocate_calls == r.deallocate_calls );
|
||||
VERIFY( r.number_of_active_allocations() == 0 );
|
||||
|
||||
// next_buffer_size should have been reset to the initial value,
|
||||
// so the allocations from upstream should be the same as before.
|
||||
r.allocate_calls = 0;
|
||||
r.deallocate_calls = 0;
|
||||
for (int i = 0; i < 100; ++i)
|
||||
(void) mbr.allocate(4,1);
|
||||
VERIFY( allocations == r.allocate_calls );
|
||||
}
|
||||
|
||||
void
|
||||
test04()
|
||||
{
|
||||
resource r;
|
||||
unsigned char buffer[1024];
|
||||
std::pmr::monotonic_buffer_resource mbr(buffer, sizeof(buffer), &r);
|
||||
void* p = mbr.allocate(800, 16);
|
||||
VERIFY( p == buffer );
|
||||
VERIFY( r.allocate_calls == 0 );
|
||||
p = mbr.allocate(300, 1);
|
||||
VERIFY( p != buffer );
|
||||
VERIFY( r.allocate_calls == 1 );
|
||||
mbr.release();
|
||||
VERIFY( r.deallocate_calls == 1 );
|
||||
VERIFY( mbr.upstream_resource() == &r );
|
||||
VERIFY( r.number_of_active_allocations() == 0 );
|
||||
// initial buffer should be used again now:
|
||||
p = mbr.allocate(1000);
|
||||
VERIFY( p == buffer );
|
||||
VERIFY( r.allocate_calls == 1 );
|
||||
}
|
||||
|
||||
void
|
||||
test05() // LWG 3120
|
||||
{
|
||||
char buffer[100];
|
||||
{
|
||||
std::pmr::monotonic_buffer_resource mr(buffer, sizeof(buffer),
|
||||
std::pmr::null_memory_resource());
|
||||
mr.release();
|
||||
(void) mr.allocate(60);
|
||||
}
|
||||
|
||||
{
|
||||
std::pmr::monotonic_buffer_resource mr(buffer, sizeof(buffer),
|
||||
std::pmr::null_memory_resource());
|
||||
(void) mr.allocate(60);
|
||||
mr.release();
|
||||
(void) mr.allocate(60);
|
||||
}
|
||||
|
||||
{
|
||||
resource r;
|
||||
std::pmr::monotonic_buffer_resource mr(&r);
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
(void) mr.allocate(1);
|
||||
mr.release();
|
||||
}
|
||||
VERIFY( r.number_of_active_allocations() == 0 );
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
test04();
|
||||
test05();
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
// Copyright (C) 2018 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/>.
|
||||
|
||||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do run { target c++17 } }
|
||||
|
||||
#include <memory_resource>
|
||||
#include <testsuite_allocator.h>
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
__gnu_test::memory_resource r;
|
||||
const auto null = std::pmr::null_memory_resource();
|
||||
const auto newdel = std::pmr::new_delete_resource();
|
||||
std::pmr::set_default_resource(null);
|
||||
|
||||
{
|
||||
std::pmr::monotonic_buffer_resource mr(&r);
|
||||
VERIFY( mr.upstream_resource() == &r );
|
||||
__gnu_test::default_resource_mgr _(newdel);
|
||||
VERIFY( mr.upstream_resource() == &r );
|
||||
}
|
||||
{
|
||||
std::pmr::monotonic_buffer_resource mr(128, &r);
|
||||
VERIFY( mr.upstream_resource() == &r );
|
||||
__gnu_test::default_resource_mgr _(newdel);
|
||||
VERIFY( mr.upstream_resource() == &r );
|
||||
}
|
||||
{
|
||||
unsigned char buf[64];
|
||||
std::pmr::monotonic_buffer_resource mr((void*)buf, sizeof(buf), &r);
|
||||
VERIFY( mr.upstream_resource() == &r );
|
||||
__gnu_test::default_resource_mgr _(newdel);
|
||||
VERIFY( mr.upstream_resource() == &r );
|
||||
}
|
||||
{
|
||||
std::pmr::monotonic_buffer_resource mr;
|
||||
VERIFY( mr.upstream_resource() == null );
|
||||
__gnu_test::default_resource_mgr _(newdel);
|
||||
VERIFY( mr.upstream_resource() == null );
|
||||
}
|
||||
{
|
||||
std::pmr::monotonic_buffer_resource mr(64);
|
||||
VERIFY( mr.upstream_resource() == null );
|
||||
__gnu_test::default_resource_mgr _(newdel);
|
||||
VERIFY( mr.upstream_resource() == null );
|
||||
}
|
||||
{
|
||||
unsigned char buf[64];
|
||||
std::pmr::monotonic_buffer_resource mr((void*)buf, sizeof(buf));
|
||||
VERIFY( mr.upstream_resource() == null );
|
||||
__gnu_test::default_resource_mgr _(newdel);
|
||||
VERIFY( mr.upstream_resource() == null );
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (C) 2018 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/>.
|
||||
|
||||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do compile { target c++17 } }
|
||||
|
||||
#include <memory_resource>
|
||||
|
||||
struct X { int i = 0; };
|
||||
|
||||
using test_type = std::pmr::polymorphic_allocator<X>;
|
||||
|
||||
static_assert(std::is_default_constructible_v<test_type>);
|
||||
static_assert(std::is_destructible_v<test_type>);
|
||||
static_assert(std::is_copy_constructible_v<test_type>);
|
||||
static_assert(!std::is_copy_assignable_v<test_type>);
|
||||
static_assert(std::is_constructible_v<test_type, std::pmr::memory_resource*>);
|
||||
|
||||
static_assert(std::is_same_v<test_type::value_type, X>);
|
||||
|
||||
static_assert(!std::is_polymorphic_v<test_type>);
|
||||
static_assert(!std::is_final_v<test_type>);
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright (C) 2018 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/>.
|
||||
|
||||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do run { target c++17 } }
|
||||
// { dg-skip-if "" { *-*-* } { -fno-aligned-new } }
|
||||
|
||||
#include <memory_resource>
|
||||
#include <testsuite_allocator.h>
|
||||
|
||||
struct X { int i = 0; };
|
||||
|
||||
using test_type = std::pmr::polymorphic_allocator<X>;
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
__gnu_test::memory_resource r;
|
||||
test_type a(&r), b(&r);
|
||||
VERIFY( a == a );
|
||||
VERIFY( ! (a != a) );
|
||||
VERIFY( a == b );
|
||||
VERIFY( ! (a != b) );
|
||||
VERIFY( a.resource() == &r );
|
||||
VERIFY( a.resource() == b.resource() );
|
||||
|
||||
__gnu_test::memory_resource r2(r);
|
||||
test_type c(&r2);
|
||||
VERIFY( c.resource() == &r2 );
|
||||
VERIFY( c.resource() != a.resource() );
|
||||
VERIFY( c == a );
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
__gnu_test::memory_resource r1, r2;
|
||||
test_type a(&r1), b(&r2);
|
||||
VERIFY( a == a );
|
||||
VERIFY( b == b );
|
||||
VERIFY( ! (a == b) );
|
||||
VERIFY( ! (b == a) );
|
||||
VERIFY( a != b );
|
||||
VERIFY( b != a );
|
||||
VERIFY( a.resource() == &r1 );
|
||||
VERIFY( a.resource() != b.resource() );
|
||||
|
||||
test_type c;
|
||||
VERIFY( c == c );
|
||||
VERIFY( ! (a == c) );
|
||||
VERIFY( ! (c == a) );
|
||||
VERIFY( ! (b == c) );
|
||||
VERIFY( ! (c == b) );
|
||||
VERIFY( a.resource() != c.resource() );
|
||||
VERIFY( c.resource() == std::pmr::get_default_resource() );
|
||||
|
||||
std::pmr::set_default_resource(&r1);
|
||||
VERIFY( c.resource() != &r1 );
|
||||
|
||||
test_type d;
|
||||
VERIFY( d.resource() == &r1 );
|
||||
VERIFY( d != c );
|
||||
VERIFY( d == a );
|
||||
|
||||
std::pmr::set_default_resource(nullptr);
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
// Copyright (C) 2018 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/>.
|
||||
|
||||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do run { target c++17 } }
|
||||
// { dg-skip-if "" { *-*-* } { -fno-aligned-new } }
|
||||
|
||||
#include <memory_resource>
|
||||
#include <testsuite_allocator.h>
|
||||
|
||||
struct X { int i = 0; };
|
||||
|
||||
using test_type = std::pmr::polymorphic_allocator<X>;
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
test_type a, b;
|
||||
VERIFY( a.select_on_container_copy_construction() == a );
|
||||
VERIFY( a.select_on_container_copy_construction() == b );
|
||||
|
||||
__gnu_test::memory_resource r;
|
||||
test_type c(&r);
|
||||
VERIFY( c.select_on_container_copy_construction() != c );
|
||||
VERIFY( c.select_on_container_copy_construction() == a );
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
__gnu_test::memory_resource r;
|
||||
test_type a(&r);
|
||||
VERIFY( a.select_on_container_copy_construction() != a );
|
||||
std::pmr::set_default_resource(&r);
|
||||
VERIFY( a.select_on_container_copy_construction() == a );
|
||||
std::pmr::set_default_resource(nullptr);
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
}
|
|
@ -31,6 +31,10 @@
|
|||
#include <ext/pointer.h>
|
||||
#include <ext/alloc_traits.h>
|
||||
#include <testsuite_hooks.h>
|
||||
#if __cplusplus >= 201703L
|
||||
# include <memory_resource>
|
||||
# include <new>
|
||||
#endif
|
||||
|
||||
namespace __gnu_test
|
||||
{
|
||||
|
@ -691,7 +695,161 @@ namespace __gnu_test
|
|||
using PointerBase_void::PointerBase_void;
|
||||
typedef Derived pointer;
|
||||
};
|
||||
#endif
|
||||
#endif // C++11
|
||||
|
||||
#if __cplusplus >= 201703L && __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)
|
||||
throw bad_size();
|
||||
if (alignment != a->alignment)
|
||||
throw bad_alignment();
|
||||
::operator delete(p, bytes, std::align_val_t(alignment));
|
||||
*aptr = a->next;
|
||||
a->next = lists->freed;
|
||||
lists->freed = a;
|
||||
return;
|
||||
}
|
||||
aptr = &a->next;
|
||||
}
|
||||
throw bad_address();
|
||||
}
|
||||
|
||||
bool
|
||||
do_is_equal(const std::pmr::memory_resource& r) const noexcept override
|
||||
{
|
||||
// Equality is determined by sharing the same allocation_lists object.
|
||||
if (auto p = dynamic_cast<const memory_resource*>(&r))
|
||||
return p->lists == lists;
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
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;
|
||||
};
|
||||
|
||||
// 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 && aligned-new
|
||||
|
||||
} // namespace __gnu_test
|
||||
|
||||
|
|
Loading…
Reference in New Issue