diff --git a/include/graph/views/breadth_first_search.hpp b/include/graph/views/breadth_first_search.hpp index 0fd0489..47ed966 100644 --- a/include/graph/views/breadth_first_search.hpp +++ b/include/graph/views/breadth_first_search.hpp @@ -260,6 +260,17 @@ class vertices_breadth_first_search_view : public bfs_base { using shadow_value_type = vertex_descriptor, shadow_vertex_type*, _detail::ref_to_ptr>; + union internal_value { + value_type value_; + shadow_value_type shadow_; + + 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; } + }; + public: iterator(const bfs_range_type& range) : the_range_(&const_cast(range)) {} iterator() = default; @@ -286,16 +297,16 @@ class vertices_breadth_first_search_view : public bfs_base { auto&& uvi = the_range_->uv_; 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(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_->Q_.empty(); } constexpr bool operator!=(const end_sentinel& rhs) const noexcept { return !operator==(rhs); } private: - mutable shadow_value_type value_ = {}; - bfs_range_type* the_range_ = nullptr; + mutable internal_value value_; + bfs_range_type* the_range_ = nullptr; friend end_sentinel; }; @@ -367,6 +378,17 @@ class vertices_breadth_first_search_view : public bfs_bas using shadow_vertex_type = remove_reference_t; using shadow_value_type = vertex_descriptor, shadow_vertex_type*, void>; + union internal_value { + value_type value_; + shadow_value_type shadow_; + + 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; } + }; + public: iterator(const bfs_range_type& range) : the_range_(&const_cast(range)) {} iterator() = default; @@ -393,16 +415,16 @@ class vertices_breadth_first_search_view : public bfs_bas auto&& uvi = the_range_->uv_; 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(value_); + value_.shadow_ = {v_id, &v}; + return value_.value_; } bool operator==(const end_sentinel&) const noexcept { return the_range_->Q_.empty(); } //bool operator!=(const end_sentinel& rhs) const noexcept { return !operator==(rhs); } private: - mutable shadow_value_type value_ = {}; - bfs_range_type* the_range_ = nullptr; + mutable internal_value value_; + bfs_range_type* the_range_ = nullptr; friend end_sentinel; }; @@ -482,6 +504,17 @@ class edges_breadth_first_search_view : public bfs_base { using shadow_value_type = edge_descriptor>; + union internal_value { + value_type value_; + shadow_value_type shadow_; + + 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; } + }; + public: iterator(const bfs_range_type& range) : the_range_(&const_cast(range)) {} iterator() = default; @@ -506,20 +539,20 @@ class edges_breadth_first_search_view : public bfs_base { auto&& u_id = the_range_->Q_.front(); auto&& uvi = the_range_->uv_; 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(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_->Q_.empty(); } bool operator!=(const end_sentinel& rhs) const noexcept { return !operator==(rhs); } private: - mutable shadow_value_type value_ = {}; - bfs_range_type* the_range_ = nullptr; + mutable internal_value value_; + bfs_range_type* the_range_ = nullptr; friend end_sentinel; }; @@ -584,6 +617,17 @@ class edges_breadth_first_search_view : public b using shadow_edge_type = remove_reference_t; using shadow_value_type = edge_descriptor; + union internal_value { + value_type value_; + shadow_value_type shadow_; + + 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; } + }; + public: iterator(const bfs_range_type& range) : the_range_(&const_cast(range)) {} iterator() = default; @@ -608,19 +652,19 @@ class edges_breadth_first_search_view : public b auto&& u_id = the_range_->Q_.front(); auto&& uvi = the_range_->uv_; 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(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_->Q_.empty(); } bool operator!=(const end_sentinel& rhs) const noexcept { return !operator==(rhs); } private: - mutable shadow_value_type value_ = {}; - bfs_range_type* the_range_ = nullptr; + mutable internal_value value_; + bfs_range_type* the_range_ = nullptr; friend end_sentinel; }; diff --git a/tests/pagerank_tests.cpp b/tests/pagerank_tests.cpp index 750953e..853d521 100644 --- a/tests/pagerank_tests.cpp +++ b/tests/pagerank_tests.cpp @@ -43,7 +43,7 @@ TEST_CASE("PageRank", "[pagerank]") { auto&& g = load_ordered_graph(TEST_DATA_ROOT_DIR "germany_routes.csv", name_order_policy::source_order_found); std::vector page_rank(size(vertices(g))); - std::graph::pagerank(g, page_rank, double(0.85), double(1e-4), 10); + std::graph::pagerank(g, page_rank, 0.85, 1e-4, 10); std::vector answer = {0.051086017487729, 0.065561667371485, 0.106818581147795, 0.141889899564636, 0.065561667371485, 0.078952299317762, 0.065561667371485, 0.078952299317762,