#include #include #include #include #include #include #include #include struct thing { int id = 0; }; bool operator==(const thing& a, const thing& b) { return a.id == b.id; } TEST_CASE("iteration exposes const") { auto do_check = [](auto v) { using value_t = typename decltype(v)::value_type; immer::for_each(v, [](auto&& x) { static_assert(std::is_same::value, ""); }); }; do_check(immer::vector{}); do_check(immer::flex_vector{}); do_check(immer::array{}); do_check(immer::map{}); do_check(immer::set{}); do_check(immer::table{}); } TEST_CASE("chunked iteration exposes const") { auto do_check = [](auto v) { using value_t = typename decltype(v)::value_type; immer::for_each_chunk(v, [](auto a, auto b) { static_assert(std::is_same::value, ""); static_assert(std::is_same::value, ""); }); }; do_check(immer::vector{}); do_check(immer::flex_vector{}); do_check(immer::array{}); do_check(immer::map{}); do_check(immer::set{}); do_check(immer::table{}); } TEST_CASE("accumulate") { auto do_check = [](auto v) { using value_t = typename decltype(v)::value_type; immer::accumulate(v, value_t{}, [](auto&& a, auto&& b) { static_assert(std::is_same::value, ""); static_assert(std::is_same::value, ""); return std::move(a); }); }; do_check(immer::vector{}); do_check(immer::flex_vector{}); do_check(immer::array{}); do_check(immer::map{}); do_check(immer::set{}); do_check(immer::table{}); } TEST_CASE("diffing exposes const") { auto do_check = [](auto v) { using value_t = typename decltype(v)::value_type; immer::diff( v, v, [](auto&& x) { static_assert(std::is_same::value, ""); }, [](auto&& x) { static_assert(std::is_same::value, ""); }, [](auto&& x, auto&& y) { static_assert(std::is_same::value, ""); static_assert(std::is_same::value, ""); }); }; do_check(immer::map{}); do_check(immer::set{}); do_check(immer::table{}); } TEST_CASE("all_of") { auto do_check = [](auto v) { using value_t = typename decltype(v)::value_type; immer::all_of(v, [](auto&& x) { static_assert(std::is_same::value, ""); return true; }); }; do_check(immer::vector{}); do_check(immer::flex_vector{}); do_check(immer::array{}); // not supported // do_check(immer::map{}); // do_check(immer::set{}); // do_check(immer::table{}); } TEST_CASE("update vectors") { auto do_check = [](auto v) { if (false) (void) v.update(0, [](auto&& x) { using type_t = std::decay_t; // vectors do copy first the whole array, and then move the // copied value into the function static_assert(std::is_same::value, ""); return x; }); }; do_check(immer::vector{}); do_check(immer::flex_vector{}); do_check(immer::array{}); } TEST_CASE("update maps") { auto do_check = [](auto v) { (void) v.update(0, [](auto&& x) { using type_t = std::decay_t; // for maps, we actually do not make a copy at all but pase the // original instance directly, as const.. static_assert(std::is_same::value, ""); return x; }); }; do_check(immer::map{}); do_check(immer::table{}); } TEST_CASE("update_if_exists maps") { auto do_check = [](auto v) { (void) v.update_if_exists(0, [](auto&& x) { using type_t = std::decay_t; // for maps, we actually do not make a copy at all but pase the // original instance directly, as const.. static_assert(std::is_same::value, ""); return x; }); }; do_check(immer::map{}); do_check(immer::table{}); } TEST_CASE("update vectors move") { auto do_check = [](auto v) { if (false) (void) std::move(v).update(0, [](auto&& x) { using type_t = std::decay_t; // vectors do copy first the whole array, and then move the // copied value into the function static_assert(std::is_same::value, ""); return x; }); }; do_check(immer::vector{}); do_check(immer::flex_vector{}); do_check(immer::array{}); } TEST_CASE("update maps move") { auto do_check = [](auto v) { (void) std::move(v).update(0, [](auto&& x) { using type_t = std::decay_t; // for maps, we actually do not make a copy at all but pase the // original instance directly, as const.. static_assert(std::is_same::value || std::is_same::value, ""); return x; }); }; do_check(immer::map{}); do_check(immer::table{}); } TEST_CASE("update_if_exists maps move") { auto do_check = [](auto v) { (void) std::move(v).update_if_exists(0, [](auto&& x) { using type_t = std::decay_t; // for maps, we actually do not make a copy at all but pase the // original instance directly, as const.. static_assert(std::is_same::value || std::is_same::value, ""); return x; }); }; do_check(immer::map{}); do_check(immer::table{}); }