From b327f08b865e95c97d898d0818ea52cdf8ae7ec0 Mon Sep 17 00:00:00 2001 From: Jeremy Siek Date: Mon, 19 Mar 2001 22:49:56 +0000 Subject: [PATCH] new files [SVN r9594] --- include/boost/graph/detail/permutation.hpp | 137 ++++++++++++++++++ .../boost/graph/detail/shadow_iterator.hpp | 122 ++++++++++++++++ 2 files changed, 259 insertions(+) create mode 100644 include/boost/graph/detail/permutation.hpp create mode 100644 include/boost/graph/detail/shadow_iterator.hpp diff --git a/include/boost/graph/detail/permutation.hpp b/include/boost/graph/detail/permutation.hpp new file mode 100644 index 00000000..bd605f4e --- /dev/null +++ b/include/boost/graph/detail/permutation.hpp @@ -0,0 +1,137 @@ +#ifndef BOOST_PERMUTATION_HPP +#define BOOST_PERMUTATION_HPP + +#include +#include +#include +#include +#include + +namespace boost { + +template +inline void permute(Iter1 permuter, Iter1 last, Iter2 result) +{ + typedef typename std::iterator_traits::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 +inline void invert_permutation(PermIter X, PermIter Xend) +{ + typedef typename std::iterator_traits::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 +inline void serialize_permutation(Iter1 q, Iter1 q_end, Iter2 q_inv, Iter3 p) +{ + typedef typename std::iterator_traits::value_type P1; + typedef typename std::iterator_traits::value_type P2; + typedef typename std::iterator_traits::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 +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 +inline void sortp(Iter first, Iter last, IterP p, Cmp cmp, Alloc alloc) +{ + typedef typename std::iterator_traits::value_type P; + typedef typename std::iterator_traits::difference_type D; + D n = last - first; + std::vector 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)); + invert_permutation(q.begin(), q.end()); + std::copy(q.begin(), q.end(), p); +} + +template +inline void sortp(Iter first, Iter last, IterP p, Cmp cmp) +{ + typedef typename std::iterator_traits::value_type P; + sortp(first, last, p, cmp, std::allocator

()); +} + +template +inline void sortp(Iter first, Iter last, IterP p) +{ + typedef typename std::iterator_traits::value_type T; + typedef typename std::iterator_traits::value_type P; + sortp(first, last, p, std::less(), std::allocator

()); +} + +template +inline void sortv(Iter first, Iter last, IterP p, Cmp cmp, Alloc alloc) +{ + typedef typename std::iterator_traits::value_type P; + typedef typename std::iterator_traits::difference_type D; + D n = last - first; + std::vector 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)); + 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 diff --git a/include/boost/graph/detail/shadow_iterator.hpp b/include/boost/graph/detail/shadow_iterator.hpp new file mode 100644 index 00000000..3e8db975 --- /dev/null +++ b/include/boost/graph/detail/shadow_iterator.hpp @@ -0,0 +1,122 @@ +#ifndef BOOST_SHADOW_ITERATOR_HPP +#define BOOST_SHADOW_ITERATOR_HPP + +#include +#include + +namespace boost { + + namespace detail { + + template + class shadow_proxy + : boost::operators< shadow_proxy > + { + 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 + 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 + void initialize(const iter_pair&) { } + + template + R dereference(type, const iter_pair& p) const { + return R(*p.first, *p.second); + } + template + bool equal(const iter_pair& p1, const iter_pair& p2) const { + return p1.first == p2.first; + } + template + void increment(iter_pair& p) { ++p.first; ++p.second; } + + template + void decrement(iter_pair& p) { --p.first; --p.second; } + + template + bool less(const iter_pair& x, const iter_pair& y) const { + return x.first < y.first; + } + template + D distance(type, const iter_pair& x, const iter_pair& y) const { + return y.first - x.first; + } + template + void advance(iter_pair& p, D n) { p.first += n; p.second += n; } + }; + + } // namespace detail + + template + struct shadow_iterator_generator { + typedef typename std::iterator_traits::value_type Aval; + typedef typename std::iterator_traits::value_type Bval; + typedef typename std::iterator_traits::reference Aref; + typedef typename std::iterator_traits::reference Bref; + typedef typename std::iterator_traits::difference_type D; + typedef detail::shadow_proxy V; + typedef detail::shadow_proxy R; + typedef iterator_adaptor< std::pair, + detail::shadow_iterator_policies, + V, R, V*, std::random_access_iterator_tag, + D> type; + }; + + // short cut for creating a shadow iterator + template + inline typename shadow_iterator_generator::type + make_shadow_iter(IterA a, IterB b) { + typedef typename shadow_iterator_generator::type Iter; + return Iter(std::make_pair(a,b)); + } + + template + struct shadow_cmp { + inline shadow_cmp(const Cmp& c) : cmp(c) { } + template + inline bool operator()(const ShadowProxy1& x, const ShadowProxy2& y) const + { + return cmp(x.a, y.a); + } + Cmp cmp; + }; + +} // namespace boost + +namespace std { + template + void swap(boost::detail::shadow_proxy x, + boost::detail::shadow_proxy y) + { + std::swap(x.a, y.a); + std::swap(x.b, y.b); + } +} + +#endif // BOOST_SHADOW_ITERATOR_HPP