auto zip_with_defaults(F f, const X& default_x, const Y& default_y, const ContainerIn1& xs, const ContainerIn2& ys) { internal::trigger_static_asserts<internal::zip_with_tag, F, X, Y>(); const auto size_xs = size_of_cont(xs); const auto size_ys = size_of_cont(ys); if (size_xs < size_ys) { const auto extended_xs = append( xs, replicate<X, ContainerIn1>(size_ys - size_xs, default_x)); return zip_with(f, extended_xs, ys); } else if (size_xs > size_ys) { const auto extended_ys = append( ys, replicate<Y, ContainerIn2>(size_xs - size_ys, default_y)); return zip_with(f, xs, extended_ys); } return zip_with(f, xs, ys); }
static constexpr auto apply(M1 const& m1, M2 const& m2) { return eval_if(bool_<R1 == R2 && C1 == C2>, [&](auto _) { return all(zip_with(_(equal), cppcon::rows(m1), cppcon::rows(m2))); }, [] { return false_; } ); }
static constexpr decltype(auto) apply(M1&& m1, M2&& m2) { static_assert(C1 == R2, "wrong dimensions for matrix multiplication"); auto cols = cppcon::columns(std::forward<M2>(m2)); return unpack( transform(cppcon::rows(std::forward<M1>(m1)), [&](auto&& row) -> decltype(auto) { return zip_with(cppcon::detail::tuple_scalar_product, replicate<tuple_tag>(std::forward<decltype(row)>(row), uint_c<R1>), cols ); } ), cppcon::matrix ); }
auto zip(const ContainerIn1& xs, const ContainerIn2& ys) { auto MakePair = [](const X& x, const Y& y) { return std::make_pair(x, y); }; return zip_with(MakePair, xs, ys); }
static constexpr auto equal_impl(M1 m1, M2 m2) { return m1.nrows() == m2.nrows() && m1.ncolumns() == m2.ncolumns() && all_of(zip_with(_==_, m1.rows_, m2.rows_)); }