38 #ifndef GMM_SUB_INDEX_H__
39 #define GMM_SUB_INDEX_H__
49 struct basic_index :
public std::vector<size_t> {
57 return (i < size()) ? std::vector<size_t>::operator[](i) :
size_type(-1);
60 basic_index() : nb_ref(1) {}
61 basic_index(
size_type j) : std::vector<size_t>(j), nb_ref(1) {}
62 template <
typename IT> basic_index(IT b, IT e)
63 : std::vector<size_t>(e-b), nb_ref(1) { std::copy(b, e, begin()); }
64 basic_index(
const basic_index *pbi) : nb_ref(1) {
65 const_iterator it = pbi->begin(), ite = pbi->end();
67 for ( ; it != ite; ++it) i = std::max(i, *it);
69 for (it = pbi->begin(), i = 0; it != ite; ++it, ++i)
70 std::vector<size_t>::operator[](*it) = i;
73 std::swap(std::vector<size_t>::operator[](i),
74 std::vector<size_t>::operator[](j));
79 typedef basic_index *pbasic_index;
81 struct index_generator {
83 template <
typename IT>
static pbasic_index create_index(IT begin, IT end)
84 {
return new basic_index(begin, end); }
85 static pbasic_index create_rindex(pbasic_index pbi)
86 {
return new basic_index(pbi); }
87 static void attach(pbasic_index pbi) {
if (pbi) pbi->nb_ref++; }
88 static void unattach(pbasic_index pbi)
89 {
if (pbi && --(pbi->nb_ref) == 0)
delete pbi; }
96 typedef basic_index base_type;
97 typedef base_type::const_iterator const_iterator;
99 mutable pbasic_index ind;
100 mutable pbasic_index rind;
102 void comp_extr(
void) {
103 std::vector<size_t>::const_iterator it = ind->begin(), ite = ind->end();
104 if (it != ite) { first_=last_= *it; ++it; }
else { first_=last_= 0; }
105 for (; it != ite; ++it)
106 { first_ = std::min(first_, *it); last_ = std::max(last_, *it); }
109 inline void test_rind(
void)
const
110 {
if (!rind) rind = index_generator::create_rindex(ind); }
111 size_type size(
void)
const {
return ind->size(); }
112 size_type first(
void)
const {
return first_; }
113 size_type last(
void)
const {
return last_; }
117 if (i < rind->size())
return (*rind)[i];
else return size_type(-1);
120 const_iterator begin(
void)
const {
return ind->begin(); }
121 const_iterator end(
void)
const {
return ind->end(); }
122 const_iterator rbegin(
void)
const { test_rind();
return rind->begin(); }
123 const_iterator rend(
void)
const { test_rind();
return rind->end(); }
125 sub_index() : ind(0), rind(0) {}
126 template <
typename IT> sub_index(IT it, IT ite)
127 : ind(index_generator::create_index(it, ite)),
128 rind(0) { comp_extr(); }
129 template <
typename CONT> sub_index(
const CONT &c)
130 : ind(index_generator::create_index(c.begin(), c.end())),
131 rind(0) { comp_extr(); }
133 index_generator::unattach(rind);
134 index_generator::unattach(ind);
136 sub_index(
const sub_index &si) : first_(si.first_), last_(si.last_),
137 ind(si.ind), rind(si.rind)
138 { index_generator::attach(rind); index_generator::attach(ind); }
139 sub_index &operator =(
const sub_index &si) {
140 index_generator::unattach(rind);
141 index_generator::unattach(ind);
142 ind = si.ind; rind = si.rind;
143 index_generator::attach(rind);
144 index_generator::attach(ind);
145 first_ = si.first_; last_ = si.last_;
150 struct unsorted_sub_index :
public sub_index {
151 typedef basic_index base_type;
152 typedef base_type::const_iterator const_iterator;
154 template <
typename IT> unsorted_sub_index(IT it, IT ite)
155 : sub_index(it, ite) {}
156 template <
typename CONT> unsorted_sub_index(
const CONT &c)
158 unsorted_sub_index() {}
159 unsorted_sub_index(
const unsorted_sub_index &si) : sub_index((const sub_index &)(si)) { }
160 unsorted_sub_index &operator =(
const unsorted_sub_index &si)
161 { sub_index::operator =(si);
return *
this; }
163 GMM_ASSERT2(ind->nb_ref <= 1,
"Operation not allowed on this index");
164 if (rind) rind->swap((*ind)[i], (*ind)[j]);
169 inline std::ostream &operator << (std::ostream &o,
const sub_index &si) {
171 if (si.size() != 0) o << si.index(0);
172 for (
size_type i = 1; i < si.size(); ++i) o <<
", " << si.index(i);
177 struct sub_interval {
180 size_type size(
void)
const {
return max - min; }
181 size_type first(
void)
const {
return min; }
182 size_type last(
void)
const {
return max; }
186 {
if (i >= min && i < max)
return i - min;
return size_type(-1); }
191 inline std::ostream &operator << (std::ostream &o,
const sub_interval &si)
192 { o <<
"sub_interval(" << si.min <<
", " << si.size() <<
")";
return o; }
197 size_type size(
void)
const {
return (max - min) / N; }
198 size_type first(
void)
const {
return min; }
199 size_type last(
void)
const {
return (min == max) ? max : max+1-N; }
203 if (i >= min && i < max)
204 {
size_type j = (i - min);
if (j % N == 0)
return j / N; }
208 : min(mi), max(mi+l*n), N(n) {}
212 inline std::ostream &operator << (std::ostream &o,
const sub_slice &si) {
213 o <<
"sub_slice(" << si.min <<
", " << si.size() <<
", " << si.step()
217 template<
class SUBI>
struct index_is_sorted
218 {
typedef linalg_true bool_type; };
219 template<>
struct index_is_sorted<unsorted_sub_index>
220 {
typedef linalg_false bool_type; };
224 #endif // GMM_SUB_INDEX_H__