Sequoia
Loading...
Searching...
No Matches
PartitionedDataTestingUtilities.hpp
Go to the documentation of this file.
1
2// Copyright Oliver J. Rosten 2019. //
3// Distributed under the GNU GENERAL PUBLIC LICENSE, Version 3.0. //
4// (See accompanying file LICENSE.md or copy at //
5// https://www.gnu.org/licenses/gpl-3.0.en.html) //
7
8#pragma once
9
13
15
16namespace sequoia::testing
17{
18 namespace impl
19 {
20 template<class CheckType, test_mode Mode, class PartitionedData>
21 void check_details(CheckType flavour, test_logger<Mode>& logger, const PartitionedData& data, const PartitionedData& prediction)
22 {
23 check(equality, "Emptiness incorrect", logger, data.empty(), prediction.empty());
24
25 check(equality, "Size incorrect", logger, data.size(), prediction.size());
26
27 if(check(equality, "Number of partitions incorrect", logger, data.num_partitions(), prediction.num_partitions()))
28 {
29 for(std::size_t i{}; i<prediction.num_partitions(); ++i)
30 {
31 const auto message{std::string{"Partition "}.append(std::to_string(i))};
32 check(equality, append_lines(message, "size_of_partition"), logger, data.size_of_partition(i), prediction.size_of_partition(i));
33
34 if(check(flavour, append_lines(message, "iterator (const)"), logger, data.begin_partition(i), data.end_partition(i), prediction.begin_partition(i), prediction.end_partition(i)))
35 {
36 for(int64_t j{}; j<std::ranges::distance(prediction.partition(i)); ++j)
37 {
38 check(flavour, append_lines(message,"[] (const)"), logger, data[i][j], prediction[i][j]);
39 }
40 }
41
42 check(flavour, append_lines(message, "r_iterator (const)"), logger, data.rbegin_partition(i), data.rend_partition(i), prediction.rbegin_partition(i), prediction.rend_partition(i));
43 check(flavour, append_lines(message, "c_iterator"), logger, data.cbegin_partition(i), data.cend_partition(i), prediction.cbegin_partition(i), prediction.cend_partition(i));
44 check(flavour, append_lines(message, "cr_iterator"), logger, data.crbegin_partition(i), data.crend_partition(i), prediction.crbegin_partition(i), prediction.crend_partition(i));
45 // TO DO: just pass the subranges as arguments; for now call begin() and end() to
46 // defer a difficult bit of cross-platform consistent demangling
47 check(flavour, append_lines(message, "subrange (const)"), logger, data.partition(i).begin(), data.partition(i).end(), prediction.partition(i).begin(), prediction.partition(i).end());
48
49 auto& r{const_cast<PartitionedData&>(prediction)};
50 auto& d{const_cast<PartitionedData&>(data)};
51 if(check(flavour, append_lines(message, "iterator"), logger, d.begin_partition(i), d.end_partition(i), r.begin_partition(i), r.end_partition(i)))
52 {
53 for(int64_t j{}; j<std::ranges::distance(r.partition(i)); ++j)
54 {
55 check(flavour, append_lines(message,"[]"), logger, d[i][j], r[i][j]);
56 }
57 }
58
59 check(flavour, append_lines(message, "r_iterator"), logger, d.rbegin_partition(i), d.rend_partition(i), r.rbegin_partition(i), r.rend_partition(i));
60 // TO DO: just pass the subranges as arguments; for now call begin() and end() to
61 // defer a difficult bit of cross-platform consistent demangling
62 check(flavour, append_lines(message, "subrange"), logger, d.partition(i).begin(), d.partition(i).end(), r.partition(i).begin(), r.partition(i).end());
63 }
64 }
65 }
66
67 template<test_mode Mode, class PartitionedData, class T=typename PartitionedData::value_type>
68 void check(equivalence_check_t, test_logger<Mode>& logger, const PartitionedData& data, std::initializer_list<std::initializer_list<T>> prediction)
69 {
70 const auto numElements{std::accumulate(prediction.begin(), prediction.end(), std::size_t{},
71 [](std::size_t val, std::initializer_list<T> partition) { return val += partition.size();})};
72
73 check(equality, "Number of elements incorrect", logger, data.size(), numElements);
74
75 if(check(equality, "Number of partitions incorrect", logger, data.num_partitions(), prediction.size()))
76 {
77 for(std::size_t i{}; i<prediction.size(); ++i)
78 {
79 const auto message{std::string{"Partition "}.append(std::to_string(i))};
80 check(equality, append_lines(message, "size_of_partition"), logger, data.size_of_partition(i), (prediction.begin() + i)->size());
81
82 check(with_best_available, message + ": iterator", logger, data.begin_partition(i), data.end_partition(i), (prediction.begin() + i)->begin(), (prediction.begin() + i)->end());
83 check(with_best_available, message + ": riterator", logger, data.rbegin_partition(i), data.rend_partition(i), std::rbegin(*(prediction.begin() + i)), std::rend(*(prediction.begin() + i)));
84 }
85 }
86 }
87 }
88
89 template<class T, class Container>
90 struct value_tester<data_structures::bucketed_sequence<T, Container>>
91 {
93
94 template<class CheckType, test_mode Mode>
95 static void test(CheckType flavour, test_logger<Mode>& logger, const type& data, const type& prediction)
96 {
97 impl::check_details(flavour, logger, data, prediction);
98 }
99
100 template<test_mode Mode>
101 static void test(equivalence_check_t, test_logger<Mode>& logger, const type& data, std::initializer_list<std::initializer_list<T>> prediction)
102 {
103 impl::check(equivalence, logger, data, prediction);
104 }
105 };
106
107 template<class T, class Container, class Partitions>
108 struct value_tester<data_structures::partitioned_sequence<T, Container, Partitions>>
109 {
111 using equivalent_type = std::initializer_list<std::initializer_list<T>>;
112
113 template<class CheckType, test_mode Mode>
114 static void test(CheckType flavour, test_logger<Mode>& logger, const type& data, const type& prediction)
115 {
116 impl::check_details(flavour, logger, data, prediction);
117 }
118
119 template<test_mode Mode>
120 static void test(equivalence_check_t, test_logger<Mode>& logger, const type& data, equivalent_type prediction)
121 {
122 impl::check(equivalence, logger, data, prediction);
123 }
124 };
125
126 template<class T, std::size_t Npartitions, std::size_t Nelements, std::integral IndexType>
127 struct value_tester<data_structures::static_partitioned_sequence<T, Npartitions, Nelements, maths::static_monotonic_sequence<IndexType, Npartitions, std::ranges::greater>>>
128 {
130
131 template<class CheckType, test_mode Mode>
132 static void test(CheckType flavour, test_logger<Mode>& logger, const type& data, const type& prediction)
133 {
134 impl::check_details(flavour, logger, data, prediction);
135 }
136
137 template<test_mode Mode>
138 static void test(equivalence_check_t, test_logger<Mode>& logger, const type& data, std::initializer_list<std::initializer_list<T>> prediction)
139 {
140 impl::check(equivalence, logger, data, prediction);
141 }
142 };
143
144 template<std::input_or_output_iterator I, class DerefPolicy>
145 requires requires(utilities::iterator<I, DerefPolicy> i){ i.partition_index(); }
146 struct value_tester<utilities::iterator<I, DerefPolicy>>
147 {
149
150 template<test_mode Mode>
151 static void test(equality_check_t, test_logger<Mode>& logger, const type& data, const type& prediction)
152 {
153 const auto dist{std::ranges::distance(data, prediction)};
154 using dist_t = decltype(dist);
155 check(equality, "Distance from prediction", logger, dist, dist_t{});
156 check(equality, "Partition Index", logger, data.partition_index(), prediction.partition_index());
157 }
158 };
159}
bool check(CheckType flavour, std::string description, test_logger< Mode > &logger, Iter first, Sentinel last, PredictionIter predictionFirst, PredictionSentinel predictionLast, tutor< Advisor > advisor={})
The workhorse for comparing the contents of ranges.
Definition: FreeCheckers.hpp:377
Classes implementing the concept of a sequence of data which is divided into partitions.
Utilities for checking regular semantics.
Storage for partitioned data such that data within each partition is contiguous.
Definition: PartitionedData.hpp:63
Definition: PartitionedData.hpp:991
Definition: PartitionedData.hpp:1099
Definition: TestLogger.hpp:183
An iterator with policies controlling dereferencing and auxiliary data.
Definition: Iterator.hpp:234
Definition: FreeCheckers.hpp:82
Definition: FreeCheckers.hpp:87
class template, specializations of which implement various comparisons for the specified type.
Definition: FreeCheckers.hpp:78