From: Ville Voutilainen Date: Tue, 13 Sep 2016 19:26:02 +0000 (+0300) Subject: Implement P0040R3, Extending memory management tools. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8e14a10cab52b37c56019b738011f8e4cef28d5a;p=gcc.git Implement P0040R3, Extending memory management tools. * include/bits/stl_uninitialized.h (utility): New include in C++17 mode. (uninitialized_default_construct): New. (uninitialized_default_construct_n): Likewise. (uninitialized_value_construct): Likewise. (uninitialized_value_construct_n): Likewise. (uninitialized_move): Likewise. (uninitialized_move_n): Likewise. (destroy_at, destroy, destroy_n): Likewise. * testsuite/20_util/specialized_algorithms/memory_management_tools/1.cc: New. From-SVN: r240122 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index a646efc482e..efd17fba91a 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,18 @@ +2016-09-13 Ville Voutilainen + + Implement P0040R3, Extending memory management tools. + * include/bits/stl_uninitialized.h (utility): New include + in C++17 mode. + (uninitialized_default_construct): New. + (uninitialized_default_construct_n): Likewise. + (uninitialized_value_construct): Likewise. + (uninitialized_value_construct_n): Likewise. + (uninitialized_move): Likewise. + (uninitialized_move_n): Likewise. + (destroy_at, destroy, destroy_n): Likewise. + * testsuite/20_util/specialized_algorithms/memory_management_tools/1.cc: + New. + 2016-09-12 Jason Merrill * config/abi/pre/gnu.ver: Use [jmy] for size_t. diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h index 6cfba13cb93..c5c81fb2c66 100644 --- a/libstdc++-v3/include/bits/stl_uninitialized.h +++ b/libstdc++-v3/include/bits/stl_uninitialized.h @@ -56,6 +56,10 @@ #ifndef _STL_UNINITIALIZED_H #define _STL_UNINITIALIZED_H 1 +#if __cplusplus > 201402L +#include +#endif + namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -682,6 +686,98 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::__iterator_category(__first)); } #endif +#if __cplusplus > 201402L + template + inline void + uninitialized_default_construct(_ForwardIterator __first, + _ForwardIterator __last) + { + for (; __first != __last; ++__first) + ::new (static_cast(std::__addressof(*__first))) + typename iterator_traits<_ForwardIterator>::value_type; + } + + template + inline _ForwardIterator + uninitialized_default_construct_n(_ForwardIterator __first, _Size __count) + { + for (; __count > 0; (void)++__first, --__count) + ::new (static_cast(std::__addressof(*__first))) + typename iterator_traits<_ForwardIterator>::value_type; + return __first; + } + + template + inline void + uninitialized_value_construct(_ForwardIterator __first, + _ForwardIterator __last) + { + for (; __first != __last; ++__first) + ::new (static_cast(std::__addressof(*__first))) + typename iterator_traits<_ForwardIterator>::value_type(); + } + + template + inline _ForwardIterator + uninitialized_value_construct_n(_ForwardIterator __first, _Size __count) + { + for (; __count > 0; (void)++__first, --__count) + ::new (static_cast(std::__addressof(*__first))) + typename iterator_traits<_ForwardIterator>::value_type(); + return __first; + } + + template + inline _ForwardIterator + uninitialized_move(_InputIterator __first, _InputIterator __last, + _ForwardIterator __result) + { + for (; __first != __last; (void)++__result, ++__first) + ::new (static_cast(std::__addressof(*__result))) + typename + iterator_traits<_ForwardIterator>::value_type(std::move(*__first)); + return __result; + } + + template + inline pair<_InputIterator, _ForwardIterator> + uninitialized_move_n(_InputIterator __first, _Size __count, + _ForwardIterator __result) + { + for (; __count > 0; ++__result, (void) ++__first, --__count) + ::new (static_cast(std::__addressof(*__result))) + typename + iterator_traits<_ForwardIterator>::value_type(std::move(*__first)); + return {__first, __result}; + } + + template + inline void + destroy_at(_Tp* __location) + { + __location->~_Tp(); + } + + template + inline void + destroy(_ForwardIterator __first, _ForwardIterator __last) + { + for (; __first != __last; ++__first) + std::destroy_at(std::__addressof(*__first)); + } + + template + inline _ForwardIterator + destroy_n(_ForwardIterator __first, _Size __count) + { + for (; __count > 0; (void)++__first, --__count) + std::destroy_at(std::__addressof(*__first)); + return __first; + } + +#endif + + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/memory_management_tools/1.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/memory_management_tools/1.cc new file mode 100644 index 00000000000..ec72b826a53 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/memory_management_tools/1.cc @@ -0,0 +1,132 @@ +// Copyright (C) 2016 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 +// . + +// { dg-options "-std=gnu++17" } + +#include +#include +#include +#include + +int del_count = 0; + +struct DelCount +{ + ~DelCount() { ++del_count; } +}; + +void test01() +{ + char test_data[] = "123456"; + std::uninitialized_default_construct(std::begin(test_data), + std::end(test_data)); + VERIFY(std::string(test_data) == "123456"); +} + +void test02() +{ + char test_data[] = "123456"; + std::uninitialized_value_construct(std::begin(test_data), + std::end(test_data)); + VERIFY(std::string(test_data, 6) == std::string("\0\0\0\0\0\0", 6)); +} + +void test03() +{ + char test_data[] = "123456"; + std::uninitialized_default_construct_n(std::begin(test_data), 6); + VERIFY(std::string(test_data) == "123456"); +} + +void test04() +{ + char test_data[] = "123456"; + std::uninitialized_value_construct_n(std::begin(test_data), 6); + VERIFY(std::string(test_data, 6) == std::string("\0\0\0\0\0\0", 6)); +} + +void test05() +{ + del_count = 0; + DelCount* x = (DelCount*)malloc(sizeof(DelCount)); + new (x) DelCount; + std::destroy_at(&x[0]); + VERIFY(del_count == 1); + del_count = 0; + free(x); +} + +void test06() +{ + del_count = 0; + DelCount* x = (DelCount*)malloc(sizeof(DelCount)*10); + for (int i = 0; i < 10; ++i) new (x+i) DelCount; + std::destroy(x, x+10); + VERIFY(del_count == 10); + del_count = 0; + free(x); +} + +void test07() +{ + del_count = 0; + DelCount* x = (DelCount*)malloc(sizeof(DelCount)*10); + for (int i = 0; i < 10; ++i) new (x+i) DelCount; + std::destroy_n(x, 10); + VERIFY(del_count == 10); + del_count = 0; + free(x); +} + +void test08() +{ + std::vector> source; + for (int i = 0; i < 10; ++i) source.push_back(std::make_unique(i)); + std::unique_ptr* target = + (std::unique_ptr*)malloc(sizeof(std::unique_ptr)*10); + std::uninitialized_move(source.begin(), source.end(), target); + for (const auto& x : source) VERIFY(!x); + for (int i = 0; i < 10; ++i) VERIFY(bool(*(target+i))); + std::destroy_n(target, 10); + free(target); +} + +void test09() +{ + std::vector> source; + for (int i = 0; i < 10; ++i) source.push_back(std::make_unique(i)); + std::unique_ptr* target = + (std::unique_ptr*)malloc(sizeof(std::unique_ptr)*10); + std::uninitialized_move_n(source.begin(), 10, target); + for (const auto& x : source) VERIFY(!x); + for (int i = 0; i < 10; ++i) VERIFY(bool(*(target+i))); + std::destroy_n(target, 10); + free(target); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); + test05(); + test06(); + test07(); + test08(); + test09(); +}