Skip to content

Commit 9c3d723

Browse files
committed
Added fake overloads to check for strict signatures.
Specifically, the fake overloads accept any set of arguments but are themselves deleted, so any non-exact match to the intended functions will instead match to the fake overload and trigger a compile-time error. In this manner, we can prevent implicit casts that might cause overflows. We also refactor for some minor improvements: - Overhaul the test_*_access() functions to avoid allocating storage within the loop body, for a slight efficiency improvement. - Slap const on function arguments and variables, for safety. - Avoid hard-coded size_t's, use I<decltype()> to infer the type.
1 parent 2eb2e0b commit 9c3d723

12 files changed

+657
-256
lines changed

include/tatami_test/ForcedOracleWrapper.hpp

Lines changed: 82 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
#ifndef TATAMI_TEST_FORCED_ORACLE_WRAPPER_HPP
22
#define TATAMI_TEST_FORCED_ORACLE_WRAPPER_HPP
33

4-
#include "tatami/base/Matrix.hpp"
5-
#include "tatami/utils/copy.hpp"
6-
74
#include <algorithm>
85
#include <memory>
96

7+
#include "tatami/base/Matrix.hpp"
8+
#include "tatami/utils/copy.hpp"
9+
1010
/**
1111
* @file ForcedOracleWrapper.hpp
1212
* @brief Forcibly use oracular extraction.
@@ -33,6 +33,19 @@ class ForcedOracleWrapper final : public tatami::Matrix<Value_, Index_> {
3333
*/
3434
ForcedOracleWrapper(std::shared_ptr<const tatami::Matrix<Value_, Index_> > matrix) : my_matrix(std::move(matrix)) {}
3535

36+
/**
37+
* @cond
38+
*/
39+
#ifdef TATAMI_STRICT_SIGNATURES
40+
ForcedOracleWrapper(std::shared_ptr<tatami::Matrix<Value_, Index_> > matrix) : ForcedOracleWrapper(std::move(matrix)) {}
41+
42+
template<typename ... Args_>
43+
ForcedOracleWrapper(Args_...) = delete;
44+
#endif
45+
/**
46+
* @endcond
47+
*/
48+
3649
private:
3750
std::shared_ptr<const tatami::Matrix<Value_, Index_> > my_matrix;
3851

@@ -66,54 +79,108 @@ class ForcedOracleWrapper final : public tatami::Matrix<Value_, Index_> {
6679
}
6780

6881
public:
69-
std::unique_ptr<tatami::MyopicDenseExtractor<Value_, Index_> > dense(bool row, const tatami::Options& opt) const {
82+
std::unique_ptr<tatami::MyopicDenseExtractor<Value_, Index_> > dense(
83+
const bool row,
84+
const tatami::Options& opt
85+
) const {
7086
return my_matrix->dense(row, opt);
7187
}
7288

73-
std::unique_ptr<tatami::MyopicDenseExtractor<Value_, Index_> > dense(bool row, Index_ bs, Index_ bl, const tatami::Options& opt) const {
89+
std::unique_ptr<tatami::MyopicDenseExtractor<Value_, Index_> > dense(
90+
const bool row,
91+
Index_ bs,
92+
Index_ bl,
93+
const tatami::Options& opt
94+
) const {
7495
return my_matrix->dense(row, bs, bl, opt);
7596
}
7697

77-
std::unique_ptr<tatami::MyopicDenseExtractor<Value_, Index_> > dense(bool row, tatami::VectorPtr<Index_> idx, const tatami::Options& opt) const {
98+
std::unique_ptr<tatami::MyopicDenseExtractor<Value_, Index_> > dense(
99+
bool row,
100+
tatami::VectorPtr<Index_> idx,
101+
const tatami::Options& opt
102+
) const {
78103
return my_matrix->dense(row, std::move(idx), opt);
79104
}
80105

81106
public:
82-
std::unique_ptr<tatami::MyopicSparseExtractor<Value_, Index_> > sparse(bool row, const tatami::Options& opt) const {
107+
std::unique_ptr<tatami::MyopicSparseExtractor<Value_, Index_> > sparse(
108+
const bool row,
109+
const tatami::Options& opt
110+
) const {
83111
return my_matrix->sparse(row, opt);
84112
}
85113

86-
std::unique_ptr<tatami::MyopicSparseExtractor<Value_, Index_> > sparse(bool row, Index_ bs, Index_ bl, const tatami::Options& opt) const {
114+
std::unique_ptr<tatami::MyopicSparseExtractor<Value_, Index_> > sparse(
115+
const bool row,
116+
const Index_ bs,
117+
const Index_ bl,
118+
const tatami::Options& opt
119+
) const {
87120
return my_matrix->sparse(row, bs, bl, opt);
88121
}
89122

90-
std::unique_ptr<tatami::MyopicSparseExtractor<Value_, Index_> > sparse(bool row, tatami::VectorPtr<Index_> idx, const tatami::Options& opt) const {
123+
std::unique_ptr<tatami::MyopicSparseExtractor<Value_, Index_> > sparse(
124+
const bool row,
125+
tatami::VectorPtr<Index_> idx,
126+
const tatami::Options& opt
127+
) const {
91128
return my_matrix->sparse(row, std::move(idx), opt);
92129
}
93130

94131
public:
95-
std::unique_ptr<tatami::OracularDenseExtractor<Value_, Index_> > dense(bool row, std::shared_ptr<const tatami::Oracle<Index_> > ora, const tatami::Options& opt) const {
132+
std::unique_ptr<tatami::OracularDenseExtractor<Value_, Index_> > dense(
133+
const bool row,
134+
std::shared_ptr<const tatami::Oracle<Index_> > ora,
135+
const tatami::Options& opt
136+
) const {
96137
return my_matrix->dense(row, std::move(ora), opt);
97138
}
98139

99-
std::unique_ptr<tatami::OracularDenseExtractor<Value_, Index_> > dense(bool row, std::shared_ptr<const tatami::Oracle<Index_> > ora, Index_ bs, Index_ bl, const tatami::Options& opt) const {
140+
std::unique_ptr<tatami::OracularDenseExtractor<Value_, Index_> > dense(
141+
const bool row,
142+
std::shared_ptr<const tatami::Oracle<Index_> > ora,
143+
const Index_ bs,
144+
const Index_ bl,
145+
const tatami::Options& opt
146+
) const {
100147
return my_matrix->dense(row, std::move(ora), bs, bl, opt);
101148
}
102149

103-
std::unique_ptr<tatami::OracularDenseExtractor<Value_, Index_> > dense(bool row, std::shared_ptr<const tatami::Oracle<Index_> > ora, tatami::VectorPtr<Index_> idx, const tatami::Options& opt) const {
150+
std::unique_ptr<tatami::OracularDenseExtractor<Value_, Index_> > dense(
151+
const bool row,
152+
std::shared_ptr<const tatami::Oracle<Index_> > ora,
153+
tatami::VectorPtr<Index_> idx,
154+
const tatami::Options& opt
155+
) const {
104156
return my_matrix->dense(row, std::move(ora), std::move(idx), opt);
105157
}
106158

107159
public:
108-
std::unique_ptr<tatami::OracularSparseExtractor<Value_, Index_> > sparse(bool row, std::shared_ptr<const tatami::Oracle<Index_> > ora, const tatami::Options& opt) const {
160+
std::unique_ptr<tatami::OracularSparseExtractor<Value_, Index_> > sparse(
161+
const bool row,
162+
std::shared_ptr<const tatami::Oracle<Index_> > ora,
163+
const tatami::Options& opt
164+
) const {
109165
return my_matrix->sparse(row, std::move(ora), opt);
110166
}
111167

112-
std::unique_ptr<tatami::OracularSparseExtractor<Value_, Index_> > sparse(bool row, std::shared_ptr<const tatami::Oracle<Index_> > ora, Index_ bs, Index_ bl, const tatami::Options& opt) const {
168+
std::unique_ptr<tatami::OracularSparseExtractor<Value_, Index_> > sparse(
169+
const bool row,
170+
std::shared_ptr<const tatami::Oracle<Index_> > ora,
171+
const Index_ bs,
172+
const Index_ bl,
173+
const tatami::Options& opt
174+
) const {
113175
return my_matrix->sparse(row, std::move(ora), bs, bl, opt);
114176
}
115177

116-
std::unique_ptr<tatami::OracularSparseExtractor<Value_, Index_> > sparse(bool row, std::shared_ptr<const tatami::Oracle<Index_> > ora, tatami::VectorPtr<Index_> idx, const tatami::Options& opt) const {
178+
std::unique_ptr<tatami::OracularSparseExtractor<Value_, Index_> > sparse(
179+
const bool row,
180+
std::shared_ptr<const tatami::Oracle<Index_> > ora,
181+
tatami::VectorPtr<Index_> idx,
182+
const tatami::Options& opt
183+
) const {
117184
return my_matrix->sparse(row, std::move(ora), std::move(idx), opt);
118185
}
119186
};

include/tatami_test/ReversedIndicesWrapper.hpp

Lines changed: 106 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
#ifndef TATAMI_TEST_REVERSED_INDICES_WRAPPER_HPP
22
#define TATAMI_TEST_REVERSED_INDICES_WRAPPER_HPP
33

4-
#include "tatami/base/Matrix.hpp"
5-
#include "tatami/utils/copy.hpp"
6-
74
#include <algorithm>
85
#include <memory>
96

7+
#include "tatami/base/Matrix.hpp"
8+
#include "tatami/utils/copy.hpp"
9+
1010
/**
1111
* @file ReversedIndicesWrapper.hpp
1212
* @brief Reverse sparse indices during extraction.
@@ -17,14 +17,23 @@ namespace tatami_test {
1717
/**
1818
* @cond
1919
*/
20-
namespace internal {
21-
2220
template<bool oracle_, typename Value_, typename Index_>
2321
class ReversedIndicesExtractor final : public tatami::SparseExtractor<oracle_, Value_, Index_> {
2422
public:
25-
ReversedIndicesExtractor(std::unique_ptr<tatami::SparseExtractor<oracle_, Value_, Index_> > host, bool must_sort) :
23+
ReversedIndicesExtractor(std::unique_ptr<tatami::SparseExtractor<oracle_, Value_, Index_> > host, const bool must_sort) :
2624
my_host(std::move(host)), my_must_sort(must_sort) {}
2725

26+
/**
27+
* @cond
28+
*/
29+
#ifdef TATAMI_STRICT_SIGNATURES
30+
template<typename ... Args_>
31+
ReversedIndicesExtractor(Args_...) = delete;
32+
#endif
33+
/**
34+
* @endcond
35+
*/
36+
2837
private:
2938
std::unique_ptr<tatami::SparseExtractor<oracle_, Value_, Index_> > my_host;
3039
bool my_must_sort;
@@ -47,8 +56,6 @@ class ReversedIndicesExtractor final : public tatami::SparseExtractor<oracle_, V
4756
return range;
4857
}
4958
};
50-
51-
}
5259
/**
5360
* @endcond
5461
*/
@@ -73,6 +80,20 @@ class ReversedIndicesWrapper final : public tatami::Matrix<Value_, Index_> {
7380
*/
7481
ReversedIndicesWrapper(std::shared_ptr<const tatami::Matrix<Value_, Index_> > matrix) : my_matrix(std::move(matrix)) {}
7582

83+
/**
84+
* @cond
85+
*/
86+
#ifdef TATAMI_STRICT_SIGNATURES
87+
ReversedIndicesWrapper(std::shared_ptr<tatami::Matrix<Value_, Index_> > matrix) : ReversedIndicesWrapper(std::move(matrix)) {}
88+
89+
template<typename ... Args_>
90+
ReversedIndicesWrapper(Args_...) = delete;
91+
#endif
92+
/**
93+
* @endcond
94+
*/
95+
96+
7697
private:
7798
std::shared_ptr<const tatami::Matrix<Value_, Index_> > my_matrix;
7899

@@ -101,60 +122,114 @@ class ReversedIndicesWrapper final : public tatami::Matrix<Value_, Index_> {
101122
return my_matrix->prefer_rows_proportion();
102123
}
103124

104-
bool uses_oracle(bool row) const {
125+
bool uses_oracle(const bool row) const {
105126
return my_matrix->uses_oracle(row);
106127
}
107128

108129
public:
109-
std::unique_ptr<tatami::MyopicDenseExtractor<Value_, Index_> > dense(bool row, const tatami::Options& opt) const {
130+
std::unique_ptr<tatami::MyopicDenseExtractor<Value_, Index_> > dense(
131+
const bool row,
132+
const tatami::Options& opt
133+
) const {
110134
return my_matrix->dense(row, opt);
111135
}
112136

113-
std::unique_ptr<tatami::MyopicDenseExtractor<Value_, Index_> > dense(bool row, Index_ bs, Index_ bl, const tatami::Options& opt) const {
137+
std::unique_ptr<tatami::MyopicDenseExtractor<Value_, Index_> > dense(
138+
const bool row,
139+
const Index_ bs,
140+
const Index_ bl,
141+
const tatami::Options& opt
142+
) const {
114143
return my_matrix->dense(row, bs, bl, opt);
115144
}
116145

117-
std::unique_ptr<tatami::MyopicDenseExtractor<Value_, Index_> > dense(bool row, tatami::VectorPtr<Index_> idx, const tatami::Options& opt) const {
146+
std::unique_ptr<tatami::MyopicDenseExtractor<Value_, Index_> > dense(
147+
const bool row,
148+
tatami::VectorPtr<Index_> idx,
149+
const tatami::Options& opt
150+
) const {
118151
return my_matrix->dense(row, std::move(idx), opt);
119152
}
120153

121154
public:
122-
std::unique_ptr<tatami::MyopicSparseExtractor<Value_, Index_> > sparse(bool row, const tatami::Options& opt) const {
123-
return std::make_unique<internal::ReversedIndicesExtractor<false, Value_, Index_> >(my_matrix->sparse(row, opt), opt.sparse_ordered_index);
155+
std::unique_ptr<tatami::MyopicSparseExtractor<Value_, Index_> > sparse(
156+
const bool row,
157+
const tatami::Options& opt
158+
) const {
159+
return std::make_unique<ReversedIndicesExtractor<false, Value_, Index_> >(my_matrix->sparse(row, opt), opt.sparse_ordered_index);
124160
}
125161

126-
std::unique_ptr<tatami::MyopicSparseExtractor<Value_, Index_> > sparse(bool row, Index_ bs, Index_ bl, const tatami::Options& opt) const {
127-
return std::make_unique<internal::ReversedIndicesExtractor<false, Value_, Index_> >(my_matrix->sparse(row, bs, bl, opt), opt.sparse_ordered_index);
162+
std::unique_ptr<tatami::MyopicSparseExtractor<Value_, Index_> > sparse(
163+
const bool row,
164+
const Index_ bs,
165+
const Index_ bl,
166+
const tatami::Options& opt
167+
) const {
168+
return std::make_unique<ReversedIndicesExtractor<false, Value_, Index_> >(my_matrix->sparse(row, bs, bl, opt), opt.sparse_ordered_index);
128169
}
129170

130-
std::unique_ptr<tatami::MyopicSparseExtractor<Value_, Index_> > sparse(bool row, tatami::VectorPtr<Index_> idx, const tatami::Options& opt) const {
131-
return std::make_unique<internal::ReversedIndicesExtractor<false, Value_, Index_> >(my_matrix->sparse(row, std::move(idx), opt), opt.sparse_ordered_index);
171+
std::unique_ptr<tatami::MyopicSparseExtractor<Value_, Index_> > sparse(
172+
const bool row,
173+
tatami::VectorPtr<Index_> idx,
174+
const tatami::Options& opt
175+
) const {
176+
return std::make_unique<ReversedIndicesExtractor<false, Value_, Index_> >(my_matrix->sparse(row, std::move(idx), opt), opt.sparse_ordered_index);
132177
}
133178

134179
public:
135-
std::unique_ptr<tatami::OracularDenseExtractor<Value_, Index_> > dense(bool row, std::shared_ptr<const tatami::Oracle<Index_> > ora, const tatami::Options& opt) const {
180+
std::unique_ptr<tatami::OracularDenseExtractor<Value_, Index_> > dense(
181+
const bool row,
182+
std::shared_ptr<const tatami::Oracle<Index_> > ora,
183+
const tatami::Options& opt
184+
) const {
136185
return my_matrix->dense(row, std::move(ora), opt);
137186
}
138187

139-
std::unique_ptr<tatami::OracularDenseExtractor<Value_, Index_> > dense(bool row, std::shared_ptr<const tatami::Oracle<Index_> > ora, Index_ bs, Index_ bl, const tatami::Options& opt) const {
188+
std::unique_ptr<tatami::OracularDenseExtractor<Value_, Index_> > dense(
189+
const bool row,
190+
std::shared_ptr<const tatami::Oracle<Index_> > ora,
191+
const Index_ bs,
192+
const Index_ bl,
193+
const tatami::Options& opt
194+
) const {
140195
return my_matrix->dense(row, std::move(ora), bs, bl, opt);
141196
}
142197

143-
std::unique_ptr<tatami::OracularDenseExtractor<Value_, Index_> > dense(bool row, std::shared_ptr<const tatami::Oracle<Index_> > ora, tatami::VectorPtr<Index_> idx, const tatami::Options& opt) const {
198+
std::unique_ptr<tatami::OracularDenseExtractor<Value_, Index_> > dense(
199+
const bool row,
200+
std::shared_ptr<const tatami::Oracle<Index_> > ora,
201+
tatami::VectorPtr<Index_> idx,
202+
const tatami::Options& opt
203+
) const {
144204
return my_matrix->dense(row, std::move(ora), std::move(idx), opt);
145205
}
146206

147207
public:
148-
std::unique_ptr<tatami::OracularSparseExtractor<Value_, Index_> > sparse(bool row, std::shared_ptr<const tatami::Oracle<Index_> > ora, const tatami::Options& opt) const {
149-
return std::make_unique<internal::ReversedIndicesExtractor<true, Value_, Index_> >(my_matrix->sparse(row, std::move(ora), opt), opt.sparse_ordered_index);
150-
}
151-
152-
std::unique_ptr<tatami::OracularSparseExtractor<Value_, Index_> > sparse(bool row, std::shared_ptr<const tatami::Oracle<Index_> > ora, Index_ bs, Index_ bl, const tatami::Options& opt) const {
153-
return std::make_unique<internal::ReversedIndicesExtractor<true, Value_, Index_> >(my_matrix->sparse(row, std::move(ora), bs, bl, opt), opt.sparse_ordered_index);
154-
}
155-
156-
std::unique_ptr<tatami::OracularSparseExtractor<Value_, Index_> > sparse(bool row, std::shared_ptr<const tatami::Oracle<Index_> > ora, tatami::VectorPtr<Index_> idx, const tatami::Options& opt) const {
157-
return std::make_unique<internal::ReversedIndicesExtractor<true, Value_, Index_> >(my_matrix->sparse(row, std::move(ora), std::move(idx), opt), opt.sparse_ordered_index);
208+
std::unique_ptr<tatami::OracularSparseExtractor<Value_, Index_> > sparse(
209+
const bool row,
210+
std::shared_ptr<const tatami::Oracle<Index_> > ora,
211+
const tatami::Options& opt
212+
) const {
213+
return std::make_unique<ReversedIndicesExtractor<true, Value_, Index_> >(my_matrix->sparse(row, std::move(ora), opt), opt.sparse_ordered_index);
214+
}
215+
216+
std::unique_ptr<tatami::OracularSparseExtractor<Value_, Index_> > sparse(
217+
const bool row,
218+
std::shared_ptr<const tatami::Oracle<Index_> > ora,
219+
const Index_ bs,
220+
const Index_ bl,
221+
const tatami::Options& opt
222+
) const {
223+
return std::make_unique<ReversedIndicesExtractor<true, Value_, Index_> >(my_matrix->sparse(row, std::move(ora), bs, bl, opt), opt.sparse_ordered_index);
224+
}
225+
226+
std::unique_ptr<tatami::OracularSparseExtractor<Value_, Index_> > sparse(
227+
const bool row,
228+
std::shared_ptr<const tatami::Oracle<Index_> > ora,
229+
tatami::VectorPtr<Index_> idx,
230+
const tatami::Options& opt
231+
) const {
232+
return std::make_unique<ReversedIndicesExtractor<true, Value_, Index_> >(my_matrix->sparse(row, std::move(ora), std::move(idx), opt), opt.sparse_ordered_index);
158233
}
159234
};
160235

0 commit comments

Comments
 (0)