Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds size checking to uni index array assignment #3218

Merged
merged 7 commits into from
Aug 9, 2023
13 changes: 9 additions & 4 deletions src/stan/model/indexing/assign.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ namespace model {
* - General overload for nested std vectors.
*/

template <typename Tuple1, typename Tuple2,
require_all_t<internal::is_tuple<Tuple1>,
internal::is_tuple<Tuple2>>* = nullptr>
inline void assign(Tuple1&& x, Tuple2&& y, const char* name);

/**
* Assign one object to another.
*
Expand Down Expand Up @@ -837,7 +842,7 @@ template <typename StdVec, typename U, require_std_vector_t<StdVec>* = nullptr,
require_t<std::is_assignable<value_type_t<StdVec>&, U>>* = nullptr>
inline void assign(StdVec&& x, U&& y, const char* name, index_uni idx) {
stan::math::check_range("array[uni,...] assign", name, x.size(), idx.n_);
x[idx.n_ - 1] = std::forward<U>(y);
assign(x[idx.n_ - 1], std::forward<U>(y), name);
}

/**
Expand Down Expand Up @@ -908,9 +913,9 @@ inline constexpr auto make_tuple_seq(std::integer_sequence<T, I...>) {
* @param y A tuple with elements to be assigned from
* @param name The name of the tuple to assign to
*/
template <typename Tuple1, typename Tuple2,
require_all_t<internal::is_tuple<Tuple1>,
internal::is_tuple<Tuple2>>* = nullptr>
template <
typename Tuple1, typename Tuple2,
require_all_t<internal::is_tuple<Tuple1>, internal::is_tuple<Tuple2>>*>
inline void assign(Tuple1&& x, Tuple2&& y, const char* name) {
constexpr auto t1_size = std::tuple_size<std::decay_t<Tuple1>>::value;
stan::math::for_each(
Expand Down
17 changes: 17 additions & 0 deletions src/test/unit/model/indexing/assign_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,23 @@ TEST(ModelIndexing, doubleToVar) {
for (int j = 0; j < 3; ++j)
EXPECT_FLOAT_EQ(c(1, j).val(), d(j));
}

TEST(ModelIndexing, std_vec_eigen_vec_size_throw) {
using stan::model::assign;

std::vector<Eigen::VectorXd> xs;
Eigen::VectorXd x1(3);
x1 << 1, 2, 3;
xs.push_back(x1);
xs.push_back(x1);
xs.push_back(x1);

Eigen::VectorXd x2(2);
x2 << 4, 5;
vector<Eigen::VectorXd> ys;
EXPECT_THROW(assign(xs, x2, "should throw", index_uni(1)),
std::invalid_argument);
}
TEST(ModelIndexing, resultSizeNegIndexing) {
using stan::model::assign;
using stan::model::index_min_max;
Expand Down