/**************************************************************************** Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd. http://www.cocos.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ****************************************************************************/ #pragma once #include #include #include namespace cc { namespace render { template struct AddressableView { explicit AddressableView(const GraphT& g) noexcept : mGraph(g) {} // GraphT using directed_category = boost::bidirectional_tag; using vertex_descriptor = typename GraphT::vertex_descriptor; using edge_descriptor = typename GraphT::ownership_descriptor; using edge_parallel_category = boost::allow_parallel_edge_tag; struct traversal_category // NOLINT(readability-identifier-naming) : virtual boost::incidence_graph_tag, virtual boost::bidirectional_graph_tag, virtual boost::adjacency_graph_tag, virtual boost::vertex_list_graph_tag, virtual boost::edge_list_graph_tag {}; static vertex_descriptor null_vertex() noexcept { // NOLINT(readability-identifier-naming) return GraphT::null_vertex(); } // IncidenceGraph using out_edge_iterator = typename GraphT::children_iterator; using degree_size_type = typename GraphT::children_size_type; // BidirectionalGraph using in_edge_iterator = typename GraphT::parent_iterator; // AdjacencyGraph using adjacency_iterator = typename boost::adjacency_iterator_generator< AddressableView, vertex_descriptor, out_edge_iterator>::type; // VertexListGraph using vertex_iterator = typename GraphT::vertex_iterator; using vertices_size_type = typename GraphT::vertices_size_type; // EdgeListGraph using edge_iterator = typename GraphT::ownership_iterator; using edges_size_type = typename GraphT::ownerships_size_type; // Member const GraphT& mGraph; }; // IncidenceGraph template inline typename AddressableView::vertex_descriptor source(const typename AddressableView::edge_descriptor& e, const AddressableView& g) noexcept { return parent(e, g.mGraph); } template inline typename AddressableView::vertex_descriptor target(const typename AddressableView::edge_descriptor& e, const AddressableView& g) noexcept { return child(e, g.mGraph); } template inline std::pair< typename AddressableView::out_edge_iterator, typename AddressableView::out_edge_iterator> out_edges( // NOLINT(readability-identifier-naming) typename AddressableView::vertex_descriptor u, const AddressableView& g) { return children(u, g.mGraph); } template inline typename AddressableView::degree_size_type out_degree( // NOLINT(readability-identifier-naming) typename AddressableView::vertex_descriptor u, const AddressableView& g) noexcept { return numChildren(u, g.mGraph); } template inline std::pair::edge_descriptor, bool> edge(typename AddressableView::vertex_descriptor u, typename AddressableView::vertex_descriptor v, const AddressableView& g) noexcept { return ownership(u, v, g.mGraph); } // BidirectionalGraph template inline std::pair::in_edge_iterator, typename AddressableView::in_edge_iterator> in_edges( // NOLINT(readability-identifier-naming) typename AddressableView::vertex_descriptor u, const AddressableView& g) noexcept { return parents(u, g.mGraph); } template inline typename AddressableView::degree_size_type in_degree( // NOLINT(readability-identifier-naming) typename AddressableView::vertex_descriptor u, const AddressableView& g) noexcept { return numParents(u, g.mGraph); } template inline typename AddressableView::degree_size_type degree(typename AddressableView::vertex_descriptor u, const AddressableView& g) noexcept { return out_degree(u, g) + in_degree(u, g); } // AdjacencyGraph template inline std::pair< typename AddressableView::adjacency_iterator, typename AddressableView::adjacency_iterator> adjacent_vertices( // NOLINT(readability-identifier-naming) typename AddressableView::vertex_descriptor u, const AddressableView& g) noexcept { auto r = out_edges(u, g); return std::make_pair( typename AddressableView::adjacency_iterator(r.first, &g), typename AddressableView::adjacency_iterator(r.second, &g)); } // VertexListGraph template inline std::pair< typename AddressableView::vertex_iterator, typename AddressableView::vertex_iterator> vertices(const AddressableView& g) noexcept { return vertices(g.mGraph); } template inline typename AddressableView::vertices_size_type num_vertices(const AddressableView& g) noexcept { // NOLINT(readability-identifier-naming) return num_vertices(g.mGraph); } // EdgeListGraph template inline std::pair< typename AddressableView::edge_iterator, typename AddressableView::edge_iterator> edges(const AddressableView& g) noexcept { return ownerships(g.mGraph); } template inline typename AddressableView::edges_size_type num_edges(const AddressableView& g) noexcept { // NOLINT(readability-identifier-naming) return num_ownerships(g.mGraph); } } // namespace render } // namespace cc namespace boost { template struct property_map, TagT> { using const_type = typename property_map::const_type; using type = typename property_map::type; }; } // namespace boost namespace cc { namespace render { template typename boost::property_map, TagT>::const_type get(TagT t, const AddressableView& g) { return get(t, g.mGraph); } template typename boost::property_map, TagT>::type get(TagT t, AddressableView& g) { return get(t, g.mGraph); } template [[nodiscard]] inline decltype(auto) get(TagT tag, const AddressableView& g, typename AddressableView::vertex_descriptor v) noexcept { return get(get(tag, g), v); } template [[nodiscard]] inline decltype(auto) get(TagT tag, AddressableView& g, typename AddressableView::vertex_descriptor v) noexcept { return get(get(tag, g), v); } template inline void put(TagT tag, AddressableView& g, typename AddressableView::vertex_descriptor v, Args&&... args) { put(get(tag, g), v, std::forward(args)...); } } // namespace render } // namespace cc