Files
container/experimental/segmented_equal_test.cpp
T

717 lines
22 KiB
C++

//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2025-2026. 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)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/experimental/segmented_equal.hpp>
#include <boost/core/lightweight_test.hpp>
#include "segmented_test_helper.hpp"
#include <boost/container/vector.hpp>
using namespace boost::container;
void test_equal_matching()
{
test_detail::seg_vector<int> sv;
int a1[] = {1, 2, 3};
int a2[] = {4, 5};
int a3[] = {6, 7, 8, 9};
sv.add_segment_range(a1, a1 + 3);
sv.add_segment_range(a2, a2 + 2);
sv.add_segment_range(a3, a3 + 4);
int ref[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
BOOST_TEST(segmented_equal(sv.begin(), sv.end(), ref));
}
void test_equal_mismatch()
{
test_detail::seg_vector<int> sv;
int a1[] = {1, 2, 3};
int a2[] = {4, 5};
sv.add_segment_range(a1, a1 + 3);
sv.add_segment_range(a2, a2 + 2);
int ref[] = {1, 2, 3, 4, 99};
BOOST_TEST(!segmented_equal(sv.begin(), sv.end(), ref));
}
void test_equal_mismatch_first_segment()
{
test_detail::seg_vector<int> sv;
int a1[] = {1, 2, 3};
int a2[] = {4, 5};
sv.add_segment_range(a1, a1 + 3);
sv.add_segment_range(a2, a2 + 2);
int ref[] = {1, 99, 3, 4, 5};
BOOST_TEST(!segmented_equal(sv.begin(), sv.end(), ref));
}
void test_equal_empty()
{
test_detail::seg_vector<int> sv;
int dummy = 0;
BOOST_TEST(segmented_equal(sv.begin(), sv.end(), &dummy));
}
void test_equal_single_segment()
{
test_detail::seg_vector<int> sv;
int a[] = {10, 20, 30};
sv.add_segment_range(a, a + 3);
int ref[] = {10, 20, 30};
BOOST_TEST(segmented_equal(sv.begin(), sv.end(), ref));
}
void test_equal_non_segmented()
{
boost::container::vector<int> v;
v.push_back(1); v.push_back(2); v.push_back(3);
int ref_match[] = {1, 2, 3};
BOOST_TEST(segmented_equal(v.begin(), v.end(), ref_match));
int ref_fail[] = {1, 2, 99};
BOOST_TEST(!segmented_equal(v.begin(), v.end(), ref_fail));
}
void test_equal_sentinel_segmented()
{
test_detail::seg_vector<int> sv;
int a1[] = {1, 2, 3};
int a2[] = {4, 5};
int a3[] = {6, 7, 8, 9};
sv.add_segment_range(a1, a1 + 3);
sv.add_segment_range(a2, a2 + 2);
sv.add_segment_range(a3, a3 + 4);
int ref[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
BOOST_TEST(segmented_equal(sv.begin(), test_detail::make_sentinel(sv.end()), ref));
}
void test_equal_sentinel_non_segmented()
{
boost::container::vector<int> v;
v.push_back(1); v.push_back(2); v.push_back(3);
int ref_match[] = {1, 2, 3};
BOOST_TEST(segmented_equal(v.begin(), test_detail::make_sentinel(v.end()), ref_match));
int ref_fail[] = {1, 2, 99};
BOOST_TEST(!segmented_equal(v.begin(), test_detail::make_sentinel(v.end()), ref_fail));
}
void test_equal_seg2()
{
test_detail::seg2_vector<int> sv2;
int a1[] = {1, 2, 3};
int a2[] = {4, 5};
int a3[] = {6, 7, 8, 9};
sv2.add_flat_segment_range(a1, a1 + 3);
sv2.add_flat_segment_range(a2, a2 + 2);
sv2.add_flat_segment_range(a3, a3 + 4);
int ref[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
BOOST_TEST(segmented_equal(sv2.begin(), sv2.end(), ref));
int ref_bad[] = {1, 2, 3, 4, 5, 6, 7, 8, 0};
BOOST_TEST(!segmented_equal(sv2.begin(), sv2.end(), ref_bad));
}
void test_equal_seg_to_seg()
{
test_detail::seg_vector<int> sv1;
int a1[] = {1, 2, 3};
int a2[] = {4, 5};
int a3[] = {6, 7, 8, 9};
sv1.add_segment_range(a1, a1 + 3);
sv1.add_segment_range(a2, a2 + 2);
sv1.add_segment_range(a3, a3 + 4);
test_detail::seg_vector<int> sv2;
int b1[] = {1, 2};
int b2[] = {3, 4, 5, 6};
int b3[] = {7, 8, 9};
sv2.add_segment_range(b1, b1 + 2);
sv2.add_segment_range(b2, b2 + 4);
sv2.add_segment_range(b3, b3 + 3);
BOOST_TEST(segmented_equal(sv1.begin(), sv1.end(), sv2.begin()));
}
void test_equal_seg_to_seg_mismatch()
{
test_detail::seg_vector<int> sv1;
int a1[] = {1, 2, 3};
int a2[] = {4, 5};
sv1.add_segment_range(a1, a1 + 3);
sv1.add_segment_range(a2, a2 + 2);
test_detail::seg_vector<int> sv2;
int b1[] = {1, 2};
int b2[] = {3, 4, 99};
sv2.add_segment_range(b1, b1 + 2);
sv2.add_segment_range(b2, b2 + 3);
BOOST_TEST(!segmented_equal(sv1.begin(), sv1.end(), sv2.begin()));
}
void test_equal_seg2_to_seg2()
{
test_detail::seg2_vector<int> sv1;
int a1[] = {1, 2, 3};
int a2[] = {4, 5};
int a3[] = {6, 7, 8, 9};
sv1.add_flat_segment_range(a1, a1 + 3);
sv1.add_flat_segment_range(a2, a2 + 2);
sv1.add_flat_segment_range(a3, a3 + 4);
test_detail::seg2_vector<int> sv2;
int b1[] = {1, 2};
int b2[] = {3, 4, 5, 6};
int b3[] = {7, 8, 9};
sv2.add_flat_segment_range(b1, b1 + 2);
sv2.add_flat_segment_range(b2, b2 + 4);
sv2.add_flat_segment_range(b3, b3 + 3);
BOOST_TEST(segmented_equal(sv1.begin(), sv1.end(), sv2.begin()));
test_detail::seg2_vector<int> sv3;
int c1[] = {1, 2, 3, 4, 5, 6, 7, 8, 0};
sv3.add_flat_segment_range(c1, c1 + 9);
BOOST_TEST(!segmented_equal(sv1.begin(), sv1.end(), sv3.begin()));
}
void test_equal_seg_to_seg_misaligned()
{
test_detail::seg_vector<int> sv1;
int a1[] = {10};
int a2[] = {20, 30};
int a3[] = {40, 50, 60};
sv1.add_segment_range(a1, a1 + 1);
sv1.add_segment_range(a2, a2 + 2);
sv1.add_segment_range(a3, a3 + 3);
test_detail::seg_vector<int> sv2;
int b1[] = {10, 20, 30, 40};
int b2[] = {50, 60};
sv2.add_segment_range(b1, b1 + 4);
sv2.add_segment_range(b2, b2 + 2);
BOOST_TEST(segmented_equal(sv1.begin(), sv1.end(), sv2.begin()));
}
//////////////////////////////////////////////////////////////////////////////
// Single-segment coverage.
//
// The segmented walkers take their single-segment branch only when
// segment(first) == segment(last). A range spanning a whole seg_vector can
// never do that, because the end iterator lives in the trailing sentinel
// segment; these tests therefore build one oversized segment and compare a
// proper sub-range of it.
//////////////////////////////////////////////////////////////////////////////
struct test_equal_double_eq
{
bool operator()(int a, int b) const { return a * 2 == b; }
};
// S1: one segment, range starting at the segment edge.
void test_equal_single_segment_full_range()
{
int vals[] = {10, 20, 30, 40, 50, 60};
test_detail::seg_vector<int> sv;
test_detail::make_range(sv, "s", vals, 6, -1);
typedef test_detail::seg_vector<int>::iterator iter_t;
const iter_t last = test_detail::iter_at(sv, 6);
int ref[] = {10, 20, 30, 40, 50, 60};
BOOST_TEST(segmented_equal(sv.begin(), last, ref));
// The element past last1 takes no part in the comparison.
int ref_tail_differs[] = {10, 20, 30, 40, 50, 60, 999};
BOOST_TEST(segmented_equal(sv.begin(), last, ref_tail_differs));
int ref_bad[] = {10, 20, 30, 40, 50, 99};
BOOST_TEST(!segmented_equal(sv.begin(), last, ref_bad));
}
// S2: one segment, both endpoints strictly interior.
void test_equal_single_segment_interior_bounds()
{
test_detail::seg_vector<int> sv;
int a[] = {-7, 10, 20, 30, 40, 50, -8};
sv.add_segment_range(a, a + 7);
typedef test_detail::seg_vector<int>::iterator iter_t;
const iter_t first = test_detail::iter_at(sv, 1);
const iter_t last = test_detail::iter_at(sv, 6);
int ref[] = {10, 20, 30, 40, 50, 777};
BOOST_TEST(segmented_equal(first, last, ref));
int ref_first_differs[] = {99, 20, 30, 40, 50, 777};
BOOST_TEST(!segmented_equal(first, last, ref_first_differs));
int ref_last_differs[] = {10, 20, 30, 40, 99, 777};
BOOST_TEST(!segmented_equal(first, last, ref_last_differs));
}
// S3: one segment, empty range positioned mid-segment.
void test_equal_single_segment_empty_range()
{
test_detail::seg_vector<int> sv;
int a[] = {10, 20, 30, 40, 50, 60};
sv.add_segment_range(a, a + 6);
typedef test_detail::seg_vector<int>::iterator iter_t;
const iter_t mid = test_detail::iter_at(sv, 3);
int ref[] = {99, 99, 99};
BOOST_TEST(segmented_equal(mid, mid, ref));
BOOST_TEST(segmented_equal(mid, mid, ref, test_equal_double_eq()));
}
// S4: S2 through the sentinel overload.
void test_equal_single_segment_sentinel()
{
test_detail::seg_vector<int> sv;
int a[] = {-7, 10, 20, 30, 40, 50, -8};
sv.add_segment_range(a, a + 7);
typedef test_detail::seg_vector<int>::iterator iter_t;
const iter_t first = test_detail::iter_at(sv, 1);
const iter_t last = test_detail::iter_at(sv, 6);
int ref[] = {10, 20, 30, 40, 50, 777};
BOOST_TEST(segmented_equal(first, test_detail::make_sentinel(last), ref));
int ref_bad[] = {10, 20, 30, 40, 99, 777};
BOOST_TEST(!segmented_equal(first, test_detail::make_sentinel(last), ref_bad));
}
// S1 and S2 through the predicate-taking overload.
void test_equal_single_segment_pred()
{
int vals[] = {1, 2, 3, 4, 5, 6};
test_detail::seg_vector<int> sv;
test_detail::make_range(sv, "s", vals, 6, -1);
typedef test_detail::seg_vector<int>::iterator iter_t;
const iter_t last = test_detail::iter_at(sv, 6);
int ref[] = {2, 4, 6, 8, 10, 12};
BOOST_TEST(segmented_equal(sv.begin(), last, ref, test_equal_double_eq()));
int ref_bad[] = {2, 4, 6, 8, 10, 99};
BOOST_TEST(!segmented_equal(sv.begin(), last, ref_bad, test_equal_double_eq()));
const iter_t inner_first = test_detail::iter_at(sv, 2);
const iter_t inner_last = test_detail::iter_at(sv, 5);
int ref_inner[] = {6, 8, 10, 999};
BOOST_TEST(segmented_equal(inner_first, inner_last, ref_inner, test_equal_double_eq()));
}
// S5: one outer segment holding several inner segments.
void test_equal_single_segment_seg2_outer()
{
int vals[] = {10, 20, 30, 40, 50};
test_detail::seg2_vector<int> sv2;
test_detail::make_range(sv2, "sm", vals, 5, -1);
typedef test_detail::seg2_vector<int>::iterator iter_t;
const iter_t last = test_detail::iter_at(sv2, 5);
int ref[] = {10, 20, 30, 40, 50, 777};
BOOST_TEST(segmented_equal(sv2.begin(), last, ref));
int ref_bad[] = {10, 20, 30, 40, 99, 777};
BOOST_TEST(!segmented_equal(sv2.begin(), last, ref_bad));
}
// S6: single segment at both levels of recursion.
void test_equal_single_segment_seg2_both_levels()
{
int vals[] = {10, 20, 30, 40, 50};
test_detail::seg2_vector<int> sv2;
test_detail::make_range(sv2, "ss", vals, 5, -1);
typedef test_detail::seg2_vector<int>::iterator iter_t;
const iter_t first = test_detail::iter_at(sv2, 1);
const iter_t last = test_detail::iter_at(sv2, 4);
int ref[] = {20, 30, 40, 777};
BOOST_TEST(segmented_equal(first, last, ref));
BOOST_TEST(segmented_equal(sv2.begin(), test_detail::iter_at(sv2, 5), vals));
int ref_bad[] = {20, 30, 99, 777};
BOOST_TEST(!segmented_equal(first, last, ref_bad));
}
// M4: multi-segment first range against a single-segment second range,
// with the inequality at every position in turn and nowhere.
void test_equal_single_segment_second_range()
{
test_detail::seg_vector<int> sv1;
int a1[] = {10, 20, 30};
int a2[] = {40, 50};
sv1.add_segment_range(a1, a1 + 3);
sv1.add_segment_range(a2, a2 + 2);
const int N = 5;
int vals[] = {10, 20, 30, 40, 50, 60, 70};
test_detail::seg_vector<int> sv2;
sv2.add_segment_range(vals, vals + 7);
BOOST_TEST(segmented_equal(sv1.begin(), sv1.end(), sv2.begin()));
for(int pos = 0; pos < N; ++pos) {
int ref[7];
for(int j = 0; j < 7; ++j) ref[j] = vals[j];
ref[pos] = -1;
test_detail::seg_vector<int> sv_bad;
sv_bad.add_segment_range(ref, ref + 7);
BOOST_TEST(!segmented_equal(sv1.begin(), sv1.end(), sv_bad.begin()));
}
// A difference past the end of the first range is never seen.
int tail[] = {10, 20, 30, 40, 50, -1, -1};
test_detail::seg_vector<int> sv_tail;
sv_tail.add_segment_range(tail, tail + 7);
BOOST_TEST(segmented_equal(sv1.begin(), sv1.end(), sv_tail.begin()));
}
// M4 reversed: single-segment first range against a multi-segment second one.
void test_equal_single_segment_first_range()
{
test_detail::seg_vector<int> sv1;
int a[] = {-7, 10, 20, 30, 40, 50, -8};
sv1.add_segment_range(a, a + 7);
typedef test_detail::seg_vector<int>::iterator iter_t;
const iter_t first = test_detail::iter_at(sv1, 1);
const iter_t last = test_detail::iter_at(sv1, 6);
test_detail::seg_vector<int> sv2;
int b1[] = {10, 20};
int b2[] = {30};
int b3[] = {40, 50, 60};
sv2.add_segment_range(b1, b1 + 2);
sv2.add_segment_range(b2, b2 + 1);
sv2.add_segment_range(b3, b3 + 3);
BOOST_TEST(segmented_equal(first, last, sv2.begin()));
test_detail::seg_vector<int> sv3;
int c1[] = {10, 20};
int c2[] = {30};
int c3[] = {40, 99, 60};
sv3.add_segment_range(c1, c1 + 2);
sv3.add_segment_range(c2, c2 + 1);
sv3.add_segment_range(c3, c3 + 3);
BOOST_TEST(!segmented_equal(first, last, sv3.begin()));
}
// M3: both ranges single-segment.
void test_equal_single_segment_both_ranges()
{
test_detail::seg_vector<int> sv1;
int a[] = {-7, 10, 20, 30, 40, 50, -8};
sv1.add_segment_range(a, a + 7);
test_detail::seg_vector<int> sv2;
int b[] = {10, 20, 30, 40, 50, 60, 70};
sv2.add_segment_range(b, b + 7);
typedef test_detail::seg_vector<int>::iterator iter_t;
const iter_t first = test_detail::iter_at(sv1, 1);
const iter_t last = test_detail::iter_at(sv1, 6);
BOOST_TEST(segmented_equal(first, last, sv2.begin()));
BOOST_TEST(segmented_equal(first, first, sv2.begin()));
test_detail::seg_vector<int> sv3;
int c[] = {10, 20, 30, 40, 99, 60, 70};
sv3.add_segment_range(c, c + 7);
BOOST_TEST(!segmented_equal(first, last, sv3.begin()));
}
// M4 with a recursively segmented second range whose outer level holds a
// single segment.
void test_equal_single_segment_second_range_seg2()
{
test_detail::seg_vector<int> sv1;
int a1[] = {10, 20, 30};
int a2[] = {40, 50};
sv1.add_segment_range(a1, a1 + 3);
sv1.add_segment_range(a2, a2 + 2);
int b[] = {10, 20, 30, 40, 50, 60, 70};
test_detail::seg2_vector<int> sv2;
test_detail::make_range(sv2, "sm", b, 7, -1);
BOOST_TEST(segmented_equal(sv1.begin(), sv1.end(), sv2.begin()));
int c[] = {10, 20, 30, 40, 50, 60, 70};
test_detail::seg2_vector<int> sv3;
test_detail::make_range(sv3, "ss", c, 7, -1);
BOOST_TEST(segmented_equal(sv1.begin(), sv1.end(), sv3.begin()));
int d[] = {10, 20, 99, 40, 50, 60, 70};
test_detail::seg2_vector<int> sv4;
test_detail::make_range(sv4, "sm", d, 7, -1);
BOOST_TEST(!segmented_equal(sv1.begin(), sv1.end(), sv4.begin()));
}
// Non-segmented first range against a single-segment segmented second range.
void test_equal_single_segment_flat_first_range()
{
boost::container::vector<int> v;
v.push_back(10); v.push_back(20); v.push_back(30);
test_detail::seg_vector<int> sv2;
int b[] = {10, 20, 30, 40, 50};
sv2.add_segment_range(b, b + 5);
BOOST_TEST(segmented_equal(v.begin(), v.end(), sv2.begin()));
test_detail::seg_vector<int> sv3;
int c[] = {10, 99, 30, 40, 50};
sv3.add_segment_range(c, c + 5);
BOOST_TEST(!segmented_equal(v.begin(), v.end(), sv3.begin()));
}
// Inequality at the first element, at the last one and nowhere, with both
// endpoints of the single segment strictly interior.
void test_equal_single_segment_every_position()
{
test_detail::seg_vector<int> sv;
int a[] = {-7, 10, 20, 30, 40, 50, -8};
sv.add_segment_range(a, a + 7);
typedef test_detail::seg_vector<int>::iterator iter_t;
const iter_t first = test_detail::iter_at(sv, 1);
const iter_t last = test_detail::iter_at(sv, 6);
const int N = 5;
int vals[] = {10, 20, 30, 40, 50};
BOOST_TEST(segmented_equal(first, last, vals));
for(int pos = 0; pos < N; ++pos) {
int ref[5];
for(int j = 0; j < N; ++j) ref[j] = vals[j];
ref[pos] = -1;
BOOST_TEST(!segmented_equal(first, last, ref));
}
}
//////////////////////////////////////////////////////////////////////////////
// Shape matrix.
//
// segmented_equal walks two independently segmented ranges at once, so the
// interesting cross product is of the two ranges' shapes, not of one range's
// shape with itself. for_each_shape2_all supplies that, including the 'e'
// shapes whose empty segments the two walkers have to skip in step with each
// other.
//
// The second range is deliberately one element longer than the first and its
// extra element is a value that appears nowhere else, so that a walker which
// runs one element past last1 compares range 1's guard against it and fails
// visibly.
//////////////////////////////////////////////////////////////////////////////
const int equal_shape_tail = 12345;
struct equal_shape_check
{
// Index of the element of range 2 that was corrupted, or n1 for none.
std::size_t bad_pos;
explicit equal_shape_check(std::size_t p) : bad_pos(p) {}
void report(const char* s1, std::size_t n1, const char* s2) const
{
BOOST_LIGHTWEIGHT_TEST_OSTREAM
<< " shapes \"" << s1 << "\" / \"" << s2 << "\", n = " << n1
<< ", differing at " << bad_pos << std::endl;
}
template<class C1, class C2>
void operator()(C1& c1, std::size_t n1, const char* s1,
C2& c2, std::size_t n2, const char* s2) const
{
typedef typename C1::iterator iter1_t;
const boost::container::vector<int> f1 = test_detail::flatten_n_ints(c1, n1);
const boost::container::vector<int> f2 = test_detail::flatten_n_ints(c2, n2);
bool expected = true;
for(std::size_t i = 0; i != f1.size(); ++i) {
if(f1[i] != f2[i]) { expected = false; break; }
}
const iter1_t first1 = c1.begin();
const iter1_t last1 = test_detail::iter_at(c1, n1);
if(!BOOST_TEST_EQ(segmented_equal(first1, last1, c2.begin()), expected))
this->report(s1, n1, s2);
// Same question through the sentinel overload, which reaches a
// different set of dispatch templates.
if(!BOOST_TEST_EQ(segmented_equal(first1, test_detail::make_sentinel(last1), c2.begin()),
expected))
this->report(s1, n1, s2);
// Neither range is an output, so both guards must still be intact.
if(!BOOST_TEST(test_detail::filler_intact(c1, n1, -999)))
this->report(s1, n1, s2);
if(!BOOST_TEST(test_detail::filler_intact(c2, n2, -999)))
this->report(s1, n1, s2);
}
};
void test_equal_shape_matrix()
{
const std::size_t sizes[] = { 0u, 1u, 2u, 5u, 9u };
for(std::size_t s = 0; s != sizeof(sizes)/sizeof(sizes[0]); ++s) {
const std::size_t n1 = sizes[s];
const std::size_t n2 = n1 + 1u;
int v1[10] = {};
for(std::size_t i = 0; i != n1; ++i)
v1[i] = int(i) + 1;
// bad == n1 means "the two ranges agree"; otherwise range 2 differs at
// exactly that position.
for(std::size_t bad = 0; bad <= n1; ++bad) {
int v2[11] = {};
for(std::size_t i = 0; i != n1; ++i)
v2[i] = v1[i];
v2[n1] = equal_shape_tail;
if(bad != n1)
v2[bad] = -7;
test_detail::for_each_shape2_all<int, int>
(v1, n1, v2, n2, -999, equal_shape_check(bad));
}
}
}
//////////////////////////////////////////////////////////////////////////////
// Predicate application count.
//
// [alg.equal] mandates "At most last1 - first1 applications of the
// corresponding predicate". The lower bound below is what stops the check
// from passing vacuously: the answer cannot be known before the first
// differing position has been looked at.
//////////////////////////////////////////////////////////////////////////////
struct eq_int
{
bool operator()(int a, int b) const { return a == b; }
};
struct equal_count_check
{
// Index of the element of range 2 that was corrupted, or n1 for none.
std::size_t bad_pos;
explicit equal_count_check(std::size_t p) : bad_pos(p) {}
template<class C1, class C2>
void operator()(C1& c1, std::size_t n1, const char* s1,
C2& c2, std::size_t n2, const char* s2) const
{
const std::size_t needed = bad_pos < n1 ? bad_pos + 1u : n1;
{
test_detail::op_counter calls;
segmented_equal(c1.begin(), test_detail::iter_at(c1, n1), c2.begin(),
test_detail::counting_pred(calls, eq_int()));
BOOST_TEST(calls.n <= n1);
BOOST_TEST(calls.n >= needed);
}
{
test_detail::op_counter calls;
segmented_equal(c1.begin(), test_detail::make_sentinel(test_detail::iter_at(c1, n1)),
c2.begin(), test_detail::counting_pred(calls, eq_int()));
BOOST_TEST(calls.n <= n1);
BOOST_TEST(calls.n >= needed);
}
BOOST_TEST(s1 != 0 && s2 != 0 && n2 != 0);
}
};
void test_equal_predicate_count()
{
const std::size_t sizes[] = { 0u, 1u, 2u, 5u, 9u };
for(std::size_t s = 0; s != sizeof(sizes)/sizeof(sizes[0]); ++s) {
const std::size_t n1 = sizes[s];
const std::size_t n2 = n1 + 1u;
int v1[10] = {};
for(std::size_t i = 0; i != n1; ++i)
v1[i] = int(i) + 1;
for(std::size_t bad = 0; bad <= n1; ++bad) {
int v2[11] = {};
for(std::size_t i = 0; i != n1; ++i)
v2[i] = v1[i];
v2[n1] = equal_shape_tail;
if(bad != n1)
v2[bad] = -7;
test_detail::for_each_shape2_all<int, int>
(v1, n1, v2, n2, -999, equal_count_check(bad));
}
}
}
int main()
{
test_equal_shape_matrix();
test_equal_matching();
test_equal_mismatch();
test_equal_mismatch_first_segment();
test_equal_empty();
test_equal_single_segment();
test_equal_non_segmented();
test_equal_sentinel_segmented();
test_equal_sentinel_non_segmented();
test_equal_seg2();
test_equal_seg_to_seg();
test_equal_seg_to_seg_mismatch();
test_equal_seg2_to_seg2();
test_equal_seg_to_seg_misaligned();
// Single-segment coverage:
test_equal_single_segment_full_range();
test_equal_single_segment_interior_bounds();
test_equal_single_segment_empty_range();
test_equal_single_segment_sentinel();
test_equal_single_segment_pred();
test_equal_single_segment_seg2_outer();
test_equal_single_segment_seg2_both_levels();
test_equal_single_segment_second_range();
test_equal_single_segment_first_range();
test_equal_single_segment_both_ranges();
test_equal_single_segment_second_range_seg2();
test_equal_single_segment_flat_first_range();
test_equal_single_segment_every_position();
test_equal_predicate_count();
return boost::report_errors();
}