// Copyright (C) 2009 Andrew Sutton // Use, modification and distribution is subject to 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 BOOST_GRAPH_LABELED_GRAPH_HPP #define BOOST_GRAPH_LABELED_GRAPH_HPP #include #include #include #include #include #include #include #include #include #include #include // This file implements a utility for creating mappings from arbitrary // identifiers to the vertices of a graph. namespace boost { // A type selector that denotes the use of some default value. struct defaultS { }; /** @internal */ namespace graph_detail { /** Returns true if the selector is the default selector. */ template < typename Selector > struct is_default : mpl::bool_< is_same< Selector, defaultS >::value > { }; /** * Choose the default map instance. If Label is an unsigned integral type * the we can use a vector to store the information. */ template < typename Label, typename Vertex > struct choose_default_map { typedef typename mpl::if_< is_unsigned< Label >, std::vector< Vertex >, std::map< Label, Vertex > // TODO: Should use unordered_map? >::type type; }; /** * @name Generate Label Map * These type generators are responsible for instantiating an associative * container for the the labeled graph. Note that the Selector must be * select a pair associative container or a vecS, which is only valid if * Label is an integral type. */ //@{ template < typename Selector, typename Label, typename Vertex > struct generate_label_map { }; template < typename Label, typename Vertex > struct generate_label_map< vecS, Label, Vertex > { typedef std::vector< Vertex > type; }; template < typename Label, typename Vertex > struct generate_label_map< mapS, Label, Vertex > { typedef std::map< Label, Vertex > type; }; template < typename Label, typename Vertex > struct generate_label_map< multimapS, Label, Vertex > { typedef std::multimap< Label, Vertex > type; }; template < typename Label, typename Vertex > struct generate_label_map< hash_mapS, Label, Vertex > { typedef boost::unordered_map< Label, Vertex > type; }; template < typename Label, typename Vertex > struct generate_label_map< hash_multimapS, Label, Vertex > { typedef boost::unordered_multimap< Label, Vertex > type; }; template < typename Selector, typename Label, typename Vertex > struct choose_custom_map { typedef typename generate_label_map< Selector, Label, Vertex >::type type; }; //@} /** * Choose and instantiate an "associative" container. Note that this can * also choose vector. */ template < typename Selector, typename Label, typename Vertex > struct choose_map { typedef typename mpl::eval_if< is_default< Selector >, choose_default_map< Label, Vertex >, choose_custom_map< Selector, Label, Vertex > >::type type; }; /** @name Insert Labeled Vertex */ //@{ // Tag dispatch on random access containers (i.e., vectors). This function // basically requires a) that Container is vector