//======================================================================= // Copyright 2007 Aaron Windsor // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= #ifndef __BOYER_MYRVOLD_PLANAR_TEST_HPP__ #define __BOYER_MYRVOLD_PLANAR_TEST_HPP__ #include #include #include #include namespace boost { struct no_kuratowski_subgraph_isolation { }; struct no_planar_embedding { }; namespace boyer_myrvold_params { BOOST_PARAMETER_KEYWORD(tag, graph) BOOST_PARAMETER_KEYWORD(tag, embedding) BOOST_PARAMETER_KEYWORD(tag, kuratowski_subgraph) BOOST_PARAMETER_KEYWORD(tag, vertex_index_map) BOOST_PARAMETER_KEYWORD(tag, edge_index_map) typedef parameter::parameters< parameter::required< tag::graph >, tag::embedding, tag::kuratowski_subgraph, tag::vertex_index_map, tag::edge_index_map > boyer_myrvold_params_t; namespace core { template < typename ArgumentPack > bool dispatched_boyer_myrvold( ArgumentPack const& args, mpl::true_, mpl::true_) { // Dispatch for no planar embedding, no kuratowski subgraph // isolation typedef typename remove_const< typename parameter::value_type< ArgumentPack, tag::graph >::type >::type graph_t; typedef typename property_map< graph_t, vertex_index_t >::const_type vertex_default_index_map_t; typedef typename parameter::value_type< ArgumentPack, tag::vertex_index_map, vertex_default_index_map_t >::type vertex_index_map_t; graph_t const& g = args[graph]; vertex_default_index_map_t v_d_map = get(vertex_index, g); vertex_index_map_t v_i_map = args[vertex_index_map | v_d_map]; boyer_myrvold_impl< graph_t, vertex_index_map_t, graph::detail::no_old_handles, graph::detail::no_embedding > planarity_tester(g, v_i_map); return planarity_tester.is_planar() ? true : false; } template < typename ArgumentPack > bool dispatched_boyer_myrvold( ArgumentPack const& args, mpl::true_, mpl::false_) { // Dispatch for no planar embedding, kuratowski subgraph isolation typedef typename remove_const< typename parameter::value_type< ArgumentPack, tag::graph >::type >::type graph_t; typedef typename property_map< graph_t, vertex_index_t >::const_type vertex_default_index_map_t; typedef typename parameter::value_type< ArgumentPack, tag::vertex_index_map, vertex_default_index_map_t >::type vertex_index_map_t; typedef typename property_map< graph_t, edge_index_t >::const_type edge_default_index_map_t; typedef typename parameter::value_type< ArgumentPack, tag::edge_index_map, edge_default_index_map_t >::type edge_index_map_t; graph_t const& g = args[graph]; vertex_default_index_map_t v_d_map = get(vertex_index, g); vertex_index_map_t v_i_map = args[vertex_index_map | v_d_map]; edge_default_index_map_t e_d_map = get(edge_index, g); edge_index_map_t e_i_map = args[edge_index_map | e_d_map]; boyer_myrvold_impl< graph_t, vertex_index_map_t, graph::detail::store_old_handles, graph::detail::no_embedding > planarity_tester(g, v_i_map); if (planarity_tester.is_planar()) return true; else { planarity_tester.extract_kuratowski_subgraph( args[kuratowski_subgraph], e_i_map); return false; } } template < typename ArgumentPack > bool dispatched_boyer_myrvold( ArgumentPack const& args, mpl::false_, mpl::true_) { // Dispatch for planar embedding, no kuratowski subgraph isolation typedef typename remove_const< typename parameter::value_type< ArgumentPack, tag::graph >::type >::type graph_t; typedef typename property_map< graph_t, vertex_index_t >::const_type vertex_default_index_map_t; typedef typename parameter::value_type< ArgumentPack, tag::vertex_index_map, vertex_default_index_map_t >::type vertex_index_map_t; graph_t const& g = args[graph]; vertex_default_index_map_t v_d_map = get(vertex_index, g); vertex_index_map_t v_i_map = args[vertex_index_map | v_d_map]; boyer_myrvold_impl< graph_t, vertex_index_map_t, graph::detail::no_old_handles, #ifdef BOOST_GRAPH_PREFER_STD_LIB graph::detail::std_list #else graph::detail::recursive_lazy_list #endif > planarity_tester(g, v_i_map); if (planarity_tester.is_planar()) { planarity_tester.make_edge_permutation(args[embedding]); return true; } else return false; } template < typename ArgumentPack > bool dispatched_boyer_myrvold( ArgumentPack const& args, mpl::false_, mpl::false_) { // Dispatch for planar embedding, kuratowski subgraph isolation typedef typename remove_const< typename parameter::value_type< ArgumentPack, tag::graph >::type >::type graph_t; typedef typename property_map< graph_t, vertex_index_t >::const_type vertex_default_index_map_t; typedef typename parameter::value_type< ArgumentPack, tag::vertex_index_map, vertex_default_index_map_t >::type vertex_index_map_t; typedef typename property_map< graph_t, edge_index_t >::const_type edge_default_index_map_t; typedef typename parameter::value_type< ArgumentPack, tag::edge_index_map, edge_default_index_map_t >::type edge_index_map_t; graph_t const& g = args[graph]; vertex_default_index_map_t v_d_map = get(vertex_index, g); vertex_index_map_t v_i_map = args[vertex_index_map | v_d_map]; edge_default_index_map_t e_d_map = get(edge_index, g); edge_index_map_t e_i_map = args[edge_index_map | e_d_map]; boyer_myrvold_impl< graph_t, vertex_index_map_t, graph::detail::store_old_handles, #ifdef BOOST_BGL_PREFER_STD_LIB graph::detail::std_list #else graph::detail::recursive_lazy_list #endif > planarity_tester(g, v_i_map); if (planarity_tester.is_planar()) { planarity_tester.make_edge_permutation(args[embedding]); return true; } else { planarity_tester.extract_kuratowski_subgraph( args[kuratowski_subgraph], e_i_map); return false; } } template < typename ArgumentPack > bool boyer_myrvold_planarity_test(ArgumentPack const& args) { typedef typename parameter::binding< ArgumentPack, tag::kuratowski_subgraph, const no_kuratowski_subgraph_isolation& >::type kuratowski_arg_t; typedef typename parameter::binding< ArgumentPack, tag::embedding, const no_planar_embedding& >::type embedding_arg_t; return dispatched_boyer_myrvold(args, boost::is_same< embedding_arg_t, const no_planar_embedding& >(), boost::is_same< kuratowski_arg_t, const no_kuratowski_subgraph_isolation& >()); } } // namespace core } // namespace boyer_myrvold_params template < typename A0 > bool boyer_myrvold_planarity_test(A0 const& arg0) { return boyer_myrvold_params::core::boyer_myrvold_planarity_test( boyer_myrvold_params::boyer_myrvold_params_t()(arg0)); } template < typename A0, typename A1 > // bool boyer_myrvold_planarity_test(A0 const& arg0, A1 const& arg1) bool boyer_myrvold_planarity_test(A0 const& arg0, A1 const& arg1) { return boyer_myrvold_params::core::boyer_myrvold_planarity_test( boyer_myrvold_params::boyer_myrvold_params_t()(arg0, arg1)); } template < typename A0, typename A1, typename A2 > bool boyer_myrvold_planarity_test( A0 const& arg0, A1 const& arg1, A2 const& arg2) { return boyer_myrvold_params::core::boyer_myrvold_planarity_test( boyer_myrvold_params::boyer_myrvold_params_t()(arg0, arg1, arg2)); } template < typename A0, typename A1, typename A2, typename A3 > bool boyer_myrvold_planarity_test( A0 const& arg0, A1 const& arg1, A2 const& arg2, A3 const& arg3) { return boyer_myrvold_params::core::boyer_myrvold_planarity_test( boyer_myrvold_params::boyer_myrvold_params_t()(arg0, arg1, arg2, arg3)); } template < typename A0, typename A1, typename A2, typename A3, typename A4 > bool boyer_myrvold_planarity_test(A0 const& arg0, A1 const& arg1, A2 const& arg2, A3 const& arg3, A4 const& arg4) { return boyer_myrvold_params::core::boyer_myrvold_planarity_test( boyer_myrvold_params::boyer_myrvold_params_t()( arg0, arg1, arg2, arg3, arg4)); } } #endif //__BOYER_MYRVOLD_PLANAR_TEST_HPP__