Skip to content

Commit b5d0cea

Browse files
authored
Merge pull request #4612 from smowton/smowton/feature/sharing-map-without-default-constructor
Sharing map: don't require a default constructor for mapped_type
2 parents 5a2a09e + ea4ec40 commit b5d0cea

File tree

3 files changed

+76
-27
lines changed

3 files changed

+76
-27
lines changed

src/pointer-analysis/value_set.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,11 @@ bool value_sett::make_union(const value_sett::valuest &new_values)
242242

243243
for(const auto &delta_entry : delta_view)
244244
{
245-
if(delta_entry.in_both)
245+
if(delta_entry.is_in_both_maps())
246246
{
247247
if(make_union_would_change(
248-
delta_entry.other_m.object_map, delta_entry.m.object_map))
248+
delta_entry.get_other_map_value().object_map,
249+
delta_entry.m.object_map))
249250
{
250251
values.update(delta_entry.k, [&](entryt &existing_entry) {
251252
make_union(existing_entry.object_map, delta_entry.m.object_map);

src/util/sharing_map.h

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -370,23 +370,35 @@ class sharing_mapt
370370
{
371371
public:
372372
delta_view_itemt(
373-
const bool in_both,
374373
const key_type &k,
375374
const mapped_type &m,
376-
const mapped_type &other_m) :
377-
in_both(in_both),
378-
k(k),
379-
m(m),
380-
other_m(other_m) {}
375+
const mapped_type &other_m)
376+
: k(k), m(m), other_m(&other_m)
377+
{
378+
}
381379

382-
// if true key is in both maps, if false key is only in the map
383-
// from which the view was obtained
384-
const bool in_both;
380+
delta_view_itemt(const key_type &k, const mapped_type &m)
381+
: k(k), m(m), other_m(nullptr)
382+
{
383+
}
385384

386385
const key_type &k;
387386

388387
const mapped_type &m;
389-
const mapped_type &other_m;
388+
389+
bool is_in_both_maps() const
390+
{
391+
return other_m != nullptr;
392+
}
393+
394+
const mapped_type &get_other_map_value() const
395+
{
396+
PRECONDITION(is_in_both_maps());
397+
return *other_m;
398+
}
399+
400+
private:
401+
const mapped_type *other_m;
390402
};
391403

392404
/// Delta view of the key-value pairs in two maps. A delta view of two maps is
@@ -411,13 +423,12 @@ class sharing_mapt
411423
/// the maps that are contained in subtrees that are not shared between them.
412424
///
413425
/// A delta view is represented as a list of structs, with each struct having
414-
/// four members (`in_both`, `key`, `value1`, `value2`). The elements `key`,
415-
/// `value1`, and `value2` are const references to the corresponding elements
416-
/// in the map. The first element indicates whether the key exists in both
417-
/// maps, the second element is the key, the third element is the mapped value
418-
/// of the first map, and the fourth element is the mapped value of the second
419-
/// map, or a dummy element if the key exists only in the first map (in which
420-
/// case `in_both` is false).
426+
/// three members (`key`, `value1`, `value2`). The elements `key`, `value1`,
427+
/// and `value2` are const references to the corresponding elements in the
428+
/// map, with the third being absent if the key only existed in the queried
429+
/// map. The first element is the key, the second element is the mapped value
430+
/// of the first map, and the third element is the mapped value of the second
431+
/// map if present.
421432
///
422433
/// Calling `A.delta_view(B, ...)` yields a view such that for each element in
423434
/// the view one of two things holds:
@@ -540,9 +551,6 @@ class sharing_mapt
540551
std::set<const void *> &marked,
541552
bool mark = true) const;
542553

543-
// dummy element returned when no element was found
544-
static mapped_type dummy;
545-
546554
static const std::string not_found_msg;
547555

548556
// config
@@ -765,7 +773,7 @@ SHARING_MAPT(void)
765773
::gather_all(const innert &n, delta_viewt &delta_view) const
766774
{
767775
auto f = [&delta_view](const key_type &k, const mapped_type &m) {
768-
delta_view.push_back(delta_view_itemt(false, k, m, dummy));
776+
delta_view.push_back(delta_view_itemt(k, m));
769777
};
770778

771779
iterate(n, f);
@@ -895,12 +903,12 @@ ::get_delta_view(
895903
{
896904
if(!l1.shares_with(*p))
897905
{
898-
delta_view.push_back({true, k1, l1.get_value(), p->get_value()});
906+
delta_view.push_back({k1, l1.get_value(), p->get_value()});
899907
}
900908
}
901909
else if(!only_common)
902910
{
903-
delta_view.push_back({false, l1.get_key(), l1.get_value(), dummy});
911+
delta_view.push_back({k1, l1.get_value()});
904912
}
905913
}
906914
}
@@ -1053,8 +1061,6 @@ SHARING_MAPT2(optionalt<std::reference_wrapper<const, mapped_type>>)::find(
10531061

10541062
SHARING_MAPT(const std::string)::not_found_msg="key not found";
10551063

1056-
SHARING_MAPT2(, mapped_type)::dummy;
1057-
10581064
SHARING_MAPT(const std::size_t)::bits = 18;
10591065
SHARING_MAPT(const std::size_t)::chunk = 3;
10601066

unit/util/sharing_map.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,3 +670,45 @@ TEST_CASE("Sharing map sharing stats", "[core][util]")
670670
}
671671
#endif
672672
}
673+
674+
struct no_default_constructort
675+
{
676+
no_default_constructort() = delete;
677+
explicit no_default_constructort(int val) : val(val)
678+
{
679+
}
680+
no_default_constructort(const no_default_constructort &) = default;
681+
682+
int val;
683+
};
684+
685+
TEST_CASE("Sharing map with a non-default-constructable value", "[core][util]")
686+
{
687+
typedef sharing_mapt<int, no_default_constructort>
688+
sharing_map_no_default_constructort;
689+
690+
sharing_map_no_default_constructort map1;
691+
692+
map1.insert(0, no_default_constructort{0});
693+
map1.insert(1, no_default_constructort{1});
694+
695+
sharing_map_no_default_constructort map2 = map1;
696+
map2.replace(1, no_default_constructort{3});
697+
map2.insert(2, no_default_constructort{2});
698+
699+
sharing_map_no_default_constructort::delta_viewt delta_view;
700+
map2.get_delta_view(map1, delta_view, false);
701+
702+
REQUIRE(delta_view.size() == 2);
703+
const auto &entry_1 = delta_view[delta_view[0].k == 1 ? 0 : 1];
704+
const auto &entry_2 = delta_view[delta_view[0].k == 1 ? 1 : 0];
705+
706+
REQUIRE(entry_1.k == 1);
707+
REQUIRE(entry_1.is_in_both_maps());
708+
REQUIRE(entry_1.m.val == 3);
709+
REQUIRE(entry_1.get_other_map_value().val == 1);
710+
711+
REQUIRE(entry_2.k == 2);
712+
REQUIRE(!entry_2.is_in_both_maps());
713+
REQUIRE(entry_2.m.val == 2);
714+
}

0 commit comments

Comments
 (0)