diff options
-rw-r--r-- | libstdc++-v3/ChangeLog | 23 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/gslice_array.h | 5 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/mask_array.h | 5 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/slice_array.h | 5 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/valarray_after.h | 11 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/valarray_before.h | 43 | ||||
-rw-r--r-- | libstdc++-v3/include/std/valarray | 11 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/26_numerics/valarray/83860.cc | 110 |
8 files changed, 195 insertions, 18 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 8aca0a3..7b17bd2 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,28 @@ 2018-05-02 Jonathan Wakely <jwakely@redhat.com> + PR libstdc++/57997 + PR libstdc++/83860 + * include/bits/gslice_array.h (gslice_array): Define default + constructor as deleted, as per C++11 standard. + * include/bits/mask_array.h (mask_array): Likewise. + * include/bits/slice_array.h (slice_array): Likewise. + * include/bits/valarray_after.h (_GBase, _GClos, _IBase, _IClos): Move + to namespace __detail. + (_GBase::_M_expr, _IBase::_M_expr): Use _ValArrayRef for type of data + members. + * include/bits/valarray_before.h (_ValArrayRef): New helper for type + of data members in closure objects. + (_FunBase, _ValFunClos, _RefFunClos, _UnBase, _UnClos, _BinBase) + (_BinBase2, _BinBase1, _BinClos, _SBase, _SClos): Move to namespace + __detail. + (_FunBase::_M_expr, _UnBase::_M_expr, _BinBase::_M_expr1) + (_BinBase::_M_expr2, _BinBase2::_M_expr1, _BinBase1::_M_expr2) + (_SBase::_M_expr): Use _ValArrayRef for type of data members. + * include/std/valarray (_UnClos, _BinClos, _SClos, _GClos, _IClos) + (_ValFunClos, _RefFunClos): Move to namespace __detail and add + using-declarations to namespace std. + * testsuite/26_numerics/valarray/83860.cc: New. + * testsuite/backward/strstream_move.cc: Remove duplicate function call. diff --git a/libstdc++-v3/include/bits/gslice_array.h b/libstdc++-v3/include/bits/gslice_array.h index 2da7e04..715c53b 100644 --- a/libstdc++-v3/include/bits/gslice_array.h +++ b/libstdc++-v3/include/bits/gslice_array.h @@ -128,8 +128,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION gslice_array(_Array<_Tp>, const valarray<size_t>&); +#if __cplusplus < 201103L // not implemented gslice_array(); +#else + public: + gslice_array() = delete; +#endif }; template<typename _Tp> diff --git a/libstdc++-v3/include/bits/mask_array.h b/libstdc++-v3/include/bits/mask_array.h index 84671cb..c11691a 100644 --- a/libstdc++-v3/include/bits/mask_array.h +++ b/libstdc++-v3/include/bits/mask_array.h @@ -131,8 +131,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const _Array<bool> _M_mask; const _Array<_Tp> _M_array; +#if __cplusplus < 201103L // not implemented mask_array(); +#else + public: + mask_array() = delete; +#endif }; template<typename _Tp> diff --git a/libstdc++-v3/include/bits/slice_array.h b/libstdc++-v3/include/bits/slice_array.h index 05b096b..b025373 100644 --- a/libstdc++-v3/include/bits/slice_array.h +++ b/libstdc++-v3/include/bits/slice_array.h @@ -192,8 +192,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const size_t _M_stride; const _Array<_Tp> _M_array; +#if __cplusplus < 201103L // not implemented slice_array(); +#else + public: + slice_array() = delete; +#endif }; template<typename _Tp> diff --git a/libstdc++-v3/include/bits/valarray_after.h b/libstdc++-v3/include/bits/valarray_after.h index 7f62b29..bb1a3c9 100644 --- a/libstdc++-v3/include/bits/valarray_after.h +++ b/libstdc++-v3/include/bits/valarray_after.h @@ -38,6 +38,8 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +namespace __detail +{ // // gslice_array closure. // @@ -59,8 +61,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return _M_index.size(); } private: - const _Dom& _M_expr; - const valarray<size_t>& _M_index; + typename _ValArrayRef<_Dom>::__type _M_expr; + const valarray<size_t>& _M_index; }; template<typename _Tp> @@ -128,8 +130,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return _M_index.size(); } private: - const _Dom& _M_expr; - const valarray<size_t>& _M_index; + typename _ValArrayRef<_Dom>::__type _M_expr; + const valarray<size_t>& _M_index; }; template<class _Dom> @@ -153,6 +155,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _IClos (const valarray<_Tp>& __a, const valarray<size_t>& __i) : _Base (__a, __i) {} }; +} // namespace __detail // // class _Expr diff --git a/libstdc++-v3/include/bits/valarray_before.h b/libstdc++-v3/include/bits/valarray_before.h index a77fdf2..fe41787 100644 --- a/libstdc++-v3/include/bits/valarray_before.h +++ b/libstdc++-v3/include/bits/valarray_before.h @@ -406,6 +406,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef bool result_type; }; +namespace __detail +{ + // Closure types already have reference semantics and are often short-lived, + // so store them by value to avoid (some cases of) dangling references to + // out-of-scope temporaries. + template<typename _Tp> + struct _ValArrayRef + { typedef const _Tp __type; }; + + // Use real references for std::valarray objects. + template<typename _Tp> + struct _ValArrayRef< valarray<_Tp> > + { typedef const valarray<_Tp>& __type; }; + // // Apply function taking a value/const reference closure // @@ -425,7 +439,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION size_t size() const { return _M_expr.size ();} private: - const _Dom& _M_expr; + typename _ValArrayRef<_Dom>::__type _M_expr; value_type (*_M_func)(_Arg); }; @@ -490,7 +504,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION size_t size() const { return _M_expr.size(); } private: - const _Arg& _M_expr; + typename _ValArrayRef<_Arg>::__type _M_expr; }; template<class _Oper, class _Dom> @@ -536,8 +550,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION size_t size() const { return _M_expr1.size(); } private: - const _FirstArg& _M_expr1; - const _SecondArg& _M_expr2; + typename _ValArrayRef<_FirstArg>::__type _M_expr1; + typename _ValArrayRef<_SecondArg>::__type _M_expr2; }; @@ -557,8 +571,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION size_t size() const { return _M_expr1.size(); } private: - const _Clos& _M_expr1; - const _Vt& _M_expr2; + typename _ValArrayRef<_Clos>::__type _M_expr1; + _Vt _M_expr2; }; template<class _Oper, class _Clos> @@ -577,8 +591,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION size_t size() const { return _M_expr2.size(); } private: - const _Vt& _M_expr1; - const _Clos& _M_expr2; + _Vt _M_expr1; + typename _ValArrayRef<_Clos>::__type _M_expr2; }; template<class _Oper, class _Dom1, class _Dom2> @@ -592,7 +606,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; template<class _Oper, typename _Tp> - struct _BinClos<_Oper,_ValArray, _ValArray, _Tp, _Tp> + struct _BinClos<_Oper, _ValArray, _ValArray, _Tp, _Tp> : _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > { typedef _BinBase<_Oper, valarray<_Tp>, valarray<_Tp> > _Base; @@ -668,10 +682,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _BinClos(const _Tp& __t, const valarray<_Tp>& __v) : _Base(__t, __v) {} }; - // - // slice_array closure. - // - template<typename _Dom> + // + // slice_array closure. + // + template<typename _Dom> class _SBase { public: @@ -689,7 +703,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return _M_slice.size (); } private: - const _Dom& _M_expr; + typename _ValArrayRef<_Dom>::__type _M_expr; const slice& _M_slice; }; @@ -736,6 +750,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _SClos (_Array<_Tp> __a, const slice& __s) : _Base (__a, __s) {} }; +} // namespace __detail _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/include/std/valarray b/libstdc++-v3/include/std/valarray index 761a2fc..03e0bad 100644 --- a/libstdc++-v3/include/std/valarray +++ b/libstdc++-v3/include/std/valarray @@ -51,6 +51,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp1, typename _Tp2> class _ValArray; +namespace __detail +{ template<class _Oper, template<class, class> class _Meta, class _Dom> struct _UnClos; @@ -74,6 +76,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<template<class, class> class _Meta, class _Dom> class _RefFunClos; +} // namespace __detail + + using __detail::_UnClos; + using __detail::_BinClos; + using __detail::_SClos; + using __detail::_GClos; + using __detail::_IClos; + using __detail::_ValFunClos; + using __detail::_RefFunClos; template<class _Tp> class valarray; // An array of type _Tp class slice; // BLAS-like slice out of an array diff --git a/libstdc++-v3/testsuite/26_numerics/valarray/83860.cc b/libstdc++-v3/testsuite/26_numerics/valarray/83860.cc new file mode 100644 index 0000000..6d82ef5 --- /dev/null +++ b/libstdc++-v3/testsuite/26_numerics/valarray/83860.cc @@ -0,0 +1,110 @@ +// 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-do run { target c++11 } } + +#include <valarray> +#include <testsuite_hooks.h> + +const std::valarray<int> v{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 +}; + +bool +all_of(const std::valarray<bool>& vals) +{ + for (bool b : vals) + if (!b) + return false; + return true; +} + +void +test01() +{ + // PR libstdc++/83860 + const std::valarray<int> va(v), vb(v), vc(v); + auto sum = va + vb + vc; + std::valarray<int> vsum = sum; + VERIFY( all_of( vsum == (3 * v) ) ); +} + +void +test02() +{ + auto neg = -(-v); + std::valarray<int> vneg = neg; + VERIFY( all_of( vneg == v ) ); +} + +void +test03() +{ + const std::valarray<int> va(v), vb(v); + auto diff = va + -vb; + std::valarray<int> vdiff = diff; + VERIFY( all_of( vdiff == (va - vb) ) ); +} + +void +test04() +{ + const std::valarray<int> va(v), vb(v); + auto sum = -va + -vb; + std::valarray<int> vsum = sum; + VERIFY( all_of( vsum == (-2 * v) ) ); +} + +void +test05() +{ + const std::valarray<int> va(v), vb(v); + auto sum = -(-va + -vb); + std::valarray<int> vsum = sum; + VERIFY( all_of( vsum == (2 * v) ) ); +} + +void +test06() +{ + auto prod = 3 * +v * 2; + std::valarray<int> vprod = prod; + VERIFY( all_of( vprod == (6 * v) ) ); +} + +void +test07() +{ + const std::valarray<int> va(v), vb(v); + auto valfun = [](int i) { return i; }; + auto reffun = [](const int& i) { return i; }; + auto sum = (va.apply(valfun) + vb.apply(reffun)); + std::valarray<int> vsum = sum; + VERIFY( all_of( vsum == (va + vb) ) ); +} + +int +main() +{ + test01(); + test02(); + test03(); + test04(); + test05(); + test06(); + test07(); +} |