Skip to content

Commit

Permalink
Fix type punning warning for dfs in gcc release
Browse files Browse the repository at this point in the history
Use union for value & shadow_value instead of reinterpret_cast<value_type*>(value_)

Also added ~internal_value() to all uses of internal_value to address warning/error
  • Loading branch information
pratzl committed Nov 16, 2023
1 parent 02039e4 commit 20f4b82
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 21 deletions.
82 changes: 61 additions & 21 deletions include/graph/views/depth_first_search.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,16 @@ class vertices_depth_first_search_view : public dfs_base<G, Stack, Alloc> {
using shadow_value_type =
vertex_descriptor<vertex_id_t<graph_type>, shadow_vertex_type*, _detail::ref_to_ptr<vertex_value_type>>;

union internal_value {
value_type value_;
shadow_value_type shadow_;

internal_value(const internal_value& rhs) : shadow_(rhs.shadow_) {}
internal_value() : shadow_{} {}
~internal_value() {}
internal_value& operator=(const internal_value& rhs) { value_.shadow = rhs.value_.shadow; }
};

public:
iterator(const dfs_range_type& range) : the_range_(&const_cast<dfs_range_type&>(range)) {}
iterator() = default;
Expand All @@ -276,16 +286,16 @@ class vertices_depth_first_search_view : public dfs_base<G, Stack, Alloc> {
auto&& [u_id, uvi] = the_range_->S_.top();
vertex_id_type v_id = the_range_->real_target_id(*uvi, u_id);
auto& v = *find_vertex(g, v_id);
value_ = {v_id, &v, invoke(*the_range_->value_fn_, v)};
return reinterpret_cast<reference>(value_);
value_.shadow_ = {v_id, &v, invoke(*the_range_->value_fn_, v)};
return value_.value_;
}

constexpr bool operator==(const end_sentinel&) const noexcept { return the_range_->S_.empty(); }
//constexpr bool operator!=(const end_sentinel& rhs) const noexcept { return !operator==(rhs); }

private:
mutable shadow_value_type value_ = {};
dfs_range_type* the_range_ = nullptr;
mutable internal_value value_;
dfs_range_type* the_range_ = nullptr;
friend end_sentinel;
};

Expand Down Expand Up @@ -350,6 +360,16 @@ class vertices_depth_first_search_view<G, void, Stack, Alloc> : public dfs_base<
using shadow_vertex_type = remove_reference_t<vertex_reference>;
using shadow_value_type = vertex_descriptor<vertex_id_t<graph_type>, shadow_vertex_type*, void>;

union internal_value {
value_type value_;
shadow_value_type shadow_;

internal_value(const internal_value& rhs) : shadow_(rhs.shadow_) {}
internal_value() : shadow_{} {}
~internal_value() {}
internal_value& operator=(const internal_value& rhs) { value_.shadow = rhs.value_.shadow; }
};

public:
iterator(const dfs_range_type& range) : the_range_(&const_cast<dfs_range_type&>(range)) {}
iterator() = default;
Expand All @@ -375,16 +395,16 @@ class vertices_depth_first_search_view<G, void, Stack, Alloc> : public dfs_base<
auto&& [u_id, uvi] = the_range_->S_.top();
vertex_id_type v_id = the_range_->real_target_id(*uvi, u_id);
auto& v = *find_vertex(g, v_id);
value_ = {v_id, &v};
return reinterpret_cast<reference>(value_);
value_.shadow_ = {v_id, &v};
return value_.value_;
}

bool operator==(const end_sentinel&) const noexcept { return the_range_->S_.empty(); }
//bool operator!=(const end_sentinel& rhs) const noexcept { return !operator==(rhs); }

private:
mutable shadow_value_type value_ = {};
dfs_range_type* the_range_ = nullptr;
mutable internal_value value_;
dfs_range_type* the_range_ = nullptr;
friend end_sentinel;
};

Expand Down Expand Up @@ -462,6 +482,16 @@ class edges_depth_first_search_view : public dfs_base<G, Stack, Alloc> {
using shadow_value_type =
edge_descriptor<vertex_id_type, Sourced, shadow_edge_type*, _detail::ref_to_ptr<edge_value_type>>;

union internal_value {
value_type value_;
shadow_value_type shadow_;

internal_value(const internal_value& rhs) : shadow_(rhs.shadow_) {}
internal_value() : shadow_{} {}
~internal_value() {}
internal_value& operator=(const internal_value& rhs) { value_.shadow = rhs.value_.shadow; }
};

public:
iterator(const dfs_range_type& range) : the_range_(&const_cast<dfs_range_type&>(range)) {}
iterator() = default;
Expand All @@ -485,20 +515,20 @@ class edges_depth_first_search_view : public dfs_base<G, Stack, Alloc> {
reference operator*() const noexcept {
auto&& [u_id, uvi] = the_range_->S_.top();
if constexpr (Sourced) {
value_.source_id = u_id;
value_.shadow_.source_id = u_id;
}
value_.target_id = the_range_->real_target_id(*uvi, u_id);
value_.edge = &*uvi;
value_.value = invoke(*the_range_->value_fn_, *uvi);
return reinterpret_cast<reference>(value_);
value_.shadow_.target_id = the_range_->real_target_id(*uvi, u_id);
value_.shadow_.edge = &*uvi;
value_.shadow_.value = invoke(*the_range_->value_fn_, *uvi);
return value_.value_;
}

bool operator==(const end_sentinel&) const noexcept { return the_range_->S_.empty(); }
//bool operator!=(const end_sentinel& rhs) const noexcept { return !operator==(rhs); }

private:
mutable shadow_value_type value_ = {};
dfs_range_type* the_range_ = nullptr;
mutable internal_value value_;
dfs_range_type* the_range_ = nullptr;
friend end_sentinel;
};

Expand Down Expand Up @@ -560,6 +590,16 @@ class edges_depth_first_search_view<G, void, Sourced, Stack, Alloc> : public dfs
using shadow_edge_type = remove_reference_t<edge_reference_type>;
using shadow_value_type = edge_descriptor<vertex_id_type, Sourced, shadow_edge_type*, void>;

union internal_value {
value_type value_;
shadow_value_type shadow_;

internal_value(const internal_value& rhs) : shadow_(rhs.shadow_) {}
internal_value() : shadow_{} {}
~internal_value() {}
internal_value& operator=(const internal_value& rhs) { value_.shadow = rhs.value_.shadow; }
};

public:
iterator(const dfs_range_type& range) : the_range_(&const_cast<dfs_range_type&>(range)) {}
iterator() = default;
Expand All @@ -583,19 +623,19 @@ class edges_depth_first_search_view<G, void, Sourced, Stack, Alloc> : public dfs
reference operator*() const noexcept {
auto&& [u_id, uvi] = the_range_->S_.top();
if constexpr (Sourced) {
value_.source_id = u_id;
value_.shadow_.source_id = u_id;
}
value_.target_id = the_range_->real_target_id(*uvi, u_id);
value_.edge = &*uvi;
return reinterpret_cast<reference>(value_);
value_.shadow_.target_id = the_range_->real_target_id(*uvi, u_id);
value_.shadow_.edge = &*uvi;
return value_.value_;
}

bool operator==(const end_sentinel&) const noexcept { return the_range_->S_.empty(); }
//bool operator!=(const end_sentinel& rhs) const noexcept { return !operator==(rhs); }

private:
mutable shadow_value_type value_ = {};
dfs_range_type* the_range_ = nullptr;
mutable internal_value value_;
dfs_range_type* the_range_ = nullptr;
friend end_sentinel;
};

Expand Down
2 changes: 2 additions & 0 deletions include/graph/views/edgelist.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ class edgelist_iterator : public edgelist_iterator_base<G> {

internal_value(const internal_value& rhs) : shadow_(rhs.shadow_) {}
internal_value() : shadow_{} {}
~internal_value() {}
internal_value& operator=(const internal_value& rhs) { value_.shadow = rhs.value_.shadow; }
};

Expand Down Expand Up @@ -218,6 +219,7 @@ class edgelist_iterator<G, void> : public edgelist_iterator_base<G> {

internal_value(const internal_value& rhs) : shadow_(rhs.shadow_) {}
internal_value() : shadow_{} {}
~internal_value() {}
internal_value& operator=(const internal_value& rhs) { value_.shadow = rhs.value_.shadow; }
};

Expand Down
2 changes: 2 additions & 0 deletions include/graph/views/incidence.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class incidence_iterator : source_vertex<G, ((Sourced && !sourced_adjacency_list

internal_value(const internal_value& rhs) : shadow_(rhs.shadow_) {}
internal_value() : shadow_{} {}
~internal_value() {}
internal_value& operator=(const internal_value& rhs) { value_.shadow = rhs.value_.shadow; }
};

Expand Down Expand Up @@ -172,6 +173,7 @@ class incidence_iterator<G, Sourced, void>

internal_value(const internal_value& rhs) : shadow_(rhs.shadow_) {}
internal_value() : shadow_{} {}
~internal_value() {}
internal_value& operator=(const internal_value& rhs) { value_.shadow = rhs.value_.shadow; }
};

Expand Down
2 changes: 2 additions & 0 deletions include/graph/views/neighbors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class neighbor_iterator

internal_value(const internal_value& rhs) : shadow_(rhs.shadow_) {}
internal_value() : shadow_{} {}
~internal_value() {}
internal_value& operator=(const internal_value& rhs) { value_.shadow = rhs.value_.shadow; }
};

Expand Down Expand Up @@ -183,6 +184,7 @@ class neighbor_iterator<G, Sourced, void>

internal_value(const internal_value& rhs) : shadow_(rhs.shadow_) {}
internal_value() : shadow_{} {}
~internal_value() {}
internal_value& operator=(const internal_value& rhs) { value_.shadow = rhs.value_.shadow; }
};

Expand Down
2 changes: 2 additions & 0 deletions include/graph/views/vertexlist.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class vertexlist_iterator {
internal_value(vertex_id_type start_at) : shadow_{} { shadow_.id = start_at; }
internal_value(const internal_value& rhs) : shadow_(rhs.shadow_) {}
internal_value() : shadow_{} {}
~internal_value() {}
internal_value& operator=(const internal_value& rhs) { value_.shadow = rhs.value_.shadow; }
};

Expand Down Expand Up @@ -147,6 +148,7 @@ class vertexlist_iterator<G, void> {
internal_value(vertex_id_type start_at) : shadow_{start_at, nullptr} {}
internal_value(const internal_value& rhs) : shadow_(rhs.shadow_) {}
internal_value() : shadow_{} {}
~internal_value() {}
internal_value& operator=(const internal_value& rhs) { value_.shadow = rhs.value_.shadow; }
};

Expand Down

0 comments on commit 20f4b82

Please sign in to comment.