Skip to content

Commit 2f7220d

Browse files
committed
Reduce copying in to_vector_{1,2,3}d
The to_vector_{1,2,3}d helper functions simply forward the const-ref when it is already a vector_{1,2,3}d. This avoids making unnecesary copies.
1 parent f0cfe32 commit 2f7220d

File tree

1 file changed

+38
-36
lines changed

1 file changed

+38
-36
lines changed

source/matplot/util/common.h

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -163,49 +163,51 @@ namespace matplot {
163163
return r;
164164
}
165165

166-
template <class T> std::vector<vector_2d> to_vector_3d(const T &v) {
167-
std::vector<vector_2d> r(v.size());
168-
size_t matrix_index = 0;
169-
for (auto matrix_it = v.begin(); matrix_it != v.end();
170-
++matrix_it, ++matrix_index) {
171-
r[matrix_index] = vector_2d(matrix_it->size());
172-
size_t i = 0;
173-
for (auto v_it = matrix_it->begin(); v_it != matrix_it->end();
174-
++v_it, ++i) {
175-
r[matrix_index][i] = vector_1d(v_it->size());
176-
size_t j = 0;
177-
for (auto vj_it = v_it->begin(); vj_it != v_it->end();
178-
++vj_it, ++j) {
179-
r[matrix_index][i][j] = static_cast<double>(*vj_it);
180-
}
181-
}
166+
namespace detail {
167+
template <typename T, typename U>
168+
using forward_or_copy =
169+
std::conditional_t<std::is_same_v<T, U>, const U &, U>;
170+
}
171+
172+
template <class T>
173+
detail::forward_or_copy<T, vector_1d> to_vector_1d(const T &v) {
174+
if constexpr (std::is_same_v<T, vector_1d>) {
175+
return v;
176+
} else {
177+
using std::begin, std::end;
178+
179+
return vector_1d(begin(v), end(v));
182180
}
183-
return r;
184181
}
185182

186-
template <class T, class DESTINATION_VALUE_TYPE = double>
187-
vector_2d to_vector_2d(const T &v) {
188-
std::vector<std::vector<DESTINATION_VALUE_TYPE>> r(v.size());
189-
size_t i = 0;
190-
for (auto v_it = v.begin(); v_it != v.end(); ++v_it, ++i) {
191-
r[i] = std::vector<DESTINATION_VALUE_TYPE>(v_it->size());
192-
size_t j = 0;
193-
for (auto vj_it = v_it->begin(); vj_it != v_it->end();
194-
++vj_it, ++j) {
195-
r[i][j] = static_cast<DESTINATION_VALUE_TYPE>(*vj_it);
196-
}
183+
template <class T>
184+
detail::forward_or_copy<T, vector_2d> to_vector_2d(const T &v) {
185+
if constexpr (std::is_same_v<T, vector_2d>) {
186+
return v;
187+
} else {
188+
using std::begin, std::end;
189+
190+
vector_2d r(std::distance(begin(v), end(v)));
191+
std::transform(
192+
begin(v), end(v), r.begin(),
193+
[](auto &&e) -> vector_1d { return to_vector_1d(e); });
194+
return r;
197195
}
198-
return r;
199196
}
200197

201-
template <class T, class DESTINATION_VALUE_TYPE = double>
202-
vector_1d to_vector_1d(const T &v) {
203-
std::vector<DESTINATION_VALUE_TYPE> r(v.size());
204-
size_t i = 0;
205-
for (auto v_it = v.begin(); v_it != v.end(); ++v_it, ++i) {
206-
r[i] = static_cast<DESTINATION_VALUE_TYPE>(*v_it);
198+
template <class T>
199+
detail::forward_or_copy<T, std::vector<vector_2d>> to_vector_3d(const T &v) {
200+
if constexpr (std::is_same_v<T, std::vector<vector_2d>>) {
201+
return v;
202+
} else {
203+
using std::begin, std::end;
204+
205+
std::vector<vector_2d> r(std::distance(begin(v), end(v)));
206+
std::transform(
207+
begin(v), end(v), r.begin(),
208+
[](auto &&e) -> vector_2d { return to_vector_2d(e); });
209+
return r;
207210
}
208-
return r;
209211
}
210212

211213
template <class T> inline T norm(const std::vector<T> &v) {

0 commit comments

Comments
 (0)