lmi-commits
[Top][All Lists]
Advanced

[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()



reply via email to

[Prev in Thread] Current Thread [Next in Thread]