94 std::vector<entry> replacements)
const {
95 std::vector<std::string_view> inputs;
96 inputs.reserve(expected_inputs.size());
97 auto removed = A::zero();
98 for (
auto const &
object_id : expected_inputs) {
99 if (std::find(inputs.begin(), inputs.end(),
object_id) != inputs.end())
100 throw std::invalid_argument(
"duplicate expected pinned input");
102 if (!old)
throw std::invalid_argument(
"expected pinned input is absent");
104 removed = A::add(removed, old->contribution);
107 auto is_input = [&](std::string_view
object_id) {
108 return std::find(inputs.begin(), inputs.end(),
object_id) != inputs.end();
110 auto added = A::zero();
111 for (std::size_t i = 0; i < replacements.size(); ++i) {
112 auto const & item = replacements[i];
114 if (
find(item.object_id))
115 throw std::invalid_argument(
"replacement must name a new immutable object");
116 for (std::size_t j = 0; j < i; ++j)
118 throw std::invalid_argument(
"duplicate replacement object identity");
119 added = A::add(added, item.contribution);
121 if (added != removed)
122 throw std::invalid_argument(
"replacement changes the pinned contribution sum");
124 auto next = std::make_shared<state>();
125 next->signature = A::add(A::subtract(
state_->signature, removed), added);
128 for (
auto const & item :
state_->entries) {
129 if (is_input(item.object_id))
continue;
130 next->entries.push_back(item);
131 next->pins.push_back(item.object);
133 for (
auto & item : replacements) {
134 next->pins.push_back(item.object);
135 next->entries.push_back(std::move(item));
137 return pin_set(std::move(next));