Added boost header
This commit is contained in:
117
test/external/boost/graph/detail/adj_list_edge_iterator.hpp
vendored
Normal file
117
test/external/boost/graph/detail/adj_list_edge_iterator.hpp
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
//
|
||||
//=======================================================================
|
||||
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
|
||||
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
|
||||
//
|
||||
// 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 BOOST_GRAPH_DETAIL_ADJ_LIST_EDGE_ITERATOR_HPP
|
||||
#define BOOST_GRAPH_DETAIL_ADJ_LIST_EDGE_ITERATOR_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
|
||||
# define BOOST_GRAPH_NO_OPTIONAL
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_GRAPH_NO_OPTIONAL
|
||||
# define BOOST_GRAPH_MEMBER .
|
||||
#else
|
||||
# define BOOST_GRAPH_MEMBER ->
|
||||
# include <boost/optional.hpp>
|
||||
#endif // ndef BOOST_GRAPH_NO_OPTIONAL
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class VertexIterator, class OutEdgeIterator, class Graph>
|
||||
class adj_list_edge_iterator {
|
||||
typedef adj_list_edge_iterator self;
|
||||
public:
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef typename OutEdgeIterator::value_type value_type;
|
||||
typedef typename OutEdgeIterator::reference reference;
|
||||
typedef typename OutEdgeIterator::pointer pointer;
|
||||
typedef typename OutEdgeIterator::difference_type difference_type;
|
||||
typedef difference_type distance_type;
|
||||
|
||||
inline adj_list_edge_iterator() {}
|
||||
|
||||
inline adj_list_edge_iterator(const self& x)
|
||||
: vBegin(x.vBegin), vCurr(x.vCurr), vEnd(x.vEnd),
|
||||
edges(x.edges), m_g(x.m_g) { }
|
||||
|
||||
template <class G>
|
||||
inline adj_list_edge_iterator(VertexIterator b,
|
||||
VertexIterator c,
|
||||
VertexIterator e,
|
||||
const G& g)
|
||||
: vBegin(b), vCurr(c), vEnd(e), m_g(&g) {
|
||||
if ( vCurr != vEnd ) {
|
||||
while ( vCurr != vEnd && out_degree(*vCurr, *m_g) == 0 )
|
||||
++vCurr;
|
||||
if ( vCurr != vEnd )
|
||||
edges = out_edges(*vCurr, *m_g);
|
||||
}
|
||||
}
|
||||
|
||||
/*Note:
|
||||
In the directed graph cases, it is fine.
|
||||
For undirected graphs, one edge go through twice.
|
||||
*/
|
||||
inline self& operator++() {
|
||||
++edges BOOST_GRAPH_MEMBER first;
|
||||
if (edges BOOST_GRAPH_MEMBER first == edges BOOST_GRAPH_MEMBER second)
|
||||
{
|
||||
++vCurr;
|
||||
while ( vCurr != vEnd && out_degree(*vCurr, *m_g) == 0 )
|
||||
++vCurr;
|
||||
if ( vCurr != vEnd )
|
||||
edges = out_edges(*vCurr, *m_g);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
inline self operator++(int) {
|
||||
self tmp = *this;
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
inline value_type operator*() const
|
||||
{ return *edges BOOST_GRAPH_MEMBER first; }
|
||||
inline bool operator==(const self& x) const {
|
||||
return vCurr == x.vCurr
|
||||
&& (vCurr == vEnd
|
||||
|| edges BOOST_GRAPH_MEMBER first == x.edges BOOST_GRAPH_MEMBER first);
|
||||
}
|
||||
inline bool operator!=(const self& x) const {
|
||||
return vCurr != x.vCurr
|
||||
|| (vCurr != vEnd
|
||||
&& edges BOOST_GRAPH_MEMBER first != x.edges BOOST_GRAPH_MEMBER first);
|
||||
}
|
||||
protected:
|
||||
VertexIterator vBegin;
|
||||
VertexIterator vCurr;
|
||||
VertexIterator vEnd;
|
||||
|
||||
#ifdef BOOST_GRAPH_NO_OPTIONAL
|
||||
std::pair<OutEdgeIterator, OutEdgeIterator> edges;
|
||||
#else
|
||||
boost::optional<std::pair<OutEdgeIterator, OutEdgeIterator> >
|
||||
edges;
|
||||
#endif // ndef BOOST_GRAPH_NO_OPTIONAL
|
||||
const Graph* m_g;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
}
|
||||
|
||||
#undef BOOST_GRAPH_MEMBER
|
||||
|
||||
#endif // BOOST_GRAPH_DETAIL_ADJ_LIST_EDGE_ITERATOR_HPP
|
||||
2838
test/external/boost/graph/detail/adjacency_list.hpp
vendored
Normal file
2838
test/external/boost/graph/detail/adjacency_list.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
181
test/external/boost/graph/detail/array_binary_tree.hpp
vendored
Normal file
181
test/external/boost/graph/detail/array_binary_tree.hpp
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
//
|
||||
//=======================================================================
|
||||
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
|
||||
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
|
||||
//
|
||||
// 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 BOOST_ARRAY_BINARY_TREE_HPP
|
||||
#define BOOST_ARRAY_BINARY_TREE_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <functional>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
/*
|
||||
* Note: array_binary_tree is a completey balanced binary tree.
|
||||
*/
|
||||
#if !defined BOOST_NO_STD_ITERATOR_TRAITS
|
||||
template <class RandomAccessIterator, class ID>
|
||||
#else
|
||||
template <class RandomAccessIterator, class ValueType, class ID>
|
||||
#endif
|
||||
class array_binary_tree_node {
|
||||
public:
|
||||
typedef array_binary_tree_node ArrayBinaryTreeNode;
|
||||
typedef RandomAccessIterator rep_iterator;
|
||||
#if !defined BOOST_NO_STD_ITERATOR_TRAITS
|
||||
typedef typename std::iterator_traits<RandomAccessIterator>::difference_type
|
||||
difference_type;
|
||||
typedef typename std::iterator_traits<RandomAccessIterator>::value_type
|
||||
value_type;
|
||||
#else
|
||||
typedef int difference_type;
|
||||
typedef ValueType value_type;
|
||||
#endif
|
||||
typedef difference_type size_type;
|
||||
|
||||
struct children_type {
|
||||
struct iterator
|
||||
: boost::iterator<std::bidirectional_iterator_tag, ArrayBinaryTreeNode,
|
||||
difference_type, array_binary_tree_node*, ArrayBinaryTreeNode&>
|
||||
{ // replace with iterator_adaptor implementation -JGS
|
||||
|
||||
inline iterator() : i(0), n(0) { }
|
||||
inline iterator(const iterator& x) : r(x.r), i(x.i), n(x.n), id(x.id) { }
|
||||
inline iterator& operator=(const iterator& x) {
|
||||
r = x.r; i = x.i; n = x.n;
|
||||
/*egcs generate a warning*/
|
||||
id = x.id;
|
||||
return *this;
|
||||
}
|
||||
inline iterator(rep_iterator rr,
|
||||
size_type ii,
|
||||
size_type nn,
|
||||
const ID& _id) : r(rr), i(ii), n(nn), id(_id) { }
|
||||
inline array_binary_tree_node operator*() {
|
||||
return ArrayBinaryTreeNode(r, i, n, id); }
|
||||
inline iterator& operator++() { ++i; return *this; }
|
||||
inline iterator operator++(int)
|
||||
{ iterator t = *this; ++(*this); return t; }
|
||||
inline bool operator==(const iterator& x) const { return i == x.i; }
|
||||
inline bool operator!=(const iterator& x) const
|
||||
{ return !(*this == x); }
|
||||
rep_iterator r;
|
||||
size_type i;
|
||||
size_type n;
|
||||
ID id;
|
||||
};
|
||||
inline children_type() : i(0), n(0) { }
|
||||
inline children_type(const children_type& x)
|
||||
: r(x.r), i(x.i), n(x.n), id(x.id) { }
|
||||
inline children_type& operator=(const children_type& x) {
|
||||
r = x.r; i = x.i; n = x.n;
|
||||
/*egcs generate a warning*/
|
||||
id = x.id;
|
||||
return *this;
|
||||
}
|
||||
inline children_type(rep_iterator rr,
|
||||
size_type ii,
|
||||
size_type nn,
|
||||
const ID& _id) : r(rr), i(ii), n(nn), id(_id) { }
|
||||
inline iterator begin() { return iterator(r, 2 * i + 1, n, id); }
|
||||
inline iterator end() { return iterator(r, 2 * i + 1 + size(), n, id); }
|
||||
inline size_type size() const {
|
||||
size_type c = 2 * i + 1;
|
||||
size_type s;
|
||||
if (c + 1 < n) s = 2;
|
||||
else if (c < n) s = 1;
|
||||
else s = 0;
|
||||
return s;
|
||||
}
|
||||
rep_iterator r;
|
||||
size_type i;
|
||||
size_type n;
|
||||
ID id;
|
||||
};
|
||||
inline array_binary_tree_node() : i(0), n(0) { }
|
||||
inline array_binary_tree_node(const array_binary_tree_node& x)
|
||||
: r(x.r), i(x.i), n(x.n), id(x.id) { }
|
||||
inline ArrayBinaryTreeNode& operator=(const ArrayBinaryTreeNode& x) {
|
||||
r = x.r;
|
||||
i = x.i;
|
||||
n = x.n;
|
||||
/*egcs generate a warning*/
|
||||
id = x.id;
|
||||
return *this;
|
||||
}
|
||||
inline array_binary_tree_node(rep_iterator start,
|
||||
rep_iterator end,
|
||||
rep_iterator pos, const ID& _id)
|
||||
: r(start), i(pos - start), n(end - start), id(_id) { }
|
||||
inline array_binary_tree_node(rep_iterator rr,
|
||||
size_type ii,
|
||||
size_type nn, const ID& _id)
|
||||
: r(rr), i(ii), n(nn), id(_id) { }
|
||||
inline value_type& value() { return *(r + i); }
|
||||
inline const value_type& value() const { return *(r + i); }
|
||||
inline ArrayBinaryTreeNode parent() const {
|
||||
return ArrayBinaryTreeNode(r, (i - 1) / 2, n, id);
|
||||
}
|
||||
inline bool has_parent() const { return i != 0; }
|
||||
inline children_type children() { return children_type(r, i, n, id); }
|
||||
/*
|
||||
inline void swap(array_binary_tree_node x) {
|
||||
value_type tmp = x.value();
|
||||
x.value() = value();
|
||||
value() = tmp;
|
||||
i = x.i;
|
||||
}
|
||||
*/
|
||||
template <class ExternalData>
|
||||
inline void swap(ArrayBinaryTreeNode x, ExternalData& edata ) {
|
||||
using boost::get;
|
||||
|
||||
value_type tmp = x.value();
|
||||
|
||||
/*swap external data*/
|
||||
edata[ get(id, tmp) ] = i;
|
||||
edata[ get(id, value()) ] = x.i;
|
||||
|
||||
x.value() = value();
|
||||
value() = tmp;
|
||||
i = x.i;
|
||||
}
|
||||
inline const children_type children() const {
|
||||
return children_type(r, i, n);
|
||||
}
|
||||
inline size_type index() const { return i; }
|
||||
rep_iterator r;
|
||||
size_type i;
|
||||
size_type n;
|
||||
ID id;
|
||||
};
|
||||
|
||||
template <class RandomAccessContainer,
|
||||
class Compare = std::less<typename RandomAccessContainer::value_type> >
|
||||
struct compare_array_node {
|
||||
typedef typename RandomAccessContainer::value_type value_type;
|
||||
compare_array_node(const Compare& x) : comp(x) {}
|
||||
compare_array_node(const compare_array_node& x) : comp(x.comp) {}
|
||||
|
||||
template< class node_type >
|
||||
inline bool operator()(const node_type& x, const node_type& y) {
|
||||
return comp(x.value(), y.value());
|
||||
}
|
||||
|
||||
template< class node_type >
|
||||
inline bool operator()(const node_type& x, const node_type& y) const {
|
||||
return comp(x.value(), y.value());
|
||||
}
|
||||
Compare comp;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif /* BOOST_ARRAY_BINARY_TREE_HPP */
|
||||
652
test/external/boost/graph/detail/compressed_sparse_row_struct.hpp
vendored
Normal file
652
test/external/boost/graph/detail/compressed_sparse_row_struct.hpp
vendored
Normal file
@@ -0,0 +1,652 @@
|
||||
// Copyright 2005-2009 The Trustees of Indiana University.
|
||||
|
||||
// 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)
|
||||
|
||||
// Authors: Jeremiah Willcock
|
||||
// Douglas Gregor
|
||||
// Andrew Lumsdaine
|
||||
|
||||
// Compressed sparse row graph type internal structure
|
||||
|
||||
#ifndef BOOST_GRAPH_COMPRESSED_SPARSE_ROW_STRUCT_HPP
|
||||
#define BOOST_GRAPH_COMPRESSED_SPARSE_ROW_STRUCT_HPP
|
||||
|
||||
#ifndef BOOST_GRAPH_COMPRESSED_SPARSE_ROW_GRAPH_HPP
|
||||
#error This file should only be included from boost/graph/compressed_sparse_row_graph.hpp
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <climits>
|
||||
#include <boost/assert.hpp>
|
||||
#include <iterator>
|
||||
#if 0
|
||||
#include <iostream> // For some debugging code below
|
||||
#endif
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <boost/graph/filtered_graph.hpp> // For keep_all
|
||||
#include <boost/graph/detail/indexed_properties.hpp>
|
||||
#include <boost/graph/detail/histogram_sort.hpp>
|
||||
#include <boost/graph/iteration_macros.hpp>
|
||||
#include <boost/iterator/counting_iterator.hpp>
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
#include <boost/iterator/zip_iterator.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#include <boost/integer.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/graph/graph_selectors.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail {
|
||||
// Forward declaration of CSR edge descriptor type, needed to pass to
|
||||
// indexed_edge_properties.
|
||||
template<typename Vertex, typename EdgeIndex>
|
||||
class csr_edge_descriptor;
|
||||
|
||||
// Add edge_index property map
|
||||
template<typename Vertex, typename EdgeIndex>
|
||||
struct csr_edge_index_map
|
||||
{
|
||||
typedef EdgeIndex value_type;
|
||||
typedef EdgeIndex reference;
|
||||
typedef csr_edge_descriptor<Vertex, EdgeIndex> key_type;
|
||||
typedef readable_property_map_tag category;
|
||||
};
|
||||
|
||||
template<typename Vertex, typename EdgeIndex>
|
||||
inline EdgeIndex
|
||||
get(const csr_edge_index_map<Vertex, EdgeIndex>&,
|
||||
const csr_edge_descriptor<Vertex, EdgeIndex>& key)
|
||||
{
|
||||
return key.idx;
|
||||
}
|
||||
|
||||
/** Compressed sparse row graph internal structure.
|
||||
*
|
||||
* Vertex and EdgeIndex should be unsigned integral types and should
|
||||
* specialize numeric_limits.
|
||||
*/
|
||||
template <typename EdgeProperty,
|
||||
typename Vertex = std::size_t, typename EdgeIndex = Vertex>
|
||||
class compressed_sparse_row_structure :
|
||||
public detail::indexed_edge_properties<
|
||||
compressed_sparse_row_structure<EdgeProperty, Vertex, EdgeIndex>,
|
||||
EdgeProperty,
|
||||
csr_edge_descriptor<Vertex, EdgeIndex>,
|
||||
csr_edge_index_map<Vertex, EdgeIndex> > {
|
||||
public:
|
||||
typedef detail::indexed_edge_properties<
|
||||
compressed_sparse_row_structure<EdgeProperty, Vertex, EdgeIndex>,
|
||||
EdgeProperty,
|
||||
csr_edge_descriptor<Vertex, EdgeIndex>,
|
||||
csr_edge_index_map<Vertex, EdgeIndex> >
|
||||
inherited_edge_properties;
|
||||
|
||||
typedef Vertex vertices_size_type;
|
||||
typedef Vertex vertex_descriptor;
|
||||
typedef EdgeIndex edges_size_type;
|
||||
|
||||
static vertex_descriptor null_vertex() { return vertex_descriptor(-1); }
|
||||
|
||||
std::vector<EdgeIndex> m_rowstart;
|
||||
std::vector<Vertex> m_column;
|
||||
|
||||
compressed_sparse_row_structure(Vertex numverts = 0)
|
||||
: m_rowstart(numverts + 1, EdgeIndex(0)), m_column()
|
||||
{}
|
||||
|
||||
// Rebuild graph from number of vertices and multi-pass unsorted list of
|
||||
// edges (filtered using source_pred and mapped using global_to_local)
|
||||
template <typename MultiPassInputIterator, typename GlobalToLocal, typename SourcePred>
|
||||
void
|
||||
assign_unsorted_multi_pass_edges(MultiPassInputIterator edge_begin,
|
||||
MultiPassInputIterator edge_end,
|
||||
vertices_size_type numlocalverts,
|
||||
const GlobalToLocal& global_to_local,
|
||||
const SourcePred& source_pred) {
|
||||
m_rowstart.clear();
|
||||
m_rowstart.resize(numlocalverts + 1, 0);
|
||||
typedef std::pair<vertices_size_type, vertices_size_type> edge_type;
|
||||
typedef boost::transform_iterator<boost::graph::detail::project1st<edge_type>, MultiPassInputIterator> source_iterator;
|
||||
typedef boost::transform_iterator<boost::graph::detail::project2nd<edge_type>, MultiPassInputIterator> target_iterator;
|
||||
source_iterator sources_begin(edge_begin, boost::graph::detail::project1st<edge_type>());
|
||||
source_iterator sources_end(edge_end, boost::graph::detail::project1st<edge_type>());
|
||||
target_iterator targets_begin(edge_begin, boost::graph::detail::project2nd<edge_type>());
|
||||
target_iterator targets_end(edge_end, boost::graph::detail::project2nd<edge_type>());
|
||||
|
||||
boost::graph::detail::count_starts
|
||||
(sources_begin, sources_end, m_rowstart.begin(), numlocalverts,
|
||||
source_pred, boost::make_property_map_function(global_to_local));
|
||||
|
||||
m_column.resize(m_rowstart.back());
|
||||
inherited_edge_properties::resize(m_rowstart.back());
|
||||
|
||||
boost::graph::detail::histogram_sort
|
||||
(sources_begin, sources_end, m_rowstart.begin(), numlocalverts,
|
||||
targets_begin, m_column.begin(),
|
||||
source_pred, boost::make_property_map_function(global_to_local));
|
||||
}
|
||||
|
||||
// Rebuild graph from number of vertices and multi-pass unsorted list of
|
||||
// edges and their properties (filtered using source_pred and mapped using
|
||||
// global_to_local)
|
||||
template <typename MultiPassInputIterator, typename EdgePropertyIterator, typename GlobalToLocal, typename SourcePred>
|
||||
void
|
||||
assign_unsorted_multi_pass_edges(MultiPassInputIterator edge_begin,
|
||||
MultiPassInputIterator edge_end,
|
||||
EdgePropertyIterator ep_iter,
|
||||
vertices_size_type numlocalverts,
|
||||
const GlobalToLocal& global_to_local,
|
||||
const SourcePred& source_pred) {
|
||||
m_rowstart.clear();
|
||||
m_rowstart.resize(numlocalverts + 1, 0);
|
||||
typedef std::pair<vertices_size_type, vertices_size_type> edge_type;
|
||||
typedef boost::transform_iterator<boost::graph::detail::project1st<edge_type>, MultiPassInputIterator> source_iterator;
|
||||
typedef boost::transform_iterator<boost::graph::detail::project2nd<edge_type>, MultiPassInputIterator> target_iterator;
|
||||
source_iterator sources_begin(edge_begin, boost::graph::detail::project1st<edge_type>());
|
||||
source_iterator sources_end(edge_end, boost::graph::detail::project1st<edge_type>());
|
||||
target_iterator targets_begin(edge_begin, boost::graph::detail::project2nd<edge_type>());
|
||||
target_iterator targets_end(edge_end, boost::graph::detail::project2nd<edge_type>());
|
||||
|
||||
boost::graph::detail::count_starts
|
||||
(sources_begin, sources_end, m_rowstart.begin(), numlocalverts,
|
||||
source_pred, boost::make_property_map_function(global_to_local));
|
||||
|
||||
m_column.resize(m_rowstart.back());
|
||||
inherited_edge_properties::resize(m_rowstart.back());
|
||||
|
||||
boost::graph::detail::histogram_sort
|
||||
(sources_begin, sources_end, m_rowstart.begin(), numlocalverts,
|
||||
targets_begin, m_column.begin(),
|
||||
ep_iter, inherited_edge_properties::begin(),
|
||||
source_pred, boost::make_property_map_function(global_to_local));
|
||||
}
|
||||
|
||||
// Assign from number of vertices and sorted list of edges
|
||||
template<typename InputIterator, typename GlobalToLocal, typename SourcePred>
|
||||
void assign_from_sorted_edges(
|
||||
InputIterator edge_begin, InputIterator edge_end,
|
||||
const GlobalToLocal& global_to_local,
|
||||
const SourcePred& source_pred,
|
||||
vertices_size_type numlocalverts,
|
||||
edges_size_type numedges_or_zero) {
|
||||
m_column.clear();
|
||||
m_column.reserve(numedges_or_zero);
|
||||
m_rowstart.resize(numlocalverts + 1);
|
||||
EdgeIndex current_edge = 0;
|
||||
Vertex current_vertex_plus_one = 1;
|
||||
m_rowstart[0] = 0;
|
||||
for (InputIterator ei = edge_begin; ei != edge_end; ++ei) {
|
||||
if (!source_pred(ei->first)) continue;
|
||||
Vertex src = get(global_to_local, ei->first);
|
||||
Vertex tgt = ei->second;
|
||||
for (; current_vertex_plus_one != src + 1; ++current_vertex_plus_one)
|
||||
m_rowstart[current_vertex_plus_one] = current_edge;
|
||||
m_column.push_back(tgt);
|
||||
++current_edge;
|
||||
}
|
||||
|
||||
// The remaining vertices have no edges
|
||||
for (; current_vertex_plus_one != numlocalverts + 1; ++current_vertex_plus_one)
|
||||
m_rowstart[current_vertex_plus_one] = current_edge;
|
||||
|
||||
// Default-construct properties for edges
|
||||
inherited_edge_properties::resize(m_column.size());
|
||||
}
|
||||
|
||||
// Assign from number of vertices and sorted list of edges
|
||||
template<typename InputIterator, typename EdgePropertyIterator, typename GlobalToLocal, typename SourcePred>
|
||||
void assign_from_sorted_edges(
|
||||
InputIterator edge_begin, InputIterator edge_end,
|
||||
EdgePropertyIterator ep_iter,
|
||||
const GlobalToLocal& global_to_local,
|
||||
const SourcePred& source_pred,
|
||||
vertices_size_type numlocalverts,
|
||||
edges_size_type numedges_or_zero) {
|
||||
// Reserving storage in advance can save us lots of time and
|
||||
// memory, but it can only be done if we have forward iterators or
|
||||
// the user has supplied the number of edges.
|
||||
edges_size_type numedges = numedges_or_zero;
|
||||
if (numedges == 0) {
|
||||
typedef typename std::iterator_traits<InputIterator>::iterator_category
|
||||
category;
|
||||
numedges = boost::graph::detail::reserve_count_for_single_pass(edge_begin, edge_end);
|
||||
}
|
||||
m_column.clear();
|
||||
m_column.reserve(numedges_or_zero);
|
||||
inherited_edge_properties::clear();
|
||||
inherited_edge_properties::reserve(numedges_or_zero);
|
||||
m_rowstart.resize(numlocalverts + 1);
|
||||
EdgeIndex current_edge = 0;
|
||||
Vertex current_vertex_plus_one = 1;
|
||||
m_rowstart[0] = 0;
|
||||
for (InputIterator ei = edge_begin; ei != edge_end; ++ei, ++ep_iter) {
|
||||
if (!source_pred(ei->first)) continue;
|
||||
Vertex src = get(global_to_local, ei->first);
|
||||
Vertex tgt = ei->second;
|
||||
for (; current_vertex_plus_one != src + 1; ++current_vertex_plus_one)
|
||||
m_rowstart[current_vertex_plus_one] = current_edge;
|
||||
m_column.push_back(tgt);
|
||||
inherited_edge_properties::push_back(*ep_iter);
|
||||
++current_edge;
|
||||
}
|
||||
|
||||
// The remaining vertices have no edges
|
||||
for (; current_vertex_plus_one != numlocalverts + 1; ++current_vertex_plus_one)
|
||||
m_rowstart[current_vertex_plus_one] = current_edge;
|
||||
}
|
||||
|
||||
// Replace graph with sources and targets given, sorting them in-place, and
|
||||
// using the given global-to-local property map to get local indices from
|
||||
// global ones in the two arrays.
|
||||
template <typename GlobalToLocal>
|
||||
void assign_sources_and_targets_global(std::vector<vertex_descriptor>& sources,
|
||||
std::vector<vertex_descriptor>& targets,
|
||||
vertices_size_type numverts,
|
||||
GlobalToLocal global_to_local) {
|
||||
BOOST_ASSERT (sources.size() == targets.size());
|
||||
// Do an in-place histogram sort (at least that's what I think it is) to
|
||||
// sort sources and targets
|
||||
m_rowstart.clear();
|
||||
m_rowstart.resize(numverts + 1);
|
||||
boost::graph::detail::count_starts
|
||||
(sources.begin(), sources.end(), m_rowstart.begin(), numverts,
|
||||
keep_all(), boost::make_property_map_function(global_to_local));
|
||||
boost::graph::detail::histogram_sort_inplace
|
||||
(sources.begin(), m_rowstart.begin(), numverts,
|
||||
targets.begin(), boost::make_property_map_function(global_to_local));
|
||||
// Now targets is the correct vector (properly sorted by source) for
|
||||
// m_column
|
||||
m_column.swap(targets);
|
||||
inherited_edge_properties::resize(m_rowstart.back());
|
||||
}
|
||||
|
||||
// Replace graph with sources and targets and edge properties given, sorting
|
||||
// them in-place, and using the given global-to-local property map to get
|
||||
// local indices from global ones in the two arrays.
|
||||
template <typename GlobalToLocal>
|
||||
void assign_sources_and_targets_global(std::vector<vertex_descriptor>& sources,
|
||||
std::vector<vertex_descriptor>& targets,
|
||||
std::vector<typename inherited_edge_properties::edge_bundled>& edge_props,
|
||||
vertices_size_type numverts,
|
||||
GlobalToLocal global_to_local) {
|
||||
BOOST_ASSERT (sources.size() == targets.size());
|
||||
BOOST_ASSERT (sources.size() == edge_props.size());
|
||||
// Do an in-place histogram sort (at least that's what I think it is) to
|
||||
// sort sources and targets
|
||||
m_rowstart.clear();
|
||||
m_rowstart.resize(numverts + 1);
|
||||
boost::graph::detail::count_starts
|
||||
(sources.begin(), sources.end(), m_rowstart.begin(), numverts,
|
||||
keep_all(), boost::make_property_map_function(global_to_local));
|
||||
boost::graph::detail::histogram_sort_inplace
|
||||
(sources.begin(), m_rowstart.begin(), numverts,
|
||||
targets.begin(), edge_props.begin(),
|
||||
boost::make_property_map_function(global_to_local));
|
||||
// Now targets is the correct vector (properly sorted by source) for
|
||||
// m_column, and edge_props for m_edge_properties
|
||||
m_column.swap(targets);
|
||||
this->m_edge_properties.swap(edge_props);
|
||||
}
|
||||
|
||||
// From any graph (slow and uses a lot of memory)
|
||||
// Requires IncidenceGraph and a vertex index map
|
||||
// Internal helper function
|
||||
// Note that numedges must be doubled for undirected source graphs
|
||||
template<typename Graph, typename VertexIndexMap>
|
||||
void
|
||||
assign(const Graph& g, const VertexIndexMap& vi,
|
||||
vertices_size_type numverts, edges_size_type numedges)
|
||||
{
|
||||
m_rowstart.resize(numverts + 1);
|
||||
m_column.resize(numedges);
|
||||
inherited_edge_properties::resize(numedges);
|
||||
EdgeIndex current_edge = 0;
|
||||
typedef typename boost::graph_traits<Graph>::vertex_descriptor g_vertex;
|
||||
typedef typename boost::graph_traits<Graph>::edge_descriptor g_edge;
|
||||
typedef typename boost::graph_traits<Graph>::out_edge_iterator
|
||||
g_out_edge_iter;
|
||||
|
||||
std::vector<g_vertex> ordered_verts_of_g(numverts);
|
||||
BGL_FORALL_VERTICES_T(v, g, Graph) {
|
||||
ordered_verts_of_g[get(vertex_index, g, v)] = v;
|
||||
}
|
||||
for (Vertex i = 0; i != numverts; ++i) {
|
||||
m_rowstart[i] = current_edge;
|
||||
g_vertex v = ordered_verts_of_g[i];
|
||||
g_out_edge_iter ei, ei_end;
|
||||
for (boost::tie(ei, ei_end) = out_edges(v, g); ei != ei_end; ++ei) {
|
||||
m_column[current_edge++] = get(vi, target(*ei, g));
|
||||
}
|
||||
}
|
||||
m_rowstart[numverts] = current_edge;
|
||||
}
|
||||
|
||||
// Add edges from a sorted (smallest sources first) range of pairs and edge
|
||||
// properties
|
||||
template <typename BidirectionalIteratorOrig, typename EPIterOrig,
|
||||
typename GlobalToLocal>
|
||||
void
|
||||
add_edges_sorted_internal(
|
||||
BidirectionalIteratorOrig first_sorted,
|
||||
BidirectionalIteratorOrig last_sorted,
|
||||
EPIterOrig ep_iter_sorted,
|
||||
const GlobalToLocal& global_to_local) {
|
||||
typedef boost::reverse_iterator<BidirectionalIteratorOrig> BidirectionalIterator;
|
||||
typedef boost::reverse_iterator<EPIterOrig> EPIter;
|
||||
// Flip sequence
|
||||
BidirectionalIterator first(last_sorted);
|
||||
BidirectionalIterator last(first_sorted);
|
||||
typedef Vertex vertex_t;
|
||||
typedef Vertex vertex_num;
|
||||
typedef EdgeIndex edge_num;
|
||||
edge_num new_edge_count = std::distance(first, last);
|
||||
|
||||
EPIter ep_iter(ep_iter_sorted);
|
||||
std::advance(ep_iter, -(std::ptrdiff_t)new_edge_count);
|
||||
edge_num edges_added_before_i = new_edge_count; // Count increment to add to rowstarts
|
||||
m_column.resize(m_column.size() + new_edge_count);
|
||||
inherited_edge_properties::resize(inherited_edge_properties::size() + new_edge_count);
|
||||
BidirectionalIterator current_new_edge = first, prev_new_edge = first;
|
||||
EPIter current_new_edge_prop = ep_iter;
|
||||
for (vertex_num i_plus_1 = m_rowstart.size() - 1; i_plus_1 > 0; --i_plus_1) {
|
||||
vertex_num i = i_plus_1 - 1;
|
||||
prev_new_edge = current_new_edge;
|
||||
// edges_added_to_this_vertex = #mbrs of new_edges with first == i
|
||||
edge_num edges_added_to_this_vertex = 0;
|
||||
while (current_new_edge != last) {
|
||||
if (get(global_to_local, current_new_edge->first) != i) break;
|
||||
++current_new_edge;
|
||||
++current_new_edge_prop;
|
||||
++edges_added_to_this_vertex;
|
||||
}
|
||||
edges_added_before_i -= edges_added_to_this_vertex;
|
||||
// Invariant: edges_added_before_i = #mbrs of new_edges with first < i
|
||||
edge_num old_rowstart = m_rowstart[i];
|
||||
edge_num new_rowstart = m_rowstart[i] + edges_added_before_i;
|
||||
edge_num old_degree = m_rowstart[i + 1] - m_rowstart[i];
|
||||
edge_num new_degree = old_degree + edges_added_to_this_vertex;
|
||||
// Move old edges forward (by #new_edges before this i) to make room
|
||||
// new_rowstart > old_rowstart, so use copy_backwards
|
||||
if (old_rowstart != new_rowstart) {
|
||||
std::copy_backward(m_column.begin() + old_rowstart,
|
||||
m_column.begin() + old_rowstart + old_degree,
|
||||
m_column.begin() + new_rowstart + old_degree);
|
||||
inherited_edge_properties::move_range(old_rowstart, old_rowstart + old_degree, new_rowstart);
|
||||
}
|
||||
// Add new edges (reversed because current_new_edge is a
|
||||
// const_reverse_iterator)
|
||||
BidirectionalIterator temp = current_new_edge;
|
||||
EPIter temp_prop = current_new_edge_prop;
|
||||
for (; temp != prev_new_edge; ++old_degree) {
|
||||
--temp;
|
||||
--temp_prop;
|
||||
m_column[new_rowstart + old_degree] = temp->second;
|
||||
inherited_edge_properties::write_by_index(new_rowstart + old_degree, *temp_prop);
|
||||
}
|
||||
m_rowstart[i + 1] = new_rowstart + new_degree;
|
||||
if (edges_added_before_i == 0) break; // No more edges inserted before this point
|
||||
// m_rowstart[i] will be fixed up on the next iteration (to avoid
|
||||
// changing the degree of vertex i - 1); the last iteration never changes
|
||||
// it (either because of the condition of the break or because
|
||||
// m_rowstart[0] is always 0)
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename Vertex, typename EdgeIndex>
|
||||
class csr_edge_descriptor
|
||||
{
|
||||
public:
|
||||
Vertex src;
|
||||
EdgeIndex idx;
|
||||
|
||||
csr_edge_descriptor(Vertex src, EdgeIndex idx): src(src), idx(idx) {}
|
||||
csr_edge_descriptor(): src(0), idx(0) {}
|
||||
|
||||
bool operator==(const csr_edge_descriptor& e) const {return idx == e.idx;}
|
||||
bool operator!=(const csr_edge_descriptor& e) const {return idx != e.idx;}
|
||||
bool operator<(const csr_edge_descriptor& e) const {return idx < e.idx;}
|
||||
bool operator>(const csr_edge_descriptor& e) const {return idx > e.idx;}
|
||||
bool operator<=(const csr_edge_descriptor& e) const {return idx <= e.idx;}
|
||||
bool operator>=(const csr_edge_descriptor& e) const {return idx >= e.idx;}
|
||||
|
||||
template<typename Archiver>
|
||||
void serialize(Archiver& ar, const unsigned int /*version*/)
|
||||
{
|
||||
ar & src & idx;
|
||||
}
|
||||
};
|
||||
|
||||
// Common out edge and edge iterators
|
||||
template<typename CSRGraph>
|
||||
class csr_out_edge_iterator
|
||||
: public iterator_facade<csr_out_edge_iterator<CSRGraph>,
|
||||
typename CSRGraph::edge_descriptor,
|
||||
std::random_access_iterator_tag,
|
||||
const typename CSRGraph::edge_descriptor&,
|
||||
typename int_t<CHAR_BIT * sizeof(typename CSRGraph::edges_size_type)>::fast>
|
||||
{
|
||||
public:
|
||||
typedef typename CSRGraph::edges_size_type EdgeIndex;
|
||||
typedef typename CSRGraph::edge_descriptor edge_descriptor;
|
||||
typedef typename int_t<CHAR_BIT * sizeof(EdgeIndex)>::fast difference_type;
|
||||
|
||||
csr_out_edge_iterator() {}
|
||||
// Implicit copy constructor OK
|
||||
explicit csr_out_edge_iterator(edge_descriptor edge) : m_edge(edge) { }
|
||||
|
||||
public: // GCC 4.2.1 doesn't like the private-and-friend thing
|
||||
// iterator_facade requirements
|
||||
const edge_descriptor& dereference() const { return m_edge; }
|
||||
|
||||
bool equal(const csr_out_edge_iterator& other) const
|
||||
{ return m_edge == other.m_edge; }
|
||||
|
||||
void increment() { ++m_edge.idx; }
|
||||
void decrement() { --m_edge.idx; }
|
||||
void advance(difference_type n) { m_edge.idx += n; }
|
||||
|
||||
difference_type distance_to(const csr_out_edge_iterator& other) const
|
||||
{ return other.m_edge.idx - m_edge.idx; }
|
||||
|
||||
edge_descriptor m_edge;
|
||||
|
||||
friend class iterator_core_access;
|
||||
};
|
||||
|
||||
template<typename CSRGraph>
|
||||
class csr_edge_iterator
|
||||
: public iterator_facade<csr_edge_iterator<CSRGraph>,
|
||||
typename CSRGraph::edge_descriptor,
|
||||
boost::forward_traversal_tag,
|
||||
typename CSRGraph::edge_descriptor>
|
||||
{
|
||||
private:
|
||||
typedef typename CSRGraph::edge_descriptor edge_descriptor;
|
||||
typedef typename CSRGraph::edges_size_type EdgeIndex;
|
||||
|
||||
public:
|
||||
csr_edge_iterator() : rowstart_array(0), current_edge(), end_of_this_vertex(0), total_num_edges(0) {}
|
||||
|
||||
csr_edge_iterator(const CSRGraph& graph,
|
||||
edge_descriptor current_edge,
|
||||
EdgeIndex end_of_this_vertex)
|
||||
: rowstart_array(&graph.m_forward.m_rowstart[0]),
|
||||
current_edge(current_edge),
|
||||
end_of_this_vertex(end_of_this_vertex),
|
||||
total_num_edges(num_edges(graph)) {}
|
||||
|
||||
public: // See above
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
edge_descriptor dereference() const {return current_edge;}
|
||||
|
||||
bool equal(const csr_edge_iterator& o) const {
|
||||
return current_edge == o.current_edge;
|
||||
}
|
||||
|
||||
void increment() {
|
||||
++current_edge.idx;
|
||||
if (current_edge.idx == total_num_edges) return;
|
||||
while (current_edge.idx == end_of_this_vertex) {
|
||||
++current_edge.src;
|
||||
end_of_this_vertex = rowstart_array[current_edge.src + 1];
|
||||
}
|
||||
}
|
||||
|
||||
const EdgeIndex* rowstart_array;
|
||||
edge_descriptor current_edge;
|
||||
EdgeIndex end_of_this_vertex;
|
||||
EdgeIndex total_num_edges;
|
||||
};
|
||||
|
||||
// Only for bidirectional graphs
|
||||
template<typename CSRGraph>
|
||||
class csr_in_edge_iterator
|
||||
: public iterator_facade<csr_in_edge_iterator<CSRGraph>,
|
||||
typename CSRGraph::edge_descriptor,
|
||||
boost::forward_traversal_tag,
|
||||
typename CSRGraph::edge_descriptor>
|
||||
{
|
||||
public:
|
||||
typedef typename CSRGraph::edges_size_type EdgeIndex;
|
||||
typedef typename CSRGraph::edge_descriptor edge_descriptor;
|
||||
|
||||
csr_in_edge_iterator(): m_graph(0) {}
|
||||
// Implicit copy constructor OK
|
||||
csr_in_edge_iterator(const CSRGraph& graph,
|
||||
EdgeIndex index_in_backward_graph)
|
||||
: m_index_in_backward_graph(index_in_backward_graph), m_graph(&graph) {}
|
||||
|
||||
public: // See above
|
||||
// iterator_facade requirements
|
||||
edge_descriptor dereference() const {
|
||||
return edge_descriptor(
|
||||
m_graph->m_backward.m_column[m_index_in_backward_graph],
|
||||
m_graph->m_backward.m_edge_properties[m_index_in_backward_graph]);
|
||||
}
|
||||
|
||||
bool equal(const csr_in_edge_iterator& other) const
|
||||
{ return m_index_in_backward_graph == other.m_index_in_backward_graph; }
|
||||
|
||||
void increment() { ++m_index_in_backward_graph; }
|
||||
void decrement() { --m_index_in_backward_graph; }
|
||||
void advance(std::ptrdiff_t n) { m_index_in_backward_graph += n; }
|
||||
|
||||
std::ptrdiff_t distance_to(const csr_in_edge_iterator& other) const
|
||||
{ return other.m_index_in_backward_graph - m_index_in_backward_graph; }
|
||||
|
||||
EdgeIndex m_index_in_backward_graph;
|
||||
const CSRGraph* m_graph;
|
||||
|
||||
friend class iterator_core_access;
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
struct transpose_pair {
|
||||
typedef std::pair<B, A> result_type;
|
||||
result_type operator()(const std::pair<A, B>& p) const {
|
||||
return result_type(p.second, p.first);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iter>
|
||||
struct transpose_iterator_gen {
|
||||
typedef typename std::iterator_traits<Iter>::value_type vt;
|
||||
typedef typename vt::first_type first_type;
|
||||
typedef typename vt::second_type second_type;
|
||||
typedef transpose_pair<first_type, second_type> transpose;
|
||||
typedef boost::transform_iterator<transpose, Iter> type;
|
||||
static type make(Iter it) {
|
||||
return type(it, transpose());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iter>
|
||||
typename transpose_iterator_gen<Iter>::type transpose_edges(Iter i) {
|
||||
return transpose_iterator_gen<Iter>::make(i);
|
||||
}
|
||||
|
||||
template<typename GraphT, typename VertexIndexMap>
|
||||
class edge_to_index_pair
|
||||
{
|
||||
typedef typename boost::graph_traits<GraphT>::vertices_size_type
|
||||
vertices_size_type;
|
||||
typedef typename boost::graph_traits<GraphT>::edge_descriptor edge_descriptor;
|
||||
|
||||
public:
|
||||
typedef std::pair<vertices_size_type, vertices_size_type> result_type;
|
||||
|
||||
edge_to_index_pair() : g(0), index() { }
|
||||
edge_to_index_pair(const GraphT& g, const VertexIndexMap& index)
|
||||
: g(&g), index(index)
|
||||
{ }
|
||||
|
||||
result_type operator()(edge_descriptor e) const
|
||||
{
|
||||
return result_type(get(index, source(e, *g)), get(index, target(e, *g)));
|
||||
}
|
||||
|
||||
private:
|
||||
const GraphT* g;
|
||||
VertexIndexMap index;
|
||||
};
|
||||
|
||||
template<typename GraphT, typename VertexIndexMap>
|
||||
edge_to_index_pair<GraphT, VertexIndexMap>
|
||||
make_edge_to_index_pair(const GraphT& g, const VertexIndexMap& index)
|
||||
{
|
||||
return edge_to_index_pair<GraphT, VertexIndexMap>(g, index);
|
||||
}
|
||||
|
||||
template<typename GraphT>
|
||||
edge_to_index_pair
|
||||
<GraphT,
|
||||
typename boost::property_map<GraphT,boost::vertex_index_t>::const_type>
|
||||
make_edge_to_index_pair(const GraphT& g)
|
||||
{
|
||||
typedef typename boost::property_map<GraphT,
|
||||
boost::vertex_index_t>::const_type
|
||||
VertexIndexMap;
|
||||
return edge_to_index_pair<GraphT, VertexIndexMap>(g,
|
||||
get(boost::vertex_index,
|
||||
g));
|
||||
}
|
||||
|
||||
template<typename GraphT, typename VertexIndexMap, typename Iter>
|
||||
boost::transform_iterator<edge_to_index_pair<GraphT, VertexIndexMap>, Iter>
|
||||
make_edge_to_index_pair_iter(const GraphT& g, const VertexIndexMap& index,
|
||||
Iter it) {
|
||||
return boost::transform_iterator<edge_to_index_pair<GraphT, VertexIndexMap>, Iter>(it, edge_to_index_pair<GraphT, VertexIndexMap>(g, index));
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<typename Vertex, typename EdgeIndex>
|
||||
struct hash<detail::csr_edge_descriptor<Vertex, EdgeIndex> >
|
||||
{
|
||||
std::size_t operator()
|
||||
(detail::csr_edge_descriptor<Vertex, EdgeIndex> const& x) const
|
||||
{
|
||||
std::size_t hash = hash_value(x.src);
|
||||
hash_combine(hash, x.idx);
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_GRAPH_COMPRESSED_SPARSE_ROW_STRUCT_HPP
|
||||
208
test/external/boost/graph/detail/connected_components.hpp
vendored
Normal file
208
test/external/boost/graph/detail/connected_components.hpp
vendored
Normal file
@@ -0,0 +1,208 @@
|
||||
//=======================================================================
|
||||
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
|
||||
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
|
||||
//
|
||||
// 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 BOOST_GRAPH_DETAIL_CONNECTED_COMPONENTS_HPP
|
||||
#define BOOST_GRAPH_DETAIL_CONNECTED_COMPONENTS_HPP
|
||||
|
||||
#if defined(__sgi) && !defined(__GNUC__)
|
||||
#pragma set woff 1234
|
||||
#endif
|
||||
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail {
|
||||
|
||||
//=========================================================================
|
||||
// Implementation details of connected_components
|
||||
|
||||
// This is used both in the connected_components algorithm and in
|
||||
// the kosaraju strong components algorithm during the second DFS
|
||||
// traversal.
|
||||
template <class ComponentsPA, class DFSVisitor>
|
||||
class components_recorder : public DFSVisitor
|
||||
{
|
||||
typedef typename property_traits<ComponentsPA>::value_type comp_type;
|
||||
public:
|
||||
components_recorder(ComponentsPA c,
|
||||
comp_type& c_count,
|
||||
DFSVisitor v)
|
||||
: DFSVisitor(v), m_component(c), m_count(c_count) {}
|
||||
|
||||
template <class Vertex, class Graph>
|
||||
void start_vertex(Vertex u, Graph& g) {
|
||||
++m_count;
|
||||
DFSVisitor::start_vertex(u, g);
|
||||
}
|
||||
template <class Vertex, class Graph>
|
||||
void discover_vertex(Vertex u, Graph& g) {
|
||||
put(m_component, u, m_count);
|
||||
DFSVisitor::discover_vertex(u, g);
|
||||
}
|
||||
protected:
|
||||
ComponentsPA m_component;
|
||||
comp_type& m_count;
|
||||
};
|
||||
|
||||
template <class DiscoverTimeMap, class FinishTimeMap, class TimeT,
|
||||
class DFSVisitor>
|
||||
class time_recorder : public DFSVisitor
|
||||
{
|
||||
public:
|
||||
time_recorder(DiscoverTimeMap d, FinishTimeMap f, TimeT& t, DFSVisitor v)
|
||||
: DFSVisitor(v), m_discover_time(d), m_finish_time(f), m_t(t) {}
|
||||
|
||||
template <class Vertex, class Graph>
|
||||
void discover_vertex(Vertex u, Graph& g) {
|
||||
put(m_discover_time, u, ++m_t);
|
||||
DFSVisitor::discover_vertex(u, g);
|
||||
}
|
||||
template <class Vertex, class Graph>
|
||||
void finish_vertex(Vertex u, Graph& g) {
|
||||
put(m_finish_time, u, ++m_t);
|
||||
DFSVisitor::discover_vertex(u, g);
|
||||
}
|
||||
protected:
|
||||
DiscoverTimeMap m_discover_time;
|
||||
FinishTimeMap m_finish_time;
|
||||
TimeT m_t;
|
||||
};
|
||||
template <class DiscoverTimeMap, class FinishTimeMap, class TimeT,
|
||||
class DFSVisitor>
|
||||
time_recorder<DiscoverTimeMap, FinishTimeMap, TimeT, DFSVisitor>
|
||||
record_times(DiscoverTimeMap d, FinishTimeMap f, TimeT& t, DFSVisitor vis)
|
||||
{
|
||||
return time_recorder<DiscoverTimeMap, FinishTimeMap, TimeT, DFSVisitor>
|
||||
(d, f, t, vis);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// Implementation detail of dynamic_components
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Helper functions for the component_index class
|
||||
|
||||
// Record the representative vertices in the header array.
|
||||
// Representative vertices now point to the component number.
|
||||
|
||||
template <class Parent, class OutputIterator, class Integer>
|
||||
inline void
|
||||
build_components_header(Parent p,
|
||||
OutputIterator header,
|
||||
Integer num_nodes)
|
||||
{
|
||||
Parent component = p;
|
||||
Integer component_num = 0;
|
||||
for (Integer v = 0; v != num_nodes; ++v)
|
||||
if (p[v] == v) {
|
||||
*header++ = v;
|
||||
component[v] = component_num++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Pushes x onto the front of the list. The list is represented in
|
||||
// an array.
|
||||
template <class Next, class T, class V>
|
||||
inline void push_front(Next next, T& head, V x)
|
||||
{
|
||||
T tmp = head;
|
||||
head = x;
|
||||
next[x] = tmp;
|
||||
}
|
||||
|
||||
|
||||
// Create a linked list of the vertices in each component
|
||||
// by reusing the representative array.
|
||||
template <class Parent1, class Parent2,
|
||||
class Integer>
|
||||
void
|
||||
link_components(Parent1 component, Parent2 header,
|
||||
Integer num_nodes, Integer num_components)
|
||||
{
|
||||
// Make the non-representative vertices point to their component
|
||||
Parent1 representative = component;
|
||||
for (Integer v = 0; v != num_nodes; ++v)
|
||||
if (component[v] >= num_components || header[component[v]] != v)
|
||||
component[v] = component[representative[v]];
|
||||
|
||||
// initialize the "head" of the lists to "NULL"
|
||||
std::fill_n(header, num_components, num_nodes);
|
||||
|
||||
// Add each vertex to the linked list for its component
|
||||
Parent1 next = component;
|
||||
for (Integer k = 0; k != num_nodes; ++k)
|
||||
push_front(next, header[component[k]], k);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class IndexContainer, class HeaderContainer>
|
||||
void
|
||||
construct_component_index(IndexContainer& index, HeaderContainer& header)
|
||||
{
|
||||
build_components_header(index.begin(),
|
||||
std::back_inserter(header),
|
||||
index.end() - index.begin());
|
||||
|
||||
link_components(index.begin(), header.begin(),
|
||||
index.end() - index.begin(),
|
||||
header.end() - header.begin());
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class IndexIterator, class Integer, class Distance>
|
||||
class component_iterator
|
||||
: boost::forward_iterator_helper<
|
||||
component_iterator<IndexIterator,Integer,Distance>,
|
||||
Integer, Distance,Integer*, Integer&>
|
||||
{
|
||||
public:
|
||||
typedef component_iterator self;
|
||||
|
||||
IndexIterator next;
|
||||
Integer node;
|
||||
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef Integer value_type;
|
||||
typedef Integer& reference;
|
||||
typedef Integer* pointer;
|
||||
typedef Distance difference_type;
|
||||
|
||||
component_iterator() {}
|
||||
component_iterator(IndexIterator x, Integer i)
|
||||
: next(x), node(i) {}
|
||||
Integer operator*() const {
|
||||
return node;
|
||||
}
|
||||
self& operator++() {
|
||||
node = next[node];
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
template <class IndexIterator, class Integer, class Distance>
|
||||
inline bool
|
||||
operator==(const component_iterator<IndexIterator, Integer, Distance>& x,
|
||||
const component_iterator<IndexIterator, Integer, Distance>& y)
|
||||
{
|
||||
return x.node == y.node;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if defined(__sgi) && !defined(__GNUC__)
|
||||
#pragma reset woff 1234
|
||||
#endif
|
||||
|
||||
#endif
|
||||
311
test/external/boost/graph/detail/d_ary_heap.hpp
vendored
Normal file
311
test/external/boost/graph/detail/d_ary_heap.hpp
vendored
Normal file
@@ -0,0 +1,311 @@
|
||||
//
|
||||
//=======================================================================
|
||||
// Copyright 2009 Trustees of Indiana University
|
||||
// Authors: Jeremiah J. Willcock, Andrew Lumsdaine
|
||||
//
|
||||
// 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 BOOST_D_ARY_HEAP_HPP
|
||||
#define BOOST_D_ARY_HEAP_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/shared_array.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
// Swap two elements in a property map without assuming they model
|
||||
// LvaluePropertyMap -- currently not used
|
||||
template <typename PropMap>
|
||||
inline void property_map_swap(
|
||||
PropMap prop_map,
|
||||
const typename boost::property_traits<PropMap>::key_type& ka,
|
||||
const typename boost::property_traits<PropMap>::key_type& kb) {
|
||||
typename boost::property_traits<PropMap>::value_type va = get(prop_map, ka);
|
||||
put(prop_map, ka, get(prop_map, kb));
|
||||
put(prop_map, kb, va);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template <typename Value>
|
||||
class fixed_max_size_vector {
|
||||
boost::shared_array<Value> m_data;
|
||||
std::size_t m_size;
|
||||
|
||||
public:
|
||||
typedef std::size_t size_type;
|
||||
fixed_max_size_vector(std::size_t max_size)
|
||||
: m_data(new Value[max_size]), m_size(0) {}
|
||||
std::size_t size() const {return m_size;}
|
||||
bool empty() const {return m_size == 0;}
|
||||
Value& operator[](std::size_t i) {return m_data[i];}
|
||||
const Value& operator[](std::size_t i) const {return m_data[i];}
|
||||
void push_back(Value v) {m_data[m_size++] = v;}
|
||||
void pop_back() {--m_size;}
|
||||
Value& back() {return m_data[m_size - 1];}
|
||||
const Value& back() const {return m_data[m_size - 1];}
|
||||
};
|
||||
}
|
||||
|
||||
// D-ary heap using an indirect compare operator (use identity_property_map
|
||||
// as DistanceMap to get a direct compare operator). This heap appears to be
|
||||
// commonly used for Dijkstra's algorithm for its good practical performance
|
||||
// on some platforms; asymptotically, it has an O(lg N) decrease-key
|
||||
// operation while that can be done in constant time on a relaxed heap. The
|
||||
// implementation is mostly based on the binary heap page on Wikipedia and
|
||||
// online sources that state that the operations are the same for d-ary
|
||||
// heaps. This code is not based on the old Boost d-ary heap code.
|
||||
//
|
||||
// - d_ary_heap_indirect is a model of UpdatableQueue as is needed for
|
||||
// dijkstra_shortest_paths.
|
||||
//
|
||||
// - Value must model Assignable.
|
||||
// - Arity must be at least 2 (optimal value appears to be 4, both in my and
|
||||
// third-party experiments).
|
||||
// - IndexInHeapMap must be a ReadWritePropertyMap from Value to
|
||||
// Container::size_type (to store the index of each stored value within the
|
||||
// heap for decrease-key aka update).
|
||||
// - DistanceMap must be a ReadablePropertyMap from Value to something
|
||||
// (typedef'ed as distance_type).
|
||||
// - Compare must be a BinaryPredicate used as a less-than operator on
|
||||
// distance_type.
|
||||
// - Container must be a random-access, contiguous container (in practice,
|
||||
// the operations used probably require that it is std::vector<Value>).
|
||||
//
|
||||
template <typename Value,
|
||||
std::size_t Arity,
|
||||
typename IndexInHeapPropertyMap,
|
||||
typename DistanceMap,
|
||||
typename Compare = std::less<Value>,
|
||||
typename Container = std::vector<Value> >
|
||||
class d_ary_heap_indirect {
|
||||
BOOST_STATIC_ASSERT (Arity >= 2);
|
||||
|
||||
public:
|
||||
typedef typename Container::size_type size_type;
|
||||
typedef Value value_type;
|
||||
typedef typename boost::property_traits<DistanceMap>::value_type key_type;
|
||||
typedef DistanceMap key_map;
|
||||
|
||||
d_ary_heap_indirect(DistanceMap distance,
|
||||
IndexInHeapPropertyMap index_in_heap,
|
||||
const Compare& compare = Compare(),
|
||||
const Container& data = Container())
|
||||
: compare(compare), data(data), distance(distance),
|
||||
index_in_heap(index_in_heap) {}
|
||||
/* Implicit copy constructor */
|
||||
/* Implicit assignment operator */
|
||||
|
||||
size_type size() const {
|
||||
return data.size();
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
return data.empty();
|
||||
}
|
||||
|
||||
void push(const Value& v) {
|
||||
size_type index = data.size();
|
||||
data.push_back(v);
|
||||
put(index_in_heap, v, index);
|
||||
preserve_heap_property_up(index);
|
||||
verify_heap();
|
||||
}
|
||||
|
||||
Value& top() {
|
||||
return data[0];
|
||||
}
|
||||
|
||||
const Value& top() const {
|
||||
return data[0];
|
||||
}
|
||||
|
||||
void pop() {
|
||||
put(index_in_heap, data[0], (size_type)(-1));
|
||||
if (data.size() != 1) {
|
||||
data[0] = data.back();
|
||||
put(index_in_heap, data[0], 0);
|
||||
data.pop_back();
|
||||
preserve_heap_property_down();
|
||||
verify_heap();
|
||||
} else {
|
||||
data.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
// This function assumes the key has been updated (using an external write
|
||||
// to the distance map or such)
|
||||
// See http://coding.derkeiler.com/Archive/General/comp.theory/2007-05/msg00043.html
|
||||
void update(const Value& v) { /* decrease-key */
|
||||
size_type index = get(index_in_heap, v);
|
||||
preserve_heap_property_up(index);
|
||||
verify_heap();
|
||||
}
|
||||
|
||||
bool contains(const Value& v) const {
|
||||
size_type index = get(index_in_heap, v);
|
||||
return (index != (size_type)(-1));
|
||||
}
|
||||
|
||||
void push_or_update(const Value& v) { /* insert if not present, else update */
|
||||
size_type index = get(index_in_heap, v);
|
||||
if (index == (size_type)(-1)) {
|
||||
index = data.size();
|
||||
data.push_back(v);
|
||||
put(index_in_heap, v, index);
|
||||
}
|
||||
preserve_heap_property_up(index);
|
||||
verify_heap();
|
||||
}
|
||||
|
||||
DistanceMap keys() const {
|
||||
return distance;
|
||||
}
|
||||
|
||||
private:
|
||||
Compare compare;
|
||||
Container data;
|
||||
DistanceMap distance;
|
||||
IndexInHeapPropertyMap index_in_heap;
|
||||
|
||||
// The distances being compared using compare and that are stored in the
|
||||
// distance map
|
||||
typedef typename boost::property_traits<DistanceMap>::value_type distance_type;
|
||||
|
||||
// Get the parent of a given node in the heap
|
||||
static size_type parent(size_type index) {
|
||||
return (index - 1) / Arity;
|
||||
}
|
||||
|
||||
// Get the child_idx'th child of a given node; 0 <= child_idx < Arity
|
||||
static size_type child(size_type index, std::size_t child_idx) {
|
||||
return index * Arity + child_idx + 1;
|
||||
}
|
||||
|
||||
// Swap two elements in the heap by index, updating index_in_heap
|
||||
void swap_heap_elements(size_type index_a, size_type index_b) {
|
||||
using std::swap;
|
||||
Value value_a = data[index_a];
|
||||
Value value_b = data[index_b];
|
||||
data[index_a] = value_b;
|
||||
data[index_b] = value_a;
|
||||
put(index_in_heap, value_a, index_b);
|
||||
put(index_in_heap, value_b, index_a);
|
||||
}
|
||||
|
||||
// Emulate the indirect_cmp that is now folded into this heap class
|
||||
bool compare_indirect(const Value& a, const Value& b) const {
|
||||
return compare(get(distance, a), get(distance, b));
|
||||
}
|
||||
|
||||
// Verify that the array forms a heap; commented out by default
|
||||
void verify_heap() const {
|
||||
// This is a very expensive test so it should be disabled even when
|
||||
// NDEBUG is not defined
|
||||
#if 0
|
||||
for (size_t i = 1; i < data.size(); ++i) {
|
||||
if (compare_indirect(data[i], data[parent(i)])) {
|
||||
BOOST_ASSERT (!"Element is smaller than its parent");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Starting at a node, move up the tree swapping elements to preserve the
|
||||
// heap property
|
||||
void preserve_heap_property_up(size_type index) {
|
||||
size_type orig_index = index;
|
||||
size_type num_levels_moved = 0;
|
||||
// The first loop just saves swaps that need to be done in order to avoid
|
||||
// aliasing issues in its search; there is a second loop that does the
|
||||
// necessary swap operations
|
||||
if (index == 0) return; // Do nothing on root
|
||||
Value currently_being_moved = data[index];
|
||||
distance_type currently_being_moved_dist =
|
||||
get(distance, currently_being_moved);
|
||||
for (;;) {
|
||||
if (index == 0) break; // Stop at root
|
||||
size_type parent_index = parent(index);
|
||||
Value parent_value = data[parent_index];
|
||||
if (compare(currently_being_moved_dist, get(distance, parent_value))) {
|
||||
++num_levels_moved;
|
||||
index = parent_index;
|
||||
continue;
|
||||
} else {
|
||||
break; // Heap property satisfied
|
||||
}
|
||||
}
|
||||
// Actually do the moves -- move num_levels_moved elements down in the
|
||||
// tree, then put currently_being_moved at the top
|
||||
index = orig_index;
|
||||
for (size_type i = 0; i < num_levels_moved; ++i) {
|
||||
size_type parent_index = parent(index);
|
||||
Value parent_value = data[parent_index];
|
||||
put(index_in_heap, parent_value, index);
|
||||
data[index] = parent_value;
|
||||
index = parent_index;
|
||||
}
|
||||
data[index] = currently_being_moved;
|
||||
put(index_in_heap, currently_being_moved, index);
|
||||
verify_heap();
|
||||
}
|
||||
|
||||
// From the root, swap elements (each one with its smallest child) if there
|
||||
// are any parent-child pairs that violate the heap property
|
||||
void preserve_heap_property_down() {
|
||||
if (data.empty()) return;
|
||||
size_type index = 0;
|
||||
Value currently_being_moved = data[0];
|
||||
distance_type currently_being_moved_dist =
|
||||
get(distance, currently_being_moved);
|
||||
size_type heap_size = data.size();
|
||||
Value* data_ptr = &data[0];
|
||||
for (;;) {
|
||||
size_type first_child_index = child(index, 0);
|
||||
if (first_child_index >= heap_size) break; /* No children */
|
||||
Value* child_base_ptr = data_ptr + first_child_index;
|
||||
size_type smallest_child_index = 0;
|
||||
distance_type smallest_child_dist = get(distance, child_base_ptr[smallest_child_index]);
|
||||
if (first_child_index + Arity <= heap_size) {
|
||||
// Special case for a statically known loop count (common case)
|
||||
for (size_t i = 1; i < Arity; ++i) {
|
||||
Value i_value = child_base_ptr[i];
|
||||
distance_type i_dist = get(distance, i_value);
|
||||
if (compare(i_dist, smallest_child_dist)) {
|
||||
smallest_child_index = i;
|
||||
smallest_child_dist = i_dist;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (size_t i = 1; i < heap_size - first_child_index; ++i) {
|
||||
distance_type i_dist = get(distance, child_base_ptr[i]);
|
||||
if (compare(i_dist, smallest_child_dist)) {
|
||||
smallest_child_index = i;
|
||||
smallest_child_dist = i_dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (compare(smallest_child_dist, currently_being_moved_dist)) {
|
||||
swap_heap_elements(smallest_child_index + first_child_index, index);
|
||||
index = smallest_child_index + first_child_index;
|
||||
continue;
|
||||
} else {
|
||||
break; // Heap property satisfied
|
||||
}
|
||||
}
|
||||
verify_heap();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_D_ARY_HEAP_HPP
|
||||
124
test/external/boost/graph/detail/edge.hpp
vendored
Normal file
124
test/external/boost/graph/detail/edge.hpp
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
//
|
||||
//=======================================================================
|
||||
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
|
||||
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
|
||||
//
|
||||
// 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 BOOST_GRAPH_DETAIL_EDGE_HPP
|
||||
#define BOOST_GRAPH_DETAIL_EDGE_HPP
|
||||
|
||||
#if __GNUC__ < 3
|
||||
#include <iostream>
|
||||
#else
|
||||
#include <iosfwd>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Directed, typename Vertex>
|
||||
struct edge_base
|
||||
{
|
||||
inline edge_base() {}
|
||||
inline edge_base(Vertex s, Vertex d)
|
||||
: m_source(s), m_target(d) { }
|
||||
Vertex m_source;
|
||||
Vertex m_target;
|
||||
};
|
||||
|
||||
template <typename Directed, typename Vertex>
|
||||
class edge_desc_impl : public edge_base<Directed,Vertex> {
|
||||
typedef edge_desc_impl self;
|
||||
typedef edge_base<Directed,Vertex> Base;
|
||||
public:
|
||||
typedef void property_type;
|
||||
|
||||
inline edge_desc_impl() : m_eproperty(0) {}
|
||||
|
||||
inline edge_desc_impl(Vertex s, Vertex d, const property_type* eplug)
|
||||
: Base(s,d), m_eproperty(const_cast<property_type*>(eplug)) { }
|
||||
|
||||
property_type* get_property() { return m_eproperty; }
|
||||
const property_type* get_property() const { return m_eproperty; }
|
||||
|
||||
// protected:
|
||||
property_type* m_eproperty;
|
||||
};
|
||||
|
||||
template <class D, class V>
|
||||
inline bool
|
||||
operator==(const detail::edge_desc_impl<D,V>& a,
|
||||
const detail::edge_desc_impl<D,V>& b)
|
||||
{
|
||||
return a.get_property() == b.get_property();
|
||||
}
|
||||
template <class D, class V>
|
||||
inline bool
|
||||
operator!=(const detail::edge_desc_impl<D,V>& a,
|
||||
const detail::edge_desc_impl<D,V>& b)
|
||||
{
|
||||
return ! (a.get_property() == b.get_property());
|
||||
}
|
||||
|
||||
// Order edges according to the address of their property object
|
||||
template <class D, class V>
|
||||
inline bool
|
||||
operator<(const detail::edge_desc_impl<D,V>& a,
|
||||
const detail::edge_desc_impl<D,V>& b)
|
||||
{
|
||||
return a.get_property() < b.get_property();
|
||||
}
|
||||
template <class D, class V>
|
||||
inline bool
|
||||
operator<=(const detail::edge_desc_impl<D,V>& a,
|
||||
const detail::edge_desc_impl<D,V>& b)
|
||||
{
|
||||
return a.get_property() <= b.get_property();
|
||||
}
|
||||
template <class D, class V>
|
||||
inline bool
|
||||
operator>(const detail::edge_desc_impl<D,V>& a,
|
||||
const detail::edge_desc_impl<D,V>& b)
|
||||
{
|
||||
return a.get_property() > b.get_property();
|
||||
}
|
||||
template <class D, class V>
|
||||
inline bool
|
||||
operator>=(const detail::edge_desc_impl<D,V>& a,
|
||||
const detail::edge_desc_impl<D,V>& b)
|
||||
{
|
||||
return a.get_property() >= b.get_property();
|
||||
}
|
||||
|
||||
} //namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
namespace std {
|
||||
|
||||
#if __GNUC__ < 3
|
||||
template <class D, class V>
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const boost::detail::edge_desc_impl<D,V>& e)
|
||||
{
|
||||
return os << "(" << e.m_source << "," << e.m_target << ")";
|
||||
}
|
||||
#else
|
||||
template <class Char, class Traits, class D, class V>
|
||||
std::basic_ostream<Char, Traits>&
|
||||
operator<<(std::basic_ostream<Char, Traits>& os,
|
||||
const boost::detail::edge_desc_impl<D,V>& e)
|
||||
{
|
||||
return os << "(" << e.m_source << "," << e.m_target << ")";
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // BOOST_GRAPH_DETAIL_DETAIL_EDGE_HPP
|
||||
130
test/external/boost/graph/detail/geodesic.hpp
vendored
Normal file
130
test/external/boost/graph/detail/geodesic.hpp
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
// (C) Copyright 2007 Andrew Sutton
|
||||
//
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0 (See accompanying file
|
||||
// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GRAPH_DETAIL_GEODESIC_HPP
|
||||
#define BOOST_GRAPH_DETAIL_GEODESIC_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/graph/graph_concepts.hpp>
|
||||
#include <boost/graph/numeric_values.hpp>
|
||||
|
||||
// TODO: Should this really be in detail?
|
||||
|
||||
namespace boost
|
||||
{
|
||||
// This is a very good discussion on centrality measures. While I can't
|
||||
// say that this has been the motivating factor for the design and
|
||||
// implementation of ths centrality framework, it does provide a single
|
||||
// point of reference for defining things like degree and closeness
|
||||
// centrality. Plus, the bibliography seems fairly complete.
|
||||
//
|
||||
// @article{citeulike:1144245,
|
||||
// author = {Borgatti, Stephen P. and Everett, Martin G.},
|
||||
// citeulike-article-id = {1144245},
|
||||
// doi = {10.1016/j.socnet.2005.11.005},
|
||||
// journal = {Social Networks},
|
||||
// month = {October},
|
||||
// number = {4},
|
||||
// pages = {466--484},
|
||||
// priority = {0},
|
||||
// title = {A Graph-theoretic perspective on centrality},
|
||||
// url = {http://dx.doi.org/10.1016/j.socnet.2005.11.005},
|
||||
// volume = {28},
|
||||
// year = {2006}
|
||||
// }
|
||||
// }
|
||||
|
||||
namespace detail {
|
||||
// Note that this assumes T == property_traits<DistanceMap>::value_type
|
||||
// and that the args and return of combine are also T.
|
||||
template <typename Graph,
|
||||
typename DistanceMap,
|
||||
typename Combinator,
|
||||
typename Distance>
|
||||
inline Distance
|
||||
combine_distances(const Graph& g,
|
||||
DistanceMap dist,
|
||||
Combinator combine,
|
||||
Distance init)
|
||||
{
|
||||
function_requires< VertexListGraphConcept<Graph> >();
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
|
||||
typedef typename graph_traits<Graph>::vertex_iterator VertexIterator;
|
||||
function_requires< ReadablePropertyMapConcept<DistanceMap,Vertex> >();
|
||||
function_requires< NumericValueConcept<Distance> >();
|
||||
typedef numeric_values<Distance> DistanceNumbers;
|
||||
function_requires< AdaptableBinaryFunction<Combinator,Distance,Distance,Distance> >();
|
||||
|
||||
// If there's ever an infinite distance, then we simply return
|
||||
// infinity. Note that this /will/ include the a non-zero
|
||||
// distance-to-self in the combined values. However, this is usually
|
||||
// zero, so it shouldn't be too problematic.
|
||||
Distance ret = init;
|
||||
VertexIterator i, end;
|
||||
for(boost::tie(i, end) = vertices(g); i != end; ++i) {
|
||||
Vertex v = *i;
|
||||
if(get(dist, v) != DistanceNumbers::infinity()) {
|
||||
ret = combine(ret, get(dist, v));
|
||||
}
|
||||
else {
|
||||
ret = DistanceNumbers::infinity();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Similar to std::plus<T>, but maximizes parameters
|
||||
// rather than adding them.
|
||||
template <typename T>
|
||||
struct maximize : public std::binary_function<T, T, T>
|
||||
{
|
||||
T operator ()(T x, T y) const
|
||||
{ BOOST_USING_STD_MAX(); return max BOOST_PREVENT_MACRO_SUBSTITUTION (x, y); }
|
||||
};
|
||||
|
||||
// Another helper, like maximize() to help abstract functional
|
||||
// concepts. This is trivially instantiated for builtin numeric
|
||||
// types, but should be specialized for those types that have
|
||||
// discrete notions of reciprocals.
|
||||
template <typename T>
|
||||
struct reciprocal : public std::unary_function<T, T>
|
||||
{
|
||||
typedef std::unary_function<T, T> function_type;
|
||||
typedef typename function_type::result_type result_type;
|
||||
typedef typename function_type::argument_type argument_type;
|
||||
T operator ()(T t)
|
||||
{ return T(1) / t; }
|
||||
};
|
||||
} /* namespace detail */
|
||||
|
||||
// This type defines the basic facilities used for computing values
|
||||
// based on the geodesic distances between vertices. Examples include
|
||||
// closeness centrality and mean geodesic distance.
|
||||
template <typename Graph, typename DistanceType, typename ResultType>
|
||||
struct geodesic_measure
|
||||
{
|
||||
typedef DistanceType distance_type;
|
||||
typedef ResultType result_type;
|
||||
typedef typename graph_traits<Graph>::vertices_size_type size_type;
|
||||
|
||||
typedef numeric_values<distance_type> distance_values;
|
||||
typedef numeric_values<result_type> result_values;
|
||||
|
||||
static inline distance_type infinite_distance()
|
||||
{ return distance_values::infinity(); }
|
||||
|
||||
static inline result_type infinite_result()
|
||||
{ return result_values::infinity(); }
|
||||
|
||||
static inline result_type zero_result()
|
||||
{ return result_values::zero(); }
|
||||
};
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#endif
|
||||
288
test/external/boost/graph/detail/histogram_sort.hpp
vendored
Normal file
288
test/external/boost/graph/detail/histogram_sort.hpp
vendored
Normal file
@@ -0,0 +1,288 @@
|
||||
// Copyright 2009 The Trustees of Indiana University.
|
||||
|
||||
// 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)
|
||||
|
||||
// Authors: Jeremiah Willcock
|
||||
// Andrew Lumsdaine
|
||||
|
||||
#ifndef BOOST_GRAPH_DETAIL_HISTOGRAM_SORT_HPP
|
||||
#define BOOST_GRAPH_DETAIL_HISTOGRAM_SORT_HPP
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace graph {
|
||||
namespace detail {
|
||||
|
||||
template<typename InputIterator>
|
||||
size_t
|
||||
reserve_count_for_single_pass_helper(InputIterator, InputIterator,
|
||||
std::input_iterator_tag)
|
||||
{
|
||||
// Do nothing: we have no idea how much storage to reserve.
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename InputIterator>
|
||||
size_t
|
||||
reserve_count_for_single_pass_helper(InputIterator first, InputIterator last,
|
||||
std::random_access_iterator_tag)
|
||||
{
|
||||
using std::distance;
|
||||
typename std::iterator_traits<InputIterator>::difference_type n =
|
||||
distance(first, last);
|
||||
return (size_t)n;
|
||||
}
|
||||
|
||||
template<typename InputIterator>
|
||||
size_t
|
||||
reserve_count_for_single_pass(InputIterator first, InputIterator last) {
|
||||
typedef typename std::iterator_traits<InputIterator>::iterator_category
|
||||
category;
|
||||
return reserve_count_for_single_pass_helper(first, last, category());
|
||||
}
|
||||
|
||||
template <typename KeyIterator, typename RowstartIterator,
|
||||
typename VerticesSize, typename KeyFilter, typename KeyTransform>
|
||||
void
|
||||
count_starts
|
||||
(KeyIterator begin, KeyIterator end,
|
||||
RowstartIterator starts, // Must support numverts + 1 elements
|
||||
VerticesSize numkeys,
|
||||
KeyFilter key_filter,
|
||||
KeyTransform key_transform) {
|
||||
|
||||
typedef VerticesSize vertices_size_type;
|
||||
typedef typename std::iterator_traits<RowstartIterator>::value_type EdgeIndex;
|
||||
|
||||
// Put the degree of each vertex v into m_rowstart[v + 1]
|
||||
for (KeyIterator i = begin; i != end; ++i) {
|
||||
if (key_filter(*i)) {
|
||||
++starts[key_transform(*i) + 1];
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the partial sum of the degrees to get the actual values of
|
||||
// m_rowstart
|
||||
EdgeIndex start_of_this_row = 0;
|
||||
starts[0] = start_of_this_row;
|
||||
for (vertices_size_type i = 1; i <= numkeys; ++i) {
|
||||
start_of_this_row += starts[i];
|
||||
starts[i] = start_of_this_row;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename KeyIterator, typename RowstartIterator,
|
||||
typename NumKeys,
|
||||
typename Value1InputIter,
|
||||
typename Value1OutputIter, typename KeyFilter, typename KeyTransform>
|
||||
void
|
||||
histogram_sort(KeyIterator key_begin, KeyIterator key_end,
|
||||
RowstartIterator rowstart, // Must support numkeys + 1 elements and be precomputed
|
||||
NumKeys numkeys,
|
||||
Value1InputIter values1_begin,
|
||||
Value1OutputIter values1_out,
|
||||
KeyFilter key_filter,
|
||||
KeyTransform key_transform) {
|
||||
|
||||
typedef NumKeys vertices_size_type;
|
||||
typedef typename std::iterator_traits<RowstartIterator>::value_type EdgeIndex;
|
||||
|
||||
// Histogram sort the edges by their source vertices, putting the targets
|
||||
// into m_column. The index current_insert_positions[v] contains the next
|
||||
// location to insert out edges for vertex v.
|
||||
std::vector<EdgeIndex>
|
||||
current_insert_positions(rowstart, rowstart + numkeys);
|
||||
Value1InputIter v1i = values1_begin;
|
||||
for (KeyIterator i = key_begin; i != key_end; ++i, ++v1i) {
|
||||
if (key_filter(*i)) {
|
||||
vertices_size_type source = key_transform(*i);
|
||||
EdgeIndex insert_pos = current_insert_positions[source];
|
||||
++current_insert_positions[source];
|
||||
values1_out[insert_pos] = *v1i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename KeyIterator, typename RowstartIterator,
|
||||
typename NumKeys,
|
||||
typename Value1InputIter,
|
||||
typename Value1OutputIter,
|
||||
typename Value2InputIter,
|
||||
typename Value2OutputIter,
|
||||
typename KeyFilter, typename KeyTransform>
|
||||
void
|
||||
histogram_sort(KeyIterator key_begin, KeyIterator key_end,
|
||||
RowstartIterator rowstart, // Must support numkeys + 1 elements and be precomputed
|
||||
NumKeys numkeys,
|
||||
Value1InputIter values1_begin,
|
||||
Value1OutputIter values1_out,
|
||||
Value2InputIter values2_begin,
|
||||
Value2OutputIter values2_out,
|
||||
KeyFilter key_filter,
|
||||
KeyTransform key_transform) {
|
||||
|
||||
typedef NumKeys vertices_size_type;
|
||||
typedef typename std::iterator_traits<RowstartIterator>::value_type EdgeIndex;
|
||||
|
||||
// Histogram sort the edges by their source vertices, putting the targets
|
||||
// into m_column. The index current_insert_positions[v] contains the next
|
||||
// location to insert out edges for vertex v.
|
||||
std::vector<EdgeIndex>
|
||||
current_insert_positions(rowstart, rowstart + numkeys);
|
||||
Value1InputIter v1i = values1_begin;
|
||||
Value2InputIter v2i = values2_begin;
|
||||
for (KeyIterator i = key_begin; i != key_end; ++i, ++v1i, ++v2i) {
|
||||
if (key_filter(*i)) {
|
||||
vertices_size_type source = key_transform(*i);
|
||||
EdgeIndex insert_pos = current_insert_positions[source];
|
||||
++current_insert_positions[source];
|
||||
values1_out[insert_pos] = *v1i;
|
||||
values2_out[insert_pos] = *v2i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename KeyIterator, typename RowstartIterator,
|
||||
typename NumKeys,
|
||||
typename Value1Iter,
|
||||
typename KeyTransform>
|
||||
void
|
||||
histogram_sort_inplace(KeyIterator key_begin,
|
||||
RowstartIterator rowstart, // Must support numkeys + 1 elements and be precomputed
|
||||
NumKeys numkeys,
|
||||
Value1Iter values1,
|
||||
KeyTransform key_transform) {
|
||||
|
||||
typedef NumKeys vertices_size_type;
|
||||
typedef typename std::iterator_traits<RowstartIterator>::value_type EdgeIndex;
|
||||
|
||||
// 1. Copy m_rowstart (except last element) to get insert positions
|
||||
std::vector<EdgeIndex> insert_positions(rowstart, rowstart + numkeys);
|
||||
// 2. Swap the sources and targets into place
|
||||
for (size_t i = 0; i < rowstart[numkeys]; ++i) {
|
||||
// While edge i is not in the right bucket:
|
||||
while (!(i >= rowstart[key_transform(key_begin[i])] && i < insert_positions[key_transform(key_begin[i])])) {
|
||||
// Add a slot in the right bucket
|
||||
size_t target_pos = insert_positions[key_transform(key_begin[i])]++;
|
||||
BOOST_ASSERT (target_pos < rowstart[key_transform(key_begin[i]) + 1]);
|
||||
if (target_pos == i) continue;
|
||||
// Swap this edge into place
|
||||
using std::swap;
|
||||
swap(key_begin[i], key_begin[target_pos]);
|
||||
swap(values1[i], values1[target_pos]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename KeyIterator, typename RowstartIterator,
|
||||
typename NumKeys,
|
||||
typename Value1Iter,
|
||||
typename Value2Iter,
|
||||
typename KeyTransform>
|
||||
void
|
||||
histogram_sort_inplace(KeyIterator key_begin,
|
||||
RowstartIterator rowstart, // Must support numkeys + 1 elements and be precomputed
|
||||
NumKeys numkeys,
|
||||
Value1Iter values1,
|
||||
Value2Iter values2,
|
||||
KeyTransform key_transform) {
|
||||
|
||||
typedef NumKeys vertices_size_type;
|
||||
typedef typename std::iterator_traits<RowstartIterator>::value_type EdgeIndex;
|
||||
|
||||
// 1. Copy m_rowstart (except last element) to get insert positions
|
||||
std::vector<EdgeIndex> insert_positions(rowstart, rowstart + numkeys);
|
||||
// 2. Swap the sources and targets into place
|
||||
for (size_t i = 0; i < rowstart[numkeys]; ++i) {
|
||||
// While edge i is not in the right bucket:
|
||||
while (!(i >= rowstart[key_transform(key_begin[i])] && i < insert_positions[key_transform(key_begin[i])])) {
|
||||
// Add a slot in the right bucket
|
||||
size_t target_pos = insert_positions[key_transform(key_begin[i])]++;
|
||||
BOOST_ASSERT (target_pos < rowstart[key_transform(key_begin[i]) + 1]);
|
||||
if (target_pos == i) continue;
|
||||
// Swap this edge into place
|
||||
using std::swap;
|
||||
swap(key_begin[i], key_begin[target_pos]);
|
||||
swap(values1[i], values1[target_pos]);
|
||||
swap(values2[i], values2[target_pos]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename InputIterator, typename VerticesSize>
|
||||
void split_into_separate_coords(InputIterator begin, InputIterator end,
|
||||
std::vector<VerticesSize>& firsts,
|
||||
std::vector<VerticesSize>& seconds) {
|
||||
firsts.clear();
|
||||
seconds.clear();
|
||||
size_t reserve_size
|
||||
= detail::reserve_count_for_single_pass(begin, end);
|
||||
firsts.reserve(reserve_size);
|
||||
seconds.reserve(reserve_size);
|
||||
for (; begin != end; ++begin) {
|
||||
std::pair<VerticesSize, VerticesSize> edge = *begin;
|
||||
firsts.push_back(edge.first);
|
||||
seconds.push_back(edge.second);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename InputIterator, typename VerticesSize, typename SourceFilter>
|
||||
void split_into_separate_coords_filtered
|
||||
(InputIterator begin, InputIterator end,
|
||||
std::vector<VerticesSize>& firsts,
|
||||
std::vector<VerticesSize>& seconds,
|
||||
const SourceFilter& filter) {
|
||||
firsts.clear();
|
||||
seconds.clear();
|
||||
for (; begin != end; ++begin) {
|
||||
std::pair<VerticesSize, VerticesSize> edge = *begin;
|
||||
if (filter(edge.first)) {
|
||||
firsts.push_back(edge.first);
|
||||
seconds.push_back(edge.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename InputIterator, typename PropInputIterator,
|
||||
typename VerticesSize, typename PropType, typename SourceFilter>
|
||||
void split_into_separate_coords_filtered
|
||||
(InputIterator begin, InputIterator end,
|
||||
PropInputIterator props,
|
||||
std::vector<VerticesSize>& firsts,
|
||||
std::vector<VerticesSize>& seconds,
|
||||
std::vector<PropType>& props_out,
|
||||
const SourceFilter& filter) {
|
||||
firsts.clear();
|
||||
seconds.clear();
|
||||
props_out.clear();
|
||||
for (; begin != end; ++begin) {
|
||||
std::pair<VerticesSize, VerticesSize> edge = *begin;
|
||||
if (filter(edge.first)) {
|
||||
firsts.push_back(edge.first);
|
||||
seconds.push_back(edge.second);
|
||||
props_out.push_back(*props);
|
||||
}
|
||||
++props;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Pair>
|
||||
struct project1st {
|
||||
typedef typename Pair::first_type result_type;
|
||||
const result_type& operator()(const Pair& p) const {return p.first;}
|
||||
};
|
||||
|
||||
template <typename Pair>
|
||||
struct project2nd {
|
||||
typedef typename Pair::second_type result_type;
|
||||
const result_type& operator()(const Pair& p) const {return p.second;}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BOOST_GRAPH_DETAIL_HISTOGRAM_SORT_HPP
|
||||
79
test/external/boost/graph/detail/incidence_iterator.hpp
vendored
Normal file
79
test/external/boost/graph/detail/incidence_iterator.hpp
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
//
|
||||
//=======================================================================
|
||||
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
|
||||
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
|
||||
//
|
||||
// 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 BOOST_GRAPH_DETAIL_INCIDENCE_ITERATOR_HPP
|
||||
#define BOOST_GRAPH_DETAIL_INCIDENCE_ITERATOR_HPP
|
||||
|
||||
#include <utility>
|
||||
#include <iterator>
|
||||
|
||||
// OBSOLETE
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail {
|
||||
// EdgeDir tags
|
||||
struct in_edge_tag { };
|
||||
struct out_edge_tag { };
|
||||
|
||||
template <class Vertex, class Edge, class Iterator1D, class EdgeDir>
|
||||
struct bidir_incidence_iterator {
|
||||
typedef bidir_incidence_iterator self;
|
||||
typedef Edge edge_type;
|
||||
typedef typename Edge::property_type EdgeProperty;
|
||||
public:
|
||||
typedef int difference_type;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef edge_type reference;
|
||||
typedef edge_type value_type;
|
||||
typedef value_type* pointer;
|
||||
inline bidir_incidence_iterator() {}
|
||||
inline bidir_incidence_iterator(Iterator1D ii, Vertex src)
|
||||
: i(ii), _src(src) { }
|
||||
|
||||
inline self& operator++() { ++i; return *this; }
|
||||
inline self operator++(int) { self tmp = *this; ++(*this); return tmp; }
|
||||
|
||||
inline reference operator*() const {
|
||||
return deref_helper(EdgeDir());
|
||||
}
|
||||
inline self* operator->() { return this; }
|
||||
|
||||
Iterator1D& iter() { return i; }
|
||||
const Iterator1D& iter() const { return i; }
|
||||
|
||||
Iterator1D i;
|
||||
Vertex _src;
|
||||
protected:
|
||||
inline reference deref_helper(out_edge_tag) const {
|
||||
return edge_type( _src, (*i).get_target(), &(*i).get_property() );
|
||||
}
|
||||
inline reference deref_helper(in_edge_tag) const {
|
||||
return edge_type((*i).get_target(), _src, &(*i).get_property() );
|
||||
}
|
||||
};
|
||||
|
||||
template <class V, class E, class Iter, class Dir>
|
||||
inline bool operator==(const bidir_incidence_iterator<V,E,Iter,Dir>& x,
|
||||
const bidir_incidence_iterator<V,E,Iter,Dir>& y)
|
||||
{
|
||||
return x.i == y.i;
|
||||
}
|
||||
template <class V, class E, class Iter, class Dir>
|
||||
inline bool operator!=(const bidir_incidence_iterator<V,E,Iter,Dir>& x,
|
||||
const bidir_incidence_iterator<V,E,Iter,Dir>& y)
|
||||
{
|
||||
return x.i != y.i;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
77
test/external/boost/graph/detail/incremental_components.hpp
vendored
Normal file
77
test/external/boost/graph/detail/incremental_components.hpp
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
//=======================================================================
|
||||
// Copyright 2002 Indiana University.
|
||||
// Copyright 2009 Trustees of Indiana University.
|
||||
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Michael Hansen
|
||||
//
|
||||
// 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 BOOST_GRAPH_DETAIL_INCREMENTAL_COMPONENTS_HPP
|
||||
#define BOOST_GRAPH_DETAIL_INCREMENTAL_COMPONENTS_HPP
|
||||
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Iterator for a component index linked list. The contents of
|
||||
// each array element represent the next index in the list. A
|
||||
// special value (the maximum index + 1) is used to terminate a
|
||||
// list.
|
||||
template <typename IndexRandomAccessIterator>
|
||||
class component_index_iterator :
|
||||
boost::forward_iterator_helper<component_index_iterator<IndexRandomAccessIterator>,
|
||||
typename std::iterator_traits<IndexRandomAccessIterator>::value_type,
|
||||
typename std::iterator_traits<IndexRandomAccessIterator>::difference_type,
|
||||
typename std::iterator_traits<IndexRandomAccessIterator>::pointer,
|
||||
typename std::iterator_traits<IndexRandomAccessIterator>::reference> {
|
||||
|
||||
private:
|
||||
typedef component_index_iterator<IndexRandomAccessIterator> self;
|
||||
|
||||
public:
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef typename std::iterator_traits<IndexRandomAccessIterator>::value_type value_type;
|
||||
typedef typename std::iterator_traits<IndexRandomAccessIterator>::difference_type reference;
|
||||
typedef typename std::iterator_traits<IndexRandomAccessIterator>::pointer pointer;
|
||||
typedef typename std::iterator_traits<IndexRandomAccessIterator>::reference difference_type;
|
||||
|
||||
// Constructor for "begin" iterator
|
||||
component_index_iterator(IndexRandomAccessIterator index_iterator,
|
||||
value_type begin_index) :
|
||||
m_index_iterator(index_iterator),
|
||||
m_current_index(begin_index) { }
|
||||
|
||||
// Constructor for "end" iterator (end_index should be the linked
|
||||
// list terminator).
|
||||
component_index_iterator(value_type end_index) :
|
||||
m_current_index(end_index) { }
|
||||
|
||||
inline value_type operator*() const {
|
||||
return (m_current_index);
|
||||
}
|
||||
|
||||
self& operator++() {
|
||||
// Move to the next element in the linked list
|
||||
m_current_index = m_index_iterator[m_current_index];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
bool operator==(const self& other_iterator) const {
|
||||
return (m_current_index == *other_iterator);
|
||||
}
|
||||
|
||||
protected:
|
||||
IndexRandomAccessIterator m_index_iterator;
|
||||
value_type m_current_index;
|
||||
|
||||
}; // class component_index_iterator
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#endif // BOOST_GRAPH_DETAIL_INCREMENTAL_COMPONENTS_HPP
|
||||
74
test/external/boost/graph/detail/index.hpp
vendored
Normal file
74
test/external/boost/graph/detail/index.hpp
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
// (C) Copyright 2007-2009 Andrew Sutton
|
||||
//
|
||||
// Use, modification and distribution are subject to the
|
||||
// Boost Software License, Version 1.0 (See accompanying file
|
||||
// LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GRAPH_DETAIL_INDEX_HPP
|
||||
#define BOOST_GRAPH_DETAIL_INDEX_HPP
|
||||
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
|
||||
// The structures in this module are responsible for selecting and defining
|
||||
// types for accessing a builting index map. Note that the selection of these
|
||||
// types requires the Graph parameter to model either VertexIndexGraph or
|
||||
// EdgeIndexGraph.
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template <typename Graph>
|
||||
struct vertex_indexer
|
||||
{
|
||||
typedef vertex_index_t index_type;
|
||||
typedef typename property_map<Graph, vertex_index_t>::type map_type;
|
||||
typedef typename property_map<Graph, vertex_index_t>::const_type const_map_type;
|
||||
typedef typename property_traits<map_type>::value_type value_type;
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor key_type;
|
||||
|
||||
static const_map_type index_map(const Graph& g)
|
||||
{ return get(vertex_index, g); }
|
||||
|
||||
static map_type index_map(Graph& g)
|
||||
{ return get(vertex_index, g); }
|
||||
|
||||
static value_type index(key_type k, const Graph& g)
|
||||
{ return get(vertex_index, g, k); }
|
||||
};
|
||||
|
||||
template <typename Graph>
|
||||
struct edge_indexer
|
||||
{
|
||||
typedef edge_index_t index_type;
|
||||
typedef typename property_map<Graph, edge_index_t>::type map_type;
|
||||
typedef typename property_map<Graph, edge_index_t>::const_type const_map_type;
|
||||
typedef typename property_traits<map_type>::value_type value_type;
|
||||
typedef typename graph_traits<Graph>::edge_descriptor key_type;
|
||||
|
||||
static const_map_type index_map(const Graph& g)
|
||||
{ return get(edge_index, g); }
|
||||
|
||||
static map_type index_map(Graph& g)
|
||||
{ return get(edge_index, g); }
|
||||
|
||||
static value_type index(key_type k, const Graph& g)
|
||||
{ return get(edge_index, g, k); }
|
||||
};
|
||||
|
||||
// NOTE: The Graph parameter MUST be a model of VertexIndexGraph or
|
||||
// VertexEdgeGraph - whichever type Key is selecting.
|
||||
template <typename Graph, typename Key>
|
||||
struct choose_indexer
|
||||
{
|
||||
typedef typename mpl::if_<
|
||||
is_same<Key, typename graph_traits<Graph>::vertex_descriptor>,
|
||||
vertex_indexer<Graph>,
|
||||
edge_indexer<Graph>
|
||||
>::type indexer_type;
|
||||
typedef typename indexer_type::index_type index_type;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
284
test/external/boost/graph/detail/indexed_properties.hpp
vendored
Normal file
284
test/external/boost/graph/detail/indexed_properties.hpp
vendored
Normal file
@@ -0,0 +1,284 @@
|
||||
// Copyright 2005 The Trustees of Indiana University.
|
||||
|
||||
// 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)
|
||||
|
||||
// Authors: Jeremiah Willcock
|
||||
// Douglas Gregor
|
||||
// Andrew Lumsdaine
|
||||
|
||||
// Indexed properties -- used for CSR and CSR-like graphs
|
||||
|
||||
#ifndef BOOST_GRAPH_INDEXED_PROPERTIES_HPP
|
||||
#define BOOST_GRAPH_INDEXED_PROPERTIES_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <climits>
|
||||
#include <iterator>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <boost/iterator/counting_iterator.hpp>
|
||||
#include <boost/integer.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
|
||||
template<typename Derived, typename Property, typename Descriptor, typename IndexMap>
|
||||
class indexed_vertex_properties
|
||||
{
|
||||
public:
|
||||
typedef no_property vertex_property_type;
|
||||
typedef Property vertex_bundled;
|
||||
typedef iterator_property_map<
|
||||
typename std::vector<Property>::iterator,
|
||||
IndexMap> vertex_map_type;
|
||||
typedef iterator_property_map<
|
||||
typename std::vector<Property>::const_iterator,
|
||||
IndexMap> const_vertex_map_type;
|
||||
|
||||
// Directly access a vertex or edge bundle
|
||||
Property& operator[](Descriptor v)
|
||||
{ return m_vertex_properties[get(vertex_index, derived(), v)]; }
|
||||
|
||||
const Property& operator[](Descriptor v) const
|
||||
{ return m_vertex_properties[get(vertex_index, derived(), v)]; }
|
||||
|
||||
vertex_map_type get_vertex_bundle(const IndexMap& index_map = IndexMap()) {
|
||||
return vertex_map_type(m_vertex_properties.begin(), index_map);
|
||||
}
|
||||
|
||||
const_vertex_map_type get_vertex_bundle(const IndexMap& index_map = IndexMap()) const {
|
||||
return const_vertex_map_type(m_vertex_properties.begin(), index_map);
|
||||
}
|
||||
|
||||
protected:
|
||||
// Default-construct with no property values
|
||||
indexed_vertex_properties() {}
|
||||
|
||||
// Initialize with n default-constructed property values
|
||||
indexed_vertex_properties(std::size_t n) : m_vertex_properties(n) { }
|
||||
|
||||
public:
|
||||
// Clear the properties vector
|
||||
void clear()
|
||||
{
|
||||
m_vertex_properties.clear();
|
||||
}
|
||||
|
||||
// Resize the properties vector
|
||||
void resize(std::size_t n)
|
||||
{
|
||||
m_vertex_properties.resize(n);
|
||||
}
|
||||
|
||||
// Reserve space in the vector of properties
|
||||
void reserve(std::size_t n)
|
||||
{
|
||||
m_vertex_properties.reserve(n);
|
||||
}
|
||||
|
||||
// Add a new property value to the back
|
||||
void push_back(const Property& prop)
|
||||
{
|
||||
m_vertex_properties.push_back(prop);
|
||||
}
|
||||
|
||||
// Write an element by raw index
|
||||
void write_by_index(std::size_t idx, const Property& prop)
|
||||
{
|
||||
m_vertex_properties[idx] = prop;
|
||||
}
|
||||
|
||||
// Access to the derived object
|
||||
Derived& derived() { return *static_cast<Derived*>(this); }
|
||||
|
||||
const Derived& derived() const
|
||||
{ return *static_cast<const Derived*>(this); }
|
||||
|
||||
public: // should be private, but friend templates not portable
|
||||
std::vector<Property> m_vertex_properties;
|
||||
};
|
||||
|
||||
template<typename Derived, typename Descriptor, typename IndexMap>
|
||||
class indexed_vertex_properties<Derived, void, Descriptor, IndexMap>
|
||||
{
|
||||
struct secret {};
|
||||
|
||||
public:
|
||||
typedef no_property vertex_property_type;
|
||||
typedef void vertex_bundled;
|
||||
typedef secret vertex_map_type;
|
||||
typedef secret const_vertex_map_type;
|
||||
|
||||
secret operator[](secret) { return secret(); }
|
||||
|
||||
vertex_map_type get_vertex_bundle() const {
|
||||
return vertex_map_type();
|
||||
}
|
||||
|
||||
protected:
|
||||
// All operations do nothing.
|
||||
indexed_vertex_properties() { }
|
||||
indexed_vertex_properties(std::size_t) { }
|
||||
|
||||
public:
|
||||
void clear() { }
|
||||
void resize(std::size_t) { }
|
||||
void reserve(std::size_t) { }
|
||||
};
|
||||
|
||||
template<typename Derived, typename Property, typename Descriptor, typename IndexMap>
|
||||
class indexed_edge_properties
|
||||
{
|
||||
public:
|
||||
typedef no_property edge_property_type;
|
||||
typedef Property edge_bundled;
|
||||
typedef Property edge_push_back_type;
|
||||
typedef iterator_property_map<
|
||||
typename std::vector<Property>::iterator,
|
||||
IndexMap> edge_map_type;
|
||||
typedef iterator_property_map<
|
||||
typename std::vector<Property>::const_iterator,
|
||||
IndexMap> const_edge_map_type;
|
||||
|
||||
// Directly access a edge or edge bundle
|
||||
Property& operator[](Descriptor v)
|
||||
{ return m_edge_properties[get(edge_index, derived(), v)]; }
|
||||
|
||||
const Property& operator[](Descriptor v) const
|
||||
{ return m_edge_properties[get(edge_index, derived(), v)]; }
|
||||
|
||||
edge_map_type get_edge_bundle(const IndexMap& index_map = IndexMap()) {
|
||||
return edge_map_type(m_edge_properties.begin(), index_map);
|
||||
}
|
||||
|
||||
const_edge_map_type get_edge_bundle(const IndexMap& index_map = IndexMap()) const {
|
||||
return const_edge_map_type(m_edge_properties.begin(), index_map);
|
||||
}
|
||||
|
||||
protected:
|
||||
// Default-construct with no property values
|
||||
indexed_edge_properties() {}
|
||||
|
||||
// Initialize with n default-constructed property values
|
||||
indexed_edge_properties(std::size_t n) : m_edge_properties(n) { }
|
||||
|
||||
// Get the size of the properties vector
|
||||
std::size_t size() const
|
||||
{
|
||||
return m_edge_properties.size();
|
||||
}
|
||||
|
||||
// Clear the properties vector
|
||||
void clear()
|
||||
{
|
||||
m_edge_properties.clear();
|
||||
}
|
||||
|
||||
// Resize the properties vector
|
||||
void resize(std::size_t n)
|
||||
{
|
||||
m_edge_properties.resize(n);
|
||||
}
|
||||
|
||||
// Reserve space in the vector of properties
|
||||
void reserve(std::size_t n)
|
||||
{
|
||||
m_edge_properties.reserve(n);
|
||||
}
|
||||
|
||||
// Write an element by raw index
|
||||
void write_by_index(std::size_t idx, const Property& prop)
|
||||
{
|
||||
m_edge_properties[idx] = prop;
|
||||
}
|
||||
|
||||
public:
|
||||
// Add a new property value to the back
|
||||
void push_back(const Property& prop)
|
||||
{
|
||||
m_edge_properties.push_back(prop);
|
||||
}
|
||||
|
||||
// Move range of properties backwards
|
||||
void move_range(std::size_t src_begin, std::size_t src_end, std::size_t dest_begin) {
|
||||
std::copy_backward(
|
||||
m_edge_properties.begin() + src_begin,
|
||||
m_edge_properties.begin() + src_end,
|
||||
m_edge_properties.begin() + dest_begin + (src_end - src_begin));
|
||||
}
|
||||
|
||||
typedef typename std::vector<Property>::iterator iterator;
|
||||
iterator begin() {return m_edge_properties.begin();}
|
||||
iterator end() {return m_edge_properties.end();}
|
||||
|
||||
private:
|
||||
// Access to the derived object
|
||||
Derived& derived() { return *static_cast<Derived*>(this); }
|
||||
|
||||
const Derived& derived() const
|
||||
{ return *static_cast<const Derived*>(this); }
|
||||
|
||||
public: // should be private, but friend templates not portable
|
||||
std::vector<Property> m_edge_properties;
|
||||
};
|
||||
|
||||
struct dummy_no_property_iterator
|
||||
: public boost::iterator_facade<dummy_no_property_iterator, no_property, std::random_access_iterator_tag> {
|
||||
mutable no_property prop;
|
||||
no_property& dereference() const {return prop;}
|
||||
bool equal(const dummy_no_property_iterator&) const {return true;}
|
||||
void increment() {}
|
||||
void decrement() {}
|
||||
void advance(std::ptrdiff_t) {}
|
||||
std::ptrdiff_t distance_to(const dummy_no_property_iterator) const {return 0;}
|
||||
};
|
||||
|
||||
template<typename Derived, typename Descriptor, typename IndexMap>
|
||||
class indexed_edge_properties<Derived, void, Descriptor, IndexMap>
|
||||
{
|
||||
struct secret {};
|
||||
|
||||
public:
|
||||
typedef no_property edge_property_type;
|
||||
typedef void edge_bundled;
|
||||
typedef void* edge_push_back_type;
|
||||
typedef secret edge_map_type;
|
||||
typedef secret const_edge_map_type;
|
||||
|
||||
secret operator[](secret) { return secret(); }
|
||||
void write_by_index(std::size_t idx, const no_property& prop) {}
|
||||
|
||||
edge_map_type get_edge_bundle(const IndexMap& = IndexMap()) const {
|
||||
return edge_map_type();
|
||||
}
|
||||
|
||||
protected:
|
||||
// All operations do nothing.
|
||||
indexed_edge_properties() { }
|
||||
indexed_edge_properties(std::size_t) { }
|
||||
std::size_t size() const {return 0;}
|
||||
void clear() { }
|
||||
void resize(std::size_t) { }
|
||||
void reserve(std::size_t) { }
|
||||
|
||||
public:
|
||||
void push_back(const edge_push_back_type&) { }
|
||||
void move_range(std::size_t src_begin, std::size_t src_end, std::size_t dest_begin) {}
|
||||
|
||||
typedef dummy_no_property_iterator iterator;
|
||||
iterator begin() {return dummy_no_property_iterator();}
|
||||
iterator end() {return dummy_no_property_iterator();}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BOOST_GRAPH_INDEXED_PROPERTIES_HPP
|
||||
237
test/external/boost/graph/detail/labeled_graph_traits.hpp
vendored
Normal file
237
test/external/boost/graph/detail/labeled_graph_traits.hpp
vendored
Normal file
@@ -0,0 +1,237 @@
|
||||
// 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_TRAITS_HPP
|
||||
#define BOOST_GRAPH_LABELED_GRAPH_TRAITS_HPP
|
||||
|
||||
#include <boost/graph/graph_mutability_traits.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
// Extend the graph mutability traits (and metafunctions) to include options
|
||||
// for labeled graphs.
|
||||
|
||||
// NOTE: the label_vertex tag denotes the fact that you can basically assign
|
||||
// arbitrary labels to vertices without modifying the actual graph.
|
||||
|
||||
// TODO: We might also overlay the uniqueness/multiplicity of labels in this
|
||||
// hierarchy also. For now, we just assumed that labels are unique.
|
||||
|
||||
struct label_vertex_tag { };
|
||||
struct labeled_add_vertex_tag : virtual label_vertex_tag { };
|
||||
struct labeled_add_vertex_property_tag : virtual labeled_add_vertex_tag { };
|
||||
struct labeled_remove_vertex_tag { };
|
||||
struct labeled_add_edge_tag : virtual label_vertex_tag { };
|
||||
struct labeled_add_edge_property_tag : virtual labeled_add_edge_tag{ };
|
||||
struct labeled_remove_edge_tag { };
|
||||
|
||||
struct labeled_mutable_vertex_graph_tag
|
||||
: virtual labeled_add_vertex_tag, virtual labeled_remove_vertex_tag
|
||||
{ };
|
||||
struct labeled_mutable_vertex_property_graph_tag
|
||||
: virtual labeled_add_vertex_property_tag, virtual labeled_remove_vertex_tag
|
||||
{ };
|
||||
struct labeled_mutable_edge_graph_tag
|
||||
: virtual labeled_add_edge_tag, virtual labeled_remove_edge_tag
|
||||
{ };
|
||||
struct labeled_mutable_edge_property_graph_tag
|
||||
: virtual labeled_add_edge_property_tag, virtual labeled_remove_edge_tag
|
||||
{ };
|
||||
|
||||
struct labeled_graph_tag
|
||||
: virtual label_vertex_tag
|
||||
{ };
|
||||
struct labeled_mutable_graph_tag
|
||||
: virtual labeled_mutable_vertex_graph_tag
|
||||
, virtual labeled_mutable_edge_graph_tag
|
||||
{ };
|
||||
struct labeled_mutable_property_graph_tag
|
||||
: virtual labeled_mutable_vertex_property_graph_tag
|
||||
, virtual labeled_mutable_edge_property_graph_tag
|
||||
{ };
|
||||
struct labeled_add_only_property_graph_tag
|
||||
: virtual labeled_add_vertex_property_tag
|
||||
, virtual labeled_mutable_edge_property_graph_tag
|
||||
{ };
|
||||
|
||||
// Metafunctions
|
||||
|
||||
template <typename Graph>
|
||||
struct graph_has_add_vertex_by_label
|
||||
: mpl::bool_<
|
||||
is_convertible<
|
||||
typename graph_mutability_traits<Graph>::category,
|
||||
labeled_add_vertex_tag
|
||||
>::value
|
||||
>
|
||||
{ };
|
||||
|
||||
template <typename Graph>
|
||||
struct graph_has_add_vertex_by_label_with_property
|
||||
: mpl::bool_<
|
||||
is_convertible<
|
||||
typename graph_mutability_traits<Graph>::category,
|
||||
labeled_add_vertex_property_tag
|
||||
>::value
|
||||
>
|
||||
{ };
|
||||
|
||||
template <typename Graph>
|
||||
struct graph_has_remove_vertex_by_label
|
||||
: mpl::bool_<
|
||||
is_convertible<
|
||||
typename graph_mutability_traits<Graph>::category,
|
||||
labeled_remove_vertex_tag
|
||||
>::value
|
||||
>
|
||||
{ };
|
||||
|
||||
template <typename Graph>
|
||||
struct graph_has_add_edge_by_label
|
||||
: mpl::bool_<
|
||||
is_convertible<
|
||||
typename graph_mutability_traits<Graph>::category,
|
||||
labeled_add_edge_tag
|
||||
>::value
|
||||
>
|
||||
{ };
|
||||
|
||||
template <typename Graph>
|
||||
struct graph_has_add_edge_by_label_with_property
|
||||
: mpl::bool_<
|
||||
is_convertible<
|
||||
typename graph_mutability_traits<Graph>::category,
|
||||
labeled_add_edge_property_tag
|
||||
>::value
|
||||
>
|
||||
{ };
|
||||
|
||||
template <typename Graph>
|
||||
struct graph_has_remove_edge_by_label
|
||||
: mpl::bool_<
|
||||
is_convertible<
|
||||
typename graph_mutability_traits<Graph>::category,
|
||||
labeled_remove_edge_tag
|
||||
>::value
|
||||
>
|
||||
{ };
|
||||
|
||||
template <typename Graph>
|
||||
struct is_labeled_mutable_vertex_graph
|
||||
: mpl::and_<
|
||||
graph_has_add_vertex_by_label<Graph>,
|
||||
graph_has_remove_vertex_by_label<Graph>
|
||||
>
|
||||
{ };
|
||||
|
||||
template <typename Graph>
|
||||
struct is_labeled_mutable_vertex_property_graph
|
||||
: mpl::and_<
|
||||
graph_has_add_vertex_by_label<Graph>,
|
||||
graph_has_remove_vertex_by_label<Graph>
|
||||
>
|
||||
{ };
|
||||
|
||||
template <typename Graph>
|
||||
struct is_labeled_mutable_edge_graph
|
||||
: mpl::and_<
|
||||
graph_has_add_edge_by_label<Graph>,
|
||||
graph_has_remove_edge_by_label<Graph>
|
||||
>
|
||||
{ };
|
||||
|
||||
template <typename Graph>
|
||||
struct is_labeled_mutable_edge_property_graph
|
||||
: mpl::and_<
|
||||
graph_has_add_edge_by_label<Graph>,
|
||||
graph_has_remove_edge_by_label<Graph>
|
||||
>
|
||||
{ };
|
||||
|
||||
template <typename Graph>
|
||||
struct is_labeled_mutable_graph
|
||||
: mpl::and_<
|
||||
is_labeled_mutable_vertex_graph<Graph>,
|
||||
is_labeled_mutable_edge_graph<Graph>
|
||||
>
|
||||
{ };
|
||||
|
||||
template <typename Graph>
|
||||
struct is_labeled_mutable_property_graph
|
||||
: mpl::and_<
|
||||
is_labeled_mutable_vertex_property_graph<Graph>,
|
||||
is_labeled_mutable_edge_property_graph<Graph>
|
||||
>
|
||||
{ };
|
||||
|
||||
template <typename Graph>
|
||||
struct is_labeled_add_only_property_graph
|
||||
: mpl::bool_<
|
||||
is_convertible<
|
||||
typename graph_mutability_traits<Graph>::category,
|
||||
labeled_add_only_property_graph_tag
|
||||
>::value
|
||||
>
|
||||
{ };
|
||||
|
||||
template <typename Graph>
|
||||
struct is_labeled_graph
|
||||
: mpl::bool_<
|
||||
is_convertible<
|
||||
typename graph_mutability_traits<Graph>::category,
|
||||
label_vertex_tag
|
||||
>::value
|
||||
>
|
||||
{ };
|
||||
|
||||
template <typename> struct graph_mutability_traits;
|
||||
|
||||
namespace graph_detail {
|
||||
// The determine mutability metafunction computes a labeled mutability tag
|
||||
// based on the mutability of the given graph type. This is used by the
|
||||
// graph_mutability_traits specialization below.
|
||||
template <typename Graph>
|
||||
struct determine_mutability {
|
||||
typedef typename mpl::if_<
|
||||
is_add_only_property_graph<Graph>,
|
||||
labeled_add_only_property_graph_tag,
|
||||
typename mpl::if_<
|
||||
is_mutable_property_graph<Graph>,
|
||||
labeled_mutable_property_graph_tag,
|
||||
typename mpl::if_<
|
||||
is_mutable_graph<Graph>,
|
||||
labeled_mutable_graph_tag,
|
||||
typename mpl::if_<
|
||||
is_mutable_edge_graph<Graph>,
|
||||
labeled_graph_tag,
|
||||
typename graph_mutability_traits<Graph>::category
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
} // namespace graph_detail
|
||||
|
||||
#define LABELED_GRAPH_PARAMS typename G, typename L, typename S
|
||||
#define LABELED_GRAPH labeled_graph<G,L,S>
|
||||
|
||||
// Specialize mutability traits for for the labeled graph.
|
||||
// This specialization depends on the mutability of the underlying graph type.
|
||||
// If the underlying graph is fully mutable, this this is also fully mutable.
|
||||
// Otherwise, it's different.
|
||||
template <LABELED_GRAPH_PARAMS>
|
||||
struct graph_mutability_traits< LABELED_GRAPH > {
|
||||
typedef typename graph_detail::determine_mutability<
|
||||
typename LABELED_GRAPH::graph_type
|
||||
>::type category;
|
||||
};
|
||||
|
||||
#undef LABELED_GRAPH_PARAMS
|
||||
#undef LABELED_GRAPH
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
220
test/external/boost/graph/detail/list_base.hpp
vendored
Normal file
220
test/external/boost/graph/detail/list_base.hpp
vendored
Normal file
@@ -0,0 +1,220 @@
|
||||
//=======================================================================
|
||||
// Copyright 2002 Indiana University.
|
||||
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
|
||||
//
|
||||
// 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 BOOST_LIST_BASE_HPP
|
||||
#define BOOST_LIST_BASE_HPP
|
||||
|
||||
#include <boost/iterator_adaptors.hpp>
|
||||
|
||||
// Perhaps this should go through formal review, and move to <boost/>.
|
||||
|
||||
/*
|
||||
An alternate interface idea:
|
||||
Extend the std::list functionality by creating remove/insert
|
||||
functions that do not require the container object!
|
||||
*/
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
|
||||
//=========================================================================
|
||||
// Linked-List Generic Implementation Functions
|
||||
|
||||
template <class Node, class Next>
|
||||
inline Node
|
||||
slist_insert_after(Node pos, Node x,
|
||||
Next next)
|
||||
{
|
||||
next(x) = next(pos);
|
||||
next(pos) = x;
|
||||
return x;
|
||||
}
|
||||
|
||||
// return next(pos) or next(next(pos)) ?
|
||||
template <class Node, class Next>
|
||||
inline Node
|
||||
slist_remove_after(Node pos,
|
||||
Next next)
|
||||
{
|
||||
Node n = next(pos);
|
||||
next(pos) = next(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
template <class Node, class Next>
|
||||
inline Node
|
||||
slist_remove_range(Node before_first, Node last,
|
||||
Next next)
|
||||
{
|
||||
next(before_first) = last;
|
||||
return last;
|
||||
}
|
||||
|
||||
template <class Node, class Next>
|
||||
inline Node
|
||||
slist_previous(Node head, Node x, Node nil,
|
||||
Next next)
|
||||
{
|
||||
while (head != nil && next(head) != x)
|
||||
head = next(head);
|
||||
return head;
|
||||
}
|
||||
|
||||
template<class Node, class Next>
|
||||
inline void
|
||||
slist_splice_after(Node pos, Node before_first, Node before_last,
|
||||
Next next)
|
||||
{
|
||||
if (pos != before_first && pos != before_last) {
|
||||
Node first = next(before_first);
|
||||
Node after = next(pos);
|
||||
next(before_first) = next(before_last);
|
||||
next(pos) = first;
|
||||
next(before_last) = after;
|
||||
}
|
||||
}
|
||||
|
||||
template <class Node, class Next>
|
||||
inline Node
|
||||
slist_reverse(Node node, Node nil,
|
||||
Next next)
|
||||
{
|
||||
Node result = node;
|
||||
node = next(node);
|
||||
next(result) = nil;
|
||||
while(node) {
|
||||
Node next = next(node);
|
||||
next(node) = result;
|
||||
result = node;
|
||||
node = next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class Node, class Next>
|
||||
inline std::size_t
|
||||
slist_size(Node head, Node nil,
|
||||
Next next)
|
||||
{
|
||||
std::size_t s = 0;
|
||||
for ( ; head != nil; head = next(head))
|
||||
++s;
|
||||
return s;
|
||||
}
|
||||
|
||||
template <class Next, class Data>
|
||||
class slist_iterator_policies
|
||||
{
|
||||
public:
|
||||
explicit slist_iterator_policies(const Next& n, const Data& d)
|
||||
: m_next(n), m_data(d) { }
|
||||
|
||||
template <class Reference, class Node>
|
||||
Reference dereference(type<Reference>, const Node& x) const
|
||||
{ return m_data(x); }
|
||||
|
||||
template <class Node>
|
||||
void increment(Node& x) const
|
||||
{ x = m_next(x); }
|
||||
|
||||
template <class Node>
|
||||
bool equal(Node& x, Node& y) const
|
||||
{ return x == y; }
|
||||
|
||||
protected:
|
||||
Next m_next;
|
||||
Data m_data;
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
// Doubly-Linked List Generic Implementation Functions
|
||||
|
||||
template <class Node, class Next, class Prev>
|
||||
inline void
|
||||
dlist_insert_before(Node pos, Node x,
|
||||
Next next, Prev prev)
|
||||
{
|
||||
next(x) = pos;
|
||||
prev(x) = prev(pos);
|
||||
next(prev(pos)) = x;
|
||||
prev(pos) = x;
|
||||
}
|
||||
|
||||
template <class Node, class Next, class Prev>
|
||||
void
|
||||
dlist_remove(Node pos,
|
||||
Next next, Prev prev)
|
||||
{
|
||||
Node next_node = next(pos);
|
||||
Node prev_node = prev(pos);
|
||||
next(prev_node) = next_node;
|
||||
prev(next_node) = prev_node;
|
||||
}
|
||||
|
||||
// This deletes every node in the list except the
|
||||
// sentinel node.
|
||||
template <class Node, class Delete>
|
||||
inline void
|
||||
dlist_clear(Node sentinel, Delete del)
|
||||
{
|
||||
Node i, tmp;
|
||||
i = next(sentinel);
|
||||
while (i != sentinel) {
|
||||
tmp = i;
|
||||
i = next(i);
|
||||
del(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Node>
|
||||
inline bool
|
||||
dlist_empty(Node dummy)
|
||||
{
|
||||
return next(dummy) == dummy;
|
||||
}
|
||||
|
||||
template <class Node, class Next, class Prev>
|
||||
void
|
||||
dlist_transfer(Node pos, Node first, Node last,
|
||||
Next next, Prev prev)
|
||||
{
|
||||
if (pos != last) {
|
||||
// Remove [first,last) from its old position
|
||||
next(prev(last)) = pos;
|
||||
next(prev(first)) = last;
|
||||
next(prev(pos)) = first;
|
||||
|
||||
// Splice [first,last) into its new position
|
||||
Node tmp = prev(pos);
|
||||
prev(pos) = prev(last);
|
||||
prev(last) = prev(first);
|
||||
prev(first) = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
template <class Next, class Prev, class Data>
|
||||
class dlist_iterator_policies
|
||||
: public slist_iterator_policies<Next, Data>
|
||||
{
|
||||
typedef slist_iterator_policies<Next, Data> Base;
|
||||
public:
|
||||
template <class Node>
|
||||
void decrement(Node& x) const
|
||||
{ x = m_prev(x); }
|
||||
|
||||
dlist_iterator_policies(Next n, Prev p, Data d)
|
||||
: Base(n,d), m_prev(p) { }
|
||||
protected:
|
||||
Prev m_prev;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_LIST_BASE_HPP
|
||||
205
test/external/boost/graph/detail/permutation.hpp
vendored
Normal file
205
test/external/boost/graph/detail/permutation.hpp
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
// (C) Copyright Jeremy Siek 2001.
|
||||
// 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 BOOST_PERMUTATION_HPP
|
||||
#define BOOST_PERMUTATION_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <boost/graph/detail/shadow_iterator.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <class Iter1, class Iter2>
|
||||
void permute_serial(Iter1 permuter, Iter1 last, Iter2 result)
|
||||
{
|
||||
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
typedef std::ptrdiff_t D:
|
||||
#else
|
||||
typedef typename std::iterator_traits<Iter1>::difference_type D;
|
||||
#endif
|
||||
|
||||
D n = 0;
|
||||
while (permuter != last) {
|
||||
std::swap(result[n], result[*permuter]);
|
||||
++n;
|
||||
++permuter;
|
||||
}
|
||||
}
|
||||
|
||||
template <class InIter, class RandIterP, class RandIterR>
|
||||
void permute_copy(InIter first, InIter last, RandIterP p, RandIterR result)
|
||||
{
|
||||
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
typedef std::ptrdiff_t i = 0;
|
||||
#else
|
||||
typename std::iterator_traits<RandIterP>::difference_type i = 0;
|
||||
#endif
|
||||
for (; first != last; ++first, ++i)
|
||||
result[p[i]] = *first;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class RandIter, class RandIterPerm, class D, class T>
|
||||
void permute_helper(RandIter first, RandIter last, RandIterPerm p, D, T)
|
||||
{
|
||||
D i = 0, pi, n = last - first, cycle_start;
|
||||
T tmp;
|
||||
std::vector<int> visited(n, false);
|
||||
|
||||
while (i != n) { // continue until all elements have been processed
|
||||
cycle_start = i;
|
||||
tmp = first[i];
|
||||
do { // walk around a cycle
|
||||
pi = p[i];
|
||||
visited[pi] = true;
|
||||
std::swap(tmp, first[pi]);
|
||||
i = pi;
|
||||
} while (i != cycle_start);
|
||||
|
||||
// find the next cycle
|
||||
for (i = 0; i < n; ++i)
|
||||
if (visited[i] == false)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class RandIter, class RandIterPerm>
|
||||
void permute(RandIter first, RandIter last, RandIterPerm p)
|
||||
{
|
||||
detail::permute_helper(first, last, p, last - first, *first);
|
||||
}
|
||||
|
||||
|
||||
// Knuth 1.3.3, Vol. 1 p 176
|
||||
// modified for zero-based arrays
|
||||
// time complexity?
|
||||
//
|
||||
// WARNING: T must be a signed integer!
|
||||
template <class PermIter>
|
||||
void invert_permutation(PermIter X, PermIter Xend)
|
||||
{
|
||||
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
typedef std::ptrdiff_t T:
|
||||
#else
|
||||
typedef typename std::iterator_traits<PermIter>::value_type T;
|
||||
#endif
|
||||
T n = Xend - X;
|
||||
T m = n;
|
||||
T j = -1;
|
||||
|
||||
while (m > 0) {
|
||||
T i = X[m-1] + 1;
|
||||
if (i > 0) {
|
||||
do {
|
||||
X[m-1] = j - 1;
|
||||
j = -m;
|
||||
m = i;
|
||||
i = X[m-1] + 1;
|
||||
} while (i > 0);
|
||||
i = j;
|
||||
}
|
||||
X[m-1] = -i - 1;
|
||||
--m;
|
||||
}
|
||||
}
|
||||
|
||||
// Takes a "normal" permutation array (and its inverse), and turns it
|
||||
// into a BLAS-style permutation array (which can be thought of as a
|
||||
// serialized permutation).
|
||||
template <class Iter1, class Iter2, class Iter3>
|
||||
inline void serialize_permutation(Iter1 q, Iter1 q_end, Iter2 q_inv, Iter3 p)
|
||||
{
|
||||
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
typedef std::ptrdiff_t P1;
|
||||
typedef std::ptrdiff_t P2;
|
||||
typedef std::ptrdiff_t D;
|
||||
#else
|
||||
typedef typename std::iterator_traits<Iter1>::value_type P1;
|
||||
typedef typename std::iterator_traits<Iter2>::value_type P2;
|
||||
typedef typename std::iterator_traits<Iter1>::difference_type D;
|
||||
#endif
|
||||
D n = q_end - q;
|
||||
for (D i = 0; i < n; ++i) {
|
||||
P1 qi = q[i];
|
||||
P2 qii = q_inv[i];
|
||||
*p++ = qii;
|
||||
std::swap(q[i], q[qii]);
|
||||
std::swap(q_inv[i], q_inv[qi]);
|
||||
}
|
||||
}
|
||||
|
||||
// Not used anymore, leaving it here for future reference.
|
||||
template <typename Iter, typename Compare>
|
||||
void merge_sort(Iter first, Iter last, Compare cmp)
|
||||
{
|
||||
if (first + 1 < last) {
|
||||
Iter mid = first + (last - first)/2;
|
||||
merge_sort(first, mid, cmp);
|
||||
merge_sort(mid, last, cmp);
|
||||
std::inplace_merge(first, mid, last, cmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// time: N log N + 3N + ?
|
||||
// space: 2N
|
||||
template <class Iter, class IterP, class Cmp, class Alloc>
|
||||
inline void sortp(Iter first, Iter last, IterP p, Cmp cmp, Alloc alloc)
|
||||
{
|
||||
typedef typename std::iterator_traits<IterP>::value_type P;
|
||||
typedef typename std::iterator_traits<IterP>::difference_type D;
|
||||
D n = last - first;
|
||||
std::vector<P, Alloc> q(n);
|
||||
for (D i = 0; i < n; ++i)
|
||||
q[i] = i;
|
||||
std::sort(make_shadow_iter(first, q.begin()),
|
||||
make_shadow_iter(last, q.end()),
|
||||
shadow_cmp<Cmp>(cmp));
|
||||
invert_permutation(q.begin(), q.end());
|
||||
std::copy(q.begin(), q.end(), p);
|
||||
}
|
||||
|
||||
template <class Iter, class IterP, class Cmp>
|
||||
inline void sortp(Iter first, Iter last, IterP p, Cmp cmp)
|
||||
{
|
||||
typedef typename std::iterator_traits<IterP>::value_type P;
|
||||
sortp(first, last, p, cmp, std::allocator<P>());
|
||||
}
|
||||
|
||||
template <class Iter, class IterP>
|
||||
inline void sortp(Iter first, Iter last, IterP p)
|
||||
{
|
||||
typedef typename std::iterator_traits<Iter>::value_type T;
|
||||
typedef typename std::iterator_traits<IterP>::value_type P;
|
||||
sortp(first, last, p, std::less<T>(), std::allocator<P>());
|
||||
}
|
||||
|
||||
template <class Iter, class IterP, class Cmp, class Alloc>
|
||||
inline void sortv(Iter first, Iter last, IterP p, Cmp cmp, Alloc alloc)
|
||||
{
|
||||
typedef typename std::iterator_traits<IterP>::value_type P;
|
||||
typedef typename std::iterator_traits<IterP>::difference_type D;
|
||||
D n = last - first;
|
||||
std::vector<P, Alloc> q(n), q_inv(n);
|
||||
for (D i = 0; i < n; ++i)
|
||||
q_inv[i] = i;
|
||||
std::sort(make_shadow_iter(first, q_inv.begin()),
|
||||
make_shadow_iter(last, q_inv.end()),
|
||||
shadow_cmp<Cmp>(cmp));
|
||||
std::copy(q_inv, q_inv.end(), q.begin());
|
||||
invert_permutation(q.begin(), q.end());
|
||||
serialize_permutation(q.begin(), q.end(), q_inv.end(), p);
|
||||
}
|
||||
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_PERMUTATION_HPP
|
||||
108
test/external/boost/graph/detail/read_graphviz_new.hpp
vendored
Normal file
108
test/external/boost/graph/detail/read_graphviz_new.hpp
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
// Copyright 2004-9 Trustees of Indiana University
|
||||
|
||||
// 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)
|
||||
|
||||
//
|
||||
// read_graphviz_new.hpp -
|
||||
// Initialize a model of the BGL's MutableGraph concept and an associated
|
||||
// collection of property maps using a graph expressed in the GraphViz
|
||||
// DOT Language.
|
||||
//
|
||||
// Based on the grammar found at:
|
||||
// http://www.graphviz.org/cvs/doc/info/lang.html
|
||||
//
|
||||
// Jeremiah rewrite used grammar found at:
|
||||
// http://www.graphviz.org/doc/info/lang.html
|
||||
// and page 34 or http://www.graphviz.org/pdf/dotguide.pdf
|
||||
//
|
||||
// See documentation for this code at:
|
||||
// http://www.boost.org/libs/graph/doc/read-graphviz.html
|
||||
//
|
||||
|
||||
// Author: Jeremiah Willcock
|
||||
// Ronald Garcia
|
||||
//
|
||||
|
||||
#ifndef BOOST_READ_GRAPHVIZ_NEW_HPP
|
||||
#define BOOST_READ_GRAPHVIZ_NEW_HPP
|
||||
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/property_map/dynamic_property_map.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace read_graphviz_detail {
|
||||
typedef std::string node_name;
|
||||
typedef std::string subgraph_name;
|
||||
|
||||
typedef std::map<std::string, std::string> properties;
|
||||
|
||||
struct node_and_port {
|
||||
node_name name;
|
||||
std::string angle; // Or empty if no angle
|
||||
std::vector<std::string> location; // Up to two identifiers
|
||||
|
||||
friend inline bool operator==(const node_and_port& a, const node_and_port& b) {
|
||||
return a.name == b.name &&
|
||||
a.angle == b.angle &&
|
||||
a.location == b.location;
|
||||
}
|
||||
|
||||
friend inline bool operator<(const node_and_port& a, const node_and_port& b) {
|
||||
if (a.name != b.name) return a.name < b.name;
|
||||
if (a.angle != b.angle) return a.angle < b.angle;
|
||||
return a.location < b.location;
|
||||
}
|
||||
};
|
||||
|
||||
struct edge_info {
|
||||
node_and_port source;
|
||||
node_and_port target;
|
||||
properties props;
|
||||
};
|
||||
|
||||
struct parser_result {
|
||||
bool graph_is_directed;
|
||||
bool graph_is_strict;
|
||||
std::map<node_name, properties> nodes; // Global set
|
||||
std::vector<edge_info> edges;
|
||||
std::map<subgraph_name, properties> graph_props; // Root and subgraphs
|
||||
};
|
||||
|
||||
// The actual parser, from libs/graph/src/read_graphviz_new.cpp
|
||||
void parse_graphviz_from_string(const std::string& str, parser_result& result, bool want_directed);
|
||||
|
||||
// Translate from those results to a graph
|
||||
void translate_results_to_graph(const parser_result& r, ::boost::detail::graph::mutate_graph* mg);
|
||||
|
||||
} // namespace read_graphviz_detail
|
||||
|
||||
namespace detail {
|
||||
namespace graph {
|
||||
BOOST_GRAPH_DECL bool read_graphviz_new(const std::string& str, boost::detail::graph::mutate_graph* mg);
|
||||
} // end namespace graph
|
||||
} // end namespace detail
|
||||
|
||||
template <typename MutableGraph>
|
||||
bool read_graphviz_new(const std::string& str,
|
||||
MutableGraph& graph, boost::dynamic_properties& dp,
|
||||
std::string const& node_id = "node_id") {
|
||||
boost::detail::graph::mutate_graph_impl<MutableGraph> mg(graph, dp, node_id);
|
||||
return detail::graph::read_graphviz_new(str, &mg);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_READ_GRAPHVIZ_NEW_HPP
|
||||
612
test/external/boost/graph/detail/read_graphviz_spirit.hpp
vendored
Normal file
612
test/external/boost/graph/detail/read_graphviz_spirit.hpp
vendored
Normal file
@@ -0,0 +1,612 @@
|
||||
// Copyright 2004-9 Trustees of Indiana University
|
||||
|
||||
// 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)
|
||||
|
||||
//
|
||||
// read_graphviz_spirit.hpp -
|
||||
// Initialize a model of the BGL's MutableGraph concept and an associated
|
||||
// collection of property maps using a graph expressed in the GraphViz
|
||||
// DOT Language.
|
||||
//
|
||||
// Based on the grammar found at:
|
||||
// http://www.graphviz.org/cvs/doc/info/lang.html
|
||||
//
|
||||
// See documentation for this code at:
|
||||
// http://www.boost.org/libs/graph/doc/read-graphviz.html
|
||||
//
|
||||
|
||||
// Author: Ronald Garcia
|
||||
//
|
||||
|
||||
#ifndef BOOST_READ_GRAPHVIZ_SPIRIT_HPP
|
||||
#define BOOST_READ_GRAPHVIZ_SPIRIT_HPP
|
||||
|
||||
// Phoenix/Spirit set these limits to 3, but I need more.
|
||||
#define PHOENIX_LIMIT 6
|
||||
#define BOOST_SPIRIT_CLOSURE_LIMIT 6
|
||||
|
||||
|
||||
#include <boost/spirit/include/classic_multi_pass.hpp>
|
||||
#include <boost/spirit/include/classic_core.hpp>
|
||||
#include <boost/spirit/include/classic_confix.hpp>
|
||||
#include <boost/spirit/include/classic_distinct.hpp>
|
||||
#include <boost/spirit/include/classic_lists.hpp>
|
||||
#include <boost/spirit/include/classic_escape_char.hpp>
|
||||
#include <boost/spirit/include/classic_attribute.hpp>
|
||||
#include <boost/spirit/include/classic_dynamic.hpp>
|
||||
#include <boost/spirit/include/classic_actor.hpp>
|
||||
#include <boost/spirit/include/classic_closure.hpp>
|
||||
#include <boost/spirit/include/phoenix1.hpp>
|
||||
#include <boost/spirit/include/phoenix1_binders.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/function/function2.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/property_map/dynamic_property_map.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <algorithm>
|
||||
#include <exception> // for std::exception
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <map>
|
||||
#include <boost/graph/graphviz.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
namespace phoenix {
|
||||
// Workaround: std::map::operator[] uses a different return type than all
|
||||
// other standard containers. Phoenix doesn't account for that.
|
||||
template <typename TK, typename T0, typename T1>
|
||||
struct binary_operator<index_op, std::map<TK,T0>, T1>
|
||||
{
|
||||
typedef typename std::map<TK,T0>::mapped_type& result_type;
|
||||
static result_type eval(std::map<TK,T0>& container, T1 const& index)
|
||||
{ return container[index]; }
|
||||
};
|
||||
} // namespace phoenix
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
namespace graph {
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Application-specific type definitions
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef std::set<edge_t> edges_t;
|
||||
typedef std::set<node_t> nodes_t;
|
||||
typedef std::set<id_t> ids_t;
|
||||
typedef std::map<edge_t,ids_t> edge_map_t;
|
||||
typedef std::map<node_t,ids_t> node_map_t;
|
||||
typedef std::map<id_t,id_t> props_t;
|
||||
typedef std::map<id_t,props_t> subgraph_props_t;
|
||||
typedef boost::function2<void, id_t const&, id_t const&> actor_t;
|
||||
typedef std::vector<edge_t> edge_stack_t;
|
||||
typedef std::map<id_t,nodes_t> subgraph_nodes_t;
|
||||
typedef std::map<id_t,edges_t> subgraph_edges_t;
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Stack frames used by semantic actions
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
struct id_closure : boost::spirit::classic::closure<id_closure, node_t> {
|
||||
member1 name;
|
||||
};
|
||||
|
||||
|
||||
struct node_id_closure : boost::spirit::classic::closure<node_id_closure, node_t> {
|
||||
member1 name;
|
||||
};
|
||||
|
||||
struct attr_list_closure : boost::spirit::classic::closure<attr_list_closure, actor_t> {
|
||||
member1 prop_actor;
|
||||
};
|
||||
|
||||
struct property_closure : boost::spirit::classic::closure<property_closure, id_t, id_t> {
|
||||
member1 key;
|
||||
member2 value;
|
||||
};
|
||||
|
||||
struct data_stmt_closure : boost::spirit::classic::closure<data_stmt_closure,
|
||||
nodes_t,nodes_t,edge_stack_t,bool,node_t> {
|
||||
member1 sources;
|
||||
member2 dests;
|
||||
member3 edge_stack;
|
||||
member4 saw_node;
|
||||
member5 active_node;
|
||||
};
|
||||
|
||||
struct subgraph_closure : boost::spirit::classic::closure<subgraph_closure,
|
||||
nodes_t, edges_t, node_t> {
|
||||
member1 nodes;
|
||||
member2 edges;
|
||||
member3 name;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Grammar and Actions for the DOT Language
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Grammar for a dot file.
|
||||
struct dot_grammar : public boost::spirit::classic::grammar<dot_grammar> {
|
||||
mutate_graph& graph_;
|
||||
explicit dot_grammar(mutate_graph& graph) : graph_(graph) { }
|
||||
|
||||
template <class ScannerT>
|
||||
struct definition {
|
||||
|
||||
definition(dot_grammar const& self) : self(self), subgraph_depth(0),
|
||||
keyword_p("0-9a-zA-Z_") {
|
||||
using namespace boost::spirit::classic;
|
||||
using namespace phoenix;
|
||||
|
||||
// RG - Future Work
|
||||
// - Handle multi-line strings using \ line continuation
|
||||
// - Make keywords case insensitive
|
||||
ID
|
||||
= ( lexeme_d[((alpha_p | ch_p('_')) >> *(alnum_p | ch_p('_')))]
|
||||
| real_p
|
||||
| lexeme_d[confix_p('"', *c_escape_ch_p, '"')]
|
||||
| comment_nest_p('<', '>')
|
||||
)[ID.name = construct_<std::string>(arg1,arg2)]
|
||||
;
|
||||
|
||||
a_list
|
||||
= list_p( ID[(a_list.key = arg1),
|
||||
(a_list.value = "true")
|
||||
]
|
||||
>> !( ch_p('=')
|
||||
>> ID[a_list.value = arg1])
|
||||
[phoenix::bind(&definition::call_prop_actor)
|
||||
(var(*this),a_list.key,a_list.value)],!ch_p(','));
|
||||
|
||||
attr_list = +(ch_p('[') >> !a_list >> ch_p(']'));
|
||||
|
||||
// RG - disregard port id's for now.
|
||||
port_location
|
||||
= (ch_p(':') >> ID)
|
||||
| (ch_p(':') >> ch_p('(') >> ID >> ch_p(',') >> ID >> ch_p(')'))
|
||||
;
|
||||
|
||||
port_angle = ch_p('@') >> ID;
|
||||
|
||||
port
|
||||
= port_location >> (!port_angle)
|
||||
| port_angle >> (!port_location);
|
||||
|
||||
|
||||
node_id
|
||||
= ( ID[node_id.name = arg1] >> (!port) )
|
||||
[phoenix::bind(&definition::memoize_node)(var(*this))];
|
||||
|
||||
graph_stmt
|
||||
= (ID[graph_stmt.key = arg1] >>
|
||||
ch_p('=') >>
|
||||
ID[graph_stmt.value = arg1])
|
||||
[phoenix::bind(&definition::call_graph_prop)
|
||||
(var(*this),graph_stmt.key,graph_stmt.value)]
|
||||
; // Graph property.
|
||||
|
||||
attr_stmt
|
||||
= (as_lower_d[keyword_p("graph")]
|
||||
>> attr_list(actor_t(phoenix::bind(&definition::default_graph_prop)
|
||||
(var(*this),arg1,arg2))))
|
||||
| (as_lower_d[keyword_p("node")]
|
||||
>> attr_list(actor_t(phoenix::bind(&definition::default_node_prop)
|
||||
(var(*this),arg1,arg2))))
|
||||
| (as_lower_d[keyword_p("edge")]
|
||||
>> attr_list(actor_t(phoenix::bind(&definition::default_edge_prop)
|
||||
(var(*this),arg1,arg2))))
|
||||
;
|
||||
|
||||
// edge_head is set depending on the graph type (directed/undirected)
|
||||
edgeop = ch_p('-') >> ch_p(boost::ref(edge_head));
|
||||
|
||||
edgeRHS
|
||||
= +( edgeop[(data_stmt.sources = data_stmt.dests),
|
||||
(data_stmt.dests = construct_<nodes_t>())]
|
||||
>> ( subgraph[data_stmt.dests = arg1]
|
||||
| node_id[phoenix::bind(&definition::insert_node)
|
||||
(var(*this),data_stmt.dests,arg1)]
|
||||
)
|
||||
[phoenix::bind(&definition::activate_edge)
|
||||
(var(*this),data_stmt.sources,data_stmt.dests,
|
||||
var(edges), var(default_edge_props))]
|
||||
);
|
||||
|
||||
|
||||
// To avoid backtracking, edge, node, and subgraph statements are
|
||||
// processed as one nonterminal.
|
||||
data_stmt
|
||||
= ( subgraph[(data_stmt.dests = arg1),// will get moved in rhs
|
||||
(data_stmt.saw_node = false)]
|
||||
| node_id[(phoenix::bind(&definition::insert_node)
|
||||
(var(*this),data_stmt.dests,arg1)),
|
||||
(data_stmt.saw_node = true),
|
||||
#ifdef BOOST_GRAPH_DEBUG
|
||||
(std::cout << val("AcTive Node: ") << arg1 << "\n"),
|
||||
#endif // BOOST_GRAPH_DEBUG
|
||||
(data_stmt.active_node = arg1)]
|
||||
) >> if_p(edgeRHS)[
|
||||
!attr_list(
|
||||
actor_t(phoenix::bind(&definition::edge_prop)
|
||||
(var(*this),arg1,arg2)))
|
||||
].else_p[
|
||||
if_p(data_stmt.saw_node)[
|
||||
!attr_list(
|
||||
actor_t(phoenix::bind(&definition::node_prop)
|
||||
(var(*this),arg1,arg2)))
|
||||
] // otherwise it's a subgraph, nothing more to do.
|
||||
];
|
||||
|
||||
|
||||
stmt
|
||||
= graph_stmt
|
||||
| attr_stmt
|
||||
| data_stmt
|
||||
;
|
||||
|
||||
stmt_list = *( stmt >> !ch_p(';') );
|
||||
|
||||
subgraph
|
||||
= !( as_lower_d[keyword_p("subgraph")]
|
||||
>> (!ID[(subgraph.name = arg1),
|
||||
(subgraph.nodes = (var(subgraph_nodes))[arg1]),
|
||||
(subgraph.edges = (var(subgraph_edges))[arg1])])
|
||||
)
|
||||
>> ch_p('{')[++var(subgraph_depth)]
|
||||
>> stmt_list
|
||||
>> ch_p('}')[--var(subgraph_depth)]
|
||||
[(var(subgraph_nodes))[subgraph.name] = subgraph.nodes]
|
||||
[(var(subgraph_edges))[subgraph.name] = subgraph.edges]
|
||||
|
||||
| as_lower_d[keyword_p("subgraph")]
|
||||
>> ID[(subgraph.nodes = (var(subgraph_nodes))[arg1]),
|
||||
(subgraph.edges = (var(subgraph_edges))[arg1])]
|
||||
;
|
||||
|
||||
the_grammar
|
||||
= (!as_lower_d[keyword_p("strict")])
|
||||
>> ( as_lower_d[keyword_p("graph")][
|
||||
(var(edge_head) = '-'),
|
||||
(phoenix::bind(&definition::check_undirected)(var(*this)))]
|
||||
| as_lower_d[keyword_p("digraph")][
|
||||
(var(edge_head) = '>'),
|
||||
(phoenix::bind(&definition::check_directed)(var(*this)))]
|
||||
)
|
||||
>> (!ID) >> ch_p('{') >> stmt_list >> ch_p('}');
|
||||
|
||||
} // definition()
|
||||
|
||||
typedef boost::spirit::classic::rule<ScannerT> rule_t;
|
||||
|
||||
rule_t const& start() const { return the_grammar; }
|
||||
|
||||
|
||||
//
|
||||
// Semantic actions
|
||||
//
|
||||
|
||||
void check_undirected() {
|
||||
if(self.graph_.is_directed())
|
||||
boost::throw_exception(boost::undirected_graph_error());
|
||||
}
|
||||
|
||||
void check_directed() {
|
||||
if(!self.graph_.is_directed())
|
||||
boost::throw_exception(boost::directed_graph_error());
|
||||
}
|
||||
|
||||
void memoize_node() {
|
||||
id_t const& node = node_id.name();
|
||||
props_t& node_props = default_node_props;
|
||||
|
||||
if(nodes.find(node) == nodes.end()) {
|
||||
nodes.insert(node);
|
||||
self.graph_.do_add_vertex(node);
|
||||
|
||||
node_map.insert(std::make_pair(node,ids_t()));
|
||||
|
||||
#ifdef BOOST_GRAPH_DEBUG
|
||||
std::cout << "Add new node " << node << std::endl;
|
||||
#endif // BOOST_GRAPH_DEBUG
|
||||
// Set the default properties for this edge
|
||||
// RG: Here I would actually set the properties
|
||||
for(props_t::iterator i = node_props.begin();
|
||||
i != node_props.end(); ++i) {
|
||||
set_node_property(node,i->first,i->second);
|
||||
}
|
||||
if(subgraph_depth > 0) {
|
||||
subgraph.nodes().insert(node);
|
||||
// Set the subgraph's default properties as well
|
||||
props_t& props = subgraph_node_props[subgraph.name()];
|
||||
for(props_t::iterator i = props.begin(); i != props.end(); ++i) {
|
||||
set_node_property(node,i->first,i->second);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#ifdef BOOST_GRAPH_DEBUG
|
||||
std::cout << "See node " << node << std::endl;
|
||||
#endif // BOOST_GRAPH_DEBUG
|
||||
}
|
||||
}
|
||||
|
||||
void activate_edge(nodes_t& sources, nodes_t& dests, edges_t& edges,
|
||||
props_t& edge_props) {
|
||||
edge_stack_t& edge_stack = data_stmt.edge_stack();
|
||||
for(nodes_t::iterator i = sources.begin(); i != sources.end(); ++i) {
|
||||
for(nodes_t::iterator j = dests.begin(); j != dests.end(); ++j) {
|
||||
// Create the edge and push onto the edge stack.
|
||||
#ifdef BOOST_GRAPH_DEBUG
|
||||
std::cout << "Edge " << *i << " to " << *j << std::endl;
|
||||
#endif // BOOST_GRAPH_DEBUG
|
||||
|
||||
edge_t edge = edge_t::new_edge();
|
||||
edge_stack.push_back(edge);
|
||||
edges.insert(edge);
|
||||
edge_map.insert(std::make_pair(edge,ids_t()));
|
||||
|
||||
// Add the real edge.
|
||||
self.graph_.do_add_edge(edge, *i, *j);
|
||||
|
||||
// Set the default properties for this edge
|
||||
for(props_t::iterator k = edge_props.begin();
|
||||
k != edge_props.end(); ++k) {
|
||||
set_edge_property(edge,k->first,k->second);
|
||||
}
|
||||
if(subgraph_depth > 0) {
|
||||
subgraph.edges().insert(edge);
|
||||
// Set the subgraph's default properties as well
|
||||
props_t& props = subgraph_edge_props[subgraph.name()];
|
||||
for(props_t::iterator k = props.begin(); k != props.end(); ++k) {
|
||||
set_edge_property(edge,k->first,k->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// node_prop - Assign the property for the current active node.
|
||||
void node_prop(id_t const& key, id_t const& value) {
|
||||
node_t& active_object = data_stmt.active_node();
|
||||
set_node_property(active_object, key, value);
|
||||
}
|
||||
|
||||
// edge_prop - Assign the property for the current active edges.
|
||||
void edge_prop(id_t const& key, id_t const& value) {
|
||||
edge_stack_t const& active_edges_ = data_stmt.edge_stack();
|
||||
for (edge_stack_t::const_iterator i = active_edges_.begin();
|
||||
i != active_edges_.end(); ++i) {
|
||||
set_edge_property(*i,key,value);
|
||||
}
|
||||
}
|
||||
|
||||
// default_graph_prop - Store as a graph property.
|
||||
void default_graph_prop(id_t const& key, id_t const& value) {
|
||||
#ifdef BOOST_GRAPH_DEBUG
|
||||
std::cout << key << " = " << value << std::endl;
|
||||
#endif // BOOST_GRAPH_DEBUG
|
||||
self.graph_.set_graph_property(key, value);
|
||||
}
|
||||
|
||||
// default_node_prop - declare default properties for any future new nodes
|
||||
void default_node_prop(id_t const& key, id_t const& value) {
|
||||
nodes_t& nodes_ =
|
||||
subgraph_depth == 0 ? nodes : subgraph.nodes();
|
||||
props_t& node_props_ =
|
||||
subgraph_depth == 0 ?
|
||||
default_node_props :
|
||||
subgraph_node_props[subgraph.name()];
|
||||
|
||||
// add this to the selected list of default node properties.
|
||||
node_props_[key] = value;
|
||||
// for each node, set its property to default-constructed value
|
||||
// if it hasn't been set already.
|
||||
// set the dynamic property map value
|
||||
for(nodes_t::iterator i = nodes_.begin(); i != nodes_.end(); ++i)
|
||||
if(node_map[*i].find(key) == node_map[*i].end()) {
|
||||
set_node_property(*i,key,id_t());
|
||||
}
|
||||
}
|
||||
|
||||
// default_edge_prop - declare default properties for any future new edges
|
||||
void default_edge_prop(id_t const& key, id_t const& value) {
|
||||
edges_t& edges_ =
|
||||
subgraph_depth == 0 ? edges : subgraph.edges();
|
||||
props_t& edge_props_ =
|
||||
subgraph_depth == 0 ?
|
||||
default_edge_props :
|
||||
subgraph_edge_props[subgraph.name()];
|
||||
|
||||
// add this to the list of default edge properties.
|
||||
edge_props_[key] = value;
|
||||
// for each edge, set its property to be empty string
|
||||
// set the dynamic property map value
|
||||
for(edges_t::iterator i = edges_.begin(); i != edges_.end(); ++i)
|
||||
if(edge_map[*i].find(key) == edge_map[*i].end())
|
||||
set_edge_property(*i,key,id_t());
|
||||
}
|
||||
|
||||
// helper function
|
||||
void insert_node(nodes_t& nodes, id_t const& name) {
|
||||
nodes.insert(name);
|
||||
}
|
||||
|
||||
void call_prop_actor(std::string const& lhs, std::string const& rhs) {
|
||||
actor_t& actor = attr_list.prop_actor();
|
||||
// If first and last characters of the rhs are double-quotes,
|
||||
// remove them.
|
||||
if (!rhs.empty() && rhs[0] == '"' && rhs[rhs.size() - 1] == '"')
|
||||
actor(lhs, rhs.substr(1, rhs.size()-2));
|
||||
else
|
||||
actor(lhs,rhs);
|
||||
}
|
||||
|
||||
void call_graph_prop(std::string const& lhs, std::string const& rhs) {
|
||||
// If first and last characters of the rhs are double-quotes,
|
||||
// remove them.
|
||||
if (!rhs.empty() && rhs[0] == '"' && rhs[rhs.size() - 1] == '"')
|
||||
this->default_graph_prop(lhs, rhs.substr(1, rhs.size()-2));
|
||||
else
|
||||
this->default_graph_prop(lhs,rhs);
|
||||
}
|
||||
|
||||
void set_node_property(node_t const& node, id_t const& key,
|
||||
id_t const& value) {
|
||||
|
||||
// Add the property key to the "set" table to avoid default overwrite
|
||||
node_map[node].insert(key);
|
||||
// Set the user's property map
|
||||
self.graph_.set_node_property(key, node, value);
|
||||
#ifdef BOOST_GRAPH_DEBUG
|
||||
// Tell the world
|
||||
std::cout << node << ": " << key << " = " << value << std::endl;
|
||||
#endif // BOOST_GRAPH_DEBUG
|
||||
}
|
||||
|
||||
void set_edge_property(edge_t const& edge, id_t const& key,
|
||||
id_t const& value) {
|
||||
|
||||
// Add the property key to the "set" table to avoid default overwrite
|
||||
edge_map[edge].insert(key);
|
||||
// Set the user's property map
|
||||
self.graph_.set_edge_property(key, edge, value);
|
||||
#ifdef BOOST_GRAPH_DEBUG
|
||||
// Tell the world
|
||||
#if 0 // RG - edge representation changed,
|
||||
std::cout << "(" << edge.first << "," << edge.second << "): "
|
||||
#else
|
||||
std::cout << "an edge: "
|
||||
#endif // 0
|
||||
<< key << " = " << value << std::endl;
|
||||
#endif // BOOST_GRAPH_DEBUG
|
||||
}
|
||||
|
||||
// Variables explicitly initialized
|
||||
dot_grammar const& self;
|
||||
// if subgraph_depth > 0, then we're processing a subgraph.
|
||||
int subgraph_depth;
|
||||
|
||||
// Keywords;
|
||||
const boost::spirit::classic::distinct_parser<> keyword_p;
|
||||
//
|
||||
// rules that make up the grammar
|
||||
//
|
||||
boost::spirit::classic::rule<ScannerT,id_closure::context_t> ID;
|
||||
boost::spirit::classic::rule<ScannerT,property_closure::context_t> a_list;
|
||||
boost::spirit::classic::rule<ScannerT,attr_list_closure::context_t> attr_list;
|
||||
rule_t port_location;
|
||||
rule_t port_angle;
|
||||
rule_t port;
|
||||
boost::spirit::classic::rule<ScannerT,node_id_closure::context_t> node_id;
|
||||
boost::spirit::classic::rule<ScannerT,property_closure::context_t> graph_stmt;
|
||||
rule_t attr_stmt;
|
||||
boost::spirit::classic::rule<ScannerT,data_stmt_closure::context_t> data_stmt;
|
||||
boost::spirit::classic::rule<ScannerT,subgraph_closure::context_t> subgraph;
|
||||
rule_t edgeop;
|
||||
rule_t edgeRHS;
|
||||
rule_t stmt;
|
||||
rule_t stmt_list;
|
||||
rule_t the_grammar;
|
||||
|
||||
|
||||
// The grammar uses edge_head to dynamically set the syntax for edges
|
||||
// directed graphs: edge_head = '>', and so edgeop = "->"
|
||||
// undirected graphs: edge_head = '-', and so edgeop = "--"
|
||||
char edge_head;
|
||||
|
||||
|
||||
//
|
||||
// Support data structures
|
||||
//
|
||||
|
||||
nodes_t nodes; // list of node names seen
|
||||
edges_t edges; // list of edges seen
|
||||
node_map_t node_map; // remember the properties set for each node
|
||||
edge_map_t edge_map; // remember the properties set for each edge
|
||||
|
||||
subgraph_nodes_t subgraph_nodes; // per-subgraph lists of nodes
|
||||
subgraph_edges_t subgraph_edges; // per-subgraph lists of edges
|
||||
|
||||
props_t default_node_props; // global default node properties
|
||||
props_t default_edge_props; // global default edge properties
|
||||
subgraph_props_t subgraph_node_props; // per-subgraph default node properties
|
||||
subgraph_props_t subgraph_edge_props; // per-subgraph default edge properties
|
||||
}; // struct definition
|
||||
}; // struct dot_grammar
|
||||
|
||||
|
||||
|
||||
//
|
||||
// dot_skipper - GraphViz whitespace and comment skipper
|
||||
//
|
||||
struct dot_skipper : public boost::spirit::classic::grammar<dot_skipper>
|
||||
{
|
||||
dot_skipper() {}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct definition
|
||||
{
|
||||
definition(dot_skipper const& /*self*/) {
|
||||
using namespace boost::spirit::classic;
|
||||
using namespace phoenix;
|
||||
// comment forms
|
||||
skip = eol_p >> comment_p("#")
|
||||
| space_p
|
||||
| comment_p("//")
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
|
||||
| confix_p(str_p("/*") ,*anychar_p, str_p("*/"))
|
||||
#else
|
||||
| confix_p("/*" ,*anychar_p, "*/")
|
||||
#endif
|
||||
;
|
||||
|
||||
#ifdef BOOST_SPIRIT_DEBUG
|
||||
BOOST_SPIRIT_DEBUG_RULE(skip);
|
||||
#endif
|
||||
}
|
||||
|
||||
boost::spirit::classic::rule<ScannerT> skip;
|
||||
boost::spirit::classic::rule<ScannerT> const&
|
||||
start() const { return skip; }
|
||||
}; // definition
|
||||
}; // dot_skipper
|
||||
|
||||
} // namespace graph
|
||||
} // namespace detail
|
||||
|
||||
template <typename MultiPassIterator, typename MutableGraph>
|
||||
bool read_graphviz_spirit(MultiPassIterator begin, MultiPassIterator end,
|
||||
MutableGraph& graph, dynamic_properties& dp,
|
||||
std::string const& node_id = "node_id") {
|
||||
using namespace boost;
|
||||
using namespace boost::spirit::classic;
|
||||
|
||||
typedef MultiPassIterator iterator_t;
|
||||
typedef skip_parser_iteration_policy< boost::detail::graph::dot_skipper>
|
||||
iter_policy_t;
|
||||
typedef scanner_policies<iter_policy_t> scanner_policies_t;
|
||||
typedef scanner<iterator_t, scanner_policies_t> scanner_t;
|
||||
|
||||
::boost::detail::graph::mutate_graph_impl<MutableGraph>
|
||||
m_graph(graph, dp, node_id);
|
||||
|
||||
::boost::detail::graph::dot_grammar p(m_graph);
|
||||
::boost::detail::graph::dot_skipper skip_p;
|
||||
|
||||
iter_policy_t iter_policy(skip_p);
|
||||
scanner_policies_t policies(iter_policy);
|
||||
|
||||
scanner_t scan(begin, end, policies);
|
||||
|
||||
return p.parse(scan);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_READ_GRAPHVIZ_SPIRIT_HPP
|
||||
418
test/external/boost/graph/detail/self_avoiding_walk.hpp
vendored
Normal file
418
test/external/boost/graph/detail/self_avoiding_walk.hpp
vendored
Normal file
@@ -0,0 +1,418 @@
|
||||
//=======================================================================
|
||||
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
|
||||
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
|
||||
//
|
||||
// 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 BOOST_SELF_AVOIDING_WALK_HPP
|
||||
#define BOOST_SELF_AVOIDING_WALK_HPP
|
||||
|
||||
/*
|
||||
This file defines necessary components for SAW.
|
||||
|
||||
mesh language: (defined by myself to clearify what is what)
|
||||
A triangle in mesh is called an triangle.
|
||||
An edge in mesh is called an line.
|
||||
A vertex in mesh is called a point.
|
||||
|
||||
A triangular mesh corresponds to a graph in which a vertex is a
|
||||
triangle and an edge(u, v) stands for triangle u and triangle v
|
||||
share an line.
|
||||
|
||||
After this point, a vertex always refers to vertex in graph,
|
||||
therefore it is a traingle in mesh.
|
||||
|
||||
*/
|
||||
|
||||
#include <utility>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
|
||||
#define SAW_SENTINAL -1
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <class T1, class T2, class T3>
|
||||
struct triple {
|
||||
T1 first;
|
||||
T2 second;
|
||||
T3 third;
|
||||
triple(const T1& a, const T2& b, const T3& c) : first(a), second(b), third(c) {}
|
||||
triple() : first(SAW_SENTINAL), second(SAW_SENTINAL), third(SAW_SENTINAL) {}
|
||||
};
|
||||
|
||||
typedef triple<int, int, int> Triple;
|
||||
|
||||
/* Define a vertex property which has a triangle inside. Triangle is
|
||||
represented by a triple. */
|
||||
struct triangle_tag { enum { num = 100 }; };
|
||||
typedef property<triangle_tag,Triple> triangle_property;
|
||||
|
||||
/* Define an edge property with a line. A line is represented by a
|
||||
pair. This is not required for SAW though.
|
||||
*/
|
||||
struct line_tag { enum { num = 101 }; };
|
||||
template <class T> struct line_property
|
||||
: public property<line_tag, std::pair<T,T> > { };
|
||||
|
||||
/*Precondition: Points in a Triangle are in order */
|
||||
template <class Triangle, class Line>
|
||||
inline void get_sharing(const Triangle& a, const Triangle& b, Line& l)
|
||||
{
|
||||
l.first = SAW_SENTINAL;
|
||||
l.second = SAW_SENTINAL;
|
||||
|
||||
if ( a.first == b.first ) {
|
||||
l.first = a.first;
|
||||
if ( a.second == b.second || a.second == b.third )
|
||||
l.second = a.second;
|
||||
else if ( a.third == b.second || a.third == b.third )
|
||||
l.second = a.third;
|
||||
|
||||
} else if ( a.first == b.second ) {
|
||||
l.first = a.first;
|
||||
if ( a.second == b.third )
|
||||
l.second = a.second;
|
||||
else if ( a.third == b.third )
|
||||
l.second = a.third;
|
||||
|
||||
} else if ( a.first == b.third ) {
|
||||
l.first = a.first;
|
||||
|
||||
|
||||
} else if ( a.second == b.first ) {
|
||||
l.first = a.second;
|
||||
if ( a.third == b.second || a.third == b.third )
|
||||
l.second = a.third;
|
||||
|
||||
} else if ( a.second == b.second ) {
|
||||
l.first = a.second;
|
||||
if ( a.third == b.third )
|
||||
l.second = a.third;
|
||||
|
||||
} else if ( a.second == b.third ) {
|
||||
l.first = a.second;
|
||||
|
||||
|
||||
} else if ( a.third == b.first
|
||||
|| a.third == b.second
|
||||
|| a.third == b.third )
|
||||
l.first = a.third;
|
||||
|
||||
/*Make it in order*/
|
||||
if ( l.first > l.second ) {
|
||||
typename Line::first_type i = l.first;
|
||||
l.first = l.second;
|
||||
l.second = i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <class TriangleDecorator, class Vertex, class Line>
|
||||
struct get_vertex_sharing {
|
||||
typedef std::pair<Vertex, Line> Pair;
|
||||
get_vertex_sharing(const TriangleDecorator& _td) : td(_td) {}
|
||||
inline Line operator()(const Vertex& u, const Vertex& v) const {
|
||||
Line l;
|
||||
get_sharing(td[u], td[v], l);
|
||||
return l;
|
||||
}
|
||||
inline Line operator()(const Pair& u, const Vertex& v) const {
|
||||
Line l;
|
||||
get_sharing(td[u.first], td[v], l);
|
||||
return l;
|
||||
}
|
||||
inline Line operator()(const Pair& u, const Pair& v) const {
|
||||
Line l;
|
||||
get_sharing(td[u.first], td[v.first], l);
|
||||
return l;
|
||||
}
|
||||
TriangleDecorator td;
|
||||
};
|
||||
|
||||
/* HList has to be a handle of data holder so that pass-by-value is
|
||||
* in right logic.
|
||||
*
|
||||
* The element of HList is a pair of vertex and line. (remember a
|
||||
* line is a pair of two ints.). That indicates the walk w from
|
||||
* current vertex is across line. (If the first of line is -1, it is
|
||||
* a point though.
|
||||
*/
|
||||
template < class TriangleDecorator, class HList, class IteratorD>
|
||||
class SAW_visitor
|
||||
: public bfs_visitor<>, public dfs_visitor<>
|
||||
{
|
||||
typedef typename boost::property_traits<IteratorD>::value_type iter;
|
||||
/*use boost shared_ptr*/
|
||||
typedef typename HList::element_type::value_type::second_type Line;
|
||||
public:
|
||||
|
||||
typedef tree_edge_tag category;
|
||||
|
||||
inline SAW_visitor(TriangleDecorator _td, HList _hlist, IteratorD ia)
|
||||
: td(_td), hlist(_hlist), iter_d(ia) {}
|
||||
|
||||
template <class Vertex, class Graph>
|
||||
inline void start_vertex(Vertex v, Graph&) {
|
||||
Line l1;
|
||||
l1.first = SAW_SENTINAL;
|
||||
l1.second = SAW_SENTINAL;
|
||||
hlist->push_front(std::make_pair(v, l1));
|
||||
iter_d[v] = hlist->begin();
|
||||
}
|
||||
|
||||
/*Several symbols:
|
||||
w(i): i-th triangle in walk w
|
||||
w(i) |- w(i+1): w enter w(i+1) from w(i) over a line
|
||||
w(i) ~> w(i+1): w enter w(i+1) from w(i) over a point
|
||||
w(i) -> w(i+1): w enter w(i+1) from w(i)
|
||||
w(i) ^ w(i+1): the line or point w go over from w(i) to w(i+1)
|
||||
*/
|
||||
template <class Edge, class Graph>
|
||||
bool tree_edge(Edge e, Graph& G) {
|
||||
using std::make_pair;
|
||||
typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
|
||||
Vertex tau = target(e, G);
|
||||
Vertex i = source(e, G);
|
||||
|
||||
get_vertex_sharing<TriangleDecorator, Vertex, Line> get_sharing_line(td);
|
||||
|
||||
Line tau_i = get_sharing_line(tau, i);
|
||||
|
||||
iter w_end = hlist->end();
|
||||
|
||||
iter w_i = iter_d[i];
|
||||
|
||||
iter w_i_m_1 = w_i;
|
||||
iter w_i_p_1 = w_i;
|
||||
|
||||
/*----------------------------------------------------------
|
||||
* true false
|
||||
*==========================================================
|
||||
*a w(i-1) |- w(i) w(i-1) ~> w(i) or w(i-1) is null
|
||||
*----------------------------------------------------------
|
||||
*b w(i) |- w(i+1) w(i) ~> w(i+1) or no w(i+1) yet
|
||||
*----------------------------------------------------------
|
||||
*/
|
||||
|
||||
bool a = false, b = false;
|
||||
|
||||
--w_i_m_1;
|
||||
++w_i_p_1;
|
||||
b = ( w_i->second.first != SAW_SENTINAL );
|
||||
|
||||
if ( w_i_m_1 != w_end ) {
|
||||
a = ( w_i_m_1->second.first != SAW_SENTINAL );
|
||||
}
|
||||
|
||||
if ( a ) {
|
||||
|
||||
if ( b ) {
|
||||
/*Case 1:
|
||||
|
||||
w(i-1) |- w(i) |- w(i+1)
|
||||
*/
|
||||
Line l1 = get_sharing_line(*w_i_m_1, tau);
|
||||
|
||||
iter w_i_m_2 = w_i_m_1;
|
||||
--w_i_m_2;
|
||||
|
||||
bool c = true;
|
||||
|
||||
if ( w_i_m_2 != w_end ) {
|
||||
c = w_i_m_2->second != l1;
|
||||
}
|
||||
|
||||
if ( c ) { /* w(i-1) ^ tau != w(i-2) ^ w(i-1) */
|
||||
/*extension: w(i-1) -> tau |- w(i) */
|
||||
w_i_m_1->second = l1;
|
||||
/*insert(pos, const T&) is to insert before pos*/
|
||||
iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
|
||||
|
||||
} else { /* w(i-1) ^ tau == w(i-2) ^ w(i-1) */
|
||||
/*must be w(i-2) ~> w(i-1) */
|
||||
|
||||
bool d = true;
|
||||
//need to handle the case when w_i_p_1 is null
|
||||
Line l3 = get_sharing_line(*w_i_p_1, tau);
|
||||
if ( w_i_p_1 != w_end )
|
||||
d = w_i_p_1->second != l3;
|
||||
if ( d ) { /* w(i+1) ^ tau != w(i+1) ^ w(i+2) */
|
||||
/*extension: w(i) |- tau -> w(i+1) */
|
||||
w_i->second = tau_i;
|
||||
iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l3));
|
||||
} else { /* w(i+1) ^ tau == w(i+1) ^ w(i+2) */
|
||||
/*must be w(1+1) ~> w(i+2) */
|
||||
Line l5 = get_sharing_line(*w_i_m_1, *w_i_p_1);
|
||||
if ( l5 != w_i_p_1->second ) { /* w(i-1) ^ w(i+1) != w(i+1) ^ w(i+2) */
|
||||
/*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> w(i+1) */
|
||||
w_i_m_2->second = get_sharing_line(*w_i_m_2, tau);
|
||||
iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
|
||||
w_i->second = w_i_m_1->second;
|
||||
w_i_m_1->second = l5;
|
||||
iter_d[w_i_m_1->first] = hlist->insert(w_i_p_1, *w_i_m_1);
|
||||
hlist->erase(w_i_m_1);
|
||||
} else {
|
||||
/*mesh is tetrahedral*/
|
||||
// dont know what that means.
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
/*Case 2:
|
||||
|
||||
w(i-1) |- w(i) ~> w(1+1)
|
||||
*/
|
||||
|
||||
if ( w_i->second.second == tau_i.first
|
||||
|| w_i->second.second == tau_i.second ) { /*w(i) ^ w(i+1) < w(i) ^ tau*/
|
||||
/*extension: w(i) |- tau -> w(i+1) */
|
||||
w_i->second = tau_i;
|
||||
Line l1 = get_sharing_line(*w_i_p_1, tau);
|
||||
iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
|
||||
} else { /*w(i) ^ w(i+1) !< w(i) ^ tau*/
|
||||
Line l1 = get_sharing_line(*w_i_m_1, tau);
|
||||
bool c = true;
|
||||
iter w_i_m_2 = w_i_m_1;
|
||||
--w_i_m_2;
|
||||
if ( w_i_m_2 != w_end )
|
||||
c = l1 != w_i_m_2->second;
|
||||
if (c) { /*w(i-1) ^ tau != w(i-2) ^ w(i-1)*/
|
||||
/*extension: w(i-1) -> tau |- w(i)*/
|
||||
w_i_m_1->second = l1;
|
||||
iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
|
||||
} else { /*w(i-1) ^ tau == w(i-2) ^ w(i-1)*/
|
||||
/*must be w(i-2)~>w(i-1)*/
|
||||
/*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> w(i+1)*/
|
||||
w_i_m_2->second = get_sharing_line(*w_i_m_2, tau);
|
||||
iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
|
||||
w_i->second = w_i_m_1->second;
|
||||
w_i_m_1->second = get_sharing_line(*w_i_m_1, *w_i_p_1);
|
||||
iter_d[w_i_m_1->first] = hlist->insert(w_i_p_1, *w_i_m_1);
|
||||
hlist->erase(w_i_m_1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ( b ) {
|
||||
/*Case 3:
|
||||
|
||||
w(i-1) ~> w(i) |- w(i+1)
|
||||
*/
|
||||
bool c = false;
|
||||
if ( w_i_m_1 != w_end )
|
||||
c = ( w_i_m_1->second.second == tau_i.first)
|
||||
|| ( w_i_m_1->second.second == tau_i.second);
|
||||
|
||||
if ( c ) { /*w(i-1) ^ w(i) < w(i) ^ tau*/
|
||||
/* extension: w(i-1) -> tau |- w(i) */
|
||||
if ( w_i_m_1 != w_end )
|
||||
w_i_m_1->second = get_sharing_line(*w_i_m_1, tau);
|
||||
iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
|
||||
} else {
|
||||
bool d = true;
|
||||
Line l1;
|
||||
l1.first = SAW_SENTINAL;
|
||||
l1.second = SAW_SENTINAL;
|
||||
if ( w_i_p_1 != w_end ) {
|
||||
l1 = get_sharing_line(*w_i_p_1, tau);
|
||||
d = l1 != w_i_p_1->second;
|
||||
}
|
||||
if (d) { /*w(i+1) ^ tau != w(i+1) ^ w(i+2)*/
|
||||
/*extension: w(i) |- tau -> w(i+1) */
|
||||
w_i->second = tau_i;
|
||||
iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
|
||||
} else {
|
||||
/*must be w(i+1) ~> w(i+2)*/
|
||||
/*extension: w(i-1) -> w(i+1) |- w(i) |- tau -> w(i+2) */
|
||||
iter w_i_p_2 = w_i_p_1;
|
||||
++w_i_p_2;
|
||||
|
||||
w_i_p_1->second = w_i->second;
|
||||
iter_d[i] = hlist->insert(w_i_p_2, make_pair(i, tau_i));
|
||||
hlist->erase(w_i);
|
||||
Line l2 = get_sharing_line(*w_i_p_2, tau);
|
||||
iter_d[tau] = hlist->insert(w_i_p_2, make_pair(tau, l2));
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
/*Case 4:
|
||||
|
||||
w(i-1) ~> w(i) ~> w(i+1)
|
||||
|
||||
*/
|
||||
bool c = false;
|
||||
if ( w_i_m_1 != w_end ) {
|
||||
c = (w_i_m_1->second.second == tau_i.first)
|
||||
|| (w_i_m_1->second.second == tau_i.second);
|
||||
}
|
||||
if ( c ) { /*w(i-1) ^ w(i) < w(i) ^ tau */
|
||||
/*extension: w(i-1) -> tau |- w(i) */
|
||||
if ( w_i_m_1 != w_end )
|
||||
w_i_m_1->second = get_sharing_line(*w_i_m_1, tau);
|
||||
iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
|
||||
} else {
|
||||
/*extension: w(i) |- tau -> w(i+1) */
|
||||
w_i->second = tau_i;
|
||||
Line l1;
|
||||
l1.first = SAW_SENTINAL;
|
||||
l1.second = SAW_SENTINAL;
|
||||
if ( w_i_p_1 != w_end )
|
||||
l1 = get_sharing_line(*w_i_p_1, tau);
|
||||
iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
TriangleDecorator td; /*a decorator for vertex*/
|
||||
HList hlist;
|
||||
/*This must be a handle of list to record the SAW
|
||||
The element type of the list is pair<Vertex, Line>
|
||||
*/
|
||||
|
||||
IteratorD iter_d;
|
||||
/*Problem statement: Need a fast access to w for triangle i.
|
||||
*Possible solution: mantain an array to record.
|
||||
iter_d[i] will return an iterator
|
||||
which points to w(i), where i is a vertex
|
||||
representing triangle i.
|
||||
*/
|
||||
};
|
||||
|
||||
template <class Triangle, class HList, class Iterator>
|
||||
inline
|
||||
SAW_visitor<Triangle, HList, Iterator>
|
||||
visit_SAW(Triangle t, HList hl, Iterator i) {
|
||||
return SAW_visitor<Triangle, HList, Iterator>(t, hl, i);
|
||||
}
|
||||
|
||||
template <class Tri, class HList, class Iter>
|
||||
inline
|
||||
SAW_visitor< random_access_iterator_property_map<Tri*,Tri,Tri&>,
|
||||
HList, random_access_iterator_property_map<Iter*,Iter,Iter&> >
|
||||
visit_SAW_ptr(Tri* t, HList hl, Iter* i) {
|
||||
typedef random_access_iterator_property_map<Tri*,Tri,Tri&> TriD;
|
||||
typedef random_access_iterator_property_map<Iter*,Iter,Iter&> IterD;
|
||||
return SAW_visitor<TriD, HList, IterD>(t, hl, i);
|
||||
}
|
||||
|
||||
// should also have combo's of pointers, and also const :(
|
||||
|
||||
}
|
||||
|
||||
#endif /*BOOST_SAW_H*/
|
||||
123
test/external/boost/graph/detail/set_adaptor.hpp
vendored
Normal file
123
test/external/boost/graph/detail/set_adaptor.hpp
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
// (C) Copyright Jeremy Siek 2001.
|
||||
// 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 BOOST_SET_ADAPTOR_HPP
|
||||
#define BOOST_SET_ADAPTOR_HPP
|
||||
|
||||
#include <set>
|
||||
#include <boost/unordered_set.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <class K, class C, class A, class T>
|
||||
bool set_contains(const std::set<K,C,A>& s, const T& x) {
|
||||
return s.find(x) != s.end();
|
||||
}
|
||||
|
||||
template <class K, class H, class C, class A, class T>
|
||||
bool set_contains(const boost::unordered_set<K,H,C,A>& s, const T& x) {
|
||||
return s.find(x) != s.end();
|
||||
}
|
||||
|
||||
template <class K, class C, class A>
|
||||
bool set_equal(const std::set<K,C,A>& x,
|
||||
const std::set<K,C,A>& y)
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
|
||||
// Not the same as lexicographical_compare_3way applied to std::set.
|
||||
// this is equivalent semantically to bitset::operator<()
|
||||
template <class K, class C, class A>
|
||||
int set_lex_order(const std::set<K,C,A>& x,
|
||||
const std::set<K,C,A>& y)
|
||||
{
|
||||
typename std::set<K,C,A>::iterator
|
||||
xi = x.begin(), yi = y.begin(), xend = x.end(), yend = y.end();
|
||||
for (; xi != xend && yi != yend; ++xi, ++yi) {
|
||||
if (*xi < *yi)
|
||||
return 1;
|
||||
else if (*yi < *xi)
|
||||
return -1;
|
||||
}
|
||||
if (xi == xend)
|
||||
return (yi == yend) ? 0 : -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <class K, class C, class A>
|
||||
void set_clear(std::set<K,C,A>& x) {
|
||||
x.clear();
|
||||
}
|
||||
|
||||
template <class K, class C, class A>
|
||||
bool set_empty(const std::set<K,C,A>& x) {
|
||||
return x.empty();
|
||||
}
|
||||
|
||||
template <class K, class C, class A, class T>
|
||||
void set_insert(std::set<K,C,A>& x, const T& a) {
|
||||
x.insert(a);
|
||||
}
|
||||
|
||||
template <class K, class C, class A, class T>
|
||||
void set_remove(std::set<K,C,A>& x, const T& a) {
|
||||
x.erase(a);
|
||||
}
|
||||
|
||||
template <class K, class C, class A>
|
||||
void set_intersect(const std::set<K,C,A>& x,
|
||||
const std::set<K,C,A>& y,
|
||||
std::set<K,C,A>& z)
|
||||
{
|
||||
z.clear();
|
||||
std::set_intersection(x.begin(), x.end(),
|
||||
y.begin(), y.end(),
|
||||
std::inserter(z));
|
||||
}
|
||||
|
||||
template <class K, class C, class A>
|
||||
void set_union(const std::set<K,C,A>& x,
|
||||
const std::set<K,C,A>& y,
|
||||
std::set<K,C,A>& z)
|
||||
{
|
||||
z.clear();
|
||||
std::set_union(x.begin(), x.end(),
|
||||
y.begin(), y.end(),
|
||||
std::inserter(z));
|
||||
}
|
||||
|
||||
template <class K, class C, class A>
|
||||
void set_difference(const std::set<K,C,A>& x,
|
||||
const std::set<K,C,A>& y,
|
||||
std::set<K,C,A>& z)
|
||||
{
|
||||
z.clear();
|
||||
std::set_difference(x.begin(), x.end(),
|
||||
y.begin(), y.end(),
|
||||
std::inserter(z, z.begin()));
|
||||
}
|
||||
|
||||
template <class K, class C, class A>
|
||||
bool set_subset(const std::set<K,C,A>& x,
|
||||
const std::set<K,C,A>& y)
|
||||
{
|
||||
return std::includes(x.begin(), x.end(), y.begin(), y.end());
|
||||
}
|
||||
|
||||
// Shit, can't implement this without knowing the size of the
|
||||
// universe.
|
||||
template <class K, class C, class A>
|
||||
void set_compliment(const std::set<K,C,A>& x,
|
||||
std::set<K,C,A>& z)
|
||||
{
|
||||
z.clear();
|
||||
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_SET_ADAPTOR_HPP
|
||||
139
test/external/boost/graph/detail/shadow_iterator.hpp
vendored
Normal file
139
test/external/boost/graph/detail/shadow_iterator.hpp
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
// (C) Copyright Jeremy Siek 2001.
|
||||
// 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 BOOST_SHADOW_ITERATOR_HPP
|
||||
#define BOOST_SHADOW_ITERATOR_HPP
|
||||
|
||||
#include <boost/iterator_adaptors.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class A, class B, class D>
|
||||
class shadow_proxy
|
||||
: boost::operators< shadow_proxy<A,B,D> >
|
||||
{
|
||||
typedef shadow_proxy self;
|
||||
public:
|
||||
inline shadow_proxy(A aa, B bb) : a(aa), b(bb) { }
|
||||
inline shadow_proxy(const self& x) : a(x.a), b(x.b) { }
|
||||
template <class Self>
|
||||
inline shadow_proxy(Self x) : a(x.a), b(x.b) { }
|
||||
inline self& operator=(const self& x) { a = x.a; b = x.b; return *this; }
|
||||
inline self& operator++() { ++a; return *this; }
|
||||
inline self& operator--() { --a; return *this; }
|
||||
inline self& operator+=(const self& x) { a += x.a; return *this; }
|
||||
inline self& operator-=(const self& x) { a -= x.a; return *this; }
|
||||
inline self& operator*=(const self& x) { a *= x.a; return *this; }
|
||||
inline self& operator/=(const self& x) { a /= x.a; return *this; }
|
||||
inline self& operator%=(const self& x) { return *this; } // JGS
|
||||
inline self& operator&=(const self& x) { return *this; } // JGS
|
||||
inline self& operator|=(const self& x) { return *this; } // JGS
|
||||
inline self& operator^=(const self& x) { return *this; } // JGS
|
||||
inline friend D operator-(const self& x, const self& y) {
|
||||
return x.a - y.a;
|
||||
}
|
||||
inline bool operator==(const self& x) const { return a == x.a; }
|
||||
inline bool operator<(const self& x) const { return a < x.a; }
|
||||
// protected:
|
||||
A a;
|
||||
B b;
|
||||
};
|
||||
|
||||
struct shadow_iterator_policies
|
||||
{
|
||||
template <typename iter_pair>
|
||||
void initialize(const iter_pair&) { }
|
||||
|
||||
template <typename Iter>
|
||||
typename Iter::reference dereference(const Iter& i) const {
|
||||
typedef typename Iter::reference R;
|
||||
return R(*i.base().first, *i.base().second);
|
||||
}
|
||||
template <typename Iter>
|
||||
bool equal(const Iter& p1, const Iter& p2) const {
|
||||
return p1.base().first == p2.base().first;
|
||||
}
|
||||
template <typename Iter>
|
||||
void increment(Iter& i) { ++i.base().first; ++i.base().second; }
|
||||
|
||||
template <typename Iter>
|
||||
void decrement(Iter& i) { --i.base().first; --i.base().second; }
|
||||
|
||||
template <typename Iter>
|
||||
bool less(const Iter& x, const Iter& y) const {
|
||||
return x.base().first < y.base().first;
|
||||
}
|
||||
template <typename Iter>
|
||||
typename Iter::difference_type
|
||||
distance(const Iter& x, const Iter& y) const {
|
||||
return y.base().first - x.base().first;
|
||||
}
|
||||
template <typename D, typename Iter>
|
||||
void advance(Iter& p, D n) { p.base().first += n; p.base().second += n; }
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename IterA, typename IterB>
|
||||
struct shadow_iterator_generator {
|
||||
|
||||
// To use the iterator_adaptor we can't derive from
|
||||
// random_access_iterator because we don't have a real reference.
|
||||
// However, we want the STL algorithms to treat the shadow
|
||||
// iterator like a random access iterator.
|
||||
struct shadow_iterator_tag : public std::input_iterator_tag {
|
||||
operator std::random_access_iterator_tag() {
|
||||
return std::random_access_iterator_tag();
|
||||
};
|
||||
};
|
||||
typedef typename std::iterator_traits<IterA>::value_type Aval;
|
||||
typedef typename std::iterator_traits<IterB>::value_type Bval;
|
||||
typedef typename std::iterator_traits<IterA>::reference Aref;
|
||||
typedef typename std::iterator_traits<IterB>::reference Bref;
|
||||
typedef typename std::iterator_traits<IterA>::difference_type D;
|
||||
typedef detail::shadow_proxy<Aval,Bval,Aval> V;
|
||||
typedef detail::shadow_proxy<Aref,Bref,Aval> R;
|
||||
typedef iterator_adaptor< std::pair<IterA, IterB>,
|
||||
detail::shadow_iterator_policies,
|
||||
V, R, V*, shadow_iterator_tag,
|
||||
D> type;
|
||||
};
|
||||
|
||||
// short cut for creating a shadow iterator
|
||||
template <class IterA, class IterB>
|
||||
inline typename shadow_iterator_generator<IterA,IterB>::type
|
||||
make_shadow_iter(IterA a, IterB b) {
|
||||
typedef typename shadow_iterator_generator<IterA,IterB>::type Iter;
|
||||
return Iter(std::make_pair(a,b));
|
||||
}
|
||||
|
||||
template <class Cmp>
|
||||
struct shadow_cmp {
|
||||
inline shadow_cmp(const Cmp& c) : cmp(c) { }
|
||||
template <class ShadowProxy1, class ShadowProxy2>
|
||||
inline bool operator()(const ShadowProxy1& x, const ShadowProxy2& y) const
|
||||
{
|
||||
return cmp(x.a, y.a);
|
||||
}
|
||||
Cmp cmp;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
namespace std {
|
||||
template <class A1, class B1, class D1,
|
||||
class A2, class B2, class D2>
|
||||
void swap(boost::detail::shadow_proxy<A1&,B1&,D1> x,
|
||||
boost::detail::shadow_proxy<A2&,B2&,D2> y)
|
||||
{
|
||||
std::swap(x.a, y.a);
|
||||
std::swap(x.b, y.b);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BOOST_SHADOW_ITERATOR_HPP
|
||||
198
test/external/boost/graph/detail/sparse_ordering.hpp
vendored
Normal file
198
test/external/boost/graph/detail/sparse_ordering.hpp
vendored
Normal file
@@ -0,0 +1,198 @@
|
||||
//=======================================================================
|
||||
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
|
||||
// Copyright 2004, 2005 Trustees of Indiana University
|
||||
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek,
|
||||
// Doug Gregor, D. Kevin McGrath
|
||||
//
|
||||
// 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 BOOST_GRAPH_DETAIL_SPARSE_ORDERING_HPP
|
||||
#define BOOST_GRAPH_DETAIL_SPARSE_ORDERING_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <boost/pending/queue.hpp>
|
||||
#include <boost/pending/mutable_queue.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/graph/breadth_first_search.hpp>
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <boost/pending/indirect_cmp.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/graph/iteration_macros.hpp>
|
||||
#include <boost/graph/depth_first_search.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace sparse {
|
||||
|
||||
// rcm_queue
|
||||
//
|
||||
// This is a custom queue type used in the
|
||||
// *_ordering algorithms.
|
||||
// In addition to the normal queue operations, the
|
||||
// rcm_queue provides:
|
||||
//
|
||||
// int eccentricity() const;
|
||||
// value_type spouse() const;
|
||||
//
|
||||
|
||||
// yes, it's a bad name...but it works, so use it
|
||||
template < class Vertex, class DegreeMap,
|
||||
class Container = std::deque<Vertex> >
|
||||
class rcm_queue : public std::queue<Vertex, Container> {
|
||||
typedef std::queue<Vertex> base;
|
||||
public:
|
||||
typedef typename base::value_type value_type;
|
||||
typedef typename base::size_type size_type;
|
||||
|
||||
/* SGI queue has not had a contructor queue(const Container&) */
|
||||
inline rcm_queue(DegreeMap deg)
|
||||
: _size(0), Qsize(1), eccen(-1), degree(deg) { }
|
||||
|
||||
inline void pop() {
|
||||
if ( !_size )
|
||||
Qsize = base::size();
|
||||
|
||||
base::pop();
|
||||
if ( _size == Qsize-1 ) {
|
||||
_size = 0;
|
||||
++eccen;
|
||||
} else
|
||||
++_size;
|
||||
|
||||
}
|
||||
|
||||
inline value_type& front() {
|
||||
value_type& u = base::front();
|
||||
if ( _size == 0 )
|
||||
w = u;
|
||||
else if (get(degree,u) < get(degree,w) )
|
||||
w = u;
|
||||
return u;
|
||||
}
|
||||
|
||||
inline const value_type& front() const {
|
||||
const value_type& u = base::front();
|
||||
if ( _size == 0 )
|
||||
w = u;
|
||||
else if (get(degree,u) < get(degree,w) )
|
||||
w = u;
|
||||
return u;
|
||||
}
|
||||
|
||||
inline value_type& top() { return front(); }
|
||||
inline const value_type& top() const { return front(); }
|
||||
|
||||
inline size_type size() const { return base::size(); }
|
||||
|
||||
inline size_type eccentricity() const { return eccen; }
|
||||
inline value_type spouse() const { return w; }
|
||||
|
||||
protected:
|
||||
size_type _size;
|
||||
size_type Qsize;
|
||||
int eccen;
|
||||
mutable value_type w;
|
||||
DegreeMap degree;
|
||||
};
|
||||
|
||||
|
||||
template <typename Tp, typename Sequence = std::deque<Tp> >
|
||||
class sparse_ordering_queue : public boost::queue<Tp, Sequence>{
|
||||
public:
|
||||
typedef typename Sequence::iterator iterator;
|
||||
typedef typename Sequence::reverse_iterator reverse_iterator;
|
||||
typedef queue<Tp,Sequence> base;
|
||||
typedef typename Sequence::size_type size_type;
|
||||
|
||||
inline iterator begin() { return this->c.begin(); }
|
||||
inline reverse_iterator rbegin() { return this->c.rbegin(); }
|
||||
inline iterator end() { return this->c.end(); }
|
||||
inline reverse_iterator rend() { return this->c.rend(); }
|
||||
inline Tp &operator[](int n) { return this->c[n]; }
|
||||
inline size_type size() {return this->c.size(); }
|
||||
protected:
|
||||
//nothing
|
||||
};
|
||||
|
||||
} // namespace sparse
|
||||
|
||||
// Compute Pseudo peripheral
|
||||
//
|
||||
// To compute an approximated peripheral for a given vertex.
|
||||
// Used in <tt>king_ordering</tt> algorithm.
|
||||
//
|
||||
template <class Graph, class Vertex, class ColorMap, class DegreeMap>
|
||||
Vertex
|
||||
pseudo_peripheral_pair(Graph const& G, const Vertex& u, int& ecc,
|
||||
ColorMap color, DegreeMap degree)
|
||||
{
|
||||
typedef typename property_traits<ColorMap>::value_type ColorValue;
|
||||
typedef color_traits<ColorValue> Color;
|
||||
|
||||
sparse::rcm_queue<Vertex, DegreeMap> Q(degree);
|
||||
|
||||
typename boost::graph_traits<Graph>::vertex_iterator ui, ui_end;
|
||||
for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui)
|
||||
if (get(color, *ui) != Color::red()) put(color, *ui, Color::white());
|
||||
breadth_first_visit(G, u, buffer(Q).color_map(color));
|
||||
|
||||
ecc = Q.eccentricity();
|
||||
return Q.spouse();
|
||||
}
|
||||
|
||||
// Find a good starting node
|
||||
//
|
||||
// This is to find a good starting node for the
|
||||
// king_ordering algorithm. "good" is in the sense
|
||||
// of the ordering generated by RCM.
|
||||
//
|
||||
template <class Graph, class Vertex, class Color, class Degree>
|
||||
Vertex find_starting_node(Graph const& G, Vertex r, Color color, Degree degree)
|
||||
{
|
||||
Vertex x, y;
|
||||
int eccen_r, eccen_x;
|
||||
|
||||
x = pseudo_peripheral_pair(G, r, eccen_r, color, degree);
|
||||
y = pseudo_peripheral_pair(G, x, eccen_x, color, degree);
|
||||
|
||||
while (eccen_x > eccen_r) {
|
||||
r = x;
|
||||
eccen_r = eccen_x;
|
||||
x = y;
|
||||
y = pseudo_peripheral_pair(G, x, eccen_x, color, degree);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
class out_degree_property_map
|
||||
: public put_get_helper<typename graph_traits<Graph>::degree_size_type,
|
||||
out_degree_property_map<Graph> >
|
||||
{
|
||||
public:
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor key_type;
|
||||
typedef typename graph_traits<Graph>::degree_size_type value_type;
|
||||
typedef value_type reference;
|
||||
typedef readable_property_map_tag category;
|
||||
out_degree_property_map(const Graph& g) : m_g(g) { }
|
||||
value_type operator[](const key_type& v) const {
|
||||
return out_degree(v, m_g);
|
||||
}
|
||||
private:
|
||||
const Graph& m_g;
|
||||
};
|
||||
template <typename Graph>
|
||||
inline out_degree_property_map<Graph>
|
||||
make_out_degree_map(const Graph& g) {
|
||||
return out_degree_property_map<Graph>(g);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_GRAPH_KING_HPP
|
||||
Reference in New Issue
Block a user