From b2ecd9a150962eee7eb3fcf270b99c336893a456 Mon Sep 17 00:00:00 2001 From: derzhavin3016 Date: Sun, 24 Jul 2022 18:55:26 +0300 Subject: [PATCH 1/5] [utils] Implemented Enumerate iterator adapter (#28) --- include/intersection/detail.hh | 8 +- include/utils/utils.hh | 175 +++++++++++++++++++++++++++++++++ lib/CMakeLists.txt | 2 +- lib/utils/CMakeLists.txt | 4 + test/unit/utils.cc | 116 ++++++++++++++++++++++ 5 files changed, 300 insertions(+), 5 deletions(-) create mode 100644 include/utils/utils.hh create mode 100644 lib/utils/CMakeLists.txt create mode 100644 test/unit/utils.cc diff --git a/include/intersection/detail.hh b/include/intersection/detail.hh index e273cc0..2b69033 100644 --- a/include/intersection/detail.hh +++ b/include/intersection/detail.hh @@ -7,6 +7,7 @@ #include "distance/distance.hh" #include "primitives/primitives.hh" #include "primitives/vec2.hh" +#include "utils/utils.hh" namespace geom::detail { @@ -128,10 +129,9 @@ Segment2D helperMollerHaines(const Triangle &tr, const Plane &pl, const std::size_t rogue = roguePos(sdist.begin(), sdist.end()); std::array segm{}; - std::array arr{(rogue + 1) % 3, (rogue + 2) % 3}; - std::transform(arr.begin(), arr.end(), segm.begin(), [&vert, &sdist, rogue](auto i) { - return vert[i] + (vert[rogue] - vert[i]) * sdist[i] / (sdist[i] - sdist[rogue]); - }); + std::array arr = {(rogue + 1) % 3, (rogue + 2) % 3}; + for (auto [idx, i] : utils::makeEnumerate(arr)) + segm[idx] = vert[i] + (vert[rogue] - vert[i]) * sdist[i] / (sdist[i] - sdist[rogue]); return std::minmax(segm[0], segm[1]); } diff --git a/include/utils/utils.hh b/include/utils/utils.hh new file mode 100644 index 0000000..fd1866b --- /dev/null +++ b/include/utils/utils.hh @@ -0,0 +1,175 @@ +#ifndef __INCLUDE_UTILS_UTILS_HH__ +#define __INCLUDE_UTILS_UTILS_HH__ + +#include +#include +#include + +namespace utils +{ +template +concept ItContainer = requires(T cont) +{ + { + std::begin(cont) + } -> std::forward_iterator; + { + std::end(cont) + } -> std::forward_iterator; + { + std::size(cont) + } -> std::convertible_to; + { + typename std::remove_reference_t::iterator() + } -> std::forward_iterator; +}; + +namespace detail +{ +template +class EnumerIt final +{ +private: + template + struct ArrowProxy + { + Ref r; + + Ref *operator->() + { + return &r; + } + }; + +public: + using iterator_category = std::forward_iterator_tag; + using difference_type = + std::pair, typename std::iterator_traits::difference_type>; + using value_type = std::pair::value_type>; + using reference = std::pair::reference>; + using pointer = ArrowProxy; + +private: + std::size_t counter_; + mutable std::size_t dummy_; + It iter_; + +public: + EnumerIt(std::size_t i, It iter) : counter_(i), dummy_(i), iter_(iter) + {} + + reference operator*() const + { + dummy_ = counter_; + return {dummy_, *iter_}; + } + + EnumerIt &operator++() + { + ++counter_; + ++iter_; + return *this; + } + + EnumerIt operator++(int) + { + auto temp{*this}; + operator++(); + return temp; + } + + bool equals(const EnumerIt &rhs) const + { + return iter_ == rhs.iter_; + } + + pointer operator->() const + { + dummy_ = counter_; + return pointer{{dummy_, *iter_}}; + } +}; + +template +bool operator==(const EnumerIt &lhs, const EnumerIt &rhs) +{ + return lhs.equals(rhs); +} + +template +bool operator!=(const EnumerIt &lhs, const EnumerIt &rhs) +{ + return !(lhs == rhs); +} + +} // namespace detail + +template +class Enumerate final +{ +private: + C &cont_; + using EnumItType = detail::EnumerIt::iterator>; + +public: + Enumerate(C &cont) : cont_(cont) + {} + + auto begin() -> decltype(auto) + { + return EnumItType(0, std::begin(cont_)); + } + auto begin() const -> decltype(auto) + { + return EnumItType(0, std::begin(cont_)); + } + + auto end() -> decltype(auto) + { + return EnumItType(std::size(cont_), std::end(cont_)); + } + auto end() const -> decltype(auto) + { + return EnumItType(std::size(cont_), std::end(cont_)); + } +}; + +template +class Enumerate final +{ +private: + C cont_; + using EnumItType = detail::EnumerIt::iterator>; + +public: + Enumerate(C &&cont) : cont_(std::move(cont)) + {} + + auto begin() -> decltype(auto) + { + return EnumItType(0, std::begin(cont_)); + } + auto begin() const -> decltype(auto) + { + return EnumItType(0, std::begin(cont_)); + } + + auto end() -> decltype(auto) + { + return EnumItType(std::size(cont_), std::end(cont_)); + } + auto end() const -> decltype(auto) + { + return EnumItType(std::size(cont_), std::end(cont_)); + } +}; + +template +auto makeEnumerate(C &&cont) +{ + return Enumerate(std::forward(cont)); +} + +} // namespace utils + +#endif /* __INCLUDE_UTILS_UTILS_HH__ */ diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 6462b00..e227e29 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,4 +1,4 @@ -set(LIBLIST primitives intersection distance kdtree) +set(LIBLIST primitives intersection distance kdtree utils) foreach(LIB ${LIBLIST}) add_subdirectory(${LIB}) diff --git a/lib/utils/CMakeLists.txt b/lib/utils/CMakeLists.txt new file mode 100644 index 0000000..6f47533 --- /dev/null +++ b/lib/utils/CMakeLists.txt @@ -0,0 +1,4 @@ +add_library(utils INTERFACE) +target_sources(utils + INTERFACE ${CMAKE_SOURCE_DIR}/include/utils/utils.hh +) diff --git a/test/unit/utils.cc b/test/unit/utils.cc new file mode 100644 index 0000000..79358ad --- /dev/null +++ b/test/unit/utils.cc @@ -0,0 +1,116 @@ +#include "utils/utils.hh" + +#include "test_header.hh" +#include +#include +#include + +using namespace utils; + +TEST(EnumerTest, ordVecSimpleBind) +{ + // Arrange + std::vector vec; + vec.resize(10); + std::iota(vec.begin(), vec.end(), 0); + + // Act && Asserts + for (auto val : makeEnumerate(vec)) + ASSERT_EQ(val.first, val.second); +} + +TEST(EnumerTest, ordVecStructBind) +{ + // Arrange + std::vector vec; + vec.resize(10); + std::iota(vec.begin(), vec.end(), 0); + + // Act && Asserts + for (auto [i, val] : makeEnumerate(vec)) + ASSERT_EQ(i, val); +} + +TEST(EnumerTest, ordVecChangeCounter) +{ + // Arrange + std::vector vec; + vec.resize(10); + std::iota(vec.begin(), vec.end(), 0); + + // Act && Asserts + for (auto [i, val] : makeEnumerate(vec)) + if (i == 0) + i = 22; + else + ASSERT_EQ(i, val); +} + +TEST(EnumerTest, ordVecChangeValue) +{ + // Arrange + std::vector vec, expect; + vec.resize(10); + expect.resize(vec.size()); + std::iota(vec.begin(), vec.end(), 0); + std::iota(expect.rbegin(), expect.rend(), -expect.size() + 1); + + // Act + for (auto [i, val] : makeEnumerate(vec)) + val = -static_cast(i); + + // Assert + ASSERT_EQ(vec, expect); +} + +TEST(EnumerTest, ordVecTemp) +{ + // Arrange + std::vector res, expect(10, 10); + res.resize(10); + + // Act + for (auto [i, val] : makeEnumerate(std::vector(expect.size(), 10))) + res[i] = val; + + // Assert + ASSERT_EQ(res, expect); +} + +TEST(EnumerTest, arrowProxy) +{ + // Arrange + struct Compl + { + int a; + + Compl &operator=(int v) + { + a = v; + return *this; + } + + bool operator==(const Compl &) const = default; + + void inc() + { + a++; + } + }; + + std::vector vec, expect; + vec.resize(10); + expect.resize(vec.size()); + std::iota(vec.begin(), vec.end(), 0); + std::iota(expect.begin(), expect.end(), 1); + + // Act + auto enumerate = makeEnumerate(vec); + for (auto it = enumerate.begin(); it != enumerate.end(); it++) + it->second.inc(); + + // Assert + ASSERT_EQ(vec, expect); +} + +#include "test_footer.hh" From e73eff38c2a4a1cd6ddf4e8445d804a515df76c7 Mon Sep 17 00:00:00 2001 From: derzhavin3016 Date: Sun, 7 Aug 2022 15:07:48 +0300 Subject: [PATCH 2/5] [utils] Improved move semantics of enumerate - Removed class template specialization for rvalue reference by specifying storage type of container conditionally - Added tests for checking move semantic's work - Removed requirement of ::iterator type in container --- include/utils/utils.hh | 49 ++++++++---------------------------------- test/unit/utils.cc | 46 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 40 deletions(-) diff --git a/include/utils/utils.hh b/include/utils/utils.hh index fd1866b..79cd711 100644 --- a/include/utils/utils.hh +++ b/include/utils/utils.hh @@ -19,9 +19,6 @@ concept ItContainer = requires(T cont) { std::size(cont) } -> std::convertible_to; - { - typename std::remove_reference_t::iterator() - } -> std::forward_iterator; }; namespace detail @@ -101,64 +98,36 @@ bool operator!=(const EnumerIt &lhs, const EnumerIt &rhs) { return !(lhs == rhs); } - } // namespace detail template class Enumerate final { private: - C &cont_; - using EnumItType = detail::EnumerIt::iterator>; - -public: - Enumerate(C &cont) : cont_(cont) - {} - - auto begin() -> decltype(auto) - { - return EnumItType(0, std::begin(cont_)); - } - auto begin() const -> decltype(auto) - { - return EnumItType(0, std::begin(cont_)); - } - - auto end() -> decltype(auto) - { - return EnumItType(std::size(cont_), std::end(cont_)); - } - auto end() const -> decltype(auto) - { - return EnumItType(std::size(cont_), std::end(cont_)); - } -}; + using NoRefC = std::remove_reference_t; + using ContStorageType = std::conditional_t, NoRefC, NoRefC &>; -template -class Enumerate final -{ -private: - C cont_; - using EnumItType = detail::EnumerIt::iterator>; + ContStorageType cont_; + using EnumItType = detail::EnumerIt; public: - Enumerate(C &&cont) : cont_(std::move(cont)) + Enumerate(C &&cont) : cont_(std::forward(cont)) {} - auto begin() -> decltype(auto) + auto begin() { return EnumItType(0, std::begin(cont_)); } - auto begin() const -> decltype(auto) + auto begin() const { return EnumItType(0, std::begin(cont_)); } - auto end() -> decltype(auto) + auto end() { return EnumItType(std::size(cont_), std::end(cont_)); } - auto end() const -> decltype(auto) + auto end() const { return EnumItType(std::size(cont_), std::end(cont_)); } diff --git a/test/unit/utils.cc b/test/unit/utils.cc index 79358ad..83e26a9 100644 --- a/test/unit/utils.cc +++ b/test/unit/utils.cc @@ -113,4 +113,50 @@ TEST(EnumerTest, arrowProxy) ASSERT_EQ(vec, expect); } +TEST(EnumerTest, MoveSemantics) +{ + // Arrangse + struct WasMovedType + {}; + struct WasCopiedType + {}; + struct ToMove + { + private: + std::vector dummy{}; + + public: + ToMove() = default; + + ToMove(const ToMove &that) : dummy(that.dummy) + { + throw WasCopiedType{}; + } + ToMove(ToMove &&that) : dummy(std::move(that.dummy)) + { + throw WasMovedType{}; + } + + auto size() const + { + return dummy.size(); + } + + auto begin() + { + return dummy.begin(); + } + + auto end() + { + return dummy.end(); + } + }; + + ToMove local; + // Act && Assert + EXPECT_THROW([[maybe_unused]] auto moved = makeEnumerate(ToMove{});, WasMovedType); + EXPECT_NO_THROW([[maybe_unused]] auto copied = makeEnumerate(local);); +} + #include "test_footer.hh" From 6d407c52829c982d5fb7a9e179d4860a197288bb Mon Sep 17 00:00:00 2001 From: derzhavin3016 Date: Sun, 7 Aug 2022 15:53:05 +0300 Subject: [PATCH 3/5] [utils] Added const to enumerate iterator's count - To prevent changing of counter, made it const in reference & value type - Removed useless dummy_ variable because of errors while using it --- include/utils/utils.hh | 13 +++++-------- test/unit/utils.cc | 38 ++++++++++++++++++++------------------ 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/include/utils/utils.hh b/include/utils/utils.hh index 79cd711..a87b96d 100644 --- a/include/utils/utils.hh +++ b/include/utils/utils.hh @@ -42,23 +42,21 @@ public: using iterator_category = std::forward_iterator_tag; using difference_type = std::pair, typename std::iterator_traits::difference_type>; - using value_type = std::pair::value_type>; - using reference = std::pair::reference>; + using value_type = std::pair::value_type>; + using reference = std::pair::reference>; using pointer = ArrowProxy; private: std::size_t counter_; - mutable std::size_t dummy_; It iter_; public: - EnumerIt(std::size_t i, It iter) : counter_(i), dummy_(i), iter_(iter) + EnumerIt(std::size_t i, It iter) : counter_(i), iter_(iter) {} reference operator*() const { - dummy_ = counter_; - return {dummy_, *iter_}; + return {counter_, *iter_}; } EnumerIt &operator++() @@ -82,8 +80,7 @@ public: pointer operator->() const { - dummy_ = counter_; - return pointer{{dummy_, *iter_}}; + return pointer{{counter_, *iter_}}; } }; diff --git a/test/unit/utils.cc b/test/unit/utils.cc index 83e26a9..7a68ae2 100644 --- a/test/unit/utils.cc +++ b/test/unit/utils.cc @@ -31,21 +31,6 @@ TEST(EnumerTest, ordVecStructBind) ASSERT_EQ(i, val); } -TEST(EnumerTest, ordVecChangeCounter) -{ - // Arrange - std::vector vec; - vec.resize(10); - std::iota(vec.begin(), vec.end(), 0); - - // Act && Asserts - for (auto [i, val] : makeEnumerate(vec)) - if (i == 0) - i = 22; - else - ASSERT_EQ(i, val); -} - TEST(EnumerTest, ordVecChangeValue) { // Arrange @@ -60,7 +45,24 @@ TEST(EnumerTest, ordVecChangeValue) val = -static_cast(i); // Assert - ASSERT_EQ(vec, expect); + EXPECT_EQ(vec, expect); +} + +TEST(EnumerTest, twiceDeref) +{ + // Arrange + std::vector vec = {1, 2, 3}; + + // Act + auto enumerate = makeEnumerate(vec); + auto it1 = enumerate.begin(); + auto v1 = *it1; + ++it1; + auto v2 = *it1; + + // Assert + EXPECT_EQ(v1.first, 0); + EXPECT_EQ(v2.first, 1); } TEST(EnumerTest, ordVecTemp) @@ -74,7 +76,7 @@ TEST(EnumerTest, ordVecTemp) res[i] = val; // Assert - ASSERT_EQ(res, expect); + EXPECT_EQ(res, expect); } TEST(EnumerTest, arrowProxy) @@ -110,7 +112,7 @@ TEST(EnumerTest, arrowProxy) it->second.inc(); // Assert - ASSERT_EQ(vec, expect); + EXPECT_EQ(vec, expect); } TEST(EnumerTest, MoveSemantics) From 7d86497e5f33dfe1db80dd5699ecbceb95e82ed1 Mon Sep 17 00:00:00 2001 From: derzhavin3016 Date: Sun, 7 Aug 2022 16:46:40 +0300 Subject: [PATCH 4/5] [utils] Removed makeEnumerate - Replaced makeEnumerate w/ ctor with deduction hint - Added size method for enumerate --- include/intersection/detail.hh | 2 +- include/utils/utils.hh | 10 ++++++---- test/unit/utils.cc | 16 ++++++++-------- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/include/intersection/detail.hh b/include/intersection/detail.hh index 2b69033..92e019d 100644 --- a/include/intersection/detail.hh +++ b/include/intersection/detail.hh @@ -130,7 +130,7 @@ Segment2D helperMollerHaines(const Triangle &tr, const Plane &pl, const std::array segm{}; std::array arr = {(rogue + 1) % 3, (rogue + 2) % 3}; - for (auto [idx, i] : utils::makeEnumerate(arr)) + for (auto [idx, i] : utils::Enumerate(arr)) segm[idx] = vert[i] + (vert[rogue] - vert[i]) * sdist[i] / (sdist[i] - sdist[rogue]); return std::minmax(segm[0], segm[1]); diff --git a/include/utils/utils.hh b/include/utils/utils.hh index a87b96d..de37980 100644 --- a/include/utils/utils.hh +++ b/include/utils/utils.hh @@ -128,13 +128,15 @@ public: { return EnumItType(std::size(cont_), std::end(cont_)); } + + auto size() const + { + return std::size(cont_); + } }; template -auto makeEnumerate(C &&cont) -{ - return Enumerate(std::forward(cont)); -} +Enumerate(C &&) -> Enumerate; } // namespace utils diff --git a/test/unit/utils.cc b/test/unit/utils.cc index 7a68ae2..868a98e 100644 --- a/test/unit/utils.cc +++ b/test/unit/utils.cc @@ -15,7 +15,7 @@ TEST(EnumerTest, ordVecSimpleBind) std::iota(vec.begin(), vec.end(), 0); // Act && Asserts - for (auto val : makeEnumerate(vec)) + for (auto val : Enumerate(vec)) ASSERT_EQ(val.first, val.second); } @@ -27,7 +27,7 @@ TEST(EnumerTest, ordVecStructBind) std::iota(vec.begin(), vec.end(), 0); // Act && Asserts - for (auto [i, val] : makeEnumerate(vec)) + for (auto [i, val] : Enumerate(vec)) ASSERT_EQ(i, val); } @@ -41,7 +41,7 @@ TEST(EnumerTest, ordVecChangeValue) std::iota(expect.rbegin(), expect.rend(), -expect.size() + 1); // Act - for (auto [i, val] : makeEnumerate(vec)) + for (auto [i, val] : Enumerate(vec)) val = -static_cast(i); // Assert @@ -54,7 +54,7 @@ TEST(EnumerTest, twiceDeref) std::vector vec = {1, 2, 3}; // Act - auto enumerate = makeEnumerate(vec); + auto enumerate = Enumerate(vec); auto it1 = enumerate.begin(); auto v1 = *it1; ++it1; @@ -72,7 +72,7 @@ TEST(EnumerTest, ordVecTemp) res.resize(10); // Act - for (auto [i, val] : makeEnumerate(std::vector(expect.size(), 10))) + for (auto [i, val] : Enumerate(std::vector(expect.size(), 10))) res[i] = val; // Assert @@ -107,7 +107,7 @@ TEST(EnumerTest, arrowProxy) std::iota(expect.begin(), expect.end(), 1); // Act - auto enumerate = makeEnumerate(vec); + auto enumerate = Enumerate(vec); for (auto it = enumerate.begin(); it != enumerate.end(); it++) it->second.inc(); @@ -157,8 +157,8 @@ TEST(EnumerTest, MoveSemantics) ToMove local; // Act && Assert - EXPECT_THROW([[maybe_unused]] auto moved = makeEnumerate(ToMove{});, WasMovedType); - EXPECT_NO_THROW([[maybe_unused]] auto copied = makeEnumerate(local);); + EXPECT_THROW([[maybe_unused]] auto moved = Enumerate(ToMove{});, WasMovedType); + EXPECT_NO_THROW([[maybe_unused]] auto copied = Enumerate(local);); } #include "test_footer.hh" From 5c870d9461a0e5c70e6a00e73db969943d4c5635 Mon Sep 17 00:00:00 2001 From: derzhavin3016 Date: Tue, 9 Aug 2022 00:12:42 +0300 Subject: [PATCH 5/5] [utils] Added test + some fixes - Added test with constant container - Removed const from reference & value_type - Removed operator!= for EnumerateIt (generated by default) - Renamed Enumer -> Enumerate --- include/utils/utils.hh | 24 +++++++++------------- test/unit/utils.cc | 46 ++++++++++++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/include/utils/utils.hh b/include/utils/utils.hh index de37980..9d51090 100644 --- a/include/utils/utils.hh +++ b/include/utils/utils.hh @@ -24,7 +24,7 @@ concept ItContainer = requires(T cont) namespace detail { template -class EnumerIt final +class EnumerateIt final { private: template @@ -42,8 +42,8 @@ public: using iterator_category = std::forward_iterator_tag; using difference_type = std::pair, typename std::iterator_traits::difference_type>; - using value_type = std::pair::value_type>; - using reference = std::pair::reference>; + using value_type = std::pair::value_type>; + using reference = std::pair::reference>; using pointer = ArrowProxy; private: @@ -51,7 +51,7 @@ private: It iter_; public: - EnumerIt(std::size_t i, It iter) : counter_(i), iter_(iter) + EnumerateIt(std::size_t i, It iter) : counter_(i), iter_(iter) {} reference operator*() const @@ -59,21 +59,21 @@ public: return {counter_, *iter_}; } - EnumerIt &operator++() + EnumerateIt &operator++() { ++counter_; ++iter_; return *this; } - EnumerIt operator++(int) + EnumerateIt operator++(int) { auto temp{*this}; operator++(); return temp; } - bool equals(const EnumerIt &rhs) const + bool equals(const EnumerateIt &rhs) const { return iter_ == rhs.iter_; } @@ -85,16 +85,10 @@ public: }; template -bool operator==(const EnumerIt &lhs, const EnumerIt &rhs) +bool operator==(const EnumerateIt &lhs, const EnumerateIt &rhs) { return lhs.equals(rhs); } - -template -bool operator!=(const EnumerIt &lhs, const EnumerIt &rhs) -{ - return !(lhs == rhs); -} } // namespace detail template @@ -105,7 +99,7 @@ private: using ContStorageType = std::conditional_t, NoRefC, NoRefC &>; ContStorageType cont_; - using EnumItType = detail::EnumerIt; + using EnumItType = detail::EnumerateIt; public: Enumerate(C &&cont) : cont_(std::forward(cont)) diff --git a/test/unit/utils.cc b/test/unit/utils.cc index 868a98e..7ea8bde 100644 --- a/test/unit/utils.cc +++ b/test/unit/utils.cc @@ -7,7 +7,7 @@ using namespace utils; -TEST(EnumerTest, ordVecSimpleBind) +TEST(EnumerateTest, ordVecSimpleBind) { // Arrange std::vector vec; @@ -19,7 +19,7 @@ TEST(EnumerTest, ordVecSimpleBind) ASSERT_EQ(val.first, val.second); } -TEST(EnumerTest, ordVecStructBind) +TEST(EnumerateTest, ordVecStructBind) { // Arrange std::vector vec; @@ -31,7 +31,7 @@ TEST(EnumerTest, ordVecStructBind) ASSERT_EQ(i, val); } -TEST(EnumerTest, ordVecChangeValue) +TEST(EnumerateTest, ordVecChangeValue) { // Arrange std::vector vec, expect; @@ -48,7 +48,7 @@ TEST(EnumerTest, ordVecChangeValue) EXPECT_EQ(vec, expect); } -TEST(EnumerTest, twiceDeref) +TEST(EnumerateTest, twiceDeref) { // Arrange std::vector vec = {1, 2, 3}; @@ -56,16 +56,26 @@ TEST(EnumerTest, twiceDeref) // Act auto enumerate = Enumerate(vec); auto it1 = enumerate.begin(); - auto v1 = *it1; - ++it1; - auto v2 = *it1; + auto it2 = enumerate.begin(); + + using value_type = + std::iterator_traits::iterator>>::value_type; + + value_type v1 = *it1++; + value_type v2 = *it1; + + auto r1 = *it2; + ++it2; + auto r2 = *it2; // Assert EXPECT_EQ(v1.first, 0); EXPECT_EQ(v2.first, 1); + + EXPECT_NE(r1, r2); } -TEST(EnumerTest, ordVecTemp) +TEST(EnumerateTest, ordVecTemp) { // Arrange std::vector res, expect(10, 10); @@ -79,7 +89,7 @@ TEST(EnumerTest, ordVecTemp) EXPECT_EQ(res, expect); } -TEST(EnumerTest, arrowProxy) +TEST(EnumerateTest, arrowProxy) { // Arrange struct Compl @@ -115,9 +125,23 @@ TEST(EnumerTest, arrowProxy) EXPECT_EQ(vec, expect); } -TEST(EnumerTest, MoveSemantics) +TEST(EnumerateTest, constContainer) { - // Arrangse + // Arrange + const std::vector vec = {1, 2, 3, 4, 5}; + std::vector vec2(vec.size()); + + // Act + for (auto [idx, val] : Enumerate(vec)) + vec2[idx] = val; + + // Assert + EXPECT_EQ(vec, vec2); +} + +TEST(EnumerateTest, MoveSemantics) +{ + // Arrange struct WasMovedType {}; struct WasCopiedType