2
0
mirror of https://github.com/boostorg/graph.git synced 2026-02-02 21:02:15 +00:00

new files

[SVN r9594]
This commit is contained in:
Jeremy Siek
2001-03-19 22:49:56 +00:00
parent 6a85d72962
commit b327f08b86
2 changed files with 259 additions and 0 deletions

View File

@@ -0,0 +1,137 @@
#ifndef BOOST_PERMUTATION_HPP
#define BOOST_PERMUTATION_HPP
#include <vector>
#include <memory>
#include <functional>
#include <algorithm>
#include <boost/graph/detail/shadow_iterator.hpp>
namespace boost {
template <class Iter1, class Iter2>
inline void permute(Iter1 permuter, Iter1 last, Iter2 result)
{
typedef typename std::iterator_traits<Iter1>::difference_type D;
D n = 0;
while (permuter != last) {
std::swap(result[n], result[*permuter]);
++n;
++permuter;
}
}
// Knuth 1.3.3, Vol. 1 p 176
// modified for zero-based arrays
// time ?
//
template <class PermIter>
inline void invert_permutation(PermIter X, PermIter Xend)
{
typedef typename std::iterator_traits<PermIter>::value_type T;
T n = Xend - X;
T m = n;
T j = -1;
while (m > 0) {
T i = X[m-1] + 1;
if (i > 0) {
do {
X[m-1] = j - 1;
j = -m;
m = i;
i = X[m-1] + 1;
} while (i > 0);
i = j;
}
X[m-1] = -i - 1;
--m;
}
}
// Takes a "normal" permutation array (and its inverse), and turns it
// into a BLAS-style permutation array (which can be thought of as a
// serialized permutation).
template <class Iter1, class Iter2, class Iter3>
inline void serialize_permutation(Iter1 q, Iter1 q_end, Iter2 q_inv, Iter3 p)
{
typedef typename std::iterator_traits<Iter1>::value_type P1;
typedef typename std::iterator_traits<Iter2>::value_type P2;
typedef typename std::iterator_traits<Iter1>::difference_type D;
D n = q_end - q;
for (D i = 0; i < n; ++i) {
P1 qi = q[i];
P2 qii = q_inv[i];
*p++ = qii;
std::swap(q[i], q[qii]);
std::swap(q_inv[i], q_inv[qi]);
}
}
// Not used anymore, leaving it here for future reference.
template <typename Iter, typename Compare>
void merge_sort(Iter first, Iter last, Compare cmp)
{
if (first + 1 < last) {
Iter mid = first + (last - first)/2;
merge_sort(first, mid, cmp);
merge_sort(mid, last, cmp);
std::inplace_merge(first, mid, last, cmp);
}
}
// time: N log N + 3N + ?
// space: 2N
template <class Iter, class IterP, class Cmp, class Alloc>
inline void sortp(Iter first, Iter last, IterP p, Cmp cmp, Alloc alloc)
{
typedef typename std::iterator_traits<IterP>::value_type P;
typedef typename std::iterator_traits<IterP>::difference_type D;
D n = last - first;
std::vector<P, Alloc> q(n);
for (D i = 0; i < n; ++i)
q[i] = i;
std::sort(make_shadow_iter(first, q.begin()),
make_shadow_iter(last, q.end()),
shadow_cmp<Cmp>(cmp));
invert_permutation(q.begin(), q.end());
std::copy(q.begin(), q.end(), p);
}
template <class Iter, class IterP, class Cmp>
inline void sortp(Iter first, Iter last, IterP p, Cmp cmp)
{
typedef typename std::iterator_traits<IterP>::value_type P;
sortp(first, last, p, cmp, std::allocator<P>());
}
template <class Iter, class IterP>
inline void sortp(Iter first, Iter last, IterP p)
{
typedef typename std::iterator_traits<Iter>::value_type T;
typedef typename std::iterator_traits<IterP>::value_type P;
sortp(first, last, p, std::less<T>(), std::allocator<P>());
}
template <class Iter, class IterP, class Cmp, class Alloc>
inline void sortv(Iter first, Iter last, IterP p, Cmp cmp, Alloc alloc)
{
typedef typename std::iterator_traits<IterP>::value_type P;
typedef typename std::iterator_traits<IterP>::difference_type D;
D n = last - first;
std::vector<P, Alloc> q(n), q_inv(n);
for (D i = 0; i < n; ++i)
q_inv[i] = i;
std::sort(make_shadow_iter(first, q_inv.begin()),
make_shadow_iter(last, q_inv.end()),
shadow_cmp<Cmp>(cmp));
std::copy(q_inv, q_inv.end(), q.begin());
invert_permutation(q.begin(), q.end());
serialize_permutation(q.begin(), q.end(), q_inv.end(), p);
}
} // namespace boost
#endif // BOOST_PERMUTATION_HPP

View File

@@ -0,0 +1,122 @@
#ifndef BOOST_SHADOW_ITERATOR_HPP
#define BOOST_SHADOW_ITERATOR_HPP
#include <boost/iterator_adaptors.hpp>
#include <boost/operators.hpp>
namespace boost {
namespace detail {
template <class A, class B, class D>
class shadow_proxy
: boost::operators< shadow_proxy<A,B,D> >
{
typedef shadow_proxy self;
public:
inline shadow_proxy(A aa, B bb) : a(aa), b(bb) { }
inline shadow_proxy(const self& x) : a(x.a), b(x.b) { }
template <class Self>
inline shadow_proxy(Self x) : a(x.a), b(x.b) { }
inline self& operator=(const self& x) { a = x.a; b = x.b; return *this; }
inline self& operator++() { ++a; return *this; }
inline self& operator--() { --a; return *this; }
inline self& operator+=(const self& x) { a += x.a; return *this; }
inline self& operator-=(const self& x) { a -= x.a; return *this; }
inline self& operator*=(const self& x) { a *= x.a; return *this; }
inline self& operator/=(const self& x) { a /= x.a; return *this; }
inline self& operator%=(const self& x) { return *this; } // JGS
inline self& operator&=(const self& x) { return *this; } // JGS
inline self& operator|=(const self& x) { return *this; } // JGS
inline self& operator^=(const self& x) { return *this; } // JGS
inline friend D operator-(const self& x, const self& y) {
return x.a - y.a;
}
inline bool operator==(const self& x) const { return a == x.a; }
inline bool operator<(const self& x) const { return a < x.a; }
// protected:
A a;
B b;
};
struct shadow_iterator_policies
{
template <typename iter_pair>
void initialize(const iter_pair&) { }
template <typename R, typename iter_pair>
R dereference(type<R>, const iter_pair& p) const {
return R(*p.first, *p.second);
}
template <typename iter_pair>
bool equal(const iter_pair& p1, const iter_pair& p2) const {
return p1.first == p2.first;
}
template <typename iter_pair>
void increment(iter_pair& p) { ++p.first; ++p.second; }
template <typename iter_pair>
void decrement(iter_pair& p) { --p.first; --p.second; }
template <typename iter_pair>
bool less(const iter_pair& x, const iter_pair& y) const {
return x.first < y.first;
}
template <typename D, typename iter_pair>
D distance(type<D>, const iter_pair& x, const iter_pair& y) const {
return y.first - x.first;
}
template <typename D, typename iter_pair>
void advance(iter_pair& p, D n) { p.first += n; p.second += n; }
};
} // namespace detail
template <typename IterA, typename IterB>
struct shadow_iterator_generator {
typedef typename std::iterator_traits<IterA>::value_type Aval;
typedef typename std::iterator_traits<IterB>::value_type Bval;
typedef typename std::iterator_traits<IterA>::reference Aref;
typedef typename std::iterator_traits<IterB>::reference Bref;
typedef typename std::iterator_traits<IterA>::difference_type D;
typedef detail::shadow_proxy<Aval,Bval,Aval> V;
typedef detail::shadow_proxy<Aref,Bref,Aval> R;
typedef iterator_adaptor< std::pair<IterA, IterB>,
detail::shadow_iterator_policies,
V, R, V*, std::random_access_iterator_tag,
D> type;
};
// short cut for creating a shadow iterator
template <class IterA, class IterB>
inline typename shadow_iterator_generator<IterA,IterB>::type
make_shadow_iter(IterA a, IterB b) {
typedef typename shadow_iterator_generator<IterA,IterB>::type Iter;
return Iter(std::make_pair(a,b));
}
template <class Cmp>
struct shadow_cmp {
inline shadow_cmp(const Cmp& c) : cmp(c) { }
template <class ShadowProxy1, class ShadowProxy2>
inline bool operator()(const ShadowProxy1& x, const ShadowProxy2& y) const
{
return cmp(x.a, y.a);
}
Cmp cmp;
};
} // namespace boost
namespace std {
template <class A1, class B1, class D1,
class A2, class B2, class D2>
void swap(boost::detail::shadow_proxy<A1&,B1&,D1> x,
boost::detail::shadow_proxy<A2&,B2&,D2> y)
{
std::swap(x.a, y.a);
std::swap(x.b, y.b);
}
}
#endif // BOOST_SHADOW_ITERATOR_HPP