update boost
This commit is contained in:
@@ -19,116 +19,140 @@
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/concept/assert.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template <class BucketType, class ValueType, class Bucket,
|
||||
class ValueIndexMap>
|
||||
class bucket_sorter {
|
||||
public:
|
||||
template < class BucketType, class ValueType, class Bucket,
|
||||
class ValueIndexMap >
|
||||
class bucket_sorter
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT(
|
||||
(ReadablePropertyMapConcept< ValueIndexMap, ValueType >));
|
||||
|
||||
public:
|
||||
typedef BucketType bucket_type;
|
||||
typedef ValueType value_type;
|
||||
typedef typename std::vector<value_type>::size_type size_type;
|
||||
|
||||
bucket_sorter(size_type _length, bucket_type _max_bucket,
|
||||
const Bucket& _bucket = Bucket(),
|
||||
const ValueIndexMap& _id = ValueIndexMap())
|
||||
: head(_max_bucket, invalid_value()),
|
||||
next(_length, invalid_value()),
|
||||
prev(_length, invalid_value()),
|
||||
id_to_value(_length),
|
||||
bucket(_bucket), id(_id) { }
|
||||
|
||||
void remove(const value_type& x) {
|
||||
const size_type i = get(id, x);
|
||||
const size_type& next_node = next[i];
|
||||
const size_type& prev_node = prev[i];
|
||||
|
||||
//check if i is the end of the bucket list
|
||||
if ( next_node != invalid_value() )
|
||||
prev[next_node] = prev_node;
|
||||
//check if i is the begin of the bucket list
|
||||
if ( prev_node != invalid_value() )
|
||||
next[prev_node] = next_node;
|
||||
else //need update head of current bucket list
|
||||
head[ bucket[x] ] = next_node;
|
||||
typedef typename std::vector< value_type >::size_type size_type;
|
||||
|
||||
bucket_sorter(size_type _length, bucket_type _max_bucket,
|
||||
const Bucket& _bucket = Bucket(),
|
||||
const ValueIndexMap& _id = ValueIndexMap())
|
||||
: head(_max_bucket, invalid_value())
|
||||
, next(_length, invalid_value())
|
||||
, prev(_length, invalid_value())
|
||||
, id_to_value(_length)
|
||||
, bucket(_bucket)
|
||||
, id(_id)
|
||||
{
|
||||
}
|
||||
|
||||
void push(const value_type& x) {
|
||||
id_to_value[get(id, x)] = x;
|
||||
(*this)[bucket[x]].push(x);
|
||||
void remove(const value_type& x)
|
||||
{
|
||||
const size_type i = get(id, x);
|
||||
const size_type& next_node = next[i];
|
||||
const size_type& prev_node = prev[i];
|
||||
|
||||
// check if i is the end of the bucket list
|
||||
if (next_node != invalid_value())
|
||||
prev[next_node] = prev_node;
|
||||
// check if i is the begin of the bucket list
|
||||
if (prev_node != invalid_value())
|
||||
next[prev_node] = next_node;
|
||||
else // need update head of current bucket list
|
||||
head[bucket[x]] = next_node;
|
||||
}
|
||||
|
||||
void update(const value_type& x) {
|
||||
remove(x);
|
||||
(*this)[bucket[x]].push(x);
|
||||
|
||||
void push(const value_type& x)
|
||||
{
|
||||
id_to_value[get(id, x)] = x;
|
||||
(*this)[bucket[x]].push(x);
|
||||
}
|
||||
// private:
|
||||
|
||||
void update(const value_type& x)
|
||||
{
|
||||
remove(x);
|
||||
(*this)[bucket[x]].push(x);
|
||||
}
|
||||
// private:
|
||||
// with KCC, the nested stack class is having access problems
|
||||
// despite the friend decl.
|
||||
static size_type invalid_value() {
|
||||
return (std::numeric_limits<size_type>::max)();
|
||||
static size_type invalid_value()
|
||||
{
|
||||
return (std::numeric_limits< size_type >::max)();
|
||||
}
|
||||
|
||||
typedef typename std::vector<size_type>::iterator Iter;
|
||||
typedef typename std::vector<value_type>::iterator IndexValueMap;
|
||||
|
||||
public:
|
||||
|
||||
typedef typename std::vector< size_type >::iterator Iter;
|
||||
typedef typename std::vector< value_type >::iterator IndexValueMap;
|
||||
|
||||
public:
|
||||
friend class stack;
|
||||
|
||||
class stack {
|
||||
class stack
|
||||
{
|
||||
public:
|
||||
stack(bucket_type _bucket_id, Iter h, Iter n, Iter p, IndexValueMap v,
|
||||
stack(bucket_type _bucket_id, Iter h, Iter n, Iter p, IndexValueMap v,
|
||||
const ValueIndexMap& _id)
|
||||
: bucket_id(_bucket_id), head(h), next(n), prev(p), value(v), id(_id) {}
|
||||
: bucket_id(_bucket_id), head(h), next(n), prev(p), value(v), id(_id)
|
||||
{
|
||||
}
|
||||
|
||||
// Avoid using default arg for ValueIndexMap so that the default
|
||||
// constructor of the ValueIndexMap is not required if not used.
|
||||
stack(bucket_type _bucket_id, Iter h, Iter n, Iter p, IndexValueMap v)
|
||||
: bucket_id(_bucket_id), head(h), next(n), prev(p), value(v)
|
||||
{
|
||||
}
|
||||
|
||||
void push(const value_type& x)
|
||||
{
|
||||
const size_type new_head = get(id, x);
|
||||
const size_type current = head[bucket_id];
|
||||
if (current != invalid_value())
|
||||
prev[current] = new_head;
|
||||
prev[new_head] = invalid_value();
|
||||
next[new_head] = current;
|
||||
head[bucket_id] = new_head;
|
||||
}
|
||||
void pop()
|
||||
{
|
||||
size_type current = head[bucket_id];
|
||||
size_type next_node = next[current];
|
||||
head[bucket_id] = next_node;
|
||||
if (next_node != invalid_value())
|
||||
prev[next_node] = invalid_value();
|
||||
}
|
||||
value_type& top() { return value[head[bucket_id]]; }
|
||||
const value_type& top() const { return value[head[bucket_id]]; }
|
||||
bool empty() const { return head[bucket_id] == invalid_value(); }
|
||||
|
||||
// Avoid using default arg for ValueIndexMap so that the default
|
||||
// constructor of the ValueIndexMap is not required if not used.
|
||||
stack(bucket_type _bucket_id, Iter h, Iter n, Iter p, IndexValueMap v)
|
||||
: bucket_id(_bucket_id), head(h), next(n), prev(p), value(v) {}
|
||||
|
||||
void push(const value_type& x) {
|
||||
const size_type new_head = get(id, x);
|
||||
const size_type current = head[bucket_id];
|
||||
if ( current != invalid_value() )
|
||||
prev[current] = new_head;
|
||||
prev[new_head] = invalid_value();
|
||||
next[new_head] = current;
|
||||
head[bucket_id] = new_head;
|
||||
}
|
||||
void pop() {
|
||||
size_type current = head[bucket_id];
|
||||
size_type next_node = next[current];
|
||||
head[bucket_id] = next_node;
|
||||
if ( next_node != invalid_value() )
|
||||
prev[next_node] = invalid_value();
|
||||
}
|
||||
value_type& top() { return value[ head[bucket_id] ]; }
|
||||
const value_type& top() const { return value[ head[bucket_id] ]; }
|
||||
bool empty() const { return head[bucket_id] == invalid_value(); }
|
||||
private:
|
||||
bucket_type bucket_id;
|
||||
Iter head;
|
||||
Iter next;
|
||||
Iter prev;
|
||||
IndexValueMap value;
|
||||
ValueIndexMap id;
|
||||
bucket_type bucket_id;
|
||||
Iter head;
|
||||
Iter next;
|
||||
Iter prev;
|
||||
IndexValueMap value;
|
||||
ValueIndexMap id;
|
||||
};
|
||||
|
||||
stack operator[](const bucket_type& i) {
|
||||
assert(i < head.size());
|
||||
return stack(i, head.begin(), next.begin(), prev.begin(),
|
||||
id_to_value.begin(), id);
|
||||
|
||||
stack operator[](const bucket_type& i)
|
||||
{
|
||||
assert(i < head.size());
|
||||
return stack(i, head.begin(), next.begin(), prev.begin(),
|
||||
id_to_value.begin(), id);
|
||||
}
|
||||
protected:
|
||||
std::vector<size_type> head;
|
||||
std::vector<size_type> next;
|
||||
std::vector<size_type> prev;
|
||||
std::vector<value_type> id_to_value;
|
||||
|
||||
protected:
|
||||
std::vector< size_type > head;
|
||||
std::vector< size_type > next;
|
||||
std::vector< size_type > prev;
|
||||
std::vector< value_type > id_to_value;
|
||||
Bucket bucket;
|
||||
ValueIndexMap id;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
// (C) Copyright Jeremy Siek 2004
|
||||
// (C) Copyright Jeremy Siek 2004
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -6,83 +6,88 @@
|
||||
#ifndef BOOST_DETAIL_DISJOINT_SETS_HPP
|
||||
#define BOOST_DETAIL_DISJOINT_SETS_HPP
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class ParentPA, class Vertex>
|
||||
Vertex
|
||||
find_representative_with_path_halving(ParentPA p, Vertex v)
|
||||
{
|
||||
Vertex parent = get(p, v);
|
||||
Vertex grandparent = get(p, parent);
|
||||
while (parent != grandparent) {
|
||||
put(p, v, grandparent);
|
||||
v = grandparent;
|
||||
parent = get(p, v);
|
||||
grandparent = get(p, parent);
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
template <class ParentPA, class Vertex>
|
||||
Vertex
|
||||
find_representative_with_full_compression(ParentPA parent, Vertex v)
|
||||
namespace boost
|
||||
{
|
||||
Vertex old = v;
|
||||
Vertex ancestor = get(parent, v);
|
||||
while (ancestor != v) {
|
||||
v = ancestor;
|
||||
ancestor = get(parent, v);
|
||||
}
|
||||
v = get(parent, old);
|
||||
while (ancestor != v) {
|
||||
put(parent, old, ancestor);
|
||||
old = v;
|
||||
v = get(parent, old);
|
||||
}
|
||||
return ancestor;
|
||||
}
|
||||
|
||||
/* the postcondition of link sets is:
|
||||
component_representative(i) == component_representative(j)
|
||||
*/
|
||||
template <class ParentPA, class RankPA, class Vertex,
|
||||
class ComponentRepresentative>
|
||||
inline void
|
||||
link_sets(ParentPA p, RankPA rank, Vertex i, Vertex j,
|
||||
ComponentRepresentative comp_rep)
|
||||
namespace detail
|
||||
{
|
||||
i = comp_rep(p, i);
|
||||
j = comp_rep(p, j);
|
||||
if (i == j) return;
|
||||
if (get(rank, i) > get(rank, j))
|
||||
put(p, j, i);
|
||||
else {
|
||||
put(p, i, j);
|
||||
if (get(rank, i) == get(rank, j))
|
||||
put(rank, j, get(rank, j) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// normalize components has the following postcondidition:
|
||||
// i >= p[i]
|
||||
// that is, the representative is the node with the smallest index in its class
|
||||
// as its precondition it it assumes that the node container is compressed
|
||||
template < class ParentPA, class Vertex >
|
||||
Vertex find_representative_with_path_halving(ParentPA p, Vertex v)
|
||||
{
|
||||
Vertex parent = get(p, v);
|
||||
Vertex grandparent = get(p, parent);
|
||||
while (parent != grandparent)
|
||||
{
|
||||
put(p, v, grandparent);
|
||||
v = grandparent;
|
||||
parent = get(p, v);
|
||||
grandparent = get(p, parent);
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
template <class ParentPA, class Vertex>
|
||||
inline void
|
||||
normalize_node(ParentPA p, Vertex i)
|
||||
{
|
||||
if (i > get(p,i) || get(p, get(p,i)) != get(p,i))
|
||||
put(p,i, get(p, get(p,i)));
|
||||
else {
|
||||
put(p, get(p,i), i);
|
||||
put(p, i, i);
|
||||
}
|
||||
}
|
||||
template < class ParentPA, class Vertex >
|
||||
Vertex find_representative_with_full_compression(ParentPA parent, Vertex v)
|
||||
{
|
||||
Vertex old = v;
|
||||
Vertex ancestor = get(parent, v);
|
||||
while (ancestor != v)
|
||||
{
|
||||
v = ancestor;
|
||||
ancestor = get(parent, v);
|
||||
}
|
||||
v = get(parent, old);
|
||||
while (ancestor != v)
|
||||
{
|
||||
put(parent, old, ancestor);
|
||||
old = v;
|
||||
v = get(parent, old);
|
||||
}
|
||||
return ancestor;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
/* the postcondition of link sets is:
|
||||
component_representative(i) == component_representative(j)
|
||||
*/
|
||||
template < class ParentPA, class RankPA, class Vertex,
|
||||
class ComponentRepresentative >
|
||||
inline void link_sets(ParentPA p, RankPA rank, Vertex i, Vertex j,
|
||||
ComponentRepresentative comp_rep)
|
||||
{
|
||||
i = comp_rep(p, i);
|
||||
j = comp_rep(p, j);
|
||||
if (i == j)
|
||||
return;
|
||||
if (get(rank, i) > get(rank, j))
|
||||
put(p, j, i);
|
||||
else
|
||||
{
|
||||
put(p, i, j);
|
||||
if (get(rank, i) == get(rank, j))
|
||||
put(rank, j, get(rank, j) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// normalize components has the following postcondidition:
|
||||
// i >= p[i]
|
||||
// that is, the representative is the node with the smallest index in its
|
||||
// class as its precondition it it assumes that the node container is
|
||||
// compressed
|
||||
|
||||
template < class ParentPA, class Vertex >
|
||||
inline void normalize_node(ParentPA p, Vertex i)
|
||||
{
|
||||
if (i > get(p, i) || get(p, get(p, i)) != get(p, i))
|
||||
put(p, i, get(p, get(p, i)));
|
||||
else
|
||||
{
|
||||
put(p, get(p, i), i);
|
||||
put(p, i, i);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_DETAIL_DISJOINT_SETS_HPP
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// (C) Copyright Jeremy Siek 2004
|
||||
// (C) Copyright Jeremy Siek 2004
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,13 +9,17 @@
|
||||
#include <utility> // for std::pair
|
||||
#include <boost/type_traits/same_traits.hpp> // for is_same
|
||||
|
||||
namespace boost {
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail {
|
||||
namespace detail
|
||||
{
|
||||
|
||||
struct error_property_not_found { };
|
||||
struct error_property_not_found
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_DETAIL_PROPERTY_HPP
|
||||
|
||||
@@ -15,197 +15,188 @@
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <boost/pending/detail/disjoint_sets.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace boost
|
||||
{
|
||||
|
||||
struct find_with_path_halving {
|
||||
template <class ParentPA, class Vertex>
|
||||
Vertex operator()(ParentPA p, Vertex v) {
|
||||
return detail::find_representative_with_path_halving(p, v);
|
||||
struct find_with_path_halving
|
||||
{
|
||||
template < class ParentPA, class Vertex >
|
||||
Vertex operator()(ParentPA p, Vertex v)
|
||||
{
|
||||
return detail::find_representative_with_path_halving(p, v);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
struct find_with_full_path_compression {
|
||||
template <class ParentPA, class Vertex>
|
||||
Vertex operator()(ParentPA p, Vertex v){
|
||||
return detail::find_representative_with_full_compression(p, v);
|
||||
struct find_with_full_path_compression
|
||||
{
|
||||
template < class ParentPA, class Vertex >
|
||||
Vertex operator()(ParentPA p, Vertex v)
|
||||
{
|
||||
return detail::find_representative_with_full_compression(p, v);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// This is a generalized functor to provide disjoint sets operations
|
||||
// with "union by rank" and "path compression". A disjoint-set data
|
||||
// structure maintains a collection S={S1, S2, ..., Sk} of disjoint
|
||||
// sets. Each set is identified by a representative, which is some
|
||||
// member of of the set. Sets are represented by rooted trees. Two
|
||||
// heuristics: "union by rank" and "path compression" are used to
|
||||
// speed up the operations.
|
||||
// This is a generalized functor to provide disjoint sets operations
|
||||
// with "union by rank" and "path compression". A disjoint-set data
|
||||
// structure maintains a collection S={S1, S2, ..., Sk} of disjoint
|
||||
// sets. Each set is identified by a representative, which is some
|
||||
// member of of the set. Sets are represented by rooted trees. Two
|
||||
// heuristics: "union by rank" and "path compression" are used to
|
||||
// speed up the operations.
|
||||
|
||||
// Disjoint Set requires two vertex properties for internal use. A
|
||||
// RankPA and a ParentPA. The RankPA must map Vertex to some Integral type
|
||||
// (preferably the size_type associated with Vertex). The ParentPA
|
||||
// must map Vertex to Vertex.
|
||||
template <class RankPA, class ParentPA,
|
||||
class FindCompress = find_with_full_path_compression
|
||||
>
|
||||
class disjoint_sets {
|
||||
// Disjoint Set requires two vertex properties for internal use. A
|
||||
// RankPA and a ParentPA. The RankPA must map Vertex to some Integral type
|
||||
// (preferably the size_type associated with Vertex). The ParentPA
|
||||
// must map Vertex to Vertex.
|
||||
template < class RankPA, class ParentPA,
|
||||
class FindCompress = find_with_full_path_compression >
|
||||
class disjoint_sets
|
||||
{
|
||||
typedef disjoint_sets self;
|
||||
|
||||
inline disjoint_sets() {}
|
||||
public:
|
||||
inline disjoint_sets(RankPA r, ParentPA p)
|
||||
: rank(r), parent(p) {}
|
||||
|
||||
inline disjoint_sets(const self& c)
|
||||
: rank(c.rank), parent(c.parent) {}
|
||||
|
||||
inline disjoint_sets() {}
|
||||
|
||||
public:
|
||||
inline disjoint_sets(RankPA r, ParentPA p) : rank(r), parent(p) {}
|
||||
|
||||
inline disjoint_sets(const self& c) : rank(c.rank), parent(c.parent) {}
|
||||
|
||||
// Make Set -- Create a singleton set containing vertex x
|
||||
template <class Element>
|
||||
inline void make_set(Element x)
|
||||
template < class Element > inline void make_set(Element x)
|
||||
{
|
||||
put(parent, x, x);
|
||||
typedef typename property_traits<RankPA>::value_type R;
|
||||
put(rank, x, R());
|
||||
put(parent, x, x);
|
||||
typedef typename property_traits< RankPA >::value_type R;
|
||||
put(rank, x, R());
|
||||
}
|
||||
|
||||
|
||||
// Link - union the two sets represented by vertex x and y
|
||||
template <class Element>
|
||||
inline void link(Element x, Element y)
|
||||
template < class Element > inline void link(Element x, Element y)
|
||||
{
|
||||
detail::link_sets(parent, rank, x, y, rep);
|
||||
detail::link_sets(parent, rank, x, y, rep);
|
||||
}
|
||||
|
||||
// Union-Set - union the two sets containing vertex x and y
|
||||
template <class Element>
|
||||
inline void union_set(Element x, Element y)
|
||||
|
||||
// Union-Set - union the two sets containing vertex x and y
|
||||
template < class Element > inline void union_set(Element x, Element y)
|
||||
{
|
||||
link(find_set(x), find_set(y));
|
||||
link(find_set(x), find_set(y));
|
||||
}
|
||||
|
||||
|
||||
// Find-Set - returns the Element representative of the set
|
||||
// containing Element x and applies path compression.
|
||||
template <class Element>
|
||||
inline Element find_set(Element x)
|
||||
template < class Element > inline Element find_set(Element x)
|
||||
{
|
||||
return rep(parent, x);
|
||||
return rep(parent, x);
|
||||
}
|
||||
|
||||
template <class ElementIterator>
|
||||
template < class ElementIterator >
|
||||
inline std::size_t count_sets(ElementIterator first, ElementIterator last)
|
||||
{
|
||||
std::size_t count = 0;
|
||||
for ( ; first != last; ++first)
|
||||
if (get(parent, *first) == *first)
|
||||
++count;
|
||||
return count;
|
||||
std::size_t count = 0;
|
||||
for (; first != last; ++first)
|
||||
if (get(parent, *first) == *first)
|
||||
++count;
|
||||
return count;
|
||||
}
|
||||
|
||||
template <class ElementIterator>
|
||||
template < class ElementIterator >
|
||||
inline void normalize_sets(ElementIterator first, ElementIterator last)
|
||||
{
|
||||
for (; first != last; ++first)
|
||||
detail::normalize_node(parent, *first);
|
||||
}
|
||||
|
||||
template <class ElementIterator>
|
||||
for (; first != last; ++first)
|
||||
detail::normalize_node(parent, *first);
|
||||
}
|
||||
|
||||
template < class ElementIterator >
|
||||
inline void compress_sets(ElementIterator first, ElementIterator last)
|
||||
{
|
||||
for (; first != last; ++first)
|
||||
detail::find_representative_with_full_compression(parent, *first);
|
||||
}
|
||||
protected:
|
||||
for (; first != last; ++first)
|
||||
detail::find_representative_with_full_compression(parent, *first);
|
||||
}
|
||||
|
||||
protected:
|
||||
RankPA rank;
|
||||
ParentPA parent;
|
||||
FindCompress rep;
|
||||
};
|
||||
};
|
||||
|
||||
template < class ID = identity_property_map,
|
||||
class InverseID = identity_property_map,
|
||||
class FindCompress = find_with_full_path_compression >
|
||||
class disjoint_sets_with_storage
|
||||
{
|
||||
typedef typename property_traits< ID >::value_type Index;
|
||||
typedef std::vector< Index > ParentContainer;
|
||||
typedef std::vector< unsigned char > RankContainer;
|
||||
|
||||
|
||||
|
||||
template <class ID = identity_property_map,
|
||||
class InverseID = identity_property_map,
|
||||
class FindCompress = find_with_full_path_compression
|
||||
>
|
||||
class disjoint_sets_with_storage
|
||||
{
|
||||
typedef typename property_traits<ID>::value_type Index;
|
||||
typedef std::vector<Index> ParentContainer;
|
||||
typedef std::vector<unsigned char> RankContainer;
|
||||
public:
|
||||
public:
|
||||
typedef typename ParentContainer::size_type size_type;
|
||||
|
||||
disjoint_sets_with_storage(size_type n = 0,
|
||||
ID id_ = ID(),
|
||||
InverseID inv = InverseID())
|
||||
: id(id_), id_to_vertex(inv), rank(n, 0), parent(n)
|
||||
disjoint_sets_with_storage(
|
||||
size_type n = 0, ID id_ = ID(), InverseID inv = InverseID())
|
||||
: id(id_), id_to_vertex(inv), rank(n, 0), parent(n)
|
||||
{
|
||||
for (Index i = 0; i < n; ++i)
|
||||
parent[i] = i;
|
||||
for (Index i = 0; i < n; ++i)
|
||||
parent[i] = i;
|
||||
}
|
||||
// note this is not normally needed
|
||||
template <class Element>
|
||||
inline void
|
||||
make_set(Element x) {
|
||||
parent[x] = x;
|
||||
rank[x] = 0;
|
||||
}
|
||||
template <class Element>
|
||||
inline void
|
||||
link(Element x, Element y)
|
||||
template < class Element > inline void make_set(Element x)
|
||||
{
|
||||
extend_sets(x,y);
|
||||
detail::link_sets(&parent[0], &rank[0],
|
||||
get(id,x), get(id,y), rep);
|
||||
parent[x] = x;
|
||||
rank[x] = 0;
|
||||
}
|
||||
template <class Element>
|
||||
inline void
|
||||
union_set(Element x, Element y) {
|
||||
Element rx = find_set(x);
|
||||
Element ry = find_set(y);
|
||||
link(rx, ry);
|
||||
template < class Element > inline void link(Element x, Element y)
|
||||
{
|
||||
extend_sets(x, y);
|
||||
detail::link_sets(&parent[0], &rank[0], get(id, x), get(id, y), rep);
|
||||
}
|
||||
template <class Element>
|
||||
inline Element find_set(Element x) {
|
||||
return id_to_vertex[rep(&parent[0], get(id,x))];
|
||||
template < class Element > inline void union_set(Element x, Element y)
|
||||
{
|
||||
Element rx = find_set(x);
|
||||
Element ry = find_set(y);
|
||||
link(rx, ry);
|
||||
}
|
||||
template < class Element > inline Element find_set(Element x)
|
||||
{
|
||||
return id_to_vertex[rep(&parent[0], get(id, x))];
|
||||
}
|
||||
|
||||
template <class ElementIterator>
|
||||
template < class ElementIterator >
|
||||
inline std::size_t count_sets(ElementIterator first, ElementIterator last)
|
||||
{
|
||||
std::size_t count = 0;
|
||||
for ( ; first != last; ++first)
|
||||
if (parent[*first] == *first)
|
||||
++count;
|
||||
return count;
|
||||
std::size_t count = 0;
|
||||
for (; first != last; ++first)
|
||||
if (parent[*first] == *first)
|
||||
++count;
|
||||
return count;
|
||||
}
|
||||
|
||||
template <class ElementIterator>
|
||||
template < class ElementIterator >
|
||||
inline void normalize_sets(ElementIterator first, ElementIterator last)
|
||||
{
|
||||
for (; first != last; ++first)
|
||||
detail::normalize_node(&parent[0], *first);
|
||||
}
|
||||
|
||||
template <class ElementIterator>
|
||||
for (; first != last; ++first)
|
||||
detail::normalize_node(&parent[0], *first);
|
||||
}
|
||||
|
||||
template < class ElementIterator >
|
||||
inline void compress_sets(ElementIterator first, ElementIterator last)
|
||||
{
|
||||
for (; first != last; ++first)
|
||||
detail::find_representative_with_full_compression(&parent[0],
|
||||
*first);
|
||||
}
|
||||
for (; first != last; ++first)
|
||||
detail::find_representative_with_full_compression(
|
||||
&parent[0], *first);
|
||||
}
|
||||
|
||||
const ParentContainer& parents() { return parent; }
|
||||
|
||||
protected:
|
||||
|
||||
template <class Element>
|
||||
inline void
|
||||
extend_sets(Element x, Element y)
|
||||
protected:
|
||||
template < class Element > inline void extend_sets(Element x, Element y)
|
||||
{
|
||||
Index needed = get(id,x) > get(id,y) ? get(id,x) + 1 : get(id,y) + 1;
|
||||
if (needed > parent.size()) {
|
||||
rank.insert(rank.end(), needed - rank.size(), 0);
|
||||
for (Index k = parent.size(); k < needed; ++k)
|
||||
parent.push_back(k);
|
||||
}
|
||||
Index needed
|
||||
= get(id, x) > get(id, y) ? get(id, x) + 1 : get(id, y) + 1;
|
||||
if (needed > parent.size())
|
||||
{
|
||||
rank.insert(rank.end(), needed - rank.size(), 0);
|
||||
for (Index k = parent.size(); k < needed; ++k)
|
||||
parent.push_back(k);
|
||||
}
|
||||
}
|
||||
|
||||
ID id;
|
||||
@@ -213,7 +204,7 @@ namespace boost {
|
||||
RankContainer rank;
|
||||
ParentContainer parent;
|
||||
FindCompress rep;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// (C) Copyright Jeremiah Willcock 2004
|
||||
// (C) Copyright Jeremiah Willcock 2004
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -30,18 +30,19 @@
|
||||
// are then popped from the front of Q, and if that is empty the front
|
||||
// of PQ.
|
||||
|
||||
namespace boost {
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<class T, class Compare = std::less<T>, bool implicit_fence = true,
|
||||
class Buffer = boost::queue<T> >
|
||||
class fenced_priority_queue {
|
||||
public:
|
||||
template < class T, class Compare = std::less< T >, bool implicit_fence = true,
|
||||
class Buffer = boost::queue< T > >
|
||||
class fenced_priority_queue
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef typename Buffer::size_type size_type;
|
||||
|
||||
fenced_priority_queue(const Compare _comp = Compare() )
|
||||
: PQ(_comp) {}
|
||||
|
||||
fenced_priority_queue(const Compare _comp = Compare()) : PQ(_comp) {}
|
||||
|
||||
void push(const T& data);
|
||||
void pop(void);
|
||||
T& top(void);
|
||||
@@ -49,104 +50,111 @@ namespace boost {
|
||||
size_type size(void) const;
|
||||
bool empty(void) const;
|
||||
void fence(void);
|
||||
|
||||
private:
|
||||
|
||||
private:
|
||||
void fence(void) const;
|
||||
|
||||
//let them mutable to allow const version of top and the same
|
||||
//semantics with non-constant version. Rich Lee
|
||||
mutable std::priority_queue<T, std::vector<T>, Compare> PQ;
|
||||
// let them mutable to allow const version of top and the same
|
||||
// semantics with non-constant version. Rich Lee
|
||||
mutable std::priority_queue< T, std::vector< T >, Compare > PQ;
|
||||
mutable Buffer Q;
|
||||
};
|
||||
|
||||
template<class T, class Compare, bool implicit_fence, class Buffer>
|
||||
inline void
|
||||
fenced_priority_queue<T, Compare, implicit_fence, Buffer>::
|
||||
push(const T &t) {
|
||||
};
|
||||
|
||||
template < class T, class Compare, bool implicit_fence, class Buffer >
|
||||
inline void fenced_priority_queue< T, Compare, implicit_fence, Buffer >::push(
|
||||
const T& t)
|
||||
{
|
||||
// Push a new element after the last fence. This puts it into the
|
||||
// priority queue to be sorted with all other elements in its
|
||||
// partition.
|
||||
PQ.push(t);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class Compare, bool implicit_fence, class Buffer>
|
||||
inline void fenced_priority_queue<T, Compare, implicit_fence, Buffer>::
|
||||
pop(void) {
|
||||
template < class T, class Compare, bool implicit_fence, class Buffer >
|
||||
inline void fenced_priority_queue< T, Compare, implicit_fence, Buffer >::pop(
|
||||
void)
|
||||
{
|
||||
// Pop one element from the front of the queue. Removes from the
|
||||
// already-sorted part of the queue if it is non-empty, otherwise
|
||||
// removes from the new-element priority queue. Runs an implicit
|
||||
// "fence" operation if the implicit_fence template argument is
|
||||
// true.
|
||||
if (implicit_fence) fence();
|
||||
if ( !Q.empty() )
|
||||
Q.pop();
|
||||
if (implicit_fence)
|
||||
fence();
|
||||
if (!Q.empty())
|
||||
Q.pop();
|
||||
else
|
||||
PQ.pop();
|
||||
}
|
||||
PQ.pop();
|
||||
}
|
||||
|
||||
template<class T, class Compare, bool implicit_fence, class Buffer>
|
||||
inline T& fenced_priority_queue<T, Compare, implicit_fence, Buffer>::
|
||||
top(void) {
|
||||
template < class T, class Compare, bool implicit_fence, class Buffer >
|
||||
inline T& fenced_priority_queue< T, Compare, implicit_fence, Buffer >::top(void)
|
||||
{
|
||||
// Get the top element from the queue. This element comes from Q if
|
||||
// possible, otherwise from PQ. Causes an implicit "fence"
|
||||
// operation if the implicit_fence template argument is true.
|
||||
if (implicit_fence) fence();
|
||||
if ( !Q.empty() )
|
||||
return Q.top();
|
||||
if (implicit_fence)
|
||||
fence();
|
||||
if (!Q.empty())
|
||||
return Q.top();
|
||||
else
|
||||
//std::priority_queue only have const version of top. Rich Lee
|
||||
return const_cast<T&>(PQ.top());
|
||||
}
|
||||
// std::priority_queue only have const version of top. Rich Lee
|
||||
return const_cast< T& >(PQ.top());
|
||||
}
|
||||
|
||||
template<class T, class Compare, bool implicit_fence, class Buffer>
|
||||
inline const T&
|
||||
fenced_priority_queue<T, Compare, implicit_fence, Buffer>::
|
||||
top(void) const {
|
||||
if (implicit_fence) fence();
|
||||
if ( !Q.empty() )
|
||||
return Q.top();
|
||||
template < class T, class Compare, bool implicit_fence, class Buffer >
|
||||
inline const T&
|
||||
fenced_priority_queue< T, Compare, implicit_fence, Buffer >::top(void) const
|
||||
{
|
||||
if (implicit_fence)
|
||||
fence();
|
||||
if (!Q.empty())
|
||||
return Q.top();
|
||||
else
|
||||
return PQ.top();
|
||||
}
|
||||
return PQ.top();
|
||||
}
|
||||
|
||||
template<class T, class Compare, bool implicit_fence, class Buffer>
|
||||
inline typename fenced_priority_queue<T, Compare, implicit_fence, Buffer>::size_type
|
||||
fenced_priority_queue<T, Compare, implicit_fence, Buffer>::
|
||||
size(void) const {
|
||||
template < class T, class Compare, bool implicit_fence, class Buffer >
|
||||
inline typename fenced_priority_queue< T, Compare, implicit_fence,
|
||||
Buffer >::size_type
|
||||
fenced_priority_queue< T, Compare, implicit_fence, Buffer >::size(void) const
|
||||
{
|
||||
// Returns the size of the queue (both parts together).
|
||||
return Q.size() + PQ.size();
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class Compare, bool implicit_fence, class Buffer>
|
||||
inline bool
|
||||
fenced_priority_queue<T, Compare, implicit_fence, Buffer>::
|
||||
empty(void) const {
|
||||
template < class T, class Compare, bool implicit_fence, class Buffer >
|
||||
inline bool fenced_priority_queue< T, Compare, implicit_fence, Buffer >::empty(
|
||||
void) const
|
||||
{
|
||||
// Returns if the queue is empty, i.e. both parts are empty.
|
||||
return Q.empty() && PQ.empty();
|
||||
}
|
||||
|
||||
template<class T, class Compare, bool implicit_fence, class Buffer>
|
||||
inline void
|
||||
fenced_priority_queue<T, Compare, implicit_fence, Buffer>::
|
||||
fence(void) {
|
||||
// Perform a fence operation. Remove elements from PQ in sorted
|
||||
// order and insert them in the back of Q.
|
||||
while ( !PQ.empty() ) {
|
||||
Q.push(PQ.top());
|
||||
PQ.pop();
|
||||
}
|
||||
}
|
||||
template<class T, class Compare, bool implicit_fence, class Buffer>
|
||||
inline void
|
||||
fenced_priority_queue<T, Compare, implicit_fence, Buffer>::
|
||||
fence(void) const {
|
||||
// Perform a fence operation. Remove elements from PQ in sorted
|
||||
// order and insert them in the back of Q.
|
||||
while ( !PQ.empty() ) {
|
||||
Q.push(PQ.top());
|
||||
PQ.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
template < class T, class Compare, bool implicit_fence, class Buffer >
|
||||
inline void fenced_priority_queue< T, Compare, implicit_fence, Buffer >::fence(
|
||||
void)
|
||||
{
|
||||
// Perform a fence operation. Remove elements from PQ in sorted
|
||||
// order and insert them in the back of Q.
|
||||
while (!PQ.empty())
|
||||
{
|
||||
Q.push(PQ.top());
|
||||
PQ.pop();
|
||||
}
|
||||
}
|
||||
template < class T, class Compare, bool implicit_fence, class Buffer >
|
||||
inline void fenced_priority_queue< T, Compare, implicit_fence, Buffer >::fence(
|
||||
void) const
|
||||
{
|
||||
// Perform a fence operation. Remove elements from PQ in sorted
|
||||
// order and insert them in the back of Q.
|
||||
while (!PQ.empty())
|
||||
{
|
||||
Q.push(PQ.top());
|
||||
PQ.pop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif /* BOOST_FENCED_PRIORITY_QUEUE_HPP */
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
#define BOOST_FIBONACCI_HEAP_HPP
|
||||
|
||||
#if defined(__sgi) && !defined(__GNUC__)
|
||||
# include <math.h>
|
||||
#include <math.h>
|
||||
#else
|
||||
# include <boost/config/no_tr1/cmath.hpp>
|
||||
#include <boost/config/no_tr1/cmath.hpp>
|
||||
#endif
|
||||
#include <iosfwd>
|
||||
#include <vector>
|
||||
@@ -21,251 +21,300 @@
|
||||
// in "The Stanford Graph Base", pages 475-482.
|
||||
//
|
||||
|
||||
namespace boost {
|
||||
namespace boost
|
||||
{
|
||||
|
||||
|
||||
template <class T,
|
||||
class Compare = std::less<T>,
|
||||
class ID = identity_property_map>
|
||||
template < class T, class Compare = std::less< T >,
|
||||
class ID = identity_property_map >
|
||||
class fibonacci_heap
|
||||
{
|
||||
typedef typename boost::property_traits<ID>::value_type size_type;
|
||||
typedef T value_type;
|
||||
protected:
|
||||
typedef fibonacci_heap self;
|
||||
typedef std::vector<size_type> LinkVec;
|
||||
typedef typename LinkVec::iterator LinkIter;
|
||||
public:
|
||||
typedef typename boost::property_traits< ID >::value_type size_type;
|
||||
typedef T value_type;
|
||||
|
||||
fibonacci_heap(size_type n,
|
||||
const Compare& cmp,
|
||||
const ID& id = identity_property_map())
|
||||
: _key(n), _left(n), _right(n), _p(n), _mark(n), _degree(n),
|
||||
_n(0), _root(n), _id(id), _compare(cmp), _child(n),
|
||||
protected:
|
||||
typedef fibonacci_heap self;
|
||||
typedef std::vector< size_type > LinkVec;
|
||||
typedef typename LinkVec::iterator LinkIter;
|
||||
|
||||
public:
|
||||
fibonacci_heap(
|
||||
size_type n, const Compare& cmp, const ID& id = identity_property_map())
|
||||
: _key(n)
|
||||
, _left(n)
|
||||
, _right(n)
|
||||
, _p(n)
|
||||
, _mark(n)
|
||||
, _degree(n)
|
||||
, _n(0)
|
||||
, _root(n)
|
||||
, _id(id)
|
||||
, _compare(cmp)
|
||||
, _child(n)
|
||||
,
|
||||
#if defined(BOOST_MSVC) || defined(__ICL) // need a new macro?
|
||||
new_roots(size_type(log(float(n))) + 5) { }
|
||||
new_roots(size_type(log(float(n))) + 5)
|
||||
{
|
||||
}
|
||||
#else
|
||||
new_roots(size_type(std::log(float(n))) + 5) { }
|
||||
new_roots(size_type(std::log(float(n))) + 5)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
// 33
|
||||
void push(const T& d) {
|
||||
++_n;
|
||||
size_type v = get(_id, d);
|
||||
_key[v] = d;
|
||||
_p[v] = nil();
|
||||
_degree[v] = 0;
|
||||
_mark[v] = false;
|
||||
_child[v] = nil();
|
||||
if (_root == nil()) {
|
||||
_root = _left[v] = _right[v] = v;
|
||||
//std::cout << "root added" << std::endl;
|
||||
} else {
|
||||
size_type u = _left[_root];
|
||||
_left[v] = u;
|
||||
_right[v] = _root;
|
||||
_left[_root] = _right[u] = v;
|
||||
if (_compare(d, _key[_root]))
|
||||
_root = v;
|
||||
//std::cout << "non-root node added" << std::endl;
|
||||
// 33
|
||||
void push(const T& d)
|
||||
{
|
||||
++_n;
|
||||
size_type v = get(_id, d);
|
||||
_key[v] = d;
|
||||
_p[v] = nil();
|
||||
_degree[v] = 0;
|
||||
_mark[v] = false;
|
||||
_child[v] = nil();
|
||||
if (_root == nil())
|
||||
{
|
||||
_root = _left[v] = _right[v] = v;
|
||||
// std::cout << "root added" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_type u = _left[_root];
|
||||
_left[v] = u;
|
||||
_right[v] = _root;
|
||||
_left[_root] = _right[u] = v;
|
||||
if (_compare(d, _key[_root]))
|
||||
_root = v;
|
||||
// std::cout << "non-root node added" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
T& top() { return _key[_root]; }
|
||||
const T& top() const { return _key[_root]; }
|
||||
T& top() { return _key[_root]; }
|
||||
const T& top() const { return _key[_root]; }
|
||||
|
||||
// 38
|
||||
void pop() {
|
||||
--_n;
|
||||
int h = -1;
|
||||
size_type v, w;
|
||||
if (_root != nil()) {
|
||||
if (_degree[_root] == 0) {
|
||||
v = _right[_root];
|
||||
} else {
|
||||
w = _child[_root];
|
||||
v = _right[w];
|
||||
_right[w] = _right[_root];
|
||||
for (w = v; w != _right[_root]; w = _right[w])
|
||||
_p[w] = nil();
|
||||
}
|
||||
while (v != _root) {
|
||||
w = _right[v];
|
||||
add_tree_to_new_roots(v, new_roots.begin(), h);
|
||||
v = w;
|
||||
}
|
||||
rebuild_root_list(new_roots.begin(), h);
|
||||
// 38
|
||||
void pop()
|
||||
{
|
||||
--_n;
|
||||
int h = -1;
|
||||
size_type v, w;
|
||||
if (_root != nil())
|
||||
{
|
||||
if (_degree[_root] == 0)
|
||||
{
|
||||
v = _right[_root];
|
||||
}
|
||||
else
|
||||
{
|
||||
w = _child[_root];
|
||||
v = _right[w];
|
||||
_right[w] = _right[_root];
|
||||
for (w = v; w != _right[_root]; w = _right[w])
|
||||
_p[w] = nil();
|
||||
}
|
||||
while (v != _root)
|
||||
{
|
||||
w = _right[v];
|
||||
add_tree_to_new_roots(v, new_roots.begin(), h);
|
||||
v = w;
|
||||
}
|
||||
rebuild_root_list(new_roots.begin(), h);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 39
|
||||
inline void add_tree_to_new_roots(size_type v,
|
||||
LinkIter new_roots,
|
||||
int& h)
|
||||
{
|
||||
int r;
|
||||
size_type u;
|
||||
r = _degree[v];
|
||||
while (1) {
|
||||
if (h < r) {
|
||||
do {
|
||||
++h;
|
||||
new_roots[h] = (h == r ? v : nil());
|
||||
} while (h < r);
|
||||
break;
|
||||
}
|
||||
if (new_roots[r] == nil()) {
|
||||
new_roots[r] = v;
|
||||
break;
|
||||
}
|
||||
u = new_roots[r];
|
||||
new_roots[r] = nil();
|
||||
if (_compare(_key[u], _key[v])) {
|
||||
// 39
|
||||
inline void add_tree_to_new_roots(size_type v, LinkIter new_roots, int& h)
|
||||
{
|
||||
int r;
|
||||
size_type u;
|
||||
r = _degree[v];
|
||||
while (1)
|
||||
{
|
||||
if (h < r)
|
||||
{
|
||||
do
|
||||
{
|
||||
++h;
|
||||
new_roots[h] = (h == r ? v : nil());
|
||||
} while (h < r);
|
||||
break;
|
||||
}
|
||||
if (new_roots[r] == nil())
|
||||
{
|
||||
new_roots[r] = v;
|
||||
break;
|
||||
}
|
||||
u = new_roots[r];
|
||||
new_roots[r] = nil();
|
||||
if (_compare(_key[u], _key[v]))
|
||||
{
|
||||
_degree[v] = r;
|
||||
_mark[v] = false;
|
||||
std::swap(u, v);
|
||||
}
|
||||
make_child(u, v, r);
|
||||
++r;
|
||||
}
|
||||
_degree[v] = r;
|
||||
_mark[v] = false;
|
||||
std::swap(u, v);
|
||||
}
|
||||
make_child(u, v, r);
|
||||
++r;
|
||||
}
|
||||
_degree[v] = r;
|
||||
_mark[v] = false;
|
||||
}
|
||||
// 40
|
||||
void make_child(size_type u, size_type v, size_type r) {
|
||||
if (r == 0) {
|
||||
_child[v] = u;
|
||||
_left[u] = u;
|
||||
_right[u] = u;
|
||||
} else {
|
||||
size_type t = _child[v];
|
||||
_right[u] = _right[t];
|
||||
_left[u] = t;
|
||||
_right[t] = u;
|
||||
_left[_right[u]] = u;
|
||||
}
|
||||
_p[u] = v;
|
||||
}
|
||||
// 41
|
||||
inline void rebuild_root_list(LinkIter new_roots, int& h)
|
||||
{
|
||||
size_type u, v, w;
|
||||
if (h < 0)
|
||||
_root = nil();
|
||||
else {
|
||||
T d;
|
||||
u = v = new_roots[h];
|
||||
d = _key[u];
|
||||
_root = u;
|
||||
for (h--; h >= 0; --h)
|
||||
if (new_roots[h] != nil()) {
|
||||
w = new_roots[h];
|
||||
_left[w] = v;
|
||||
_right[v] = w;
|
||||
if (_compare(_key[w], d)) {
|
||||
_root = w;
|
||||
d = _key[w];
|
||||
}
|
||||
v = w;
|
||||
// 40
|
||||
void make_child(size_type u, size_type v, size_type r)
|
||||
{
|
||||
if (r == 0)
|
||||
{
|
||||
_child[v] = u;
|
||||
_left[u] = u;
|
||||
_right[u] = u;
|
||||
}
|
||||
_right[v] = u;
|
||||
_left[u] = v;
|
||||
}
|
||||
}
|
||||
|
||||
// 34
|
||||
void update(const T& d) {
|
||||
size_type v = get(_id, d);
|
||||
assert(!_compare(_key[v], d));
|
||||
_key[v] = d;
|
||||
size_type p = _p[v];
|
||||
if (p == nil()) {
|
||||
if (_compare(d, _key[_root]))
|
||||
_root = v;
|
||||
} else if (_compare(d, _key[p]))
|
||||
while (1) {
|
||||
size_type r = _degree[p];
|
||||
if (r >= 2)
|
||||
remove_from_family(v, p);
|
||||
insert_into_forest(v, d);
|
||||
size_type pp = _p[p];
|
||||
if (pp == nil()) {
|
||||
--_degree[p];
|
||||
break;
|
||||
else
|
||||
{
|
||||
size_type t = _child[v];
|
||||
_right[u] = _right[t];
|
||||
_left[u] = t;
|
||||
_right[t] = u;
|
||||
_left[_right[u]] = u;
|
||||
}
|
||||
_p[u] = v;
|
||||
}
|
||||
// 41
|
||||
inline void rebuild_root_list(LinkIter new_roots, int& h)
|
||||
{
|
||||
size_type u, v, w;
|
||||
if (h < 0)
|
||||
_root = nil();
|
||||
else
|
||||
{
|
||||
T d;
|
||||
u = v = new_roots[h];
|
||||
d = _key[u];
|
||||
_root = u;
|
||||
for (h--; h >= 0; --h)
|
||||
if (new_roots[h] != nil())
|
||||
{
|
||||
w = new_roots[h];
|
||||
_left[w] = v;
|
||||
_right[v] = w;
|
||||
if (_compare(_key[w], d))
|
||||
{
|
||||
_root = w;
|
||||
d = _key[w];
|
||||
}
|
||||
v = w;
|
||||
}
|
||||
_right[v] = u;
|
||||
_left[u] = v;
|
||||
}
|
||||
}
|
||||
|
||||
// 34
|
||||
void update(const T& d)
|
||||
{
|
||||
size_type v = get(_id, d);
|
||||
assert(!_compare(_key[v], d));
|
||||
_key[v] = d;
|
||||
size_type p = _p[v];
|
||||
if (p == nil())
|
||||
{
|
||||
if (_compare(d, _key[_root]))
|
||||
_root = v;
|
||||
}
|
||||
else if (_compare(d, _key[p]))
|
||||
while (1)
|
||||
{
|
||||
size_type r = _degree[p];
|
||||
if (r >= 2)
|
||||
remove_from_family(v, p);
|
||||
insert_into_forest(v, d);
|
||||
size_type pp = _p[p];
|
||||
if (pp == nil())
|
||||
{
|
||||
--_degree[p];
|
||||
break;
|
||||
}
|
||||
if (_mark[p] == false)
|
||||
{
|
||||
_mark[p] = true;
|
||||
--_degree[p];
|
||||
break;
|
||||
}
|
||||
else
|
||||
--_degree[p];
|
||||
v = p;
|
||||
p = pp;
|
||||
}
|
||||
}
|
||||
|
||||
inline size_type size() const { return _n; }
|
||||
inline bool empty() const { return _n == 0; }
|
||||
|
||||
void print(std::ostream& os)
|
||||
{
|
||||
if (_root != nil())
|
||||
{
|
||||
size_type i = _root;
|
||||
do
|
||||
{
|
||||
print_recur(i, os);
|
||||
os << std::endl;
|
||||
i = _right[i];
|
||||
} while (i != _root);
|
||||
}
|
||||
if (_mark[p] == false) {
|
||||
_mark[p] = true;
|
||||
--_degree[p];
|
||||
break;
|
||||
} else
|
||||
--_degree[p];
|
||||
v = p;
|
||||
p = pp;
|
||||
}
|
||||
}
|
||||
|
||||
inline size_type size() const { return _n; }
|
||||
inline bool empty() const { return _n == 0; }
|
||||
|
||||
void print(std::ostream& os) {
|
||||
if (_root != nil()) {
|
||||
size_type i = _root;
|
||||
do {
|
||||
print_recur(i, os);
|
||||
os << std::endl;
|
||||
i = _right[i];
|
||||
} while (i != _root);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
// 35
|
||||
inline void remove_from_family(size_type v, size_type p) {
|
||||
size_type u = _left[v];
|
||||
size_type w = _right[v];
|
||||
_right[u] = w;
|
||||
_left[w] = u;
|
||||
if (_child[p] == v)
|
||||
_child[p] = w;
|
||||
}
|
||||
// 36
|
||||
inline void insert_into_forest(size_type v, const T& d) {
|
||||
_p[v] = nil();
|
||||
size_type u = _left[_root];
|
||||
_left[v] = u;
|
||||
_right[v] = _root;
|
||||
_left[_root] = _right[u] = v;
|
||||
if (_compare(d, _key[_root]))
|
||||
_root = v;
|
||||
}
|
||||
|
||||
void print_recur(size_type x, std::ostream& os) {
|
||||
if (x != nil()) {
|
||||
os << x;
|
||||
if (_degree[x] > 0) {
|
||||
os << "(";
|
||||
size_type i = _child[x];
|
||||
do {
|
||||
print_recur(i, os); os << " ";
|
||||
i = _right[i];
|
||||
} while (i != _child[x]);
|
||||
os << ")";
|
||||
}
|
||||
// 35
|
||||
inline void remove_from_family(size_type v, size_type p)
|
||||
{
|
||||
size_type u = _left[v];
|
||||
size_type w = _right[v];
|
||||
_right[u] = w;
|
||||
_left[w] = u;
|
||||
if (_child[p] == v)
|
||||
_child[p] = w;
|
||||
}
|
||||
// 36
|
||||
inline void insert_into_forest(size_type v, const T& d)
|
||||
{
|
||||
_p[v] = nil();
|
||||
size_type u = _left[_root];
|
||||
_left[v] = u;
|
||||
_right[v] = _root;
|
||||
_left[_root] = _right[u] = v;
|
||||
if (_compare(d, _key[_root]))
|
||||
_root = v;
|
||||
}
|
||||
}
|
||||
|
||||
size_type nil() const { return _left.size(); }
|
||||
|
||||
std::vector<T> _key;
|
||||
LinkVec _left, _right, _p;
|
||||
std::vector<bool> _mark;
|
||||
LinkVec _degree;
|
||||
size_type _n, _root;
|
||||
ID _id;
|
||||
Compare _compare;
|
||||
LinkVec _child;
|
||||
LinkVec new_roots;
|
||||
void print_recur(size_type x, std::ostream& os)
|
||||
{
|
||||
if (x != nil())
|
||||
{
|
||||
os << x;
|
||||
if (_degree[x] > 0)
|
||||
{
|
||||
os << "(";
|
||||
size_type i = _child[x];
|
||||
do
|
||||
{
|
||||
print_recur(i, os);
|
||||
os << " ";
|
||||
i = _right[i];
|
||||
} while (i != _child[x]);
|
||||
os << ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_type nil() const { return _left.size(); }
|
||||
|
||||
std::vector< T > _key;
|
||||
LinkVec _left, _right, _p;
|
||||
std::vector< bool > _mark;
|
||||
LinkVec _degree;
|
||||
size_type _n, _root;
|
||||
ID _id;
|
||||
Compare _compare;
|
||||
LinkVec _child;
|
||||
LinkVec new_roots;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_FIBONACCI_HEAP_HPP
|
||||
|
||||
@@ -16,72 +16,77 @@
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace boost
|
||||
{
|
||||
|
||||
//: indirect_cmp
|
||||
//
|
||||
// could also do this with compose_f_gx_hx, and the member binder...
|
||||
//
|
||||
//!category: functors
|
||||
//!component: type
|
||||
//!tparam: ReadablePropertyMap - a model of ReadablePropertyMap
|
||||
//!definition: functor.h
|
||||
template <class ReadablePropertyMap, class Compare>
|
||||
class indirect_cmp {
|
||||
public:
|
||||
typedef typename boost::property_traits<ReadablePropertyMap>::value_type T;
|
||||
typedef typename boost::property_traits<ReadablePropertyMap>::key_type K;
|
||||
//: indirect_cmp
|
||||
//
|
||||
// could also do this with compose_f_gx_hx, and the member binder...
|
||||
//
|
||||
//! category: functors
|
||||
//! component: type
|
||||
//! tparam: ReadablePropertyMap - a model of ReadablePropertyMap
|
||||
//! definition: functor.h
|
||||
template < class ReadablePropertyMap, class Compare > class indirect_cmp
|
||||
{
|
||||
public:
|
||||
typedef
|
||||
typename boost::property_traits< ReadablePropertyMap >::value_type T;
|
||||
typedef typename boost::property_traits< ReadablePropertyMap >::key_type K;
|
||||
typedef K first_argument_type;
|
||||
typedef K second_argument_type;
|
||||
typedef bool result_type;
|
||||
inline indirect_cmp(const ReadablePropertyMap& df, const Compare& c = Compare())
|
||||
: d(df), cmp(c) { }
|
||||
|
||||
template <class A, class B>
|
||||
inline bool
|
||||
operator()(const A& u, const B& v) const {
|
||||
const T& du = get(d, u);
|
||||
const T& dv = get(d, v);
|
||||
return cmp(du, dv);
|
||||
inline indirect_cmp(
|
||||
const ReadablePropertyMap& df, const Compare& c = Compare())
|
||||
: d(df), cmp(c)
|
||||
{
|
||||
}
|
||||
protected:
|
||||
|
||||
template < class A, class B >
|
||||
inline bool operator()(const A& u, const B& v) const
|
||||
{
|
||||
const T& du = get(d, u);
|
||||
const T& dv = get(d, v);
|
||||
return cmp(du, dv);
|
||||
}
|
||||
|
||||
protected:
|
||||
ReadablePropertyMap d;
|
||||
Compare cmp;
|
||||
};
|
||||
};
|
||||
|
||||
template <typename Compare, typename ReadablePropertyMap>
|
||||
indirect_cmp<ReadablePropertyMap, Compare>
|
||||
make_indirect_cmp(const Compare& cmp, ReadablePropertyMap pmap) {
|
||||
indirect_cmp<ReadablePropertyMap, Compare> p(pmap, cmp);
|
||||
template < typename Compare, typename ReadablePropertyMap >
|
||||
indirect_cmp< ReadablePropertyMap, Compare > make_indirect_cmp(
|
||||
const Compare& cmp, ReadablePropertyMap pmap)
|
||||
{
|
||||
indirect_cmp< ReadablePropertyMap, Compare > p(pmap, cmp);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
template <class ReadablePropertyMap>
|
||||
class indirect_pmap {
|
||||
public:
|
||||
typedef typename boost::property_traits<ReadablePropertyMap>::value_type T;
|
||||
typedef typename boost::property_traits<ReadablePropertyMap>::key_type K;
|
||||
template < class ReadablePropertyMap > class indirect_pmap
|
||||
{
|
||||
public:
|
||||
typedef
|
||||
typename boost::property_traits< ReadablePropertyMap >::value_type T;
|
||||
typedef typename boost::property_traits< ReadablePropertyMap >::key_type K;
|
||||
typedef K argument_type;
|
||||
typedef T result_type;
|
||||
inline indirect_pmap(const ReadablePropertyMap& df)
|
||||
: d(df) { }
|
||||
inline indirect_pmap(const ReadablePropertyMap& df) : d(df) {}
|
||||
|
||||
inline T operator()(const K& u) const {
|
||||
return get(d, u);
|
||||
}
|
||||
protected:
|
||||
inline T operator()(const K& u) const { return get(d, u); }
|
||||
|
||||
protected:
|
||||
ReadablePropertyMap d;
|
||||
};
|
||||
};
|
||||
|
||||
template <typename ReadablePropertyMap>
|
||||
indirect_pmap<ReadablePropertyMap>
|
||||
make_indirect_pmap(ReadablePropertyMap pmap) {
|
||||
indirect_pmap<ReadablePropertyMap> f(pmap);
|
||||
template < typename ReadablePropertyMap >
|
||||
indirect_pmap< ReadablePropertyMap > make_indirect_pmap(
|
||||
ReadablePropertyMap pmap)
|
||||
{
|
||||
indirect_pmap< ReadablePropertyMap > f(pmap);
|
||||
return f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // GGCL_INDIRECT_CMP_HPP
|
||||
|
||||
@@ -9,53 +9,54 @@
|
||||
//=======================================================================
|
||||
//
|
||||
#if __KCC
|
||||
namespace std {
|
||||
|
||||
template <class RandomAccessIterator, class Distance>
|
||||
bool __is_heap(RandomAccessIterator first, RandomAccessIterator last,
|
||||
Distance*)
|
||||
namespace std
|
||||
{
|
||||
const Distance n = last - first;
|
||||
|
||||
Distance parent = 0;
|
||||
for (Distance child = 1; child < n; ++child) {
|
||||
if (first[parent] < first[child])
|
||||
return false;
|
||||
if ((child & 1) == 0)
|
||||
++parent;
|
||||
}
|
||||
return true;
|
||||
template < class RandomAccessIterator, class Distance >
|
||||
bool __is_heap(RandomAccessIterator first, RandomAccessIterator last, Distance*)
|
||||
{
|
||||
const Distance n = last - first;
|
||||
|
||||
Distance parent = 0;
|
||||
for (Distance child = 1; child < n; ++child)
|
||||
{
|
||||
if (first[parent] < first[child])
|
||||
return false;
|
||||
if ((child & 1) == 0)
|
||||
++parent;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class RandomAccessIterator>
|
||||
template < class RandomAccessIterator >
|
||||
inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last)
|
||||
{
|
||||
return __is_heap(first, last, distance_type(first));
|
||||
return __is_heap(first, last, distance_type(first));
|
||||
}
|
||||
|
||||
|
||||
template <class RandomAccessIterator, class Distance, class StrictWeakOrdering>
|
||||
template < class RandomAccessIterator, class Distance,
|
||||
class StrictWeakOrdering >
|
||||
bool __is_heap(RandomAccessIterator first, RandomAccessIterator last,
|
||||
StrictWeakOrdering comp,
|
||||
Distance*)
|
||||
StrictWeakOrdering comp, Distance*)
|
||||
{
|
||||
const Distance n = last - first;
|
||||
const Distance n = last - first;
|
||||
|
||||
Distance parent = 0;
|
||||
for (Distance child = 1; child < n; ++child) {
|
||||
if (comp(first[parent], first[child]))
|
||||
return false;
|
||||
if ((child & 1) == 0)
|
||||
++parent;
|
||||
}
|
||||
return true;
|
||||
Distance parent = 0;
|
||||
for (Distance child = 1; child < n; ++child)
|
||||
{
|
||||
if (comp(first[parent], first[child]))
|
||||
return false;
|
||||
if ((child & 1) == 0)
|
||||
++parent;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class RandomAccessIterator, class StrictWeakOrdering>
|
||||
template < class RandomAccessIterator, class StrictWeakOrdering >
|
||||
inline bool is_heap(RandomAccessIterator first, RandomAccessIterator last,
|
||||
StrictWeakOrdering comp)
|
||||
StrictWeakOrdering comp)
|
||||
{
|
||||
return __is_heap(first, last, comp, distance_type(first));
|
||||
return __is_heap(first, last, comp, distance_type(first));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ void forward_iterator_test(Iterator i, T v1, T v2)
|
||||
trivial_iterator_test(i, i2, v2);
|
||||
|
||||
// borland doesn't allow non-type template parameters
|
||||
# if !defined(__BORLANDC__) || (__BORLANDC__ > 0x551)
|
||||
# if !defined(BOOST_BORLANDC) || (BOOST_BORLANDC > 0x551)
|
||||
lvalue_test<(boost::is_pointer<Iterator>::value)>::check(i);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -30,35 +30,38 @@
|
||||
|
||||
*/
|
||||
|
||||
namespace boost {
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template <class TreeNode, class Compare, class ExternalData>
|
||||
inline TreeNode up_heap(TreeNode x, const Compare& comp, ExternalData& edata) {
|
||||
template < class TreeNode, class Compare, class ExternalData >
|
||||
inline TreeNode up_heap(TreeNode x, const Compare& comp, ExternalData& edata)
|
||||
{
|
||||
while (x.has_parent() && comp(x, x.parent()))
|
||||
x.swap(x.parent(), edata);
|
||||
x.swap(x.parent(), edata);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
template <class TreeNode, class Compare, class ExternalData>
|
||||
inline TreeNode down_heap(TreeNode x, const Compare& comp, ExternalData& edata) {
|
||||
while (x.children().size() > 0) {
|
||||
typename TreeNode::children_type::iterator
|
||||
child_iter = std::min_element(x.children().begin(),
|
||||
x.children().end(),
|
||||
comp);
|
||||
if (comp(*child_iter, x))
|
||||
x.swap(*child_iter, edata);
|
||||
else
|
||||
break;
|
||||
template < class TreeNode, class Compare, class ExternalData >
|
||||
inline TreeNode down_heap(TreeNode x, const Compare& comp, ExternalData& edata)
|
||||
{
|
||||
while (x.children().size() > 0)
|
||||
{
|
||||
typename TreeNode::children_type::iterator child_iter
|
||||
= std::min_element(x.children().begin(), x.children().end(), comp);
|
||||
if (comp(*child_iter, x))
|
||||
x.swap(*child_iter, edata);
|
||||
else
|
||||
break;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
template <class TreeNode, class Compare, class ExternalData>
|
||||
inline void update_heap(TreeNode x, const Compare& comp, ExternalData& edata) {
|
||||
template < class TreeNode, class Compare, class ExternalData >
|
||||
inline void update_heap(TreeNode x, const Compare& comp, ExternalData& edata)
|
||||
{
|
||||
x = down_heap(x, comp, edata);
|
||||
(void)up_heap(x, comp, edata);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -20,88 +20,97 @@
|
||||
#include <boost/graph/detail/array_binary_tree.hpp>
|
||||
#include <iterator>
|
||||
|
||||
namespace boost {
|
||||
namespace boost
|
||||
{
|
||||
|
||||
// The mutable queue whose elements are indexed
|
||||
//
|
||||
// This adaptor provides a special kind of priority queue that has
|
||||
// and update operation. This allows the ordering of the items to
|
||||
// change. After the ordering criteria for item x changes, one must
|
||||
// call the Q.update(x)
|
||||
//
|
||||
// In order to efficiently find x in the queue, a functor must be
|
||||
// provided to map value_type to a unique ID, which the
|
||||
// mutable_queue will then use to map to the location of the
|
||||
// item. The ID's generated must be between 0 and N, where N is the
|
||||
// value passed to the constructor of mutable_queue
|
||||
// The mutable queue whose elements are indexed
|
||||
//
|
||||
// This adaptor provides a special kind of priority queue that has
|
||||
// and update operation. This allows the ordering of the items to
|
||||
// change. After the ordering criteria for item x changes, one must
|
||||
// call the Q.update(x)
|
||||
//
|
||||
// In order to efficiently find x in the queue, a functor must be
|
||||
// provided to map value_type to a unique ID, which the
|
||||
// mutable_queue will then use to map to the location of the
|
||||
// item. The ID's generated must be between 0 and N, where N is the
|
||||
// value passed to the constructor of mutable_queue
|
||||
|
||||
template <class IndexedType,
|
||||
class RandomAccessContainer = std::vector<IndexedType>,
|
||||
class Comp = std::less<typename RandomAccessContainer::value_type>,
|
||||
class ID = identity_property_map >
|
||||
class mutable_queue {
|
||||
public:
|
||||
template < class IndexedType,
|
||||
class RandomAccessContainer = std::vector< IndexedType >,
|
||||
class Comp = std::less< typename RandomAccessContainer::value_type >,
|
||||
class ID = identity_property_map >
|
||||
class mutable_queue
|
||||
{
|
||||
public:
|
||||
typedef IndexedType value_type;
|
||||
typedef typename RandomAccessContainer::size_type size_type;
|
||||
protected:
|
||||
|
||||
protected:
|
||||
typedef typename RandomAccessContainer::iterator iterator;
|
||||
#if !defined BOOST_NO_STD_ITERATOR_TRAITS
|
||||
typedef array_binary_tree_node<iterator, ID> Node;
|
||||
typedef array_binary_tree_node< iterator, ID > Node;
|
||||
#else
|
||||
typedef array_binary_tree_node<iterator, value_type, ID> Node;
|
||||
typedef array_binary_tree_node< iterator, value_type, ID > Node;
|
||||
#endif
|
||||
typedef compare_array_node<RandomAccessContainer,Comp> Compare;
|
||||
typedef std::vector<size_type> IndexArray;
|
||||
public:
|
||||
typedef compare_array_node< RandomAccessContainer, Comp > Compare;
|
||||
typedef std::vector< size_type > IndexArray;
|
||||
|
||||
public:
|
||||
typedef Compare value_compare;
|
||||
typedef ID id_generator;
|
||||
|
||||
mutable_queue(size_type n, const Comp& x, const ID& _id)
|
||||
: index_array(n), comp(x), id(_id) {
|
||||
c.reserve(n);
|
||||
}
|
||||
template <class ForwardIterator>
|
||||
mutable_queue(ForwardIterator first, ForwardIterator last,
|
||||
const Comp& x, const ID& _id)
|
||||
: index_array(std::distance(first, last)), comp(x), id(_id)
|
||||
: index_array(n), comp(x), id(_id)
|
||||
{
|
||||
while( first != last ) {
|
||||
push(*first);
|
||||
++first;
|
||||
}
|
||||
c.reserve(n);
|
||||
}
|
||||
template < class ForwardIterator >
|
||||
mutable_queue(ForwardIterator first, ForwardIterator last, const Comp& x,
|
||||
const ID& _id)
|
||||
: index_array(std::distance(first, last)), comp(x), id(_id)
|
||||
{
|
||||
while (first != last)
|
||||
{
|
||||
push(*first);
|
||||
++first;
|
||||
}
|
||||
}
|
||||
|
||||
bool empty() const { return c.empty(); }
|
||||
|
||||
void pop() {
|
||||
value_type tmp = c.back();
|
||||
c.back() = c.front();
|
||||
c.front() = tmp;
|
||||
void pop()
|
||||
{
|
||||
value_type tmp = c.back();
|
||||
c.back() = c.front();
|
||||
c.front() = tmp;
|
||||
|
||||
size_type id_f = get(id, c.back());
|
||||
size_type id_b = get(id, tmp);
|
||||
size_type i = index_array[ id_b ];
|
||||
index_array[ id_b ] = index_array[ id_f ];
|
||||
index_array[ id_f ] = i;
|
||||
size_type id_f = get(id, c.back());
|
||||
size_type id_b = get(id, tmp);
|
||||
size_type i = index_array[id_b];
|
||||
index_array[id_b] = index_array[id_f];
|
||||
index_array[id_f] = i;
|
||||
|
||||
c.pop_back();
|
||||
Node node(c.begin(), c.end(), c.begin(), id);
|
||||
down_heap(node, comp, index_array);
|
||||
c.pop_back();
|
||||
Node node(c.begin(), c.end(), c.begin(), id);
|
||||
down_heap(node, comp, index_array);
|
||||
}
|
||||
void push(const IndexedType& x) {
|
||||
c.push_back(x);
|
||||
/*set index-array*/
|
||||
index_array[ get(id, x) ] = c.size()-1;
|
||||
Node node(c.begin(), c.end(), c.end() - 1, id);
|
||||
up_heap(node, comp, index_array);
|
||||
void push(const IndexedType& x)
|
||||
{
|
||||
c.push_back(x);
|
||||
/*set index-array*/
|
||||
index_array[get(id, x)] = c.size() - 1;
|
||||
Node node(c.begin(), c.end(), c.end() - 1, id);
|
||||
up_heap(node, comp, index_array);
|
||||
}
|
||||
|
||||
void update(const IndexedType& x) {
|
||||
size_type current_pos = index_array[ get(id, x) ];
|
||||
c[current_pos] = x;
|
||||
void update(const IndexedType& x)
|
||||
{
|
||||
size_type current_pos = index_array[get(id, x)];
|
||||
c[current_pos] = x;
|
||||
|
||||
Node node(c.begin(), c.end(), c.begin()+current_pos, id);
|
||||
update_heap(node, comp, index_array);
|
||||
Node node(c.begin(), c.end(), c.begin() + current_pos, id);
|
||||
update_heap(node, comp, index_array);
|
||||
}
|
||||
|
||||
value_type& front() { return c.front(); }
|
||||
@@ -122,13 +131,12 @@ namespace boost {
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
protected:
|
||||
IndexArray index_array;
|
||||
Compare comp;
|
||||
RandomAccessContainer c;
|
||||
ID id;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -13,256 +13,365 @@
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace boost
|
||||
{
|
||||
|
||||
struct no_property {};
|
||||
struct no_property
|
||||
{
|
||||
};
|
||||
|
||||
template <class Tag, class T, class Base = no_property>
|
||||
struct property {
|
||||
template < class Tag, class T, class Base = no_property > struct property
|
||||
{
|
||||
typedef Base next_type;
|
||||
typedef Tag tag_type;
|
||||
typedef T value_type;
|
||||
property(const T& v = T()) : m_value(v) { }
|
||||
property(const T& v, const Base& b) : m_value(v), m_base(b) { }
|
||||
property(const T& v = T()) : m_value(v) {}
|
||||
property(const T& v, const Base& b) : m_value(v), m_base(b) {}
|
||||
// copy constructor and assignment operator will be generated by compiler
|
||||
|
||||
T m_value;
|
||||
Base m_base;
|
||||
};
|
||||
};
|
||||
|
||||
// Kinds of properties
|
||||
namespace graph_introspect_detail {
|
||||
// Kinds of properties
|
||||
namespace graph_introspect_detail
|
||||
{
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(kind)
|
||||
template <typename T, bool Cond> struct get_kind {typedef void type;};
|
||||
template <typename T> struct get_kind<T, true> {typedef typename T::kind type;};
|
||||
}
|
||||
template < typename T, bool Cond > struct get_kind
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
template < typename T > struct get_kind< T, true >
|
||||
{
|
||||
typedef typename T::kind type;
|
||||
};
|
||||
}
|
||||
|
||||
// Having a default is to make this trait work for any type, not just valid
|
||||
// properties, to work around VC++ <= 10 bugs related to SFINAE in
|
||||
// compressed_sparse_row_graph's get functions and similar
|
||||
template <class PropertyTag>
|
||||
struct property_kind:
|
||||
graph_introspect_detail::get_kind<PropertyTag, graph_introspect_detail::has_kind<PropertyTag>::value>
|
||||
{};
|
||||
// Having a default is to make this trait work for any type, not just valid
|
||||
// properties, to work around VC++ <= 10 bugs related to SFINAE in
|
||||
// compressed_sparse_row_graph's get functions and similar
|
||||
template < class PropertyTag >
|
||||
struct property_kind
|
||||
: graph_introspect_detail::get_kind< PropertyTag,
|
||||
graph_introspect_detail::has_kind< PropertyTag >::value >
|
||||
{
|
||||
};
|
||||
|
||||
// Some standard properties defined independently of Boost.Graph:
|
||||
enum vertex_all_t {vertex_all};
|
||||
enum edge_all_t {edge_all};
|
||||
enum graph_all_t {graph_all};
|
||||
enum vertex_bundle_t {vertex_bundle};
|
||||
enum edge_bundle_t {edge_bundle};
|
||||
enum graph_bundle_t {graph_bundle};
|
||||
// Some standard properties defined independently of Boost.Graph:
|
||||
enum vertex_all_t
|
||||
{
|
||||
vertex_all
|
||||
};
|
||||
enum edge_all_t
|
||||
{
|
||||
edge_all
|
||||
};
|
||||
enum graph_all_t
|
||||
{
|
||||
graph_all
|
||||
};
|
||||
enum vertex_bundle_t
|
||||
{
|
||||
vertex_bundle
|
||||
};
|
||||
enum edge_bundle_t
|
||||
{
|
||||
edge_bundle
|
||||
};
|
||||
enum graph_bundle_t
|
||||
{
|
||||
graph_bundle
|
||||
};
|
||||
|
||||
// Code to look up one property in a property list:
|
||||
template <typename PList, typename PropName, typename Enable = void>
|
||||
struct lookup_one_property_internal {BOOST_STATIC_CONSTANT(bool, found = false); typedef void type;};
|
||||
// Code to look up one property in a property list:
|
||||
template < typename PList, typename PropName, typename Enable = void >
|
||||
struct lookup_one_property_internal
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, found = false);
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
// Special-case properties (vertex_all, edge_all, graph_all)
|
||||
#define BGL_ALL_PROP(tag) \
|
||||
template <typename T> \
|
||||
struct lookup_one_property_internal<T, tag> { \
|
||||
BOOST_STATIC_CONSTANT(bool, found = true); \
|
||||
typedef T type; \
|
||||
static T& lookup(T& x, tag) {return x;} \
|
||||
static const T& lookup(const T& x, tag) {return x;} \
|
||||
}; \
|
||||
template <typename Tag, typename T, typename Base> \
|
||||
struct lookup_one_property_internal<property<Tag, T, Base>, tag> { /* Avoid ambiguity */ \
|
||||
BOOST_STATIC_CONSTANT(bool, found = true); \
|
||||
typedef property<Tag, T, Base> type; \
|
||||
static type& lookup(type& x, tag) {return x;} \
|
||||
static const type& lookup(const type& x, tag) {return x;} \
|
||||
};
|
||||
// Special-case properties (vertex_all, edge_all, graph_all)
|
||||
#define BGL_ALL_PROP(tag) \
|
||||
template < typename T > struct lookup_one_property_internal< T, tag > \
|
||||
{ \
|
||||
BOOST_STATIC_CONSTANT(bool, found = true); \
|
||||
typedef T type; \
|
||||
static T& lookup(T& x, tag) { return x; } \
|
||||
static const T& lookup(const T& x, tag) { return x; } \
|
||||
}; \
|
||||
template < typename Tag, typename T, typename Base > \
|
||||
struct lookup_one_property_internal< property< Tag, T, Base >, tag > \
|
||||
{ /* Avoid ambiguity */ \
|
||||
BOOST_STATIC_CONSTANT(bool, found = true); \
|
||||
typedef property< Tag, T, Base > type; \
|
||||
static type& lookup(type& x, tag) { return x; } \
|
||||
static const type& lookup(const type& x, tag) { return x; } \
|
||||
};
|
||||
|
||||
BGL_ALL_PROP(vertex_all_t)
|
||||
BGL_ALL_PROP(edge_all_t)
|
||||
BGL_ALL_PROP(graph_all_t)
|
||||
BGL_ALL_PROP(vertex_all_t)
|
||||
BGL_ALL_PROP(edge_all_t)
|
||||
BGL_ALL_PROP(graph_all_t)
|
||||
#undef BGL_ALL_PROP
|
||||
|
||||
// *_bundled; these need to be macros rather than inheritance to resolve ambiguities
|
||||
#define BGL_DO_ONE_BUNDLE_TYPE(kind) \
|
||||
template <typename T> \
|
||||
struct lookup_one_property_internal<T, BOOST_JOIN(kind, _bundle_t)> { \
|
||||
BOOST_STATIC_CONSTANT(bool, found = true); \
|
||||
typedef T type; \
|
||||
static T& lookup(T& x, BOOST_JOIN(kind, _bundle_t)) {return x;} \
|
||||
static const T& lookup(const T& x, BOOST_JOIN(kind, _bundle_t)) {return x;} \
|
||||
}; \
|
||||
\
|
||||
template <typename Tag, typename T, typename Base> \
|
||||
struct lookup_one_property_internal<property<Tag, T, Base>, BOOST_JOIN(kind, _bundle_t)>: lookup_one_property_internal<Base, BOOST_JOIN(kind, _bundle_t)> { \
|
||||
private: \
|
||||
typedef lookup_one_property_internal<Base, BOOST_JOIN(kind, _bundle_t)> base_type; \
|
||||
public: \
|
||||
template <typename BundleTag> \
|
||||
static typename lazy_enable_if_c<(base_type::found && (is_same<BundleTag, BOOST_JOIN(kind, _bundle_t)>::value)), \
|
||||
add_reference<typename base_type::type> >::type \
|
||||
lookup(property<Tag, T, Base>& p, BundleTag) {return base_type::lookup(p.m_base, BOOST_JOIN(kind, _bundle_t)());} \
|
||||
template <typename BundleTag> \
|
||||
static typename lazy_enable_if_c<(base_type::found && (is_same<BundleTag, BOOST_JOIN(kind, _bundle_t)>::value)), \
|
||||
add_reference<const typename base_type::type> >::type \
|
||||
lookup(const property<Tag, T, Base>& p, BundleTag) {return base_type::lookup(p.m_base, BOOST_JOIN(kind, _bundle_t)());} \
|
||||
}; \
|
||||
// *_bundled; these need to be macros rather than inheritance to resolve
|
||||
// ambiguities
|
||||
#define BGL_DO_ONE_BUNDLE_TYPE(kind) \
|
||||
template < typename T > \
|
||||
struct lookup_one_property_internal< T, BOOST_JOIN(kind, _bundle_t) > \
|
||||
{ \
|
||||
BOOST_STATIC_CONSTANT(bool, found = true); \
|
||||
typedef T type; \
|
||||
static T& lookup(T& x, BOOST_JOIN(kind, _bundle_t)) { return x; } \
|
||||
static const T& lookup(const T& x, BOOST_JOIN(kind, _bundle_t)) \
|
||||
{ \
|
||||
return x; \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
template < typename Tag, typename T, typename Base > \
|
||||
struct lookup_one_property_internal< property< Tag, T, Base >, \
|
||||
BOOST_JOIN(kind, _bundle_t) > \
|
||||
: lookup_one_property_internal< Base, BOOST_JOIN(kind, _bundle_t) > \
|
||||
{ \
|
||||
private: \
|
||||
typedef lookup_one_property_internal< Base, \
|
||||
BOOST_JOIN(kind, _bundle_t) > \
|
||||
base_type; \
|
||||
\
|
||||
public: \
|
||||
template < typename BundleTag > \
|
||||
static typename lazy_enable_if_c< \
|
||||
(base_type::found \
|
||||
&& (is_same< BundleTag, \
|
||||
BOOST_JOIN(kind, _bundle_t) >::value)), \
|
||||
add_reference< typename base_type::type > >::type \
|
||||
lookup(property< Tag, T, Base >& p, BundleTag) \
|
||||
{ \
|
||||
return base_type::lookup(p.m_base, BOOST_JOIN(kind, _bundle_t)()); \
|
||||
} \
|
||||
template < typename BundleTag > \
|
||||
static typename lazy_enable_if_c< \
|
||||
(base_type::found \
|
||||
&& (is_same< BundleTag, \
|
||||
BOOST_JOIN(kind, _bundle_t) >::value)), \
|
||||
add_reference< const typename base_type::type > >::type \
|
||||
lookup(const property< Tag, T, Base >& p, BundleTag) \
|
||||
{ \
|
||||
return base_type::lookup(p.m_base, BOOST_JOIN(kind, _bundle_t)()); \
|
||||
} \
|
||||
};
|
||||
|
||||
BGL_DO_ONE_BUNDLE_TYPE(vertex)
|
||||
BGL_DO_ONE_BUNDLE_TYPE(edge)
|
||||
BGL_DO_ONE_BUNDLE_TYPE(graph)
|
||||
BGL_DO_ONE_BUNDLE_TYPE(vertex)
|
||||
BGL_DO_ONE_BUNDLE_TYPE(edge)
|
||||
BGL_DO_ONE_BUNDLE_TYPE(graph)
|
||||
#undef BGL_DO_ONE_BUNDLE_TYPE
|
||||
|
||||
// Normal old-style properties; second case also handles chaining of bundled property accesses
|
||||
template <typename Tag, typename T, typename Base>
|
||||
struct lookup_one_property_internal<boost::property<Tag, T, Base>, Tag> {
|
||||
// Normal old-style properties; second case also handles chaining of bundled
|
||||
// property accesses
|
||||
template < typename Tag, typename T, typename Base >
|
||||
struct lookup_one_property_internal< boost::property< Tag, T, Base >, Tag >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, found = true);
|
||||
typedef property<Tag, T, Base> prop;
|
||||
typedef property< Tag, T, Base > prop;
|
||||
typedef T type;
|
||||
template <typename U>
|
||||
static typename enable_if<is_same<prop, U>, T&>::type
|
||||
lookup(U& prop, const Tag&) {return prop.m_value;}
|
||||
template <typename U>
|
||||
static typename enable_if<is_same<prop, U>, const T&>::type
|
||||
lookup(const U& prop, const Tag&) {return prop.m_value;}
|
||||
};
|
||||
|
||||
template <typename Tag, typename T, typename Base, typename PropName>
|
||||
struct lookup_one_property_internal<boost::property<Tag, T, Base>, PropName>: lookup_one_property_internal<Base, PropName> {
|
||||
private:
|
||||
typedef lookup_one_property_internal<Base, PropName> base_type;
|
||||
public:
|
||||
template <typename PL>
|
||||
static typename lazy_enable_if<is_same<PL, boost::property<Tag, T, Base> >,
|
||||
add_reference<typename base_type::type> >::type
|
||||
lookup(PL& prop, const PropName& tag) {
|
||||
return base_type::lookup(prop.m_base, tag);
|
||||
template < typename U >
|
||||
static typename enable_if< is_same< prop, U >, T& >::type lookup(
|
||||
U& prop, const Tag&)
|
||||
{
|
||||
return prop.m_value;
|
||||
}
|
||||
template <typename PL>
|
||||
static typename lazy_enable_if<is_same<PL, boost::property<Tag, T, Base> >,
|
||||
add_reference<const typename base_type::type> >::type
|
||||
lookup(const PL& prop, const PropName& tag) {
|
||||
return base_type::lookup(prop.m_base, tag);
|
||||
template < typename U >
|
||||
static typename enable_if< is_same< prop, U >, const T& >::type lookup(
|
||||
const U& prop, const Tag&)
|
||||
{
|
||||
return prop.m_value;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Pointer-to-member access to bundled properties
|
||||
template < typename Tag, typename T, typename Base, typename PropName >
|
||||
struct lookup_one_property_internal< boost::property< Tag, T, Base >, PropName >
|
||||
: lookup_one_property_internal< Base, PropName >
|
||||
{
|
||||
private:
|
||||
typedef lookup_one_property_internal< Base, PropName > base_type;
|
||||
|
||||
public:
|
||||
template < typename PL >
|
||||
static
|
||||
typename lazy_enable_if< is_same< PL, boost::property< Tag, T, Base > >,
|
||||
add_reference< typename base_type::type > >::type
|
||||
lookup(PL& prop, const PropName& tag)
|
||||
{
|
||||
return base_type::lookup(prop.m_base, tag);
|
||||
}
|
||||
template < typename PL >
|
||||
static
|
||||
typename lazy_enable_if< is_same< PL, boost::property< Tag, T, Base > >,
|
||||
add_reference< const typename base_type::type > >::type
|
||||
lookup(const PL& prop, const PropName& tag)
|
||||
{
|
||||
return base_type::lookup(prop.m_base, tag);
|
||||
}
|
||||
};
|
||||
|
||||
// Pointer-to-member access to bundled properties
|
||||
#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
|
||||
template <typename T, typename TMaybeBase, typename R>
|
||||
struct lookup_one_property_internal<T, R TMaybeBase::*, typename enable_if<is_base_of<TMaybeBase, T> >::type> {
|
||||
template < typename T, typename TMaybeBase, typename R >
|
||||
struct lookup_one_property_internal< T, R TMaybeBase::*,
|
||||
typename enable_if< is_base_of< TMaybeBase, T > >::type >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, found = true);
|
||||
typedef R type;
|
||||
static R& lookup(T& x, R TMaybeBase::*ptr) {return x.*ptr;}
|
||||
static const R& lookup(const T& x, R TMaybeBase::*ptr) {return x.*ptr;}
|
||||
};
|
||||
static R& lookup(T& x, R TMaybeBase::*ptr) { return x.*ptr; }
|
||||
static const R& lookup(const T& x, R TMaybeBase::*ptr) { return x.*ptr; }
|
||||
};
|
||||
#endif
|
||||
|
||||
// Version of above handling const property lists properly
|
||||
template <typename T, typename Tag>
|
||||
struct lookup_one_property: lookup_one_property_internal<T, Tag> {};
|
||||
// Version of above handling const property lists properly
|
||||
template < typename T, typename Tag >
|
||||
struct lookup_one_property : lookup_one_property_internal< T, Tag >
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T, typename Tag>
|
||||
struct lookup_one_property<const T, Tag> {
|
||||
BOOST_STATIC_CONSTANT(bool, found = (lookup_one_property_internal<T, Tag>::found));
|
||||
typedef const typename lookup_one_property_internal<T, Tag>::type type;
|
||||
template <typename U>
|
||||
static typename lazy_enable_if<is_same<T, U>,
|
||||
add_reference<const typename lookup_one_property_internal<T, Tag>::type> >::type
|
||||
lookup(const U& p, Tag tag) {
|
||||
return lookup_one_property_internal<T, Tag>::lookup(p, tag);
|
||||
template < typename T, typename Tag > struct lookup_one_property< const T, Tag >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, found = (lookup_one_property_internal< T, Tag >::found));
|
||||
typedef const typename lookup_one_property_internal< T, Tag >::type type;
|
||||
template < typename U >
|
||||
static typename lazy_enable_if< is_same< T, U >,
|
||||
add_reference< const typename lookup_one_property_internal< T,
|
||||
Tag >::type > >::type
|
||||
lookup(const U& p, Tag tag)
|
||||
{
|
||||
return lookup_one_property_internal< T, Tag >::lookup(p, tag);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// The BGL properties specialize property_kind and
|
||||
// property_num, and use enum's for the Property type (see
|
||||
// graph/properties.hpp), but the user may want to use a class
|
||||
// instead with a nested kind type and num. Also, we may want to
|
||||
// switch BGL back to using class types for properties at some point.
|
||||
// The BGL properties specialize property_kind and
|
||||
// property_num, and use enum's for the Property type (see
|
||||
// graph/properties.hpp), but the user may want to use a class
|
||||
// instead with a nested kind type and num. Also, we may want to
|
||||
// switch BGL back to using class types for properties at some point.
|
||||
|
||||
template <class P>
|
||||
struct has_property : boost::mpl::true_ {};
|
||||
template <>
|
||||
struct has_property<no_property> : boost::mpl::false_ {};
|
||||
template < class P > struct has_property : boost::mpl::true_
|
||||
{
|
||||
};
|
||||
template <> struct has_property< no_property > : boost::mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/pending/detail/property.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template <class PropertyList, class Tag>
|
||||
struct property_value: lookup_one_property<PropertyList, Tag> {};
|
||||
template < class PropertyList, class Tag >
|
||||
struct property_value : lookup_one_property< PropertyList, Tag >
|
||||
{
|
||||
};
|
||||
|
||||
template <class PropertyList, class Tag>
|
||||
inline typename lookup_one_property<PropertyList, Tag>::type&
|
||||
get_property_value(PropertyList& p, Tag tag) {
|
||||
return lookup_one_property<PropertyList, Tag>::lookup(p, tag);
|
||||
}
|
||||
template < class PropertyList, class Tag >
|
||||
inline typename lookup_one_property< PropertyList, Tag >::type&
|
||||
get_property_value(PropertyList& p, Tag tag)
|
||||
{
|
||||
return lookup_one_property< PropertyList, Tag >::lookup(p, tag);
|
||||
}
|
||||
|
||||
template <class PropertyList, class Tag>
|
||||
inline const typename lookup_one_property<PropertyList, Tag>::type&
|
||||
get_property_value(const PropertyList& p, Tag tag) {
|
||||
return lookup_one_property<PropertyList, Tag>::lookup(p, tag);
|
||||
}
|
||||
template < class PropertyList, class Tag >
|
||||
inline const typename lookup_one_property< PropertyList, Tag >::type&
|
||||
get_property_value(const PropertyList& p, Tag tag)
|
||||
{
|
||||
return lookup_one_property< PropertyList, Tag >::lookup(p, tag);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
namespace detail
|
||||
{
|
||||
|
||||
/** This trait returns true if T is no_property. */
|
||||
template <typename T>
|
||||
struct is_no_property
|
||||
: mpl::bool_<is_same<T, no_property>::value>
|
||||
{ };
|
||||
|
||||
template <typename PList, typename Tag>
|
||||
class lookup_one_property_f;
|
||||
|
||||
template <typename PList, typename Tag, typename F> struct lookup_one_property_f_result;
|
||||
|
||||
template <typename PList, typename Tag>
|
||||
struct lookup_one_property_f_result<PList, Tag, const lookup_one_property_f<PList, Tag>(PList)> {
|
||||
typedef typename lookup_one_property<PList, Tag>::type type;
|
||||
/** This trait returns true if T is no_property. */
|
||||
template < typename T >
|
||||
struct is_no_property : mpl::bool_< is_same< T, no_property >::value >
|
||||
{
|
||||
};
|
||||
|
||||
template <typename PList, typename Tag>
|
||||
struct lookup_one_property_f_result<PList, Tag, const lookup_one_property_f<PList, Tag>(PList&)> {
|
||||
typedef typename lookup_one_property<PList, Tag>::type& type;
|
||||
template < typename PList, typename Tag > class lookup_one_property_f;
|
||||
|
||||
template < typename PList, typename Tag, typename F >
|
||||
struct lookup_one_property_f_result;
|
||||
|
||||
template < typename PList, typename Tag >
|
||||
struct lookup_one_property_f_result< PList, Tag,
|
||||
const lookup_one_property_f< PList, Tag >(PList) >
|
||||
{
|
||||
typedef typename lookup_one_property< PList, Tag >::type type;
|
||||
};
|
||||
|
||||
template <typename PList, typename Tag>
|
||||
struct lookup_one_property_f_result<PList, Tag, const lookup_one_property_f<PList, Tag>(const PList&)> {
|
||||
typedef const typename lookup_one_property<PList, Tag>::type& type;
|
||||
template < typename PList, typename Tag >
|
||||
struct lookup_one_property_f_result< PList, Tag,
|
||||
const lookup_one_property_f< PList, Tag >(PList&) >
|
||||
{
|
||||
typedef typename lookup_one_property< PList, Tag >::type& type;
|
||||
};
|
||||
|
||||
template <typename PList, typename Tag>
|
||||
class lookup_one_property_f {
|
||||
Tag tag;
|
||||
public:
|
||||
lookup_one_property_f(Tag tag): tag(tag) {}
|
||||
template <typename F> struct result: lookup_one_property_f_result<PList, Tag, F> {};
|
||||
template < typename PList, typename Tag >
|
||||
struct lookup_one_property_f_result< PList, Tag,
|
||||
const lookup_one_property_f< PList, Tag >(const PList&) >
|
||||
{
|
||||
typedef const typename lookup_one_property< PList, Tag >::type& type;
|
||||
};
|
||||
|
||||
typename lookup_one_property_f_result<PList, Tag, const lookup_one_property_f(PList&)>::type
|
||||
operator()(PList& pl) const {
|
||||
return lookup_one_property<PList, Tag>::lookup(pl, tag);
|
||||
}
|
||||
template < typename PList, typename Tag > class lookup_one_property_f
|
||||
{
|
||||
Tag tag;
|
||||
|
||||
public:
|
||||
lookup_one_property_f(Tag tag) : tag(tag) {}
|
||||
template < typename F >
|
||||
struct result : lookup_one_property_f_result< PList, Tag, F >
|
||||
{
|
||||
};
|
||||
|
||||
typename lookup_one_property_f_result< PList, Tag,
|
||||
const lookup_one_property_f(PList&) >::type
|
||||
operator()(PList& pl) const
|
||||
{
|
||||
return lookup_one_property< PList, Tag >::lookup(pl, tag);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
namespace detail {
|
||||
// Stuff for directed_graph and undirected_graph to skip over their first
|
||||
// vertex_index and edge_index properties when providing vertex_all and
|
||||
// edge_all; make sure you know the exact structure of your properties if you
|
||||
// use there.
|
||||
struct remove_first_property {
|
||||
template <typename F>
|
||||
struct result {
|
||||
typedef typename boost::function_traits<F>::arg1_type a1;
|
||||
typedef typename boost::remove_reference<a1>::type non_ref;
|
||||
typedef typename non_ref::next_type nx;
|
||||
typedef typename boost::mpl::if_<boost::is_const<non_ref>, boost::add_const<nx>, nx>::type with_const;
|
||||
typedef typename boost::add_reference<with_const>::type type;
|
||||
namespace detail
|
||||
{
|
||||
// Stuff for directed_graph and undirected_graph to skip over their first
|
||||
// vertex_index and edge_index properties when providing vertex_all and
|
||||
// edge_all; make sure you know the exact structure of your properties if
|
||||
// you use there.
|
||||
struct remove_first_property
|
||||
{
|
||||
template < typename F > struct result
|
||||
{
|
||||
typedef typename boost::function_traits< F >::arg1_type a1;
|
||||
typedef typename boost::remove_reference< a1 >::type non_ref;
|
||||
typedef typename non_ref::next_type nx;
|
||||
typedef typename boost::mpl::if_< boost::is_const< non_ref >,
|
||||
boost::add_const< nx >, nx >::type with_const;
|
||||
typedef typename boost::add_reference< with_const >::type type;
|
||||
};
|
||||
template < typename Prop >
|
||||
typename Prop::next_type& operator()(Prop& p) const
|
||||
{
|
||||
return p.m_base;
|
||||
}
|
||||
template < typename Prop >
|
||||
const typename Prop::next_type& operator()(const Prop& p) const
|
||||
{
|
||||
return p.m_base;
|
||||
}
|
||||
};
|
||||
template <typename Prop>
|
||||
typename Prop::next_type& operator()(Prop& p) const {return p.m_base;}
|
||||
template <typename Prop>
|
||||
const typename Prop::next_type& operator()(const Prop& p) const {return p.m_base;}
|
||||
};
|
||||
}
|
||||
|
||||
} // namesapce boost
|
||||
|
||||
@@ -7,64 +7,93 @@
|
||||
#define BOOST_PROPERTY_SERIALIZE_HPP
|
||||
|
||||
#include <boost/pending/property.hpp>
|
||||
#ifdef BOOST_GRAPH_USE_MPI
|
||||
#include <boost/mpi/datatype.hpp>
|
||||
#include <boost/serialization/is_bitwise_serializable.hpp>
|
||||
#endif // BOOST_GRAPH_USE_MPI
|
||||
|
||||
#include <boost/serialization/base_object.hpp>
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
|
||||
namespace boost {
|
||||
template<class Archive>
|
||||
inline void serialize(Archive&, no_property&, const unsigned int) { }
|
||||
namespace boost
|
||||
{
|
||||
template < class Archive >
|
||||
inline void serialize(Archive&, no_property&, const unsigned int)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Archive, class Tag, class T, class Base>
|
||||
void
|
||||
serialize(Archive& ar, property<Tag, T, Base>& prop,
|
||||
const unsigned int /*version*/)
|
||||
{
|
||||
ar & serialization::make_nvp( "property_value" , prop.m_value );
|
||||
ar & serialization::make_nvp( "property_base" , prop.m_base );
|
||||
}
|
||||
template < class Archive, class Tag, class T, class Base >
|
||||
void serialize(
|
||||
Archive& ar, property< Tag, T, Base >& prop, const unsigned int /*version*/)
|
||||
{
|
||||
ar& serialization::make_nvp("property_value", prop.m_value);
|
||||
ar& serialization::make_nvp("property_base", prop.m_base);
|
||||
}
|
||||
|
||||
#ifdef BOOST_GRAPH_USE_MPI
|
||||
namespace mpi {
|
||||
template<typename Tag, typename T, typename Base>
|
||||
struct is_mpi_datatype<property<Tag, T, Base> >
|
||||
: mpl::and_<is_mpi_datatype<T>,
|
||||
is_mpi_datatype<Base> > { };
|
||||
}
|
||||
|
||||
namespace serialization {
|
||||
template<typename Tag, typename T, typename Base>
|
||||
struct is_bitwise_serializable<property<Tag, T, Base> >
|
||||
: mpl::and_<is_bitwise_serializable<T>,
|
||||
is_bitwise_serializable<Base> > { };
|
||||
// Setting the serialization properties of boost::property<> and
|
||||
// boost::no_property to is_bitwise_serializable, object_serializable,
|
||||
// track_never only when BOOST_GRAPH_USE_MPI is defined is dubious.
|
||||
//
|
||||
// This changes the serialization format of these classes, and hence
|
||||
// of boost::adjacency_list, depending on whether BOOST_GRAPH_USE_MPI
|
||||
// is defined.
|
||||
//
|
||||
// These serialization properties should probably be set in either case.
|
||||
//
|
||||
// Unfortunately, doing that now will change the serialization format
|
||||
// of boost::adjacency_list in the non-MPI case, and could potentially
|
||||
// break software that reads files serialized with an older release.
|
||||
|
||||
template<typename Tag, typename T, typename Base>
|
||||
struct implementation_level<property<Tag, T, Base> >
|
||||
: mpl::int_<object_serializable> {} ;
|
||||
namespace mpi
|
||||
{
|
||||
|
||||
template<typename Tag, typename T, typename Base>
|
||||
struct tracking_level<property<Tag, T, Base> >
|
||||
: mpl::int_<track_never> {} ;
|
||||
// forward declaration, to avoid including mpi
|
||||
template < typename T > struct is_mpi_datatype;
|
||||
|
||||
}
|
||||
template < typename Tag, typename T, typename Base >
|
||||
struct is_mpi_datatype< property< Tag, T, Base > >
|
||||
: mpl::and_< is_mpi_datatype< T >, is_mpi_datatype< Base > >
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
namespace serialization
|
||||
{
|
||||
template < typename Tag, typename T, typename Base >
|
||||
struct is_bitwise_serializable< property< Tag, T, Base > >
|
||||
: mpl::and_< is_bitwise_serializable< T >, is_bitwise_serializable< Base > >
|
||||
{
|
||||
};
|
||||
|
||||
template < typename Tag, typename T, typename Base >
|
||||
struct implementation_level< property< Tag, T, Base > >
|
||||
: mpl::int_< object_serializable >
|
||||
{
|
||||
};
|
||||
|
||||
template < typename Tag, typename T, typename Base >
|
||||
struct tracking_level< property< Tag, T, Base > > : mpl::int_< track_never >
|
||||
{
|
||||
};
|
||||
|
||||
}
|
||||
#endif // BOOST_GRAPH_USE_MPI
|
||||
|
||||
|
||||
} // end namespace boost
|
||||
|
||||
#ifdef BOOST_GRAPH_USE_MPI
|
||||
namespace boost { namespace mpi {
|
||||
template<>
|
||||
struct is_mpi_datatype<boost::no_property> : mpl::true_ { };
|
||||
namespace boost
|
||||
{
|
||||
namespace mpi
|
||||
{
|
||||
template <> struct is_mpi_datatype< boost::no_property > : mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
} } // end namespace boost::mpi
|
||||
}
|
||||
} // end namespace boost::mpi
|
||||
|
||||
BOOST_IS_BITWISE_SERIALIZABLE(boost::no_property)
|
||||
BOOST_CLASS_IMPLEMENTATION(boost::no_property,object_serializable)
|
||||
BOOST_CLASS_TRACKING(boost::no_property,track_never)
|
||||
BOOST_CLASS_IMPLEMENTATION(boost::no_property, object_serializable)
|
||||
BOOST_CLASS_TRACKING(boost::no_property, track_never)
|
||||
#endif // BOOST_GRAPH_USE_MPI
|
||||
|
||||
#endif // BOOST_PROPERTY_SERIALIZE_HPP
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// (C) Copyright Jeremy Siek 2004
|
||||
// (C) Copyright Jeremy Siek 2004
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -9,109 +9,109 @@
|
||||
#include <deque>
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost {
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template <class _Tp,
|
||||
class _Sequence = std::deque<_Tp> >
|
||||
class queue;
|
||||
template < class _Tp, class _Sequence = std::deque< _Tp > > class queue;
|
||||
|
||||
template <class _Tp, class _Seq>
|
||||
inline bool operator==(const queue<_Tp, _Seq>&, const queue<_Tp, _Seq>&);
|
||||
template < class _Tp, class _Seq >
|
||||
inline bool operator==(const queue< _Tp, _Seq >&, const queue< _Tp, _Seq >&);
|
||||
|
||||
template <class _Tp, class _Seq>
|
||||
inline bool operator<(const queue<_Tp, _Seq>&, const queue<_Tp, _Seq>&);
|
||||
template < class _Tp, class _Seq >
|
||||
inline bool operator<(const queue< _Tp, _Seq >&, const queue< _Tp, _Seq >&);
|
||||
|
||||
|
||||
template <class _Tp, class _Sequence>
|
||||
class queue {
|
||||
template < class _Tp, class _Sequence > class queue
|
||||
{
|
||||
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
template <class _Tp1, class _Seq1>
|
||||
friend bool operator== (const queue<_Tp1, _Seq1>&,
|
||||
const queue<_Tp1, _Seq1>&);
|
||||
template <class _Tp1, class _Seq1>
|
||||
friend bool operator< (const queue<_Tp1, _Seq1>&,
|
||||
const queue<_Tp1, _Seq1>&);
|
||||
template < class _Tp1, class _Seq1 >
|
||||
friend bool operator==(
|
||||
const queue< _Tp1, _Seq1 >&, const queue< _Tp1, _Seq1 >&);
|
||||
template < class _Tp1, class _Seq1 >
|
||||
friend bool operator<(
|
||||
const queue< _Tp1, _Seq1 >&, const queue< _Tp1, _Seq1 >&);
|
||||
#endif
|
||||
public:
|
||||
typedef typename _Sequence::value_type value_type;
|
||||
typedef typename _Sequence::size_type size_type;
|
||||
typedef _Sequence container_type;
|
||||
typedef typename _Sequence::value_type value_type;
|
||||
typedef typename _Sequence::size_type size_type;
|
||||
typedef _Sequence container_type;
|
||||
|
||||
typedef typename _Sequence::reference reference;
|
||||
typedef typename _Sequence::const_reference const_reference;
|
||||
typedef typename _Sequence::reference reference;
|
||||
typedef typename _Sequence::const_reference const_reference;
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
protected:
|
||||
#endif
|
||||
_Sequence c;
|
||||
_Sequence c;
|
||||
|
||||
public:
|
||||
queue() : c() {}
|
||||
explicit queue(const _Sequence& __c) : c(__c) {}
|
||||
queue() : c() {}
|
||||
explicit queue(const _Sequence& __c) : c(__c) {}
|
||||
|
||||
bool empty() const { return c.empty(); }
|
||||
size_type size() const { return c.size(); }
|
||||
reference front() { return c.front(); }
|
||||
const_reference front() const { return c.front(); }
|
||||
reference top() { return c.front(); }
|
||||
const_reference top() const { return c.front(); }
|
||||
reference back() { return c.back(); }
|
||||
const_reference back() const { return c.back(); }
|
||||
void push(const value_type& __x) { c.push_back(__x); }
|
||||
void pop() { c.pop_front(); }
|
||||
bool empty() const { return c.empty(); }
|
||||
size_type size() const { return c.size(); }
|
||||
reference front() { return c.front(); }
|
||||
const_reference front() const { return c.front(); }
|
||||
reference top() { return c.front(); }
|
||||
const_reference top() const { return c.front(); }
|
||||
reference back() { return c.back(); }
|
||||
const_reference back() const { return c.back(); }
|
||||
void push(const value_type& __x) { c.push_back(__x); }
|
||||
void pop() { c.pop_front(); }
|
||||
|
||||
void swap(queue& other)
|
||||
{
|
||||
using std::swap;
|
||||
swap(c, other.c);
|
||||
}
|
||||
void swap(queue& other)
|
||||
{
|
||||
using std::swap;
|
||||
swap(c, other.c);
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Tp, class _Sequence>
|
||||
bool
|
||||
operator==(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y)
|
||||
template < class _Tp, class _Sequence >
|
||||
bool operator==(
|
||||
const queue< _Tp, _Sequence >& __x, const queue< _Tp, _Sequence >& __y)
|
||||
{
|
||||
return __x.c == __y.c;
|
||||
return __x.c == __y.c;
|
||||
}
|
||||
|
||||
template <class _Tp, class _Sequence>
|
||||
bool
|
||||
operator<(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y)
|
||||
template < class _Tp, class _Sequence >
|
||||
bool operator<(
|
||||
const queue< _Tp, _Sequence >& __x, const queue< _Tp, _Sequence >& __y)
|
||||
{
|
||||
return __x.c < __y.c;
|
||||
return __x.c < __y.c;
|
||||
}
|
||||
|
||||
template <class _Tp, class _Sequence>
|
||||
bool
|
||||
operator!=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y)
|
||||
template < class _Tp, class _Sequence >
|
||||
bool operator!=(
|
||||
const queue< _Tp, _Sequence >& __x, const queue< _Tp, _Sequence >& __y)
|
||||
{
|
||||
return !(__x == __y);
|
||||
return !(__x == __y);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Sequence>
|
||||
bool
|
||||
operator>(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y)
|
||||
template < class _Tp, class _Sequence >
|
||||
bool operator>(
|
||||
const queue< _Tp, _Sequence >& __x, const queue< _Tp, _Sequence >& __y)
|
||||
{
|
||||
return __y < __x;
|
||||
return __y < __x;
|
||||
}
|
||||
|
||||
template <class _Tp, class _Sequence>
|
||||
bool
|
||||
operator<=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y)
|
||||
template < class _Tp, class _Sequence >
|
||||
bool operator<=(
|
||||
const queue< _Tp, _Sequence >& __x, const queue< _Tp, _Sequence >& __y)
|
||||
{
|
||||
return !(__y < __x);
|
||||
return !(__y < __x);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Sequence>
|
||||
bool
|
||||
operator>=(const queue<_Tp, _Sequence>& __x, const queue<_Tp, _Sequence>& __y)
|
||||
template < class _Tp, class _Sequence >
|
||||
bool operator>=(
|
||||
const queue< _Tp, _Sequence >& __x, const queue< _Tp, _Sequence >& __y)
|
||||
{
|
||||
return !(__x < __y);
|
||||
return !(__x < __y);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Sequence>
|
||||
inline void
|
||||
swap(queue<_Tp, _Sequence>& __x, queue<_Tp, _Sequence>& __y)
|
||||
{ __x.swap(__y); }
|
||||
template < class _Tp, class _Sequence >
|
||||
inline void swap(queue< _Tp, _Sequence >& __x, queue< _Tp, _Sequence >& __y)
|
||||
{
|
||||
__x.swap(__y);
|
||||
}
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
// (C) Copyright Jeremy Siek 2004
|
||||
// (C) Copyright Jeremy Siek 2004
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -55,27 +55,24 @@
|
||||
* -end example]
|
||||
*
|
||||
* pedwards@jaj.com May 1999
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <cstring> // for strchr
|
||||
|
||||
#include <cstring> // for strchr
|
||||
|
||||
/*****************************************************************
|
||||
* This is the only part of the implementation that I don't like.
|
||||
* It can probably be improved upon by the reader...
|
||||
*/
|
||||
*/
|
||||
|
||||
inline bool
|
||||
isws (char c, char const * const wstr)
|
||||
{
|
||||
using namespace std;
|
||||
return (strchr(wstr,c) != NULL);
|
||||
}
|
||||
inline bool isws(char c, char const* const wstr)
|
||||
{
|
||||
using namespace std;
|
||||
return (strchr(wstr, c) != NULL);
|
||||
}
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace boost
|
||||
{
|
||||
|
||||
/*****************************************************************
|
||||
* Simplistic and quite Standard, but a bit slow. This should be
|
||||
@@ -84,33 +81,36 @@ namespace boost {
|
||||
* I had hoped that "whitespace" would be a trait, but it isn't, so
|
||||
* the user must supply it. Enh, this lets them break up strings on
|
||||
* different things easier than traits would anyhow.
|
||||
*/
|
||||
template <typename Container>
|
||||
void
|
||||
stringtok (Container &l, std::string const &s, char const * const ws = " \t\n")
|
||||
*/
|
||||
template < typename Container >
|
||||
void stringtok(
|
||||
Container& l, std::string const& s, char const* const ws = " \t\n")
|
||||
{
|
||||
typedef std::string::size_type size_type;
|
||||
const size_type S = s.size();
|
||||
size_type i = 0;
|
||||
typedef std::string::size_type size_type;
|
||||
const size_type S = s.size();
|
||||
size_type i = 0;
|
||||
|
||||
while (i < S) {
|
||||
while (i < S)
|
||||
{
|
||||
// eat leading whitespace
|
||||
while ((i < S) && (isws(s[i],ws))) ++i;
|
||||
if (i == S) return; // nothing left but WS
|
||||
while ((i < S) && (isws(s[i], ws)))
|
||||
++i;
|
||||
if (i == S)
|
||||
return; // nothing left but WS
|
||||
|
||||
// find end of word
|
||||
size_type j = i+1;
|
||||
while ((j < S) && (!isws(s[j],ws))) ++j;
|
||||
size_type j = i + 1;
|
||||
while ((j < S) && (!isws(s[j], ws)))
|
||||
++j;
|
||||
|
||||
// add word
|
||||
l.push_back(s.substr(i,j-i));
|
||||
l.push_back(s.substr(i, j - i));
|
||||
|
||||
// set up for next loop
|
||||
i = j+1;
|
||||
i = j + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_STRINGTOK_HPP
|
||||
|
||||
Reference in New Issue
Block a user