From 3cb1f25f7522af0bfbb636525b99674e608a5224 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Sat, 30 Oct 2021 12:36:59 +0300 Subject: [PATCH 01/12] : _RERAISE -> scope guard Towards #2307 --- stl/inc/deque | 53 +++++++++++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/stl/inc/deque b/stl/inc/deque index b57c45eb523..2173b59d001 100644 --- a/stl/inc/deque +++ b/stl/inc/deque @@ -1220,6 +1220,24 @@ public: return begin() + static_cast(_Off); } + template + struct _Restore_old_size_guard { + deque* _Container; + const size_type _Oldsize; + + ~_Restore_old_size_guard() { + if (_Container) { + while (_Oldsize < _Container->_Mysize()) { + if constexpr (_Front) { + _Container->pop_front(); // restore old size, at least + } else { + _Container->pop_back(); // restore old size, at least + } + } + } + } + }; + template , int> = 0> iterator insert(const_iterator _Where, _Iter _First, _Iter _Last) { // insert [_First, _Last) at _Where, input iterators @@ -1237,37 +1255,25 @@ public: if (_UFirst != _ULast) { if (_Off <= _Mysize() / 2) { // closer to front, push to front then rotate - _TRY_BEGIN + _Restore_old_size_guard _Guard{this, _Oldsize}; for (; _UFirst != _ULast; ++_UFirst) { emplace_front(*_UFirst); // prepend flipped } - _CATCH_ALL - while (_Oldsize < _Mysize()) { - pop_front(); // restore old size, at least - } - - _RERAISE; - _CATCH_END + _Guard._Container = nullptr; size_type _Num = _Mysize() - _Oldsize; _STD reverse(begin(), begin() + static_cast(_Num)); // flip new stuff in place _STD rotate(begin(), begin() + static_cast(_Num), begin() + static_cast(_Num + _Off)); } else { // closer to back - _TRY_BEGIN + _Restore_old_size_guard _Guard{this, _Oldsize}; _Orphan_all(); for (; _UFirst != _ULast; ++_UFirst) { _Emplace_back_internal(*_UFirst); } - _CATCH_ALL - while (_Oldsize < _Mysize()) { - pop_back(); // restore old size, at least - } - - _RERAISE; - _CATCH_END + _Guard._Container = nullptr; _STD rotate(begin() + static_cast(_Off), begin() + static_cast(_Oldsize), end()); @@ -1362,7 +1368,7 @@ private: #endif // _ITERATOR_DEBUG_LEVEL == 2 if (_Off < _Rem) { // closer to front - _TRY_BEGIN + _Restore_old_size_guard _Guard{this, _Oldsize}; if (_Off < _Count) { // insert longer than prefix for (_Num = _Count - _Off; 0 < _Num; --_Num) { push_front(_Val); // push excess values @@ -1385,15 +1391,8 @@ private: _STD fill(begin() + static_cast(_Off), _Mid + static_cast(_Off), _Tmp._Get_value()); // fill in values } - _CATCH_ALL - while (_Oldsize < _Mysize()) { - pop_front(); // restore old size, at least - } - - _RERAISE; - _CATCH_END } else { // closer to back - _TRY_BEGIN + _Restore_old_size_guard _Guard{this, _Oldsize}; if (_Rem < _Count) { // insert longer than suffix _Orphan_all(); for (_Num = _Count - _Rem; 0 < _Num; --_Num) { @@ -1418,10 +1417,6 @@ private: _STD fill(_Mid, _Mid + static_cast(_Count), _Tmp._Get_value()); // fill in values } - _CATCH_ALL - _Erase_last_n(_Mysize() - _Oldsize); - _RERAISE; - _CATCH_END } } From 7026f01f9b7c7021db5e2983269d19272b907ec7 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Sat, 30 Oct 2021 12:40:34 +0300 Subject: [PATCH 02/12] exit guard --- stl/inc/deque | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/stl/inc/deque b/stl/inc/deque index 2173b59d001..44cea4f092a 100644 --- a/stl/inc/deque +++ b/stl/inc/deque @@ -1379,6 +1379,8 @@ private: _Mid = begin() + static_cast(_Count); _STD fill(_Mid, _Mid + static_cast(_Off), _Val); // fill in rest of values + + _Guard._Container = nullptr; } else { // insert not longer than prefix for (_Num = _Count; 0 < _Num; --_Num) { push_front(begin()[static_cast(_Count - 1)]); // push part of prefix @@ -1390,6 +1392,8 @@ private: _Mid); // copy rest of prefix _STD fill(begin() + static_cast(_Off), _Mid + static_cast(_Off), _Tmp._Get_value()); // fill in values + + _Guard._Container = nullptr; } } else { // closer to back _Restore_old_size_guard _Guard{this, _Oldsize}; From ae22e86f58e61c8611b92e50d3fd5004cc0f509b Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Sat, 30 Oct 2021 12:41:53 +0300 Subject: [PATCH 03/12] exit guard right --- stl/inc/deque | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/stl/inc/deque b/stl/inc/deque index 44cea4f092a..f4e46072189 100644 --- a/stl/inc/deque +++ b/stl/inc/deque @@ -1380,7 +1380,6 @@ private: _Mid = begin() + static_cast(_Count); _STD fill(_Mid, _Mid + static_cast(_Off), _Val); // fill in rest of values - _Guard._Container = nullptr; } else { // insert not longer than prefix for (_Num = _Count; 0 < _Num; --_Num) { push_front(begin()[static_cast(_Count - 1)]); // push part of prefix @@ -1392,9 +1391,8 @@ private: _Mid); // copy rest of prefix _STD fill(begin() + static_cast(_Off), _Mid + static_cast(_Off), _Tmp._Get_value()); // fill in values - - _Guard._Container = nullptr; } + _Guard._Container = nullptr; } else { // closer to back _Restore_old_size_guard _Guard{this, _Oldsize}; if (_Rem < _Count) { // insert longer than suffix @@ -1421,6 +1419,7 @@ private: _STD fill(_Mid, _Mid + static_cast(_Count), _Tmp._Get_value()); // fill in values } + _Guard._Container = nullptr; } } From 45160c52ca71cd9d82861683070c5e01ac510fff Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Sat, 30 Oct 2021 14:19:44 +0300 Subject: [PATCH 04/12] test for strong exception guarantee preserved --- tests/std/test.lst | 1 + .../tests/GH_002307_usual_scope_guard/env.lst | 4 + .../GH_002307_usual_scope_guard/test.cpp | 90 +++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 tests/std/tests/GH_002307_usual_scope_guard/env.lst create mode 100644 tests/std/tests/GH_002307_usual_scope_guard/test.cpp diff --git a/tests/std/test.lst b/tests/std/test.lst index ceb95122ef5..41922799a0e 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -188,6 +188,7 @@ tests\GH_001914_cached_position tests\GH_002039_byte_is_not_trivially_swappable tests\GH_002058_debug_iterator_race tests\GH_002120_streambuf_seekpos_and_seekoff +tests\GH_002307_usual_scope_guard tests\LWG2597_complex_branch_cut tests\LWG3018_shared_ptr_function tests\LWG3422_seed_seq_ctors diff --git a/tests/std/tests/GH_002307_usual_scope_guard/env.lst b/tests/std/tests/GH_002307_usual_scope_guard/env.lst new file mode 100644 index 00000000000..19f025bd0e6 --- /dev/null +++ b/tests/std/tests/GH_002307_usual_scope_guard/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\usual_matrix.lst diff --git a/tests/std/tests/GH_002307_usual_scope_guard/test.cpp b/tests/std/tests/GH_002307_usual_scope_guard/test.cpp new file mode 100644 index 00000000000..78549d58a9d --- /dev/null +++ b/tests/std/tests/GH_002307_usual_scope_guard/test.cpp @@ -0,0 +1,90 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#define _CORE_HEADERS_ONLY + +#include +#include +#include + +using namespace std; + +struct bomb { + int val; + + static int countdown; + + void tick() { + if (countdown == 0) { + throw runtime_error("BOOM"); + } else { + --countdown; + } + } + + bomb(int init) : val(init) { + tick(); + } + + bomb(const bomb& other) : val(other.val) { + tick(); + } + + bomb& operator=(const bomb& other) { + val = other.val; + return *this; + } + + bool operator==(int other) const { + return val == other; + } +}; + +int bomb::countdown = 0; + + +int main() { + const int data[] = {1, 2, 3, 4, 5, 6, 7}; + + bomb::countdown = 8; + + deque dq(begin(data), end(data)); + + try { + bomb::countdown = 3; + const int data_x[] = {10, 11, 12, 13, 14}; + dq.insert(dq.end() - 2, begin(data_x), end(data_x)); + abort(); + } catch (runtime_error&) { + } + + assert(equal(dq.begin(), dq.end(), data)); + + try { + bomb::countdown = 3; + const int data_x[] = {10, 11, 12, 13, 14}; + dq.insert(dq.begin() + 2, begin(data_x), end(data_x)); + abort(); + } catch (runtime_error&) { + } + + assert(equal(dq.begin(), dq.end(), data)); + + try { + bomb::countdown = 3; + dq.insert(dq.end() - 2, 6, 10); + abort(); + } catch (runtime_error&) { + } + + assert(equal(dq.begin(), dq.end(), data)); + + try { + bomb::countdown = 3; + dq.insert(dq.begin() + 2, 6, 11); + abort(); + } catch (runtime_error&) { + } + + assert(equal(dq.begin(), dq.end(), data)); +} From f013e32157c50b6becfcd5b2aeefd90dd83ffd55 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Sat, 30 Oct 2021 15:22:26 +0300 Subject: [PATCH 05/12] @miscco still does not like my bools --- stl/inc/deque | 18 ++++--- .../GH_002307_usual_scope_guard/test.cpp | 50 ++++++++++++------- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/stl/inc/deque b/stl/inc/deque index f4e46072189..760da70539e 100644 --- a/stl/inc/deque +++ b/stl/inc/deque @@ -1220,7 +1220,12 @@ public: return begin() + static_cast(_Off); } - template + enum class _Restore_old_size_guard_direction : bool { + _Remove_front, + _Remove_back, + }; + + template <_Restore_old_size_guard_direction _Direction> struct _Restore_old_size_guard { deque* _Container; const size_type _Oldsize; @@ -1228,7 +1233,7 @@ public: ~_Restore_old_size_guard() { if (_Container) { while (_Oldsize < _Container->_Mysize()) { - if constexpr (_Front) { + if constexpr (_Direction == _Restore_old_size_guard_direction::_Remove_front) { _Container->pop_front(); // restore old size, at least } else { _Container->pop_back(); // restore old size, at least @@ -1255,7 +1260,7 @@ public: if (_UFirst != _ULast) { if (_Off <= _Mysize() / 2) { // closer to front, push to front then rotate - _Restore_old_size_guard _Guard{this, _Oldsize}; + _Restore_old_size_guard<_Restore_old_size_guard_direction::_Remove_front> _Guard{this, _Oldsize}; for (; _UFirst != _ULast; ++_UFirst) { emplace_front(*_UFirst); // prepend flipped } @@ -1267,7 +1272,7 @@ public: _STD rotate(begin(), begin() + static_cast(_Num), begin() + static_cast(_Num + _Off)); } else { // closer to back - _Restore_old_size_guard _Guard{this, _Oldsize}; + _Restore_old_size_guard<_Restore_old_size_guard_direction::_Remove_back> _Guard{this, _Oldsize}; _Orphan_all(); for (; _UFirst != _ULast; ++_UFirst) { _Emplace_back_internal(*_UFirst); @@ -1368,7 +1373,7 @@ private: #endif // _ITERATOR_DEBUG_LEVEL == 2 if (_Off < _Rem) { // closer to front - _Restore_old_size_guard _Guard{this, _Oldsize}; + _Restore_old_size_guard<_Restore_old_size_guard_direction::_Remove_front> _Guard{this, _Oldsize}; if (_Off < _Count) { // insert longer than prefix for (_Num = _Count - _Off; 0 < _Num; --_Num) { push_front(_Val); // push excess values @@ -1379,7 +1384,6 @@ private: _Mid = begin() + static_cast(_Count); _STD fill(_Mid, _Mid + static_cast(_Off), _Val); // fill in rest of values - } else { // insert not longer than prefix for (_Num = _Count; 0 < _Num; --_Num) { push_front(begin()[static_cast(_Count - 1)]); // push part of prefix @@ -1394,7 +1398,7 @@ private: } _Guard._Container = nullptr; } else { // closer to back - _Restore_old_size_guard _Guard{this, _Oldsize}; + _Restore_old_size_guard<_Restore_old_size_guard_direction::_Remove_back> _Guard{this, _Oldsize}; if (_Rem < _Count) { // insert longer than suffix _Orphan_all(); for (_Num = _Count - _Rem; 0 < _Num; --_Num) { diff --git a/tests/std/tests/GH_002307_usual_scope_guard/test.cpp b/tests/std/tests/GH_002307_usual_scope_guard/test.cpp index 78549d58a9d..1d30fdcca85 100644 --- a/tests/std/tests/GH_002307_usual_scope_guard/test.cpp +++ b/tests/std/tests/GH_002307_usual_scope_guard/test.cpp @@ -42,49 +42,63 @@ struct bomb { int bomb::countdown = 0; +constexpr int init_data[] = {1, 2, 3, 4, 5, 6, 7}; +constexpr int more_data[] = {10, 11, 12, 13, 14}; -int main() { - const int data[] = {1, 2, 3, 4, 5, 6, 7}; + +template +void check(Container& c) { + assert(equal(c.begin(), c.end(), init_data)); +} + +void check_exception(runtime_error& ex) { + assert(strcmp(ex.what(), "BOOM") == 0); +} + +void test_deque() { bomb::countdown = 8; - deque dq(begin(data), end(data)); + deque dq(begin(init_data), end(init_data)); try { - bomb::countdown = 3; - const int data_x[] = {10, 11, 12, 13, 14}; - dq.insert(dq.end() - 2, begin(data_x), end(data_x)); + bomb::countdown = 3; + dq.insert(dq.end() - 2, begin(more_data), end(more_data)); abort(); - } catch (runtime_error&) { + } catch (runtime_error& ex) { + check_exception(ex); + check(dq); } - assert(equal(dq.begin(), dq.end(), data)); - try { bomb::countdown = 3; const int data_x[] = {10, 11, 12, 13, 14}; - dq.insert(dq.begin() + 2, begin(data_x), end(data_x)); + dq.insert(dq.begin() + 2, begin(more_data), end(more_data)); abort(); - } catch (runtime_error&) { + } catch (runtime_error& ex) { + check_exception(ex); + check(dq); } - assert(equal(dq.begin(), dq.end(), data)); - try { bomb::countdown = 3; dq.insert(dq.end() - 2, 6, 10); abort(); - } catch (runtime_error&) { + } catch (runtime_error& ex) { + check_exception(ex); + check(dq); } - assert(equal(dq.begin(), dq.end(), data)); - try { bomb::countdown = 3; dq.insert(dq.begin() + 2, 6, 11); abort(); - } catch (runtime_error&) { + } catch (runtime_error& ex) { + check_exception(ex); + check(dq); } +} - assert(equal(dq.begin(), dq.end(), data)); +int main() { + test_deque(); } From 14acbe546cde0b0c6ba79c8ceabc00c34022fc40 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Sat, 30 Oct 2021 15:25:32 +0300 Subject: [PATCH 06/12] data_x --- tests/std/tests/GH_002307_usual_scope_guard/test.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/std/tests/GH_002307_usual_scope_guard/test.cpp b/tests/std/tests/GH_002307_usual_scope_guard/test.cpp index 1d30fdcca85..02e1a622c0d 100644 --- a/tests/std/tests/GH_002307_usual_scope_guard/test.cpp +++ b/tests/std/tests/GH_002307_usual_scope_guard/test.cpp @@ -71,8 +71,7 @@ void test_deque() { } try { - bomb::countdown = 3; - const int data_x[] = {10, 11, 12, 13, 14}; + bomb::countdown = 3; dq.insert(dq.begin() + 2, begin(more_data), end(more_data)); abort(); } catch (runtime_error& ex) { From 7b37da63fa83a3cebce30978b149057ec408ad05 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Sat, 30 Oct 2021 17:37:50 +0300 Subject: [PATCH 07/12] minor cleanup --- tests/std/tests/GH_002307_usual_scope_guard/test.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/std/tests/GH_002307_usual_scope_guard/test.cpp b/tests/std/tests/GH_002307_usual_scope_guard/test.cpp index 02e1a622c0d..16c7377198f 100644 --- a/tests/std/tests/GH_002307_usual_scope_guard/test.cpp +++ b/tests/std/tests/GH_002307_usual_scope_guard/test.cpp @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#define _CORE_HEADERS_ONLY - #include #include #include @@ -31,6 +29,7 @@ struct bomb { } bomb& operator=(const bomb& other) { + tick(); val = other.val; return *this; } @@ -45,7 +44,6 @@ int bomb::countdown = 0; constexpr int init_data[] = {1, 2, 3, 4, 5, 6, 7}; constexpr int more_data[] = {10, 11, 12, 13, 14}; - template void check(Container& c) { assert(equal(c.begin(), c.end(), init_data)); @@ -56,7 +54,6 @@ void check_exception(runtime_error& ex) { } void test_deque() { - bomb::countdown = 8; deque dq(begin(init_data), end(init_data)); From 9396682cc10ea2ebd1e7392ec75ef352f02f876f Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Sat, 30 Oct 2021 20:33:18 +0300 Subject: [PATCH 08/12] Persistent @miscco --- tests/std/tests/GH_002307_usual_scope_guard/test.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/std/tests/GH_002307_usual_scope_guard/test.cpp b/tests/std/tests/GH_002307_usual_scope_guard/test.cpp index 16c7377198f..6b7f01baa18 100644 --- a/tests/std/tests/GH_002307_usual_scope_guard/test.cpp +++ b/tests/std/tests/GH_002307_usual_scope_guard/test.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include +#include #include #include @@ -61,7 +62,7 @@ void test_deque() { try { bomb::countdown = 3; dq.insert(dq.end() - 2, begin(more_data), end(more_data)); - abort(); + assert(false, "Should have thrown an exception"); } catch (runtime_error& ex) { check_exception(ex); check(dq); @@ -70,7 +71,7 @@ void test_deque() { try { bomb::countdown = 3; dq.insert(dq.begin() + 2, begin(more_data), end(more_data)); - abort(); + assert(false, "Should have thrown an exception"); } catch (runtime_error& ex) { check_exception(ex); check(dq); @@ -79,7 +80,7 @@ void test_deque() { try { bomb::countdown = 3; dq.insert(dq.end() - 2, 6, 10); - abort(); + assert(false, "Should have thrown an exception"); } catch (runtime_error& ex) { check_exception(ex); check(dq); @@ -88,7 +89,7 @@ void test_deque() { try { bomb::countdown = 3; dq.insert(dq.begin() + 2, 6, 11); - abort(); + assert(false, "Should have thrown an exception"); } catch (runtime_error& ex) { check_exception(ex); check(dq); From 7759c954ec73ff31de680ced8656caff8607c8d5 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Sat, 30 Oct 2021 20:48:22 +0300 Subject: [PATCH 09/12] no, it is not `static_assert` ! --- tests/std/tests/GH_002307_usual_scope_guard/test.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/std/tests/GH_002307_usual_scope_guard/test.cpp b/tests/std/tests/GH_002307_usual_scope_guard/test.cpp index 6b7f01baa18..b1452b32534 100644 --- a/tests/std/tests/GH_002307_usual_scope_guard/test.cpp +++ b/tests/std/tests/GH_002307_usual_scope_guard/test.cpp @@ -62,7 +62,7 @@ void test_deque() { try { bomb::countdown = 3; dq.insert(dq.end() - 2, begin(more_data), end(more_data)); - assert(false, "Should have thrown an exception"); + assert(false); // Should have thrown an exception } catch (runtime_error& ex) { check_exception(ex); check(dq); @@ -71,7 +71,7 @@ void test_deque() { try { bomb::countdown = 3; dq.insert(dq.begin() + 2, begin(more_data), end(more_data)); - assert(false, "Should have thrown an exception"); + assert(false); // Should have thrown an exception } catch (runtime_error& ex) { check_exception(ex); check(dq); @@ -80,7 +80,7 @@ void test_deque() { try { bomb::countdown = 3; dq.insert(dq.end() - 2, 6, 10); - assert(false, "Should have thrown an exception"); + assert(false); // Should have thrown an exception } catch (runtime_error& ex) { check_exception(ex); check(dq); @@ -89,7 +89,7 @@ void test_deque() { try { bomb::countdown = 3; dq.insert(dq.begin() + 2, 6, 11); - assert(false, "Should have thrown an exception"); + assert(false); // Should have thrown an exception } catch (runtime_error& ex) { check_exception(ex); check(dq); From c81043da211091c45625372efce75b4482fa3f86 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Wed, 23 Feb 2022 16:31:09 +0200 Subject: [PATCH 10/12] review comments --- stl/inc/deque | 22 +++++---- .../GH_002307_usual_scope_guard/test.cpp | 47 ++++++++++--------- 2 files changed, 36 insertions(+), 33 deletions(-) diff --git a/stl/inc/deque b/stl/inc/deque index 760da70539e..7ebde9cbc35 100644 --- a/stl/inc/deque +++ b/stl/inc/deque @@ -1220,20 +1220,21 @@ public: return begin() + static_cast(_Off); } - enum class _Restore_old_size_guard_direction : bool { - _Remove_front, - _Remove_back, +private: + enum class _Pop_direction : bool { + _Front, + _Back, }; - template <_Restore_old_size_guard_direction _Direction> - struct _Restore_old_size_guard { + template <_Pop_direction _Direction> + struct _NODISCARD _Restore_old_size_guard { deque* _Container; const size_type _Oldsize; ~_Restore_old_size_guard() { if (_Container) { while (_Oldsize < _Container->_Mysize()) { - if constexpr (_Direction == _Restore_old_size_guard_direction::_Remove_front) { + if constexpr (_Direction == _Pop_direction::_Front) { _Container->pop_front(); // restore old size, at least } else { _Container->pop_back(); // restore old size, at least @@ -1242,6 +1243,7 @@ public: } } }; +public: template , int> = 0> iterator insert(const_iterator _Where, _Iter _First, _Iter _Last) { @@ -1260,7 +1262,7 @@ public: if (_UFirst != _ULast) { if (_Off <= _Mysize() / 2) { // closer to front, push to front then rotate - _Restore_old_size_guard<_Restore_old_size_guard_direction::_Remove_front> _Guard{this, _Oldsize}; + _Restore_old_size_guard<_Pop_direction::_Front> _Guard{this, _Oldsize}; for (; _UFirst != _ULast; ++_UFirst) { emplace_front(*_UFirst); // prepend flipped } @@ -1272,7 +1274,7 @@ public: _STD rotate(begin(), begin() + static_cast(_Num), begin() + static_cast(_Num + _Off)); } else { // closer to back - _Restore_old_size_guard<_Restore_old_size_guard_direction::_Remove_back> _Guard{this, _Oldsize}; + _Restore_old_size_guard<_Pop_direction::_Back> _Guard{this, _Oldsize}; _Orphan_all(); for (; _UFirst != _ULast; ++_UFirst) { _Emplace_back_internal(*_UFirst); @@ -1373,7 +1375,7 @@ private: #endif // _ITERATOR_DEBUG_LEVEL == 2 if (_Off < _Rem) { // closer to front - _Restore_old_size_guard<_Restore_old_size_guard_direction::_Remove_front> _Guard{this, _Oldsize}; + _Restore_old_size_guard<_Pop_direction::_Front> _Guard{this, _Oldsize}; if (_Off < _Count) { // insert longer than prefix for (_Num = _Count - _Off; 0 < _Num; --_Num) { push_front(_Val); // push excess values @@ -1398,7 +1400,7 @@ private: } _Guard._Container = nullptr; } else { // closer to back - _Restore_old_size_guard<_Restore_old_size_guard_direction::_Remove_back> _Guard{this, _Oldsize}; + _Restore_old_size_guard<_Pop_direction::_Back> _Guard{this, _Oldsize}; if (_Rem < _Count) { // insert longer than suffix _Orphan_all(); for (_Num = _Count - _Rem; 0 < _Num; --_Num) { diff --git a/tests/std/tests/GH_002307_usual_scope_guard/test.cpp b/tests/std/tests/GH_002307_usual_scope_guard/test.cpp index b1452b32534..5c6034c1b31 100644 --- a/tests/std/tests/GH_002307_usual_scope_guard/test.cpp +++ b/tests/std/tests/GH_002307_usual_scope_guard/test.cpp @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include #include #include #include @@ -8,28 +9,28 @@ using namespace std; -struct bomb { +struct countdown { int val; - static int countdown; + static int count; void tick() { - if (countdown == 0) { - throw runtime_error("BOOM"); + if (count == 0) { + throw runtime_error{"GO"}; } else { - --countdown; + --count; } } - bomb(int init) : val(init) { + countdown(const int init) : val(init) { tick(); } - bomb(const bomb& other) : val(other.val) { + countdown(const countdown& other) : val(other.val) { tick(); } - bomb& operator=(const bomb& other) { + countdown& operator=(const countdown& other) { tick(); val = other.val; return *this; @@ -40,57 +41,57 @@ struct bomb { } }; -int bomb::countdown = 0; +int countdown::count = 0; constexpr int init_data[] = {1, 2, 3, 4, 5, 6, 7}; constexpr int more_data[] = {10, 11, 12, 13, 14}; template -void check(Container& c) { - assert(equal(c.begin(), c.end(), init_data)); +void check(const Container& c) { + assert(equal(c.begin(), c.end(), begin(init_data), end(init_data))); } -void check_exception(runtime_error& ex) { - assert(strcmp(ex.what(), "BOOM") == 0); +void check_exception(const runtime_error& ex) { + assert(strcmp(ex.what(), "GO") == 0); } void test_deque() { - bomb::countdown = 8; + countdown::count = 8; - deque dq(begin(init_data), end(init_data)); + deque dq(begin(init_data), end(init_data)); try { - bomb::countdown = 3; + countdown::count = 3; dq.insert(dq.end() - 2, begin(more_data), end(more_data)); assert(false); // Should have thrown an exception - } catch (runtime_error& ex) { + } catch (const runtime_error& ex) { check_exception(ex); check(dq); } try { - bomb::countdown = 3; + countdown::count = 3; dq.insert(dq.begin() + 2, begin(more_data), end(more_data)); assert(false); // Should have thrown an exception - } catch (runtime_error& ex) { + } catch (const runtime_error& ex) { check_exception(ex); check(dq); } try { - bomb::countdown = 3; + countdown::count = 3; dq.insert(dq.end() - 2, 6, 10); assert(false); // Should have thrown an exception - } catch (runtime_error& ex) { + } catch (const runtime_error& ex) { check_exception(ex); check(dq); } try { - bomb::countdown = 3; + countdown::count = 3; dq.insert(dq.begin() + 2, 6, 11); assert(false); // Should have thrown an exception - } catch (runtime_error& ex) { + } catch (const runtime_error& ex) { check_exception(ex); check(dq); } From 3c9a6ac9c26bcfec7eb6b79f87d1d5d3f155cc30 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Wed, 23 Feb 2022 16:47:31 +0200 Subject: [PATCH 11/12] clang format --- stl/inc/deque | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stl/inc/deque b/stl/inc/deque index 7ebde9cbc35..999c1fa4fb5 100644 --- a/stl/inc/deque +++ b/stl/inc/deque @@ -998,8 +998,8 @@ public: } _NODISCARD size_type max_size() const noexcept { - return (_STD min) (static_cast((numeric_limits::max) ()), - _Alty_traits::max_size(_Getal())); + return (_STD min)( + static_cast((numeric_limits::max)()), _Alty_traits::max_size(_Getal())); } _NODISCARD bool empty() const noexcept { @@ -1181,7 +1181,7 @@ public: _Orphan_all(); auto _Myfirst = _Unchecked_begin(); const auto _Oldsize = _Mysize(); - auto _Assign_count = (_STD min) (_Count, _Oldsize); + auto _Assign_count = (_STD min)(_Count, _Oldsize); for (; 0 < _Assign_count; --_Assign_count) { *_Myfirst = _Val; ++_Myfirst; @@ -1243,8 +1243,8 @@ private: } } }; -public: +public: template , int> = 0> iterator insert(const_iterator _Where, _Iter _First, _Iter _Last) { // insert [_First, _Last) at _Where, input iterators From f6592eff5c6da419bb8c47c44f2def4e32de328d Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Mon, 21 Mar 2022 13:13:26 -0700 Subject: [PATCH 12/12] Casey's review comments --- stl/inc/deque | 8 ++++---- tests/std/tests/GH_002307_usual_scope_guard/test.cpp | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/stl/inc/deque b/stl/inc/deque index 17c847de2ea..84bfc1d5be7 100644 --- a/stl/inc/deque +++ b/stl/inc/deque @@ -1230,13 +1230,13 @@ private: deque* _Container; const size_type _Oldsize; - ~_Restore_old_size_guard() { + ~_Restore_old_size_guard() { // restore old size, at least if (_Container) { while (_Oldsize < _Container->_Mysize()) { if constexpr (_Direction == _Pop_direction::_Front) { - _Container->pop_front(); // restore old size, at least + _Container->pop_front(); } else { - _Container->pop_back(); // restore old size, at least + _Container->pop_back(); } } } @@ -1273,8 +1273,8 @@ public: _STD rotate(begin(), begin() + static_cast(_Num), begin() + static_cast(_Num + _Off)); } else { // closer to back - _Restore_old_size_guard<_Pop_direction::_Back> _Guard{this, _Oldsize}; _Orphan_all(); + _Restore_old_size_guard<_Pop_direction::_Back> _Guard{this, _Oldsize}; for (; _UFirst != _ULast; ++_UFirst) { _Emplace_back_internal(*_UFirst); } diff --git a/tests/std/tests/GH_002307_usual_scope_guard/test.cpp b/tests/std/tests/GH_002307_usual_scope_guard/test.cpp index 5c6034c1b31..e1d4a95bb77 100644 --- a/tests/std/tests/GH_002307_usual_scope_guard/test.cpp +++ b/tests/std/tests/GH_002307_usual_scope_guard/test.cpp @@ -22,7 +22,7 @@ struct countdown { } } - countdown(const int init) : val(init) { + explicit countdown(const int init) : val(init) { tick(); } @@ -80,7 +80,7 @@ void test_deque() { try { countdown::count = 3; - dq.insert(dq.end() - 2, 6, 10); + dq.insert(dq.end() - 2, 6, countdown{10}); assert(false); // Should have thrown an exception } catch (const runtime_error& ex) { check_exception(ex); @@ -89,7 +89,7 @@ void test_deque() { try { countdown::count = 3; - dq.insert(dq.begin() + 2, 6, 11); + dq.insert(dq.begin() + 2, 6, countdown{11}); assert(false); // Should have thrown an exception } catch (const runtime_error& ex) { check_exception(ex);