update boost

This commit is contained in:
2023-11-24 12:56:13 -06:00
parent cfc99971af
commit 19d727037a
9260 changed files with 849256 additions and 299957 deletions

View File

@@ -15,100 +15,118 @@
#include <utility>
#include <boost/detail/workaround.hpp>
#if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
# define BOOST_GRAPH_NO_OPTIONAL
#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>
#define BOOST_GRAPH_MEMBER .
#else
#define BOOST_GRAPH_MEMBER ->
#include <boost/optional.hpp>
#endif // ndef BOOST_GRAPH_NO_OPTIONAL
namespace boost {
namespace boost
{
namespace detail {
namespace detail
{
template < class VertexIterator, class OutEdgeIterator, class Graph >
class adj_list_edge_iterator
{
typedef adj_list_edge_iterator self;
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;
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() {}
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)
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)
{
++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);
}
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;
VertexIterator vBegin;
VertexIterator vCurr;
VertexIterator vEnd;
#ifdef BOOST_GRAPH_NO_OPTIONAL
std::pair<OutEdgeIterator, OutEdgeIterator> edges;
std::pair< OutEdgeIterator, OutEdgeIterator > edges;
#else
boost::optional<std::pair<OutEdgeIterator, OutEdgeIterator> >
edges;
boost::optional< std::pair< OutEdgeIterator, OutEdgeIterator > > edges;
#endif // ndef BOOST_GRAPH_NO_OPTIONAL
const Graph* m_g;
const Graph* m_g;
};
} // namespace detail
} // namespace detail
}

File diff suppressed because it is too large Load Diff

View File

@@ -14,170 +14,224 @@
#include <iterator>
#include <functional>
#include <boost/config.hpp>
#include <boost/iterator.hpp>
namespace boost {
namespace boost
{
/*
* Note: array_binary_tree is a completey balanced binary tree.
*/
#if !defined BOOST_NO_STD_ITERATOR_TRAITS
template <class RandomAccessIterator, class ID>
template < class RandomAccessIterator, class ID >
#else
template <class RandomAccessIterator, class ValueType, class ID>
template < class RandomAccessIterator, class ValueType, class ID >
#endif
class array_binary_tree_node {
class array_binary_tree_node
{
public:
typedef array_binary_tree_node ArrayBinaryTreeNode;
typedef RandomAccessIterator rep_iterator;
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;
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;
typedef int difference_type;
typedef ValueType value_type;
#endif
typedef difference_type size_type;
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
struct children_type
{
struct iterator
{ // replace with iterator_adaptor implementation -JGS
typedef std::bidirectional_iterator_tag iterator_category;
typedef ArrayBinaryTreeNode value_type;
typedef size_type difference_type;
typedef array_binary_tree_node* pointer;
typedef ArrayBinaryTreeNode& reference;
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;
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 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 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 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;
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;
};
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 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)
{
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;
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

View File

@@ -1,6 +1,6 @@
//=======================================================================
// Copyright 2013 University of Warsaw.
// Authors: Piotr Wygocki
// Authors: Piotr Wygocki
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -12,52 +12,55 @@
#include <boost/graph/filtered_graph.hpp>
namespace boost {
namespace detail {
template <class Graph, class ResCapMap>
filtered_graph<const Graph, is_residual_edge<ResCapMap> >
residual_graph(const Graph& g, ResCapMap residual_capacity) {
return filtered_graph<const Graph, is_residual_edge<ResCapMap> >
(g, is_residual_edge<ResCapMap>(residual_capacity));
}
template <class Graph, class PredEdgeMap, class ResCapMap,
class RevEdgeMap>
inline void
augment(const Graph& g,
typename graph_traits<Graph>::vertex_descriptor src,
typename graph_traits<Graph>::vertex_descriptor sink,
PredEdgeMap p,
ResCapMap residual_capacity,
RevEdgeMap reverse_edge)
namespace boost
{
namespace detail
{
typename graph_traits<Graph>::edge_descriptor e;
typename graph_traits<Graph>::vertex_descriptor u;
typedef typename property_traits<ResCapMap>::value_type FlowValue;
// find minimum residual capacity along the augmenting path
FlowValue delta = (std::numeric_limits<FlowValue>::max)();
e = get(p, sink);
do {
BOOST_USING_STD_MIN();
delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(delta, get(residual_capacity, e));
u = source(e, g);
e = get(p, u);
} while (u != src);
template < class Graph, class ResCapMap >
filtered_graph< const Graph, is_residual_edge< ResCapMap > > residual_graph(
const Graph& g, ResCapMap residual_capacity)
{
return filtered_graph< const Graph, is_residual_edge< ResCapMap > >(
g, is_residual_edge< ResCapMap >(residual_capacity));
}
// push delta units of flow along the augmenting path
e = get(p, sink);
do {
put(residual_capacity, e, get(residual_capacity, e) - delta);
put(residual_capacity, get(reverse_edge, e), get(residual_capacity, get(reverse_edge, e)) + delta);
u = source(e, g);
e = get(p, u);
} while (u != src);
}
template < class Graph, class PredEdgeMap, class ResCapMap,
class RevEdgeMap >
inline void augment(const Graph& g,
typename graph_traits< Graph >::vertex_descriptor src,
typename graph_traits< Graph >::vertex_descriptor sink, PredEdgeMap p,
ResCapMap residual_capacity, RevEdgeMap reverse_edge)
{
typename graph_traits< Graph >::edge_descriptor e;
typename graph_traits< Graph >::vertex_descriptor u;
typedef typename property_traits< ResCapMap >::value_type FlowValue;
// find minimum residual capacity along the augmenting path
FlowValue delta = (std::numeric_limits< FlowValue >::max)();
e = get(p, sink);
do
{
BOOST_USING_STD_MIN();
delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(
delta, get(residual_capacity, e));
u = source(e, g);
e = get(p, u);
} while (u != src);
// push delta units of flow along the augmenting path
e = get(p, sink);
do
{
put(residual_capacity, e, get(residual_capacity, e) - delta);
put(residual_capacity, get(reverse_edge, e),
get(residual_capacity, get(reverse_edge, e)) + delta);
u = source(e, g);
e = get(p, u);
} while (u != src);
}
} // namespace detail
} //namespace boost
} // namespace boost
#endif /* BOOST_GRAPH_AUGMENT_HPP */

View File

@@ -15,9 +15,11 @@
#include <boost/operators.hpp>
namespace boost {
namespace boost
{
namespace detail {
namespace detail
{
//=========================================================================
// Implementation details of connected_components
@@ -25,184 +27,180 @@ namespace boost {
// 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>
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) {}
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);
}
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;
ComponentsPA m_component;
comp_type& m_count;
};
template <class DiscoverTimeMap, class FinishTimeMap, class TimeT,
class DFSVisitor>
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) {}
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);
}
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;
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>
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);
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)
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++;
}
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>
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;
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)
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);
}
// 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]];
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());
// 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 IndexIterator, class Integer, class Distance>
class component_iterator
: boost::forward_iterator_helper<
component_iterator<IndexIterator,Integer,Distance>,
Integer, Distance,Integer*, Integer&>
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;
}
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)
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;
return x.node == y.node;
}
} // namespace detail
} // namespace detail
} // namespace detail
#if defined(__sgi) && !defined(__GNUC__)
#pragma reset woff 1234
#endif
#endif
#endif

View File

@@ -25,160 +25,172 @@
// (without move support from C++11), but it deep-copies the heap contents yet
// shallow-copies the index_in_heap_map.
namespace boost {
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);
// 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);
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 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) {}
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();
}
size_type size() const { return data.size(); }
bool empty() const {
return data.empty();
}
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() {
BOOST_ASSERT (!this->empty());
return data[0];
}
const Value& top() const {
BOOST_ASSERT (!this->empty());
return data[0];
}
void pop() {
BOOST_ASSERT (!this->empty());
put(index_in_heap, data[0], (size_type)(-1));
if (data.size() != 1) {
data[0] = data.back();
put(index_in_heap, data[0], (size_type)(0));
data.pop_back();
preserve_heap_property_down();
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();
} else {
data.pop_back();
}
}
Value& top()
{
BOOST_ASSERT(!this->empty());
return data[0];
}
const Value& top() const
{
BOOST_ASSERT(!this->empty());
return data[0];
}
void pop()
{
BOOST_ASSERT(!this->empty());
put(index_in_heap, data[0], (size_type)(-1));
if (data.size() != 1)
{
data[0] = data.back();
put(index_in_heap, data[0], (size_type)(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();
// 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));
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();
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;
}
DistanceMap keys() const { return distance; }
private:
private:
Compare compare;
Container data;
DistanceMap distance;
@@ -186,38 +198,41 @@ namespace boost {
// The distances being compared using compare and that are stored in the
// distance map
typedef typename boost::property_traits<DistanceMap>::value_type distance_type;
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;
}
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;
// Get the first child of a given node
static size_type first_child(size_type index)
{
return index * Arity + 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);
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));
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
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)])) {
@@ -229,90 +244,114 @@ namespace boost {
// 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
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();
// 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;
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 = first_child(index);
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;
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
}
}
}
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();
verify_heap();
}
};
};
} // namespace boost

View File

@@ -15,107 +15,108 @@
#include <boost/functional/hash.hpp>
namespace boost {
namespace boost
{
namespace detail {
namespace detail
{
template <typename Directed, typename Vertex>
struct edge_base
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;
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 < 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)
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();
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)
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());
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)
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();
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)
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();
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)
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();
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)
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();
return a.get_property() >= b.get_property();
}
} //namespace detail
} // namespace detail
} // namespace boost
namespace std {
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)
{
namespace std
{
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 << ")";
}
}
}
// Boost's functional/hash
namespace boost {
template<typename D, typename V>
struct hash<boost::detail::edge_desc_impl<D, V> >
{
std::size_t operator()(const boost::detail::edge_desc_impl<D, V> & x) const
{ return hash_value(x.get_property()); }
};
namespace boost
{
template < typename D, typename V >
struct hash< boost::detail::edge_desc_impl< D, V > >
{
std::size_t operator()(const boost::detail::edge_desc_impl< D, V >& x) const
{
return hash_value(x.get_property());
}
};
}
#endif // BOOST_GRAPH_DETAIL_DETAIL_EDGE_HPP

View File

@@ -0,0 +1,10 @@
#ifndef BOOST_GRAPH_DETAIL_EMPTY_HEADER_HPP_INCLUDED
#define BOOST_GRAPH_DETAIL_EMPTY_HEADER_HPP_INCLUDED
// Copyright 2018 Peter Dimov
//
// 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)
#endif // #ifndef BOOST_GRAPH_DETAIL_EMPTY_HEADER_HPP_INCLUDED

View File

@@ -33,32 +33,31 @@ namespace boost
// pages = {466--484},
// priority = {0},
// title = {A Graph-theoretic perspective on centrality},
// url = {http://dx.doi.org/10.1016/j.socnet.2005.11.005},
// url = {https://doi.org/10.1016/j.socnet.2005.11.005},
// volume = {28},
// year = {2006}
// }
// }
namespace detail {
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)
template < typename Graph, typename DistanceMap, typename Combinator,
typename Distance >
inline Distance combine_distances(
const Graph& g, DistanceMap dist, Combinator combine, Distance init)
{
BOOST_CONCEPT_ASSERT(( VertexListGraphConcept<Graph> ));
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
typedef typename graph_traits<Graph>::vertex_iterator VertexIterator;
BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept<DistanceMap,Vertex> ));
BOOST_CONCEPT_ASSERT(( NumericValueConcept<Distance> ));
typedef numeric_values<Distance> DistanceNumbers;
BOOST_CONCEPT_ASSERT(( AdaptableBinaryFunction<Combinator,Distance,Distance,Distance> ));
BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
typedef typename graph_traits< Graph >::vertex_iterator VertexIterator;
BOOST_CONCEPT_ASSERT(
(ReadablePropertyMapConcept< DistanceMap, Vertex >));
BOOST_CONCEPT_ASSERT((NumericValueConcept< Distance >));
typedef numeric_values< Distance > DistanceNumbers;
// NOTE: Disabled until this concept assert is fixed in Boost.ConceptCheck.
// BOOST_CONCEPT_ASSERT((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
@@ -66,12 +65,15 @@ namespace detail {
// zero, so it shouldn't be too problematic.
Distance ret = init;
VertexIterator i, end;
for(boost::tie(i, end) = vertices(g); i != end; ++i) {
for (boost::tie(i, end) = vertices(g); i != end; ++i)
{
Vertex v = *i;
if(get(dist, v) != DistanceNumbers::infinity()) {
if (get(dist, v) != DistanceNumbers::infinity())
{
ret = combine(ret, get(dist, v));
}
else {
else
{
ret = DistanceNumbers::infinity();
break;
}
@@ -81,51 +83,54 @@ namespace detail {
// Similar to std::plus<T>, but maximizes parameters
// rather than adding them.
template <typename T>
struct maximize
template < typename T > struct maximize
{
typedef T result_type;
typedef T first_argument_type;
typedef T second_argument_type;
T operator ()(T x, T y) const
{ BOOST_USING_STD_MAX(); return max BOOST_PREVENT_MACRO_SUBSTITUTION (x, y); }
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
template < typename T > struct reciprocal
{
typedef T result_type;
typedef T argument_type;
T operator ()(T t)
{ return T(1) / t; }
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>
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 typename graph_traits< Graph >::vertices_size_type size_type;
typedef numeric_values<distance_type> distance_values;
typedef numeric_values<result_type> result_values;
typedef numeric_values< distance_type > distance_values;
typedef numeric_values< result_type > result_values;
static inline distance_type infinite_distance()
{ return distance_values::infinity(); }
{
return distance_values::infinity();
}
static inline result_type infinite_result()
{ return result_values::infinity(); }
{
return result_values::infinity();
}
static inline result_type zero_result()
{ return result_values::zero(); }
static inline result_type zero_result() { return result_values::zero(); }
};
} /* namespace boost */

View File

@@ -12,282 +12,308 @@
#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)
namespace boost
{
// 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)
namespace graph
{
using std::distance;
typename std::iterator_traits<InputIterator>::difference_type n =
distance(first, last);
return (size_t)n;
}
namespace detail
{
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 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 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) {
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;
}
typedef typename std::iterator_traits<RowstartIterator>::value_type EdgeIndex;
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());
}
// Put the degree of each vertex v into m_rowstart[v + 1]
for (KeyIterator i = begin; i != end; ++i) {
if (key_filter(*i)) {
BOOST_ASSERT (key_transform(*i) < numkeys);
++starts[key_transform(*i) + 1];
}
}
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)
{
// 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 (VerticesSize i = 1; i < numkeys + 1; ++i) {
start_of_this_row += starts[i];
starts[i] = start_of_this_row;
}
}
typedef
typename std::iterator_traits< RowstartIterator >::value_type
EdgeIndex;
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) {
// Put the degree of each vertex v into m_rowstart[v + 1]
for (KeyIterator i = begin; i != end; ++i)
{
if (key_filter(*i))
{
BOOST_ASSERT(key_transform(*i) < numkeys);
++starts[key_transform(*i) + 1];
}
}
typedef typename std::iterator_traits<RowstartIterator>::value_type EdgeIndex;
// 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 (VerticesSize i = 1; i < numkeys + 1; ++i)
{
start_of_this_row += starts[i];
starts[i] = start_of_this_row;
}
}
// 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)) {
NumKeys source = key_transform(*i);
BOOST_ASSERT (source < numkeys);
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 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)
{
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
typename std::iterator_traits< RowstartIterator >::value_type
EdgeIndex;
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))
{
NumKeys source = key_transform(*i);
BOOST_ASSERT(source < numkeys);
EdgeIndex insert_pos = current_insert_positions[source];
++current_insert_positions[source];
values1_out[insert_pos] = *v1i;
}
}
}
// 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)) {
NumKeys source = key_transform(*i);
BOOST_ASSERT (source < numkeys);
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 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)
{
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
typename std::iterator_traits< RowstartIterator >::value_type
EdgeIndex;
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))
{
NumKeys source = key_transform(*i);
BOOST_ASSERT(source < numkeys);
EdgeIndex insert_pos = current_insert_positions[source];
++current_insert_positions[source];
values1_out[insert_pos] = *v1i;
values2_out[insert_pos] = *v2i;
}
}
}
// 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) {
BOOST_ASSERT (key_transform(key_begin[i]) < numkeys);
// 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 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)
{
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
typename std::iterator_traits< RowstartIterator >::value_type
EdgeIndex;
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)
{
BOOST_ASSERT(key_transform(key_begin[i]) < numkeys);
// 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]);
}
}
}
// 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) {
BOOST_ASSERT (key_transform(key_begin[i]) < numkeys);
// 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 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)
{
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);
}
}
typedef
typename std::iterator_traits< RowstartIterator >::value_type
EdgeIndex;
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);
}
}
}
// 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)
{
BOOST_ASSERT(key_transform(key_begin[i]) < numkeys);
// 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 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 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);
}
}
// The versions of operator()() here can't return by reference because the
// actual type passed in may not match Pair, in which case the reference
// parameter is bound to a temporary that could end up dangling after the
// operator returns.
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 Pair>
struct project1st {
typedef typename Pair::first_type result_type;
result_type operator()(const Pair& p) const {return p.first;}
};
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 project2nd {
typedef typename Pair::second_type result_type;
result_type operator()(const Pair& p) const {return p.second;}
};
// The versions of operator()() here can't return by reference because
// the actual type passed in may not match Pair, in which case the
// reference parameter is bound to a temporary that could end up
// dangling after the operator returns.
template < typename Pair > struct project1st
{
typedef typename Pair::first_type result_type;
result_type operator()(const Pair& p) const { return p.first; }
};
template < typename Pair > struct project2nd
{
typedef typename Pair::second_type result_type;
result_type operator()(const Pair& p) const { return p.second; }
};
}
}
}
}
#endif // BOOST_GRAPH_DETAIL_HISTOGRAM_SORT_HPP

View File

@@ -16,64 +16,83 @@
// OBSOLETE
namespace boost {
namespace boost
{
namespace detail {
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() );
}
struct in_edge_tag
{
};
struct out_edge_tag
{
};
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)
template < class Vertex, class Edge, class Iterator1D, class EdgeDir >
struct bidir_incidence_iterator
{
return x.i == y.i;
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)
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;
return x.i != y.i;
}
}
}
}
}
#endif

View File

@@ -13,65 +13,80 @@
#include <boost/operators.hpp>
namespace boost {
namespace boost
{
namespace detail {
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> {
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;
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;
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 "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) { }
// 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);
}
inline value_type operator*() const { return (m_current_index); }
bool operator==(const self& other_iterator) const {
return (m_current_index == *other_iterator);
}
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;
IndexRandomAccessIterator m_index_iterator;
value_type m_current_index;
}; // class component_index_iterator
} // namespace detail
} // namespace detail
} // namespace detail
#endif // BOOST_GRAPH_DETAIL_INCREMENTAL_COMPONENTS_HPP

View File

@@ -16,59 +16,62 @@
namespace boost
{
namespace detail
namespace detail
{
template < typename Graph > struct vertex_indexer
{
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)
{
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;
return get(vertex_index, g);
}
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 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
static value_type index(key_type k, const Graph& g)
{
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;
return get(vertex_index, g, k);
}
};
static const_map_type index_map(const Graph& g)
{ return get(edge_index, g); }
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 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
static const_map_type index_map(const Graph& g)
{
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;
};
}
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

View File

@@ -26,257 +26,271 @@
#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
namespace boost
{
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>
namespace detail
{
struct secret {};
public:
typedef no_property vertex_property_type;
typedef void vertex_bundled;
typedef secret vertex_map_type;
typedef secret const_vertex_map_type;
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;
secret operator[](secret) { return secret(); }
// Directly access a vertex or edge bundle
Property& operator[](Descriptor v)
{
return m_vertex_properties[get(vertex_index, derived(), v)];
}
vertex_map_type get_vertex_bundle() const {
return vertex_map_type();
}
const Property& operator[](Descriptor v) const
{
return m_vertex_properties[get(vertex_index, derived(), v)];
}
protected:
// All operations do nothing.
indexed_vertex_properties() { }
indexed_vertex_properties(std::size_t) { }
vertex_map_type get_vertex_bundle(
const IndexMap& index_map = IndexMap())
{
return vertex_map_type(m_vertex_properties.begin(), index_map);
}
public:
void clear() { }
void resize(std::size_t) { }
void reserve(std::size_t) { }
};
const_vertex_map_type get_vertex_bundle(
const IndexMap& index_map = IndexMap()) const
{
return const_vertex_map_type(
m_vertex_properties.begin(), index_map);
}
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;
protected:
// Default-construct with no property values
indexed_vertex_properties() {}
// Directly access a edge or edge bundle
Property& operator[](Descriptor v)
{ return m_edge_properties[get(edge_index, derived(), v)]; }
// Initialize with n default-constructed property values
indexed_vertex_properties(std::size_t n) : m_vertex_properties(n) {}
const Property& operator[](Descriptor v) const
{ return m_edge_properties[get(edge_index, derived(), v)]; }
public:
// Clear the properties vector
void clear() { m_vertex_properties.clear(); }
edge_map_type get_edge_bundle(const IndexMap& index_map = IndexMap()) {
return edge_map_type(m_edge_properties.begin(), index_map);
}
// Resize the properties vector
void resize(std::size_t n) { m_vertex_properties.resize(n); }
const_edge_map_type get_edge_bundle(const IndexMap& index_map = IndexMap()) const {
return const_edge_map_type(m_edge_properties.begin(), index_map);
}
// Reserve space in the vector of properties
void reserve(std::size_t n) { m_vertex_properties.reserve(n); }
protected:
// Default-construct with no property values
indexed_edge_properties() {}
// Add a new property value to the back
void push_back(const Property& prop)
{
m_vertex_properties.push_back(prop);
}
// Initialize with n default-constructed property values
indexed_edge_properties(std::size_t n) : m_edge_properties(n) { }
// Write an element by raw index
void write_by_index(std::size_t idx, const Property& prop)
{
m_vertex_properties[idx] = prop;
}
// Get the size of the properties vector
std::size_t size() const
{
return m_edge_properties.size();
}
// Access to the derived object
Derived& derived() { return *static_cast< Derived* >(this); }
// Clear the properties vector
void clear()
{
m_edge_properties.clear();
}
const Derived& derived() const
{
return *static_cast< const Derived* >(this);
}
// Resize the properties vector
void resize(std::size_t n)
{
m_edge_properties.resize(n);
}
public: // should be private, but friend templates not portable
std::vector< Property > m_vertex_properties;
};
// Reserve space in the vector of properties
void reserve(std::size_t n)
{
m_edge_properties.reserve(n);
}
template < typename Derived, typename Descriptor, typename IndexMap >
class indexed_vertex_properties< Derived, void, Descriptor, IndexMap >
{
struct secret
{
};
// Write an element by raw index
void write_by_index(std::size_t idx, const Property& prop)
{
m_edge_properties[idx] = prop;
}
public:
typedef no_property vertex_property_type;
typedef void vertex_bundled;
typedef secret vertex_map_type;
typedef secret const_vertex_map_type;
public:
// Add a new property value to the back
void push_back(const Property& prop)
{
m_edge_properties.push_back(prop);
}
secret operator[](secret) { return secret(); }
// 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));
}
vertex_map_type get_vertex_bundle() const { return vertex_map_type(); }
typedef typename std::vector<Property>::iterator iterator;
iterator begin() {return m_edge_properties.begin();}
iterator end() {return m_edge_properties.end();}
protected:
// All operations do nothing.
indexed_vertex_properties() {}
indexed_vertex_properties(std::size_t) {}
private:
// Access to the derived object
Derived& derived() { return *static_cast<Derived*>(this); }
public:
void clear() {}
void resize(std::size_t) {}
void reserve(std::size_t) {}
};
const Derived& derived() const
{ return *static_cast<const Derived*>(this); }
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;
public: // should be private, but friend templates not portable
std::vector<Property> m_edge_properties;
};
// Directly access a edge or edge bundle
Property& operator[](Descriptor v)
{
return m_edge_properties[get(edge_index, derived(), v)];
}
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;}
};
const Property& operator[](Descriptor v) const
{
return m_edge_properties[get(edge_index, derived(), v)];
}
template<typename Derived, typename Descriptor, typename IndexMap>
class indexed_edge_properties<Derived, void, Descriptor, IndexMap>
{
struct secret {};
edge_map_type get_edge_bundle(const IndexMap& index_map = IndexMap())
{
return edge_map_type(m_edge_properties.begin(), index_map);
}
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;
const_edge_map_type get_edge_bundle(
const IndexMap& index_map = IndexMap()) const
{
return const_edge_map_type(m_edge_properties.begin(), index_map);
}
secret operator[](secret) { return secret(); }
void write_by_index(std::size_t /*idx*/, const no_property& /*prop*/) {}
protected:
// Default-construct with no property values
indexed_edge_properties() {}
edge_map_type get_edge_bundle(const IndexMap& = IndexMap()) const {
return edge_map_type();
}
// Initialize with n default-constructed property values
indexed_edge_properties(std::size_t n) : m_edge_properties(n) {}
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) { }
// Get the size of the properties vector
std::size_t size() const { return m_edge_properties.size(); }
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*/) {}
// Clear the properties vector
void clear() { m_edge_properties.clear(); }
typedef dummy_no_property_iterator iterator;
iterator begin() {return dummy_no_property_iterator();}
iterator end() {return dummy_no_property_iterator();}
// 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(); }
};
}
}

View File

@@ -17,10 +17,14 @@
#include <boost/mpl/bool.hpp>
namespace boost {
namespace detail {
template <typename> struct is_distributed_selector: boost::mpl::false_ {};
}
namespace boost
{
namespace detail
{
template < typename > struct is_distributed_selector : boost::mpl::false_
{
};
}
}
#endif // BOOST_GRAPH_DETAIL_IS_DISTRIBUTED_SELECTOR_HPP

View File

@@ -9,7 +9,8 @@
#include <boost/graph/graph_mutability_traits.hpp>
namespace boost {
namespace boost
{
// Extend the graph mutability traits (and metafunctions) to include options
// for labeled graphs.
@@ -20,213 +21,207 @@ namespace boost {
// 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 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_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
{ };
: 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
{ };
: 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_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
{ };
: 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
{ };
: virtual labeled_add_vertex_property_tag,
virtual labeled_mutable_edge_property_graph_tag
{
};
// Metafunctions
template <typename Graph>
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
>
{ };
: mpl::bool_<
is_convertible< typename graph_mutability_traits< Graph >::category,
labeled_add_vertex_tag >::value >
{
};
template <typename Graph>
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
>
{ };
: mpl::bool_<
is_convertible< typename graph_mutability_traits< Graph >::category,
labeled_add_vertex_property_tag >::value >
{
};
template <typename Graph>
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
>
{ };
: mpl::bool_<
is_convertible< typename graph_mutability_traits< Graph >::category,
labeled_remove_vertex_tag >::value >
{
};
template <typename Graph>
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
>
{ };
: mpl::bool_<
is_convertible< typename graph_mutability_traits< Graph >::category,
labeled_add_edge_tag >::value >
{
};
template <typename Graph>
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
>
{ };
: mpl::bool_<
is_convertible< typename graph_mutability_traits< Graph >::category,
labeled_add_edge_property_tag >::value >
{
};
template <typename Graph>
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
>
{ };
: mpl::bool_<
is_convertible< typename graph_mutability_traits< Graph >::category,
labeled_remove_edge_tag >::value >
{
};
template <typename Graph>
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>
>
{ };
: mpl::and_< graph_has_add_vertex_by_label< Graph >,
graph_has_remove_vertex_by_label< Graph > >
{
};
template <typename 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>
>
{ };
: mpl::and_< graph_has_add_vertex_by_label< Graph >,
graph_has_remove_vertex_by_label< Graph > >
{
};
template <typename 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>
>
{ };
: mpl::and_< graph_has_add_edge_by_label< Graph >,
graph_has_remove_edge_by_label< Graph > >
{
};
template <typename 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>
>
{ };
: mpl::and_< graph_has_add_edge_by_label< Graph >,
graph_has_remove_edge_by_label< Graph > >
{
};
template <typename Graph>
template < typename Graph >
struct is_labeled_mutable_graph
: mpl::and_<
is_labeled_mutable_vertex_graph<Graph>,
is_labeled_mutable_edge_graph<Graph>
>
{ };
: mpl::and_< is_labeled_mutable_vertex_graph< Graph >,
is_labeled_mutable_edge_graph< Graph > >
{
};
template <typename 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>
>
{ };
: mpl::and_< is_labeled_mutable_vertex_property_graph< Graph >,
is_labeled_mutable_edge_property_graph< Graph > >
{
};
template <typename 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
>
{ };
: mpl::bool_<
is_convertible< typename graph_mutability_traits< Graph >::category,
labeled_add_only_property_graph_tag >::value >
{
};
template <typename Graph>
template < typename Graph >
struct is_labeled_graph
: mpl::bool_<
is_convertible<
typename graph_mutability_traits<Graph>::category,
label_vertex_tag
>::value
>
{ };
: mpl::bool_<
is_convertible< typename graph_mutability_traits< Graph >::category,
label_vertex_tag >::value >
{
};
template <typename> struct graph_mutability_traits;
template < typename > struct graph_mutability_traits;
namespace graph_detail {
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>,
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>,
typename mpl::if_< is_mutable_property_graph< Graph >,
labeled_mutable_property_graph_tag,
typename mpl::if_<
is_mutable_graph<Graph>,
typename mpl::if_< is_mutable_graph< Graph >,
labeled_mutable_graph_tag,
typename mpl::if_<
is_mutable_edge_graph<Graph>,
typename mpl::if_< is_mutable_edge_graph< Graph >,
labeled_graph_tag,
typename graph_mutability_traits<Graph>::category
>::type
>::type
>::type
>::type type;
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>
#define LABELED_GRAPH labeled_graph< G, L, S >
// Specialize mutability traits for the labeled graph.
// This specialization depends on the mutability of the underlying graph type.
// If the underlying graph is fully mutable, this is also fully mutable.
// Otherwise, it's different.
template <LABELED_GRAPH_PARAMS>
struct graph_mutability_traits< LABELED_GRAPH > {
template < LABELED_GRAPH_PARAMS >
struct graph_mutability_traits< LABELED_GRAPH >
{
typedef typename graph_detail::determine_mutability<
typename LABELED_GRAPH::graph_type
>::type category;
typename LABELED_GRAPH::graph_type >::type category;
};
#undef LABELED_GRAPH_PARAMS

View File

@@ -20,201 +20,187 @@
functions that do not require the container object!
*/
namespace boost {
namespace detail {
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)
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;
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)
template < class Node, class Next >
inline Node slist_remove_after(Node pos, Next next)
{
Node n = next(pos);
next(pos) = next(n);
return n;
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)
template < class Node, class Next >
inline Node slist_remove_range(Node before_first, Node last, Next next)
{
next(before_first) = last;
return last;
next(before_first) = last;
return last;
}
template <class Node, class Next>
inline Node
slist_previous(Node head, Node x, Node empty,
Next next)
template < class Node, class Next >
inline Node slist_previous(Node head, Node x, Node empty, Next next)
{
while (head != empty && next(head) != x)
head = next(head);
return head;
while (head != empty && 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)
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;
}
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 empty,
Next next)
template < class Node, class Next >
inline Node slist_reverse(Node node, Node empty, Next next)
{
Node result = node;
node = next(node);
next(result) = empty;
while(node) {
Node next = next(node);
next(node) = result;
result = node;
node = next;
}
return result;
Node result = node;
node = next(node);
next(result) = empty;
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 empty,
Next next)
template < class Node, class Next >
inline std::size_t slist_size(Node head, Node empty, Next next)
{
std::size_t s = 0;
for ( ; head != empty; head = next(head))
++s;
return s;
std::size_t s = 0;
for (; head != empty; head = next(head))
++s;
return s;
}
template <class Next, class Data>
class slist_iterator_policies
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) { }
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 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 > void increment(Node& x) const { x = m_next(x); }
template <class Node>
bool equal(Node& x, Node& y) const
{ return x == y; }
template < class Node > bool equal(Node& x, Node& y) const
{
return x == y;
}
protected:
Next m_next;
Data m_data;
Next m_next;
Data m_data;
};
//===========================================================================
// Doubly-Linked List Generic Implementation Functions
//===========================================================================
// 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)
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;
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)
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;
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)
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;
Node i, tmp;
i = next(sentinel);
while (i != sentinel)
{
tmp = i;
i = next(i);
del(tmp);
}
}
template <class Node, class Next, class Prev>
void
dlist_transfer(Node pos, Node first, Node last,
Next next, Prev prev)
template < class Node > inline bool dlist_empty(Node dummy)
{
if (pos != last) {
// Remove [first,last) from its old position
next(prev(last)) = pos;
next(prev(first)) = last;
next(prev(pos)) = first;
return next(dummy) == dummy;
}
// 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>
template < class Node, class Next, class Prev >
void dlist_transfer(Node pos, Node first, Node last, Next next, Prev prev)
{
typedef slist_iterator_policies<Next, Data> Base;
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); }
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)
{
}
dlist_iterator_policies(Next n, Prev p, Data d)
: Base(n,d), m_prev(p) { }
protected:
Prev m_prev;
Prev m_prev;
};
} // namespace detail
} // namespace detail
} // namespace boost
#endif // BOOST_LIST_BASE_HPP

View File

@@ -0,0 +1,16 @@
#ifndef BOOST_GRAPH_DETAIL_MPI_INCLUDE_HPP_INCLUDED
#define BOOST_GRAPH_DETAIL_MPI_INCLUDE_HPP_INCLUDED
// Copyright 2018 Peter Dimov
//
// 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)
#if defined BOOST_GRAPH_USE_MPI
#define BOOST_GRAPH_MPI_INCLUDE(x) x
#else
#define BOOST_GRAPH_MPI_INCLUDE(x) <boost/graph/detail/empty_header.hpp>
#endif
#endif // #ifndef BOOST_GRAPH_DETAIL_MPI_INCLUDE_HPP_INCLUDED

View File

@@ -12,194 +12,200 @@
#include <algorithm>
#include <boost/graph/detail/shadow_iterator.hpp>
namespace boost {
namespace boost
{
template <class Iter1, class Iter2>
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:
typedef std::ptrdiff_t D :
#else
typedef typename std::iterator_traits<Iter1>::difference_type D;
typedef typename std::iterator_traits< Iter1 >::difference_type D;
#endif
D n = 0;
while (permuter != last) {
std::swap(result[n], result[*permuter]);
++n;
++permuter;
}
D n
= 0;
while (permuter != last)
{
std::swap(result[n], result[*permuter]);
++n;
++permuter;
}
}
template <class InIter, class RandIterP, class RandIterR>
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;
typedef std::ptrdiff_t i = 0;
#else
typename std::iterator_traits<RandIterP>::difference_type i = 0;
typename std::iterator_traits< RandIterP >::difference_type i = 0;
#endif
for (; first != last; ++first, ++i)
result[p[i]] = *first;
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)
namespace detail
{
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;
}
}
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>
template < class RandIter, class RandIterPerm >
void permute(RandIter first, RandIter last, RandIterPerm p)
{
detail::permute_helper(first, last, p, last - first, *first);
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)
template < class PermIter > void invert_permutation(PermIter X, PermIter Xend)
{
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
typedef std::ptrdiff_t T:
typedef std::ptrdiff_t T :
#else
typedef typename std::iterator_traits<PermIter>::value_type T;
typedef typename std::iterator_traits< PermIter >::value_type T;
#endif
T n = Xend - X;
T m = n;
T j = -1;
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;
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;
}
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>
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;
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;
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]);
}
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>
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);
}
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>
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);
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>
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>());
typedef typename std::iterator_traits< IterP >::value_type P;
sortp(first, last, p, cmp, std::allocator< P >());
}
template <class Iter, class IterP>
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>());
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>
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);
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

View File

@@ -5,19 +5,19 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
// read_graphviz_new.hpp -
// 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.
// DOT Language.
//
// Based on the grammar found at:
// http://www.graphviz.org/cvs/doc/info/lang.html
// https://web.archive.org/web/20041213234742/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:
// See documentation for this code at:
// http://www.boost.org/libs/graph/doc/read_graphviz.html
//
@@ -41,66 +41,82 @@
#include <iostream>
#include <cstdlib>
namespace boost {
namespace boost
{
namespace read_graphviz_detail {
typedef std::string node_name;
typedef std::string subgraph_name;
namespace read_graphviz_detail
{
typedef std::string node_name;
typedef std::string subgraph_name;
typedef std::map<std::string, std::string> properties;
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
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)
{
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;
}
};
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 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
};
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);
// 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);
// 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
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);
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

File diff suppressed because it is too large Load Diff

View File

@@ -10,19 +10,19 @@
#define BOOST_SELF_AVOIDING_WALK_HPP
/*
This file defines necessary components for SAW.
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.
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
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.
therefore it is a traingle in mesh.
*/
@@ -33,135 +33,161 @@
#define SAW_SENTINAL -1
namespace boost {
namespace boost
{
template <class T1, class T2, class T3>
struct triple {
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(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;
typedef triple< int, int, int > Triple;
/* 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> > { };
/* 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;
/*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)
{
/* 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;
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;
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;
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 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 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;
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:
};
/* 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) {}
: 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();
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:
@@ -171,248 +197,287 @@ namespace boost {
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);
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();
get_vertex_sharing< TriangleDecorator, Vertex, Line > get_sharing_line(
td);
iter w_i = iter_d[i];
Line tau_i = get_sharing_line(tau, i);
iter w_i_m_1 = w_i;
iter w_i_p_1 = w_i;
iter w_end = hlist->end();
/*----------------------------------------------------------
* 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;
iter w_i = iter_d[i];
--w_i_m_1;
++w_i_p_1;
b = ( w_i->second.first != SAW_SENTINAL );
iter w_i_m_1 = w_i;
iter w_i_p_1 = w_i;
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);
/*----------------------------------------------------------
* 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
*----------------------------------------------------------
*/
iter w_i_m_2 = w_i_m_1;
--w_i_m_2;
bool a = false, b = false;
bool c = true;
if ( w_i_m_2 != w_end ) {
c = w_i_m_2->second != l1;
}
--w_i_m_1;
++w_i_p_1;
b = (w_i->second.first != SAW_SENTINAL);
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);
}
}
if (w_i_m_1 != w_end)
{
a = (w_i_m_1->second.first != SAW_SENTINAL);
}
} 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;
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:
protected:
TriangleDecorator td; /*a decorator for vertex*/
HList hlist;
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;
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
*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 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);
}
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 :(
// should also have combo's of pointers, and also const :(
}
#endif /*BOOST_SAW_H*/

View File

@@ -9,115 +9,110 @@
#include <set>
#include <boost/unordered_set.hpp>
namespace boost {
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;
}
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();
}
// 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)
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)
{
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;
return 1;
else if (*yi < *xi)
return -1;
}
if (xi == xend)
return -1;
}
if (xi == xend)
return (yi == yend) ? 0 : -1;
else
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 > 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 >
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_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, 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_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_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_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 >
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>
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());
}
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()));
}
// 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
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

View File

@@ -9,131 +9,175 @@
#include <boost/iterator_adaptors.hpp>
#include <boost/operators.hpp>
namespace boost {
namespace boost
{
namespace detail {
namespace detail
{
template <class A, class B, class D>
class shadow_proxy
: boost::operators< shadow_proxy<A,B,D> >
template < class A, class B, class D >
class shadow_proxy : boost::operators< shadow_proxy< A, B, D > >
{
typedef shadow_proxy self;
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;
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_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 >
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 > 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; }
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
} // namespace detail
template < typename IterA, typename IterB > struct shadow_iterator_generator
{
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();
};
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;
};
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));
}
// 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>
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);
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)
{
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

View File

@@ -21,13 +21,14 @@
#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 boost
{
namespace sparse {
namespace sparse
{
// rcm_queue
//
@@ -35,164 +36,175 @@ namespace boost {
// *_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;
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;
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) { }
/* 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();
inline void pop()
{
if (!_size)
Qsize = base::size();
base::pop();
if ( _size == Qsize-1 ) {
_size = 0;
++eccen;
} else
++_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 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 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 value_type& top() { return front(); }
inline const value_type& top() const { return front(); }
inline size_type size() const { return base::size(); }
inline size_type size() const { return base::size(); }
inline size_type eccentricity() const { return eccen; }
inline value_type spouse() const { return w; }
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;
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;
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(); }
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
// 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);
} // namespace sparse
typename boost::graph_traits<Graph>::vertex_iterator ui, ui_end;
// 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());
if (get(color, *ui) != Color::red())
put(color, *ui, Color::white());
breadth_first_visit(G, u, buffer(Q).color_map(color));
ecc = Q.eccentricity();
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)
{
// 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);
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> >
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);
}
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;
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);
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