00001
00002 #ifndef _INSTIGATE_STL_INTERNAL_HEADER_IN_ALGORITHM
00003 #error This is an internal header file used to implement Instigate STL.\
00004 It should never be included directly by a program.
00005 #endif
00006
00007 #ifndef INSTIGATE_STL_PREV_PERMUTATION_HPP
00008 #define INSTIGATE_STL_PREV_PERMUTATION_HPP
00009
00059
00060 #include "concept.hpp"
00061 #include "_basis.hpp"
00062 #include "_iter_swap.hpp"
00063 #include "_reverse.hpp"
00064
00065
00066
00067
00068
00069
00070 namespace instigate {
00071 namespace stl {
00072 template <typename I>
00073 bool prev_permutation(I b, I e);
00074 template <typename I, typename C>
00075 bool prev_permutation(I b, I e, C c);
00076 }
00077 }
00078
00116 template <typename I>
00117 bool instigate::stl::prev_permutation(I b, I e)
00118 {
00119 namespace BI = instigate::stl::bidirectional_iterator;
00120 typedef typename instigate::stl::readable_iterator::interface<I>::
00121 value_type value_type;
00122 CHECK(instigate::stl::bidirectional_iterator::requirements<I>);
00123 CHECK(instigate::stl::readable_iterator::requirements<I>);
00124 if(equal(b, e)) {
00125 return false;
00126 }
00127 char k[sizeof(I)];
00128 I* i = 0;;
00129 assign(i, copy_constructor(k, b));
00130 assert(0 != i);
00131 increment(*i);
00132 if (equal(*i, e)) {
00133 return false;
00134 }
00135 assign(*i, e);
00136 decrement(*i);
00137 for(;;) {
00138 char k1[sizeof(I)];
00139 I* ii = 0;;
00140 assign(ii, copy_constructor(k1, *i));
00141 assert(0 != ii);
00142 decrement(*i);
00143 if (less_than(const_dereference(*ii), const_dereference(*i))) {
00144 char k2[sizeof(I)];
00145 I* j = 0;;
00146 assign(j, copy_constructor(k2, e));
00147 assert(0 != j);
00148 decrement(*j);
00149 while(!less_than(const_dereference(*j),
00150 const_dereference(*i)))
00151 {
00152 decrement(*j);
00153 }
00154 instigate::stl::iter_swap(*i, *j);
00155 instigate::stl::reverse(*ii, e);
00156 return true;
00157 }
00158 if (equal(*i, b)) {
00159 instigate::stl::reverse(b, e);
00160 return false;
00161 }
00162 }
00163 }
00164
00199 template <typename I, typename C>
00200 bool instigate::stl::prev_permutation(I b, I e, C c)
00201 {
00202 typedef typename instigate::stl::readable_iterator::interface<I>::
00203 value_type value_type;
00204 CHECK(instigate::stl::bidirectional_iterator::requirements<I>);
00205 CHECK(instigate::stl::readable_iterator::requirements<I>);
00206 CHECK(instigate::stl::binary_predicate::requirements<C>);
00207 if (equal(b, e)) {
00208 return false;
00209 }
00210 char k[sizeof(I)];
00211 I* i = 0;;
00212 assign(i, copy_constructor(k, b));
00213 assert(0 != i);
00214 increment(*i);
00215 if (equal(*i, e)) {
00216 return false;
00217 }
00218 assign(*i, e);
00219 decrement(*i);
00220 for (;;) {
00221 char k1[sizeof(I)];
00222 I* ii = 0;;
00223 assign(ii, copy_constructor(k1, *i));
00224 assert(0 != ii);
00225 decrement(*i);
00226 if (invoke_predicate(c, const_dereference(*ii),
00227 const_dereference(*i)))
00228 {
00229 char k2[sizeof(I)];
00230 I* j = 0;;
00231 assign(j, copy_constructor(k2, e));
00232 assert(0 != j);
00233 decrement(*j);
00234 while (!invoke_predicate(c, const_dereference(*j),
00235 const_dereference(*i)))
00236 {
00237 decrement(*j);
00238 }
00239 instigate::stl::iter_swap(*i, *j);
00240 instigate::stl::reverse(*ii, e);
00241 return true;
00242 }
00243 if (equal(*i, b)) {
00244 instigate::stl::reverse(b, e);
00245 return false;
00246 }
00247 }
00248 }
00249
00250
00251
00252 #endif // INSTIGATE_STL_PREV_PERMUTATION_HPP