source: Sophya/trunk/Poubelle/DPC:FitsIOServer/Blitz/blitz/array/cartesian.h

Last change on this file was 658, checked in by ansari, 26 years ago

no message

File size: 3.8 KB
Line 
1#ifndef BZ_ARRAY_CARTESIAN_H
2#define BZ_ARRAY_CARTESIAN_H
3
4/*
5 * CartesianProduct<T_tuple,T_container> is an adaptor which represents
6 * the cartesian product of several containers.
7 */
8
9// forward declaration of iterator
10template<class T_tuple, class T_container, int N_containers>
11class CartesianProductIterator;
12
13struct _cp_end_tag { };
14
15template<class T_tuple, class T_container, int N_containers>
16class CartesianProduct {
17public:
18 typedef T_tuple value_type;
19 typedef T_tuple& reference;
20 typedef const T_tuple& const_reference;
21 typedef CartesianProductIterator<T_tuple,T_container,N_containers> iterator;
22 typedef int difference_type;
23 typedef int size_type;
24
25 iterator begin()
26 { return iterator(*this); }
27
28 iterator end()
29 { return iterator(_cp_end_tag()); }
30
31 CartesianProduct(const T_container& container0,
32 const T_container& container1)
33 {
34 BZPRECONDITION(N_containers == 2);
35 containers_[0] = &container0;
36 containers_[1] = &container1;
37 }
38
39 CartesianProduct(const T_container& container0,
40 const T_container& container1,
41 const T_container& container2)
42 {
43 BZPRECONDITION(N_containers == 3);
44 containers_[0] = &container0;
45 containers_[1] = &container1;
46 containers_[2] = &container2;
47 }
48
49 const T_container& operator[](int i)
50 { return *(containers_[i]); }
51
52 void debugDump();
53
54protected:
55 const T_container* containers_[N_containers];
56};
57
58template<class T_tuple, class T_container, int N_containers>
59void CartesianProduct<T_tuple,T_container,N_containers>::debugDump()
60{
61 cout << "Dump of CartesianProduct<..,..," << N_containers << ">" << endl;
62 for (int i=0; i < N_containers; ++i)
63 {
64 cout << "Container " << (i+1) << ": ";
65 _bz_typename T_container::const_iterator iter = containers_[i]->begin(),
66 end = containers_[i]->end();
67 for (; iter != end; ++iter)
68 cout << (*iter) << '\t';
69 }
70}
71
72template<class T_tuple, class T_container, int N_containers>
73class CartesianProductIterator {
74public:
75 typedef _bz_typename T_container::const_iterator citerator;
76 typedef CartesianProductIterator<T_tuple,T_container,N_containers> iterator;
77 typedef CartesianProduct<T_tuple,T_container,N_containers> T_cp;
78
79 CartesianProductIterator(T_cp& container)
80 {
81 for (int i=0; i < N_containers; ++i)
82 {
83 firstiters_[i] = container[i].begin();
84 iters_[i] = firstiters_[i];
85 enditers_[i] = container[i].end();
86 tuple_[i] = *iters_[i];
87 }
88
89 endflag_ = _bz_false;
90 }
91
92 void operator++();
93
94 CartesianProductIterator(_cp_end_tag)
95 {
96 endflag_ = _bz_true;
97 }
98
99 _bz_bool operator==(const iterator& x) const
100 {
101 return (endflag_ == x.endflag_);
102 }
103
104 _bz_bool operator!=(const iterator& x) const
105 {
106 return endflag_ != x.endflag_;
107 }
108
109 const T_tuple& operator*() const
110 { return tuple_; }
111
112protected:
113 citerator iters_[N_containers];
114 citerator firstiters_[N_containers];
115 citerator enditers_[N_containers];
116 T_tuple tuple_;
117 _bz_bool endflag_;
118};
119
120template<class T_tuple, class T_container, int N_containers>
121void CartesianProductIterator<T_tuple, T_container,
122 N_containers>::operator++()
123{
124 // NEEDS_WORK: put in short-circuit for most common case
125 // (just increment the last iterator)
126
127 // Usual stack-style increment
128 const int Nminus1 = N_containers - 1;
129
130 int i = Nminus1;
131
132 for (; i >= 0; --i)
133 {
134 ++iters_[i];
135 if (iters_[i] != enditers_[i])
136 break;
137 }
138
139 if (i == -1)
140 {
141 endflag_ = _bz_true;
142 return;
143 }
144
145 tuple_[i] = *iters_[i];
146
147 for (++i; i < N_containers; ++i)
148 {
149 iters_[i] = firstiters_[i];
150 tuple_[i] = *iters_[i];
151 }
152}
153
154#endif // BZ_ARRAY_CARTESIAN_H
155
Note: See TracBrowser for help on using the repository browser.