1 #ifndef POPS_RASTER_HPP
2 #define POPS_RASTER_HPP
25 #include <initializer_list>
26 #include <type_traits>
33 template<
class InputIt1,
class InputIt2,
class BinaryOperation>
35 for_each_zip(InputIt1 first1, InputIt1 last1, InputIt2 first2, BinaryOperation f)
37 for (; first1 != last1; ++first1, ++first2) {
96 template<
typename Number,
typename Index =
int>
141 other.data_ =
nullptr;
155 this->data_ =
new Number[
cols_ *
rows_]{value};
171 Raster(std::initializer_list<std::initializer_list<Number>> l)
172 :
Raster(l.size(), l.begin()->size())
176 for (
const auto& subl : l) {
177 for (
const auto& value : subl) {
217 const Number*
data() const noexcept
232 template<
class UnaryOperation>
250 if (
this != &other) {
263 if (
this != &other) {
270 other.data_ =
nullptr;
275 template<
typename OtherNumber>
283 template<
typename OtherNumber>
291 template<
typename OtherNumber>
299 template<
typename OtherNumber>
307 template<
typename OtherNumber>
308 typename std::enable_if<
309 std::is_floating_point<Number>::value
310 || std::is_same<Number, OtherNumber>::value,
318 [](Number& a,
const OtherNumber& b) { a += b; });
322 template<
typename OtherNumber>
323 typename std::enable_if<
324 std::is_floating_point<Number>::value
325 || std::is_same<Number, OtherNumber>::value,
333 [](Number& a,
const OtherNumber& b) { a -= b; });
337 template<
typename OtherNumber>
338 typename std::enable_if<
339 std::is_floating_point<Number>::value
340 || std::is_same<Number, OtherNumber>::value,
348 [](Number& a,
const OtherNumber& b) { a *= b; });
352 template<
typename OtherNumber>
353 typename std::enable_if<
354 std::is_floating_point<Number>::value
355 || std::is_same<Number, OtherNumber>::value,
363 [](Number& a,
const OtherNumber& b) { a /= b; });
370 for (Index i = 0; i <
cols_; i++) {
371 for (Index j = 0; j <
cols_; j++) {
382 for (Index i = 0; i <
cols_; i++) {
383 for (Index j = 0; j <
cols_; j++) {
391 template<
typename OtherNumber>
393 typename std::enable_if<std::is_arithmetic<OtherNumber>::value,
Raster>::type
402 [&value](
const Number& a) { return a + value; });
406 template<
typename OtherNumber>
408 typename std::enable_if<std::is_arithmetic<OtherNumber>::value,
Raster>::type
417 [&value](
const Number& a) { return a - value; });
421 template<
typename OtherNumber>
423 typename std::enable_if<std::is_arithmetic<OtherNumber>::value,
Raster>::type
432 [&value](
const Number& a) { return a * value; });
436 template<
typename OtherNumber>
438 typename std::enable_if<std::is_arithmetic<OtherNumber>::value,
Raster>::type
447 [&value](
const Number& a) { return a / value; });
451 template<
typename OtherNumber>
453 typename std::enable_if<std::is_arithmetic<OtherNumber>::value,
Raster>::type
456 return raster + value;
459 template<
typename OtherNumber>
461 typename std::enable_if<std::is_arithmetic<OtherNumber>::value,
Raster>::type
470 [&value](
const Number& a) { return value - a; });
474 template<
typename OtherNumber>
476 typename std::enable_if<std::is_arithmetic<OtherNumber>::value,
Raster>::type
479 return raster * value;
482 template<
typename OtherNumber>
484 typename std::enable_if<std::is_arithmetic<OtherNumber>::value,
Raster>::type
493 [&value](
const Number& a) { return value / a; });
499 image.
for_each([value](Number& a) { a = std::pow(a, value); });
504 image.
for_each([](Number& a) { a = std::sqrt(a); });
511 for (Index i = 0; i < image.
rows_; i++) {
514 for (Index j = 0; j < image.
cols_; j++) {
527 typename RightNumber,
528 typename ResultNumber =
typename std::common_type<LeftNumber, RightNumber>::type>
533 throw std::invalid_argument(
534 "Raster::operator+: The number of rows or columns does not match");
543 [](
const LeftNumber& a,
const RightNumber& b) { return a + b; });
549 typename RightNumber,
550 typename ResultNumber =
typename std::common_type<LeftNumber, RightNumber>::type>
555 throw std::invalid_argument(
556 "Raster::operator-: The number of rows or columns does not match");
565 [](
const LeftNumber& a,
const RightNumber& b) { return a - b; });
571 typename RightNumber,
572 typename ResultNumber =
typename std::common_type<LeftNumber, RightNumber>::type>
577 throw std::invalid_argument(
578 "Raster::operator*: The number of rows or columns does not match");
587 [](
const LeftNumber& a,
const RightNumber& b) { return a * b; });
593 typename RightNumber,
594 typename ResultNumber =
typename std::common_type<LeftNumber, RightNumber>::type>
599 throw std::invalid_argument(
600 "Raster::operator/: The number of rows or columns does not match");
609 [](
const LeftNumber& a,
const RightNumber& b) { return a / b; });
615 #endif // POPS_RASTER_HPP