/* Copyright (c) Marshall Clow 2013. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) For more information, see http://www.boost.org */ #include #include #include "iterator_test.hpp" #define BOOST_TEST_MAIN #include template BOOST_CXX14_CONSTEXPR bool eq ( const T& a, const T& b ) { return a == b; } template bool never_eq ( const T&, const T& ) { return false; } int comparison_count = 0; template bool counting_equals ( const T &a, const T &b ) { ++comparison_count; return a == b; } namespace ba = boost::algorithm; void test_equal () { // Note: The literal values here are tested against directly, careful if you change them: int num[] = { 1, 1, 2, 3, 5 }; const int sz = sizeof (num)/sizeof(num[0]); // Empty sequences are equal to each other, but not to non-empty sequences BOOST_CHECK ( ba::equal ( input_iterator(num), input_iterator(num), input_iterator(num), input_iterator(num))); BOOST_CHECK ( ba::equal ( input_iterator(num), input_iterator(num), input_iterator(num), input_iterator(num), never_eq )); BOOST_CHECK ( ba::equal ( random_access_iterator(num), random_access_iterator(num), random_access_iterator(num), random_access_iterator(num), never_eq )); BOOST_CHECK (!ba::equal ( input_iterator(num), input_iterator(num), input_iterator(num), input_iterator(num + 1))); BOOST_CHECK (!ba::equal ( input_iterator(num + 1), input_iterator(num + 2), input_iterator(num), input_iterator(num))); BOOST_CHECK (!ba::equal ( random_access_iterator(num + 1), random_access_iterator(num + 2), random_access_iterator(num), random_access_iterator(num))); // Single element sequences are equal if they contain the same value BOOST_CHECK ( ba::equal ( input_iterator(num), input_iterator(num + 1), input_iterator(num), input_iterator(num + 1))); BOOST_CHECK ( ba::equal ( input_iterator(num), input_iterator(num + 1), input_iterator(num), input_iterator(num + 1), eq )); BOOST_CHECK ( ba::equal ( random_access_iterator(num), random_access_iterator(num + 1), random_access_iterator(num), random_access_iterator(num + 1), eq )); BOOST_CHECK (!ba::equal ( input_iterator(num), input_iterator(num + 1), input_iterator(num), input_iterator(num + 1), never_eq )); BOOST_CHECK (!ba::equal ( random_access_iterator(num), random_access_iterator(num + 1), random_access_iterator(num), random_access_iterator(num + 1), never_eq )); BOOST_CHECK ( ba::equal ( input_iterator(num), input_iterator(num + 1), input_iterator(num + 1), input_iterator(num + 2))); BOOST_CHECK ( ba::equal ( input_iterator(num), input_iterator(num + 1), input_iterator(num + 1), input_iterator(num + 2), eq )); BOOST_CHECK (!ba::equal ( input_iterator(num + 2), input_iterator(num + 3), input_iterator(num), input_iterator(num + 1))); BOOST_CHECK (!ba::equal ( input_iterator(num + 2), input_iterator(num + 3), input_iterator(num), input_iterator(num + 1), eq )); // Identical long sequences are equal. BOOST_CHECK ( ba::equal ( input_iterator(num), input_iterator(num + sz), input_iterator(num), input_iterator(num + sz))); BOOST_CHECK ( ba::equal ( input_iterator(num), input_iterator(num + sz), input_iterator(num), input_iterator(num + sz), eq )); BOOST_CHECK (!ba::equal ( input_iterator(num), input_iterator(num + sz), input_iterator(num), input_iterator(num + sz), never_eq )); BOOST_CHECK ( ba::equal ( input_iterator(num), input_iterator(num + sz), random_access_iterator(num), random_access_iterator(num + sz), eq )); // different sequences are different BOOST_CHECK (!ba::equal ( input_iterator(num + 1), input_iterator(num + sz), input_iterator(num), input_iterator(num + sz))); BOOST_CHECK (!ba::equal ( input_iterator(num + 1), input_iterator(num + sz), input_iterator(num), input_iterator(num + sz), eq )); BOOST_CHECK (!ba::equal ( input_iterator(num), input_iterator(num + sz), input_iterator(num), input_iterator(num + sz - 1))); BOOST_CHECK (!ba::equal ( input_iterator(num), input_iterator(num + sz), input_iterator(num), input_iterator(num + sz - 1), eq )); // When there's a cheap check, bail early comparison_count = 0; BOOST_CHECK (!ba::equal ( random_access_iterator(num), random_access_iterator(num + sz), random_access_iterator(num), random_access_iterator(num + sz - 1), counting_equals )); BOOST_CHECK ( comparison_count == 0 ); // And when there's not, we can't comparison_count = 0; BOOST_CHECK (!ba::equal ( input_iterator(num), input_iterator(num + sz), input_iterator(num), input_iterator(num + sz - 1), counting_equals )); BOOST_CHECK ( comparison_count > 0 ); } BOOST_CXX14_CONSTEXPR bool test_constexpr_equal() { int num[] = { 1, 1, 2, 3, 5}; const int sz = sizeof (num)/sizeof(num[0]); bool res = true; // Empty sequences are equal to each other res = ( ba::equal ( input_iterator(num), input_iterator(num), input_iterator(num), input_iterator(num)) // Identical long sequences are equal && ba::equal ( input_iterator(num), input_iterator(num + sz), input_iterator(num), input_iterator(num + sz), eq ) // Different sequences are different && !ba::equal ( input_iterator(num + 1), input_iterator(num + sz), input_iterator(num), input_iterator(num + sz)) ); #ifdef __cpp_lib_array_constexpr // or cpp17 compiler // Turn on tests for random_access_iterator, because std functions used in equal are marked constexpr_res res = ( res // Empty sequences are equal to each other && ba::equal ( random_access_iterator(num), random_access_iterator(num), random_access_iterator(num), random_access_iterator(num)) // Identical long sequences are equal && ba::equal ( random_access_iterator(num), random_access_iterator(num + sz), random_access_iterator(num), random_access_iterator(num + sz), eq ) // Different sequences are different && !ba::equal ( random_access_iterator(num + 1), random_access_iterator(num + sz), random_access_iterator(num), random_access_iterator(num + sz)) ); #endif return res; } BOOST_AUTO_TEST_CASE( test_main ) { test_equal (); BOOST_CXX14_CONSTEXPR bool constexpr_res = test_constexpr_equal (); BOOST_CHECK (constexpr_res); }