[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master d7153f9 4/4: Improve each_equal() efficiency;
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master d7153f9 4/4: Improve each_equal() efficiency; augment its unit test |
Date: |
Sun, 22 Jan 2017 01:55:05 +0000 (UTC) |
branch: master
commit d7153f9db59c3d2d84191db03e35fac3ddc19938
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>
Improve each_equal() efficiency; augment its unit test
The original implementation of the iterator overload did not return
as soon as the result was known to be false (VZ). Now it does.
Added unit tests for empty ranges.
The original (commented out) invalid unit test no longer happens to
segfault reproducibly for me, but such is UB. Lest we be tempted to
treat that particular special case as an empty range in the hope of
precluding UB, another invalid example has been added that cannot be
remediated in that way because no code we write can detect it.
---
miscellany.hpp | 6 +++++-
miscellany_test.cpp | 23 +++++++++++++++++------
2 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/miscellany.hpp b/miscellany.hpp
index 9343a30..370a2c0 100644
--- a/miscellany.hpp
+++ b/miscellany.hpp
@@ -42,7 +42,11 @@
template<typename InputIterator, typename T>
bool each_equal(InputIterator first, InputIterator last, T const& t)
{
- return std::distance(first, last) == std::count(first, last, t);
+ for(InputIterator i = first; i != last; ++i)
+ {
+ if(t != *i) return false;
+ }
+ return true;
}
/// Test whether every element in a range equals the specified constant.
diff --git a/miscellany_test.cpp b/miscellany_test.cpp
index 0b9d0ee..367545a 100644
--- a/miscellany_test.cpp
+++ b/miscellany_test.cpp
@@ -30,10 +30,10 @@
void test_each_equal()
{
- int a0[] {0, 0, 0, 0};
- int const a1[] {0, 1, 1, 1};
- int volatile a2[] {0, 1, 2, 2};
- int const volatile a3[] {0, 1, 2, 3};
+ int a0[] {0, 0, 0, 0};
+ int const a1[] {0, 1, 1, 1};
+ int volatile a2[] {0, 1, 2, 2};
+ int const volatile a3[] {0, 1, 2, 3};
// There can be no volatile standard container.
std::vector<int> v0 {0, 0, 0, 0};
@@ -67,10 +67,21 @@ void test_each_equal()
BOOST_TEST( each_equal(v2.begin() + 2, v2.end(), 2));
BOOST_TEST( each_equal(v3.begin() + 3, v3.end(), 3));
- // Iterators are also more prone to error.
- // This crashes with g++-mingw-w64-i686 4.9.1:
+ // Iterators are also more prone to error. The following examples
+ // have undefined behavior.
// BOOST_TEST( each_equal(v0.begin() + 7, v0.end(), 0));
+// BOOST_TEST( each_equal(v0.begin() , v3.end(), 0));
+
+ // Test empty ranges. There can be no empty array [8.3.4/1].
+ // By arbitrary definition, any value compares equal to an empty
+ // range.
+
+ BOOST_TEST( each_equal(v0.end(), v0.end(), 0)); // both end()
+ BOOST_TEST( each_equal(v0.end(), v0.end(), 12345)); // both end()
+ std::vector<int> v_empty;
+ BOOST_TEST( each_equal(v_empty, 23456));
+ BOOST_TEST( each_equal(v_empty.begin(), v_empty.end(), 34567));
}
void test_files_are_identical()