mirror of git://gcc.gnu.org/git/gcc.git
re PR libstdc++/77619 (uninitialized_meow_construct and friends not exception safe)
PR libstdc++/77619 * include/bits/stl_construct.h: (_Construct_novalue): New. (_Destroy_n_aux, _Destroy_n): New. * include/bits/stl_uninitialized.h: (type_traits): New include in C++11 mode. (__uninitialized_default_novalue_1): New. (__uninitialized_default_novalue_n_1): Likewise. (__uninitialized_default_novalue): Likewise. (__uninitialized_default_novalue_n): Likewise. (__uninitialized_copy_n_pair): Likewise. (uninitialized_default_construct): Use __uninitialized_default_novalue. (uninitialized_default_construct_n): Use __uninitialized_default_novalue_n. (uninitialized_value_construct): Use __uninitialized_default. (uninitialized_value_construct_n): Use __uninitialized_default_n. (uninitialized_move): Use uninitialized_copy. (uninitialized_move_n): Use __uninitialized_copy_n_pair. (destroy_at): Use _Destroy. (destroy): Likewise. (destroy_n): Likewise. * testsuite/20_util/specialized_algorithms/ memory_management_tools/1.cc: Add tests for exceptions, add tests for trivial cases for construct and move. From-SVN: r240264
This commit is contained in:
parent
7d9cf80159
commit
377f30c00f
|
|
@ -1,3 +1,30 @@
|
||||||
|
2016-09-20 Ville Voutilainen <ville.voutilainen@gmail.com>
|
||||||
|
|
||||||
|
PR libstdc++/77619
|
||||||
|
* include/bits/stl_construct.h: (_Construct_novalue): New.
|
||||||
|
(_Destroy_n_aux, _Destroy_n): New.
|
||||||
|
* include/bits/stl_uninitialized.h: (type_traits):
|
||||||
|
New include in C++11 mode.
|
||||||
|
(__uninitialized_default_novalue_1): New.
|
||||||
|
(__uninitialized_default_novalue_n_1): Likewise.
|
||||||
|
(__uninitialized_default_novalue): Likewise.
|
||||||
|
(__uninitialized_default_novalue_n): Likewise.
|
||||||
|
(__uninitialized_copy_n_pair): Likewise.
|
||||||
|
(uninitialized_default_construct):
|
||||||
|
Use __uninitialized_default_novalue.
|
||||||
|
(uninitialized_default_construct_n):
|
||||||
|
Use __uninitialized_default_novalue_n.
|
||||||
|
(uninitialized_value_construct): Use __uninitialized_default.
|
||||||
|
(uninitialized_value_construct_n): Use __uninitialized_default_n.
|
||||||
|
(uninitialized_move): Use uninitialized_copy.
|
||||||
|
(uninitialized_move_n): Use __uninitialized_copy_n_pair.
|
||||||
|
(destroy_at): Use _Destroy.
|
||||||
|
(destroy): Likewise.
|
||||||
|
(destroy_n): Likewise.
|
||||||
|
* testsuite/20_util/specialized_algorithms/
|
||||||
|
memory_management_tools/1.cc: Add tests for exceptions,
|
||||||
|
add tests for trivial cases for construct and move.
|
||||||
|
|
||||||
2016-09-20 Jonathan Wakely <jwakely@redhat.com>
|
2016-09-20 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
* python/libstdcxx/v6/xmethods.py (DequeWorkerBase.__init__)
|
* python/libstdcxx/v6/xmethods.py (DequeWorkerBase.__init__)
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template<typename _T1>
|
||||||
|
inline void
|
||||||
|
_Construct_novalue(_T1* __p)
|
||||||
|
{ ::new(static_cast<void*>(__p)) _T1; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy the object pointed to by a pointer type.
|
* Destroy the object pointed to by a pointer type.
|
||||||
*/
|
*/
|
||||||
|
|
@ -127,6 +132,46 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
__destroy(__first, __last);
|
__destroy(__first, __last);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<bool>
|
||||||
|
struct _Destroy_n_aux
|
||||||
|
{
|
||||||
|
template<typename _ForwardIterator, typename _Size>
|
||||||
|
static _ForwardIterator
|
||||||
|
__destroy_n(_ForwardIterator __first, _Size __count)
|
||||||
|
{
|
||||||
|
for (; __count > 0; (void)++__first, --__count)
|
||||||
|
std::_Destroy(std::__addressof(*__first));
|
||||||
|
return __first;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct _Destroy_n_aux<true>
|
||||||
|
{
|
||||||
|
template<typename _ForwardIterator, typename _Size>
|
||||||
|
static _ForwardIterator
|
||||||
|
__destroy_n(_ForwardIterator __first, _Size __count)
|
||||||
|
{
|
||||||
|
std::advance(__first, __count);
|
||||||
|
return __first;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy a range of objects. If the value_type of the object has
|
||||||
|
* a trivial destructor, the compiler should optimize all of this
|
||||||
|
* away, otherwise the objects' destructors must be invoked.
|
||||||
|
*/
|
||||||
|
template<typename _ForwardIterator, typename _Size>
|
||||||
|
inline _ForwardIterator
|
||||||
|
_Destroy_n(_ForwardIterator __first, _Size __count)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<_ForwardIterator>::value_type
|
||||||
|
_Value_type;
|
||||||
|
return std::_Destroy_n_aux<__has_trivial_destructor(_Value_type)>::
|
||||||
|
__destroy_n(__first, __count);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy a range of objects using the supplied allocator. For
|
* Destroy a range of objects using the supplied allocator. For
|
||||||
* nondefault allocators we do not optimize away invocation of
|
* nondefault allocators we do not optimize away invocation of
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,10 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __cplusplus >= 201103L
|
||||||
|
#include <type_traits>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace std _GLIBCXX_VISIBILITY(default)
|
namespace std _GLIBCXX_VISIBILITY(default)
|
||||||
{
|
{
|
||||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
@ -640,6 +644,100 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
allocator<_Tp>&)
|
allocator<_Tp>&)
|
||||||
{ return std::__uninitialized_default_n(__first, __n); }
|
{ return std::__uninitialized_default_n(__first, __n); }
|
||||||
|
|
||||||
|
template<bool _TrivialValueType>
|
||||||
|
struct __uninitialized_default_novalue_1
|
||||||
|
{
|
||||||
|
template<typename _ForwardIterator>
|
||||||
|
static void
|
||||||
|
__uninit_default_novalue(_ForwardIterator __first,
|
||||||
|
_ForwardIterator __last)
|
||||||
|
{
|
||||||
|
_ForwardIterator __cur = __first;
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
for (; __cur != __last; ++__cur)
|
||||||
|
std::_Construct_novalue(std::__addressof(*__cur));
|
||||||
|
}
|
||||||
|
__catch(...)
|
||||||
|
{
|
||||||
|
std::_Destroy(__first, __cur);
|
||||||
|
__throw_exception_again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct __uninitialized_default_novalue_1<true>
|
||||||
|
{
|
||||||
|
template<typename _ForwardIterator>
|
||||||
|
static void
|
||||||
|
__uninit_default_novalue(_ForwardIterator __first,
|
||||||
|
_ForwardIterator __last)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<bool _TrivialValueType>
|
||||||
|
struct __uninitialized_default_novalue_n_1
|
||||||
|
{
|
||||||
|
template<typename _ForwardIterator, typename _Size>
|
||||||
|
static _ForwardIterator
|
||||||
|
__uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
|
||||||
|
{
|
||||||
|
_ForwardIterator __cur = __first;
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
for (; __n > 0; --__n, ++__cur)
|
||||||
|
std::_Construct_novalue(std::__addressof(*__cur));
|
||||||
|
return __cur;
|
||||||
|
}
|
||||||
|
__catch(...)
|
||||||
|
{
|
||||||
|
std::_Destroy(__first, __cur);
|
||||||
|
__throw_exception_again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct __uninitialized_default_novalue_n_1<true>
|
||||||
|
{
|
||||||
|
template<typename _ForwardIterator, typename _Size>
|
||||||
|
static _ForwardIterator
|
||||||
|
__uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// __uninitialized_default_novalue
|
||||||
|
// Fills [first, last) with std::distance(first, last) default-initialized
|
||||||
|
// value_types(s).
|
||||||
|
template<typename _ForwardIterator>
|
||||||
|
inline void
|
||||||
|
__uninitialized_default_novalue(_ForwardIterator __first,
|
||||||
|
_ForwardIterator __last)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<_ForwardIterator>::value_type
|
||||||
|
_ValueType;
|
||||||
|
|
||||||
|
std::__uninitialized_default_novalue_1<
|
||||||
|
is_trivially_default_constructible<_ValueType>::value>::
|
||||||
|
__uninit_default_novalue(__first, __last);
|
||||||
|
}
|
||||||
|
|
||||||
|
// __uninitialized_default_n
|
||||||
|
// Fills [first, first + n) with n default-initialized value_type(s).
|
||||||
|
template<typename _ForwardIterator, typename _Size>
|
||||||
|
inline _ForwardIterator
|
||||||
|
__uninitialized_default_novalue_n(_ForwardIterator __first, _Size __n)
|
||||||
|
{
|
||||||
|
typedef typename iterator_traits<_ForwardIterator>::value_type
|
||||||
|
_ValueType;
|
||||||
|
|
||||||
|
return __uninitialized_default_novalue_n_1<
|
||||||
|
is_trivially_default_constructible<_ValueType>::value>::
|
||||||
|
__uninit_default_novalue_n(__first, __n);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename _InputIterator, typename _Size,
|
template<typename _InputIterator, typename _Size,
|
||||||
typename _ForwardIterator>
|
typename _ForwardIterator>
|
||||||
|
|
@ -669,6 +767,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
random_access_iterator_tag)
|
random_access_iterator_tag)
|
||||||
{ return std::uninitialized_copy(__first, __first + __n, __result); }
|
{ return std::uninitialized_copy(__first, __first + __n, __result); }
|
||||||
|
|
||||||
|
template<typename _InputIterator, typename _Size,
|
||||||
|
typename _ForwardIterator>
|
||||||
|
pair<_InputIterator, _ForwardIterator>
|
||||||
|
__uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
|
||||||
|
_ForwardIterator __result, input_iterator_tag)
|
||||||
|
{
|
||||||
|
_ForwardIterator __cur = __result;
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
for (; __n > 0; --__n, ++__first, ++__cur)
|
||||||
|
std::_Construct(std::__addressof(*__cur), *__first);
|
||||||
|
return {__first, __cur};
|
||||||
|
}
|
||||||
|
__catch(...)
|
||||||
|
{
|
||||||
|
std::_Destroy(__result, __cur);
|
||||||
|
__throw_exception_again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename _RandomAccessIterator, typename _Size,
|
||||||
|
typename _ForwardIterator>
|
||||||
|
inline pair<_RandomAccessIterator, _ForwardIterator>
|
||||||
|
__uninitialized_copy_n_pair(_RandomAccessIterator __first, _Size __n,
|
||||||
|
_ForwardIterator __result,
|
||||||
|
random_access_iterator_tag)
|
||||||
|
{
|
||||||
|
auto __second_res = uninitialized_copy(__first, __first + __n, __result);
|
||||||
|
auto __first_res = std::next(__first, __n);
|
||||||
|
return {__first_res, __second_res};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Copies the range [first,first+n) into result.
|
* @brief Copies the range [first,first+n) into result.
|
||||||
* @param __first An input iterator.
|
* @param __first An input iterator.
|
||||||
|
|
@ -684,6 +814,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
_ForwardIterator __result)
|
_ForwardIterator __result)
|
||||||
{ return std::__uninitialized_copy_n(__first, __n, __result,
|
{ return std::__uninitialized_copy_n(__first, __n, __result,
|
||||||
std::__iterator_category(__first)); }
|
std::__iterator_category(__first)); }
|
||||||
|
|
||||||
|
template<typename _InputIterator, typename _Size, typename _ForwardIterator>
|
||||||
|
inline pair<_InputIterator, _ForwardIterator>
|
||||||
|
__uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
|
||||||
|
_ForwardIterator __result)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
std::__uninitialized_copy_n_pair(__first, __n, __result,
|
||||||
|
std::__iterator_category(__first));
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __cplusplus > 201402L
|
#if __cplusplus > 201402L
|
||||||
|
|
@ -692,19 +833,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
uninitialized_default_construct(_ForwardIterator __first,
|
uninitialized_default_construct(_ForwardIterator __first,
|
||||||
_ForwardIterator __last)
|
_ForwardIterator __last)
|
||||||
{
|
{
|
||||||
for (; __first != __last; ++__first)
|
__uninitialized_default_novalue(__first, __last);
|
||||||
::new (static_cast<void*>(std::__addressof(*__first)))
|
|
||||||
typename iterator_traits<_ForwardIterator>::value_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename _ForwardIterator, typename _Size>
|
template <typename _ForwardIterator, typename _Size>
|
||||||
inline _ForwardIterator
|
inline _ForwardIterator
|
||||||
uninitialized_default_construct_n(_ForwardIterator __first, _Size __count)
|
uninitialized_default_construct_n(_ForwardIterator __first, _Size __count)
|
||||||
{
|
{
|
||||||
for (; __count > 0; (void)++__first, --__count)
|
return __uninitialized_default_novalue_n(__first, __count);
|
||||||
::new (static_cast<void*>(std::__addressof(*__first)))
|
|
||||||
typename iterator_traits<_ForwardIterator>::value_type;
|
|
||||||
return __first;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename _ForwardIterator>
|
template <typename _ForwardIterator>
|
||||||
|
|
@ -712,19 +848,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
uninitialized_value_construct(_ForwardIterator __first,
|
uninitialized_value_construct(_ForwardIterator __first,
|
||||||
_ForwardIterator __last)
|
_ForwardIterator __last)
|
||||||
{
|
{
|
||||||
for (; __first != __last; ++__first)
|
return __uninitialized_default(__first, __last);
|
||||||
::new (static_cast<void*>(std::__addressof(*__first)))
|
|
||||||
typename iterator_traits<_ForwardIterator>::value_type();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename _ForwardIterator, typename _Size>
|
template <typename _ForwardIterator, typename _Size>
|
||||||
inline _ForwardIterator
|
inline _ForwardIterator
|
||||||
uninitialized_value_construct_n(_ForwardIterator __first, _Size __count)
|
uninitialized_value_construct_n(_ForwardIterator __first, _Size __count)
|
||||||
{
|
{
|
||||||
for (; __count > 0; (void)++__first, --__count)
|
return __uninitialized_default_n(__first, __count);
|
||||||
::new (static_cast<void*>(std::__addressof(*__first)))
|
|
||||||
typename iterator_traits<_ForwardIterator>::value_type();
|
|
||||||
return __first;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename _InputIterator, typename _ForwardIterator>
|
template <typename _InputIterator, typename _ForwardIterator>
|
||||||
|
|
@ -732,11 +863,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
uninitialized_move(_InputIterator __first, _InputIterator __last,
|
uninitialized_move(_InputIterator __first, _InputIterator __last,
|
||||||
_ForwardIterator __result)
|
_ForwardIterator __result)
|
||||||
{
|
{
|
||||||
for (; __first != __last; (void)++__result, ++__first)
|
return std::uninitialized_copy
|
||||||
::new (static_cast<void*>(std::__addressof(*__result)))
|
(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
|
||||||
typename
|
_GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result);
|
||||||
iterator_traits<_ForwardIterator>::value_type(std::move(*__first));
|
|
||||||
return __result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename _InputIterator, typename _Size, typename _ForwardIterator>
|
template <typename _InputIterator, typename _Size, typename _ForwardIterator>
|
||||||
|
|
@ -744,35 +873,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
uninitialized_move_n(_InputIterator __first, _Size __count,
|
uninitialized_move_n(_InputIterator __first, _Size __count,
|
||||||
_ForwardIterator __result)
|
_ForwardIterator __result)
|
||||||
{
|
{
|
||||||
for (; __count > 0; ++__result, (void) ++__first, --__count)
|
auto __res = std::__uninitialized_copy_n_pair
|
||||||
::new (static_cast<void*>(std::__addressof(*__result)))
|
(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
|
||||||
typename
|
__count, __result);
|
||||||
iterator_traits<_ForwardIterator>::value_type(std::move(*__first));
|
return {__res.first.base(), __res.second};
|
||||||
return {__first, __result};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename _Tp>
|
template <typename _Tp>
|
||||||
inline void
|
inline void
|
||||||
destroy_at(_Tp* __location)
|
destroy_at(_Tp* __location)
|
||||||
{
|
{
|
||||||
__location->~_Tp();
|
std::_Destroy(__location);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename _ForwardIterator>
|
template <typename _ForwardIterator>
|
||||||
inline void
|
inline void
|
||||||
destroy(_ForwardIterator __first, _ForwardIterator __last)
|
destroy(_ForwardIterator __first, _ForwardIterator __last)
|
||||||
{
|
{
|
||||||
for (; __first != __last; ++__first)
|
std::_Destroy(__first, __last);
|
||||||
std::destroy_at(std::__addressof(*__first));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename _ForwardIterator, typename _Size>
|
template <typename _ForwardIterator, typename _Size>
|
||||||
inline _ForwardIterator
|
inline _ForwardIterator
|
||||||
destroy_n(_ForwardIterator __first, _Size __count)
|
destroy_n(_ForwardIterator __first, _Size __count)
|
||||||
{
|
{
|
||||||
for (; __count > 0; (void)++__first, --__count)
|
return std::_Destroy_n(__first, __count);
|
||||||
std::destroy_at(std::__addressof(*__first));
|
|
||||||
return __first;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -21,14 +21,40 @@
|
||||||
#include <testsuite_hooks.h>
|
#include <testsuite_hooks.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
int del_count = 0;
|
int del_count = 0;
|
||||||
|
int ctor_count = 0;
|
||||||
|
int throw_after = 0;
|
||||||
|
|
||||||
struct DelCount
|
struct DelCount
|
||||||
{
|
{
|
||||||
~DelCount() { ++del_count; }
|
~DelCount() { ++del_count; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ThrowAfterN
|
||||||
|
{
|
||||||
|
ThrowAfterN()
|
||||||
|
{
|
||||||
|
if (++ctor_count == throw_after) {
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "ThrowAfterN(), ctor_count: " << ctor_count
|
||||||
|
<< " throw_after: " << throw_after << std::endl;
|
||||||
|
throw std::runtime_error(os.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ThrowAfterN(ThrowAfterN&&)
|
||||||
|
{
|
||||||
|
if (++ctor_count == throw_after) {
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "ThrowAfterN(), ctor_count: " << ctor_count
|
||||||
|
<< " throw_after: " << throw_after << std::endl;
|
||||||
|
throw std::runtime_error(os.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DelCount dc;
|
||||||
|
};
|
||||||
|
|
||||||
void test01()
|
void test01()
|
||||||
{
|
{
|
||||||
char test_data[] = "123456";
|
char test_data[] = "123456";
|
||||||
|
|
@ -118,6 +144,153 @@ void test09()
|
||||||
free(target);
|
free(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test10()
|
||||||
|
{
|
||||||
|
char* x = (char*)malloc(sizeof(char)*10);
|
||||||
|
for (int i = 0; i < 10; ++i) new (x+i) char;
|
||||||
|
std::destroy(x, x+10);
|
||||||
|
free(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test11()
|
||||||
|
{
|
||||||
|
char* x = (char*)malloc(sizeof(char)*10);
|
||||||
|
for (int i = 0; i < 10; ++i) new (x+i) char;
|
||||||
|
std::destroy_n(x, 10);
|
||||||
|
free(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test12()
|
||||||
|
{
|
||||||
|
throw_after = 5;
|
||||||
|
del_count = 0;
|
||||||
|
ctor_count = 0;
|
||||||
|
ThrowAfterN* target =
|
||||||
|
(ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10);
|
||||||
|
try {
|
||||||
|
std::uninitialized_default_construct(target, target+10);
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
VERIFY(ctor_count == 5);
|
||||||
|
VERIFY(del_count == 5);
|
||||||
|
throw_after = 0;
|
||||||
|
del_count = 0;
|
||||||
|
ctor_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test13()
|
||||||
|
{
|
||||||
|
throw_after = 5;
|
||||||
|
del_count = 0;
|
||||||
|
ctor_count = 0;
|
||||||
|
ThrowAfterN* target =
|
||||||
|
(ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10);
|
||||||
|
try {
|
||||||
|
std::uninitialized_value_construct(target, target+10);
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
VERIFY(ctor_count == 5);
|
||||||
|
VERIFY(del_count == 5);
|
||||||
|
throw_after = 0;
|
||||||
|
del_count = 0;
|
||||||
|
ctor_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test14()
|
||||||
|
{
|
||||||
|
throw_after = 5;
|
||||||
|
del_count = 0;
|
||||||
|
ctor_count = 0;
|
||||||
|
ThrowAfterN* target =
|
||||||
|
(ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10);
|
||||||
|
try {
|
||||||
|
std::uninitialized_default_construct_n(target, 10);
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
VERIFY(ctor_count == 5);
|
||||||
|
VERIFY(del_count == 5);
|
||||||
|
throw_after = 0;
|
||||||
|
del_count = 0;
|
||||||
|
ctor_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test15()
|
||||||
|
{
|
||||||
|
throw_after = 5;
|
||||||
|
del_count = 0;
|
||||||
|
ctor_count = 0;
|
||||||
|
ThrowAfterN* target =
|
||||||
|
(ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10);
|
||||||
|
try {
|
||||||
|
std::uninitialized_value_construct_n(target, 10);
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
VERIFY(ctor_count == 5);
|
||||||
|
VERIFY(del_count == 5);
|
||||||
|
throw_after = 0;
|
||||||
|
del_count = 0;
|
||||||
|
ctor_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test16()
|
||||||
|
{
|
||||||
|
std::vector<ThrowAfterN> source(10);
|
||||||
|
del_count = 0;
|
||||||
|
ctor_count = 0;
|
||||||
|
throw_after = 5;
|
||||||
|
throw_after = 5;
|
||||||
|
ThrowAfterN* target =
|
||||||
|
(ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10);
|
||||||
|
try {
|
||||||
|
std::uninitialized_move(source.begin(), source.end(), target);
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
VERIFY(ctor_count == 5);
|
||||||
|
VERIFY(del_count == 5);
|
||||||
|
throw_after = 0;
|
||||||
|
del_count = 0;
|
||||||
|
ctor_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test17()
|
||||||
|
{
|
||||||
|
std::vector<ThrowAfterN> source(10);
|
||||||
|
del_count = 0;
|
||||||
|
ctor_count = 0;
|
||||||
|
throw_after = 5;
|
||||||
|
ThrowAfterN* target =
|
||||||
|
(ThrowAfterN*)malloc(sizeof(ThrowAfterN)*10);
|
||||||
|
try {
|
||||||
|
std::uninitialized_move_n(source.begin(), 10, target);
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
VERIFY(ctor_count == 5);
|
||||||
|
VERIFY(del_count == 5);
|
||||||
|
throw_after = 0;
|
||||||
|
del_count = 0;
|
||||||
|
ctor_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test18()
|
||||||
|
{
|
||||||
|
char test_source[] = "123456";
|
||||||
|
char test_target[] = "000000";
|
||||||
|
std::uninitialized_move(std::begin(test_source),
|
||||||
|
std::end(test_source),
|
||||||
|
test_target);
|
||||||
|
VERIFY(std::string(test_target) == "123456");
|
||||||
|
}
|
||||||
|
|
||||||
|
void test19()
|
||||||
|
{
|
||||||
|
char test_source[] = "123456";
|
||||||
|
char test_target[] = "000000";
|
||||||
|
std::uninitialized_move_n(std::begin(test_source),
|
||||||
|
6,
|
||||||
|
test_target);
|
||||||
|
VERIFY(std::string(test_target) == "123456");
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
test01();
|
test01();
|
||||||
|
|
@ -129,4 +302,14 @@ int main()
|
||||||
test07();
|
test07();
|
||||||
test08();
|
test08();
|
||||||
test09();
|
test09();
|
||||||
|
test10();
|
||||||
|
test11();
|
||||||
|
test12();
|
||||||
|
test13();
|
||||||
|
test14();
|
||||||
|
test15();
|
||||||
|
test16();
|
||||||
|
test17();
|
||||||
|
test18();
|
||||||
|
test19();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue