00001
00005
00006
00007
00008
00009
00010
00011 #ifndef TBCI_INDEX_H
00012 #define TBCI_INDEX_H
00013
00014 #include "vector.h"
00015
00016
00017 #if !defined(NO_GD) && !defined(AUTO_DECL)
00018 # include "index_gd.h"
00019 #endif
00020
00021 NAMESPACE_TBCI
00022
00023 #ifdef EXCEPT
00024 class IdxErr : public NumErr
00025 {
00026 public:
00027 IdxErr()
00028 : NumErr("Error in Index class") {}
00029 IdxErr(const char* t, const long i = 0)
00030 : NumErr(t, i) {}
00031 IdxErr(const IdxErr& ie)
00032 : NumErr(ie) {}
00033 virtual ~IdxErr() throw() {}
00034 };
00035 #endif
00036
00040 #if defined(PRAGMA_I) && defined (PRAGMA_I_IDX) && ! defined(_NO_IDX_PRAGMA)
00041 # pragma interface "index.h"
00042 #endif
00043
00048 class Index : public Vector <unsigned>
00049 {
00050
00051 protected:
00052
00053 public:
00054 Index () : Vector <unsigned> () {}
00055 Index (const unsigned dim) : Vector<unsigned> (dim) {}
00056 Index (const unsigned value, const unsigned dim) : Vector<unsigned> (value, dim) {}
00057 Index (const Index & idx) : Vector<unsigned> (idx) {}
00058 Index (const Vector <unsigned> & vec) : Vector<unsigned> (vec) {}
00059 Index (const TVector <unsigned> & tv) : Vector<unsigned> (tv) {}
00060
00061 Index (vararg va, ...) : Vector <unsigned> ((unsigned)va)
00062 {
00063 va_list vl;
00064 va_start (vl, va);
00065 for (unsigned i = 0; i < (unsigned)va; ++i)
00066 (*this) (i) = va_arg (vl, unsigned);
00067 va_end (vl);
00068 }
00069
00070 void lin_read (vararg va, ...)
00071 {
00072
00073 va_list vl;
00074 va_start (vl, va);
00075 for (unsigned i = 0; i < (unsigned)va; ++i)
00076 (*this) (i) = va_arg (vl, unsigned);
00077 va_end (vl);
00078 }
00079
00080
00081
00082
00083
00084
00085
00086 Index next_idx (const Index& max)
00087 {
00088 BCHK (dim != max.dim, IdxErr, Indexes of iterators must have same dim, max.dim, *this);
00089 (*this)(dim-1)++;
00090 for (unsigned r = dim-1; r; r--)
00091 if ((*this)(r) >= max(r)) { (*this)(r-1)++; (*this)(r) = 0; }
00092 return *this;
00093 }
00094 Index prev_idx (const Index& max)
00095 {
00096 BCHK (dim != max.dim, IdxErr, Indices of iterators must have same dim, max.dim, *this);
00097 (*this)(dim-1)--;
00098 for (unsigned r = dim-1; r; r--)
00099 if ((signed)(*this)(r) < 0) { (*this)(r-1)--; (*this)(r) = max(r); }
00100 return *this;
00101 }
00102
00103
00104
00105 TVector<unsigned> idx_fill_in1 (const unsigned, const unsigned) const;
00106
00107
00108 TVector<unsigned> idx_fill_in2 (const unsigned, const unsigned,
00109 const unsigned, const unsigned) const;
00110
00111
00112 TVector<unsigned> idx_remove1 (const unsigned) const;
00113
00114 TVector<unsigned> idx_remove2 (const unsigned, const unsigned) const;
00115
00116 TVector<unsigned> idx_set1 (const unsigned, const unsigned) const;
00117 };
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 inline TVector<unsigned>
00130 Index::idx_fill_in1 (const unsigned where, const unsigned what) const
00131 {
00132 TVector<unsigned> ix (size()+1);
00133 BCHK (where >= ix.size(), IdxErr, Index nr. out of range, where, *this);
00134 ix.set (what, where);
00135 unsigned i = 0;
00136 for (unsigned j = 0; j < size(); j++)
00137 {
00138 if (i == where) i++;
00139 ix.set ((*this)(j), i++);
00140 }
00141 return ix;
00142 }
00143
00144 INST(class Index friend TVector<unsigned> idx_fill_in1 (const Index&, const unsigned, const unsigned);)
00145 inline TVector<unsigned>
00146 idx_fill_in1 (const Index& idx, const unsigned where, const unsigned what)
00147 { return idx.idx_fill_in1 (where, what); }
00148
00149 inline TVector<unsigned>
00150 Index::idx_fill_in2 (const unsigned where1, const unsigned what1,
00151 const unsigned where2, const unsigned what2) const
00152 {
00153 TVector<unsigned> ix (size()+2);
00154 BCHK (where1 >= ix.size(), IdxErr, Index nr. 1 out of range, where1, *this);
00155 BCHK (where2 >= ix.size(), IdxErr, Index nr. 2 out of range, where2, *this);
00156 ix.set (what1, where1); ix.set (what2, where2);
00157 unsigned i = 0;
00158 for (unsigned j = 0; j < size(); j++)
00159 {
00160 while (i == where1 || i == where2) i++;
00161 ix.set ((*this)(j), i++);
00162 }
00163 return ix;
00164 }
00165
00166 INST(class Index friend TVector<unsigned> idx_fill_in2 (const Index&, const unsigned, const unsigned, const unsigned, const unsigned);)
00167 inline TVector<unsigned>
00168 idx_fill_in2 (const Index& idx, const unsigned where1, const unsigned what1,
00169 const unsigned where2, const unsigned what2)
00170 { return idx.idx_fill_in2 (where1, what1, where2, what2); }
00171
00172
00173 inline TVector<unsigned>
00174 Index::idx_remove1 (const unsigned which) const
00175 {
00176 BCHK (which >= size(), IdxErr, Tried to remove non-existing index, which, *this);
00177 TVector<unsigned> ix (size()-1);
00178 unsigned i = 0;
00179 for (unsigned j = 0; j < size(); j++)
00180 if (which != j) ix.set ((*this)(j), i++);
00181 return ix;
00182 }
00183
00184 INST(class Index friend TVector<unsigned> idx_remove1 (const Index&, const unsigned);)
00185 inline TVector<unsigned>
00186 idx_remove1 (const Index& idx, const unsigned which)
00187 { return idx.idx_remove1 (which); }
00188
00189
00190 inline TVector<unsigned>
00191 Index::idx_remove2 (const unsigned which1, const unsigned which2) const
00192 {
00193 BCHK (size() < 2, IdxErr, Cannot remove two indices from a Index with just one or zero, size(), *this);
00194 BCHK (which1 >= size(), IdxErr, Tried to remove non-existing index1, which1, *this);
00195 BCHK (which2 >= size(), IdxErr, Tried to remove non-existing index2, which2, *this);
00196 TVector<unsigned> ix (size()-2);
00197 unsigned i = 0;
00198 for (unsigned j = 0; j < size(); j++)
00199 if (which1 != j && which2 != j) ix.set ((*this)(j), i++);
00200 return ix;
00201 }
00202
00203 INST(class Index friend TVector<unsigned> idx_remove2 (const Index&, const unsigned, const unsigned);)
00204 inline TVector<unsigned>
00205 idx_remove2 (const Index& idx, const unsigned which1, const unsigned which2)
00206 { return idx.idx_remove2 (which1, which2); }
00207
00208 inline TVector<unsigned>
00209 Index::idx_set1 (const unsigned which, const unsigned what) const
00210 {
00211 BCHK (which >= size(), IdxErr, Cannot set index (out of range), which, *this);
00212 TVector<unsigned> ix (*this);
00213 ix.set (what, which);
00214 return ix;
00215 }
00216
00217 INST(class Index friend TVector<unsigned> idx_set1 (const Index&, const unsigned, const unsigned);)
00218 inline TVector<unsigned>
00219 idx_set1 (const Index& idx, const unsigned which, const unsigned what)
00220 { return idx.idx_set1 (which, what); }
00221
00222 NAMESPACE_END
00223
00224 #endif