22#ifndef GINAC_UTILS_MULTI_ITERATOR_H
23#define GINAC_UTILS_MULTI_ITERATOR_H
42 template <
typename C>
static yes_type &
test(
decltype(std::distance<C>) ) ;
56template<
typename T>
typename std::enable_if<has_distance<T>::value,
typename std::iterator_traits<T>::difference_type>::type
format_index_value(
const T & a,
const T & b) {
57 return std::distance(a,b);
65template<
typename T>
typename std::enable_if<!has_distance<T>::value, T>::type
format_index_value(
const T & a,
const T & b) {
109 size_t size(
void)
const;
111 const std::vector<T> &
get_vector(
void)
const;
453 flag_overflow =
false;
455 for (
size_t i=0; i<v.size(); i++) {
468 return flag_overflow;
544 os <<
"basic_multi_iterator(";
545 for (
size_t i=0; i<v.
size(); i++) {
595 this->flag_overflow =
false;
598 for (
size_t i=0; i < this->v.size(); i++) {
618 int k = this->size();
620 T Upper_limit = this->N;
624 if ( this->v[j] == Upper_limit ) {
635 if (this->v[j] == Upper_limit) this->flag_overflow=
true;
639 for (
int jj=j+1;jj<
k;jj++) {
640 this->v[jj] = this->v[jj-1];
658 os <<
"multi_iterator_ordered(";
659 for (
size_t i=0; i<v.
size(); i++) {
709 this->flag_overflow =
false;
711 for (
size_t i=0; i < this->v.size(); i++) {
712 this->v[i] = this->B;
730 int k = this->size();
735 if ( this->v[j] == this->N ) {
745 if (this->v[j] == this->N) {
746 this->flag_overflow=
true;
751 for (
int jj=j+1;jj<
k;jj++) {
752 this->v[jj] = this->v[jj-1];
769 os <<
"multi_iterator_ordered_eq(";
770 for (
size_t i=0; i<v.
size(); i++) {
821 this->flag_overflow =
false;
823 for (
size_t i=0; i < this->v.size(); i++) {
824 this->v[i] = this->B;
842 int k = this->size();
847 if ( this->v[j] == Nv[j] ) {
857 if (this->v[j] == Nv[j]) {
858 this->flag_overflow=
true;
863 for (
int jj=j+1;jj<
k;jj++) {
864 this->v[jj] = this->v[jj-1];
881 os <<
"multi_iterator_ordered_eq_indv(";
882 for (
size_t i=0; i<v.
size(); i++) {
933 this->flag_overflow =
false;
935 for (
size_t i=0; i < this->v.size(); i++) {
936 this->v[i] = this->B;
954 int k = this->size();
959 if ( this->v[j] == this->N ) {
960 this->v[j] = this->B;
970 if (this->v[j] == this->N) {
971 this->v[j] = this->B;
972 this->flag_overflow=
true;
989 os <<
"multi_iterator_counter(";
990 for (
size_t i=0; i<v.
size(); i++) {
1041 this->flag_overflow =
false;
1043 for (
size_t i=0; i < this->v.size(); i++) {
1044 this->v[i] = this->B;
1062 int k = this->size();
1067 if ( this->v[j] == Nv[j] ) {
1068 this->v[j] = this->B;
1078 if (this->v[j] == Nv[j]) {
1079 this->v[j] = this->B;
1080 this->flag_overflow=
true;
1097 os <<
"multi_iterator_counter_indv(";
1098 for (
size_t i=0; i<v.
size(); i++) {
1149 this->flag_overflow =
false;
1152 for (
size_t i=0; i < this->v.size(); i++) {
1172 int k = this->size();
1176 bool flag_have_already =
true;
1177 while ( flag_have_already ) {
1181 flag_have_already =
false;
1182 for (
int ii=0; ii<j; ii++) {
1183 if (this->v[j] == this->v[ii]) {
1184 flag_have_already =
true;
1189 if ( this->v[j] == this->N ) {
1197 for (
int l=j+1; l<
k; l++) {
1198 this->v[l] = this->B;
1200 bool flag_have_already;
1202 flag_have_already =
false;
1203 for (
int ii=0; ii<l; ii++) {
1204 if (this->v[l] == this->v[ii]) {
1205 flag_have_already =
true;
1208 if (flag_have_already) {
1212 while (flag_have_already);
1216 this->flag_overflow =
true;
1218 for (
int ii=0; ii<
k; ii++) {
1219 if (this->v[ii] != it) {
1220 this->flag_overflow =
false;
1244 int k = this->size();
1246 for (
int i=0; i<
k; i++) {
1247 for (
int j=i+1; j<
k; j++) {
1249 if ( this->v[i] > this->v[j] ) {
1269 os <<
"multi_iterator_permutation(";
1270 for (
size_t i=0; i<v.
size(); i++) {
1301 for (
size_t i=0; i<a.size(); i++) {
1302 this->
v.push_back( a[i] );
1303 this->
v_orig.push_back( a[i] );
1306 for (
size_t i=0; i<b.size(); i++) {
1307 this->
v.push_back( b[i] );
1308 this->
v_orig.push_back( b[i] );
1322 this->flag_overflow =
false;
1324 for (
size_t i=0; i < this->v_internal.size(); i++) {
1325 this->v_internal[i] = i;
1327 for (
size_t i=0; i < this->v.size(); i++) {
1328 this->v[i] = this->v_orig[i];
1346 int k = this->v_internal.
size();
1348 size_t Upper_limit = this->N_internal;
1351 this->v_internal[j]++;
1352 if ( this->v_internal[j] == Upper_limit ) {
1362 this->v_internal[j]++;
1363 if (this->v_internal[j] == Upper_limit) {
1364 this->flag_overflow=
true;
1369 for (
int jj=j+1;jj<
k;jj++) {
1370 this->v_internal[jj] = this->v_internal[jj-1];
1371 this->v_internal[jj]++;
1376 if ( !(this->flag_overflow) ) {
1380 for (
size_t j=0; j<
k; j++) {
1381 for (
size_t i=i_all; i < this->v_internal[j]; i++) {
1382 this->v[i_all] = this->v_orig[
k+i_b];
1386 this->v[i_all] = this->v_orig[i_a];
1390 for (
size_t i = this->v_internal[
k-1]+1; i < this->v.size(); i++) {
1391 this->v[i_all] = this->v_orig[
k+i_b];
1410 os <<
"multi_iterator_shuffle(";
1411 for (
size_t i=0; i<v.
size(); i++) {
1450 this->flag_overflow =
false;
1452 for (
size_t i=0; i < this->v_internal.size(); i++) {
1453 this->v_internal[i] = i;
1455 for (
size_t i=0; i < this->v.size(); i++) {
1456 this->v[i] = this->v_orig[i];
1474 os <<
"multi_iterator_shuffle_prime(";
1475 for (
size_t i=0; i<v.
size(); i++) {
basic_multi_iterator is a base class.
T operator[](size_t i) const
Subscription via [].
size_t size(void) const
Returns the size of a multi_iterator.
basic_multi_iterator(void)
Default constructor.
T operator()(size_t i) const
Subscription via ()
friend std::ostream & operator<<(std::ostream &os, const basic_multi_iterator< TT > &v)
virtual basic_multi_iterator< T > & operator++(int)
No effect for basic_multi_iterator.
virtual basic_multi_iterator< T > & init(void)
Initialize the multi-index to.
virtual ~basic_multi_iterator()
Destructor.
bool overflow(void) const
Return the overflow flag.
const std::vector< T > & get_vector(void) const
Returns a reference to the vector v.
SFINAE test for distance.
static no_type & test(...)
static yes_type & test(decltype(std::distance< C >))
The class multi_iterator_counter_indv defines a multi_iterator , such that.
basic_multi_iterator< T > & init(void)
Initialize the multi-index to.
multi_iterator_counter_indv(void)
Default constructor.
basic_multi_iterator< T > & operator++(int)
The postfix increment operator allows to write for a multi-index n++, which will update n to the next...
friend std::ostream & operator<<(std::ostream &os, const multi_iterator_counter_indv< TT > &v)
The class multi_iterator_counter defines a multi_iterator , such that.
basic_multi_iterator< T > & operator++(int)
The postfix increment operator allows to write for a multi-index n++, which will update n to the next...
multi_iterator_counter(void)
Default constructor.
friend std::ostream & operator<<(std::ostream &os, const multi_iterator_counter< TT > &v)
basic_multi_iterator< T > & init(void)
Initialize the multi-index to.
The class multi_iterator_ordered_eq_indv defines a multi_iterator , such that.
friend std::ostream & operator<<(std::ostream &os, const multi_iterator_ordered_eq_indv< TT > &v)
basic_multi_iterator< T > & init(void)
Initialize the multi-index to.
multi_iterator_ordered_eq_indv(void)
Default constructor.
basic_multi_iterator< T > & operator++(int)
The postfix increment operator allows to write for a multi-index n++, which will update n to the next...
The class multi_iterator_ordered_eq defines a multi_iterator , such that.
basic_multi_iterator< T > & operator++(int)
The postfix increment operator allows to write for a multi-index n++, which will update n to the next...
basic_multi_iterator< T > & init(void)
Initialize the multi-index to.
friend std::ostream & operator<<(std::ostream &os, const multi_iterator_ordered_eq< TT > &v)
multi_iterator_ordered_eq(void)
Default constructor.
The class multi_iterator_ordered defines a multi_iterator , such that.
basic_multi_iterator< T > & operator++(int)
The postfix increment operator allows to write for a multi-index n++, which will update n to the next...
basic_multi_iterator< T > & init(void)
Initialize the multi-index to.
friend std::ostream & operator<<(std::ostream &os, const multi_iterator_ordered< TT > &v)
multi_iterator_ordered(void)
Default constructor.
The class multi_iterator_permutation defines a multi_iterator , for which.
int get_sign(void) const
Returns the sign of the permutation, defined by.
basic_multi_iterator< T > & operator++(int)
The postfix increment operator allows to write for a multi-index n++, which will update n to the next...
basic_multi_iterator< T > & init(void)
Initialize the multi-index to.
multi_iterator_permutation(void)
Default constructor.
friend std::ostream & operator<<(std::ostream &os, const multi_iterator_permutation< TT > &v)
The class multi_iterator_shuffle_prime defines a multi_iterator, which runs over all shuffles of a an...
multi_iterator_shuffle_prime(void)
Default constructor.
basic_multi_iterator< T > & init(void)
Initialize the multi-index to the first shuffle.
friend std::ostream & operator<<(std::ostream &os, const multi_iterator_shuffle_prime< TT > &v)
The class multi_iterator_shuffle defines a multi_iterator, which runs over all shuffles of a and b.
basic_multi_iterator< T > & operator++(int)
The postfix increment operator allows to write for a multi-index n++, which will update n to the next...
std::vector< size_t > v_internal
friend std::ostream & operator<<(std::ostream &os, const multi_iterator_shuffle< TT > &v)
multi_iterator_shuffle(void)
Default constructor.
basic_multi_iterator< T > & init(void)
Initialize the multi-index to the first shuffle.
std::ostream & operator<<(std::ostream &os, const archive_node &n)
Write archive_node to binary data stream.
std::enable_if< has_distance< T >::value, typenamestd::iterator_traits< T >::difference_type >::type format_index_value(const T &a, const T &b)
For printing a multi-index: If the templates are used, where T is an iterator, printing the address w...