aimstil  5.0.5
rle_array.h
Go to the documentation of this file.
1 #ifndef TIL_RLE_ARRAY_H
2 #define TIL_RLE_ARRAY_H
3 
4 // includes from STL
5 #include <list>
6 
7 // includes from TIL
8 #include "til/traits.h"
9 #include "til/value_proxy.h"
10 
11 namespace til
12 {
23  template < typename T, typename TCount = unsigned int >
24  class rle_array
25  {
26  public: // classes
27 
28  class sparse_iterator;
30  class iterator;
31  class const_iterator;
32  class Segment;
33 
34  private: // typedefs
35 
36  typedef std::list<Segment> Data;
37  typedef value_proxy<rle_array<T,TCount>, std::pair<typename Data::iterator, TCount> > ValueProxy;
38 
39  public: // typedefs
40 
42  typedef T value_type;
43  typedef const T & const_reference;
44  typedef const T * const_pointer;
45  typedef ValueProxy reference;
46  typedef TCount count_type;
47 
48  public: // constructors & destructor
49 
52  : m_data()
53  , m_size(0)
54  {}
55 
58  rle_array(std::size_t i, T value = T())
59  : m_data(1, Segment(TCount(i), value))
60  , m_size(i)
61  {}
62 
63  public: // iterators
64 
66  { return const_iterator(m_data.begin(), 0, 0); }
68  { return const_iterator(m_data.end(), 0, m_size); }
70  { return iterator(m_data.begin(), 0, 0, *this); }
72  { return iterator(m_data.end(), 0, m_size, *this); }
73 
74  public: // operators
75 
76  const T & operator[](std::size_t i) const;
77  ValueProxy operator[](std::size_t i);
78 
79  public: // set & get for proxies
80 
81  void set(std::pair<typename Data::iterator, TCount> & index, const T & value);
82  template < typename XIterator >
83  const T & get(std::pair<XIterator, TCount> & index) const
84  { return index.first->value(); }
85 
86  std::size_t size() const { return m_size; }
87  public: // functions
88 
89  void print() const
90  {
91  for (typename Data::const_iterator iRepValue = m_data.begin(); iRepValue != m_data.end(); ++iRepValue)
92  {
93  std::cout << "Value : " << iRepValue->value() << " ";
94  std::cout << "Repeat : " << iRepValue->length() << ", ";
95  }
96  std::cout << std::endl;
97  }
98 
99  private: // data
100 
101  Data m_data;
102  std::size_t m_size;
103  };
104 
105  //---------------------------------------------------------------------------
106 
109  template < typename T, typename TCount >
110  class rle_array<T,TCount>::Segment
111  {
112  public: // typedefs
113  typedef TCount count_type;
114  public: // constructors & destructor
115 
116  Segment() : m_value(), m_length(0) {};
117  // follow std container convention for container constructors: first length, then value
118  Segment(TCount r, const T &v) : m_value(v), m_length(r) {};
119 
120  public: // set & get
121 
122  // I think a good reason not to return a TCount for const is that if we
123  // do ++(x.length()) we can't be sure if the const has not actually been called!
124  const TCount & length() const { return m_length; }
125  TCount & length() { return m_length; }
126  const T & value() const { return m_value; }
127  T & value() { return m_value; }
128  //void setValue(T v) { m_value = v; }
129 
130  private: // data
131 
133  T m_value;
135  TCount m_length;
136  };
137 
138  //---------------------------------------------------------------------------
139 
140  template < typename T, typename TCount >
141  class rle_array<T,TCount>::const_sparse_iterator : public Data::const_iterator
142  {
143  public: // typedefs
144  typedef typename Data::const_iterator Base;
145  public: // constructors & destructor
146  //sparse_iterator() : Base() {}
147  const_sparse_iterator(const Base & b) : Base(b) {}
148  };
149 
150  template < typename T, typename TCount >
151  class rle_array<T,TCount>::sparse_iterator : public Data::iterator
152  {
153  public: // typedefs
154  typedef typename Data::iterator Base;
155  public: // constructors & destructor
156  sparse_iterator() : Base() {}
157  sparse_iterator(const Base & b) : Base(b) {}
158  };
159 
160  namespace detail
161  {
162 
163  //-------------------------------------------------------------------------
164 
165  // TODO: I think the whole crap can be redesigned so that a value proxy is used
166  // for const and non-const without penalty, so that index is always stored
167  // inside value_proxy and there is not value_proxy of value& kind of crap.
168  template < typename TRLEArray, typename TIterator >
170  {
171  public: // typedefs
172 
174  typedef TRLEArray container;
175  typedef typename TRLEArray::count_type count_type;
176  typedef std::pair<TIterator, count_type> index_type;
177  // NB: the access policy has to pass a reference on the index here, since the index
178  // may be modified by the set function.
182  //typedef const T & reference;
183  //typedef typename TIterator::reference reference;
184  //typedef typename TIterator::pointer pointer;
185  typedef typename ValueProxy & reference;
187 
188  public: // constructors & destructor
189 
190  rle_array_iterator_base(const TIterator & i, count_type segindex, std::size_t pos, container & c)
191  : m_valueProxy(index_type(i, segindex), c)
192  , m_i(pos)
193  {
194  }
195 
196  template < typename XRLEArray, typename XIterator >
198  : m_valueProxy(b.proxy())
199  , m_i(b.pos())
200  {
201  }
202 
203  public: // set & get
204 
206  std::size_t pos() const { return m_i; }
207  //index_type & index() { return m_index; }
208  //const index_type & index() const { return m_index; }
209  const ValueProxy & proxy() const { return m_valueProxy; }
210 
211  public: // operators
212 
213  // NB: It is essential that a reference on ValueProxy is passed, because
214  // an assignment might affect the iterator hold by the value proxy, due to
215  // list insertions.
216  //const T & operator*() { return m_index.first->value(); }
217  reference operator*() { return m_valueProxy; }
218 
219  //pointer operator->() { return m_index.first->operator->(); }
220  pointer operator->() { return m_valueProxy.operator->(); }
221 
222  void operator++()
223  {
224  ++m_i;
225  // Are we at the end of a segment?
226  //if (++(m_index.second) == m_index.first->length())
227  if (++(m_valueProxy.index().second) == m_valueProxy.index().first->length())
228  {
229  // go to next segment
230  //++m_index.first;
231  //m_index.second = 0;
232  ++(m_valueProxy.index().first);
233  m_valueProxy.index().second = 0;
234  }
235  }
236 
237  void print()
238  {
239  std::cout << "Pointing on " << m_valueProxy.index().first->value() <<" "<< m_valueProxy.index().first->length() << std::endl;
240  std::cout << "Local pos: " << m_valueProxy.index().second << std::endl;
241  std::cout << "Absolute pos: " << m_i << std::endl;
242  }
243 
244  /*
245  void operator=(const Self & other)
246  {
247  m_valueProxy = other.m_valueProxy;
248  m_i = other.m_i;
249  }
250  */
251 
252  private: // data
253 
254  ValueProxy m_valueProxy;
255  //index_type m_index;
257  std::size_t m_i;
258  };
259 
260  //-------------------------------------------------------------------------
261 
262  template < typename TRLEArray1, typename TRLEArray2, typename TIterator1, typename TIterator2 >
263  inline
264  bool operator==
265  (
268  )
269  { return (i1.proxy().index().first == i2.proxy().index().first) && (i1.proxy().index().second == i2.proxy().index().second); }
270 
271  //-------------------------------------------------------------------------
272 
273  template < typename TRLEArray1, typename TRLEArray2, typename TIterator1, typename TIterator2 >
274  inline
275  bool operator!=
276  (
279  )
280  { return !(i1 == i2); }
281 
282  //-------------------------------------------------------------------------
283 
284  } // namespace
285 
286  //-------------------------------------------------------------------------
287 
288  template < typename T, typename TCount >
289  class rle_array<T,TCount>::const_iterator : public detail::rle_array_iterator_base<const rle_array<T,TCount>, typename Data::const_iterator>
290  {
291  public: // typedefs
292  typedef detail::rle_array_iterator_base<const rle_array<T,TCount>, typename Data::const_iterator> Base;
293  typedef typename Base::value_type value_type;
294  typedef typename Base::reference reference;
295  typedef typename Base::pointer pointer;
296  public: // constructors & destructor
297  const_iterator(const typename Data::const_iterator & i, TCount segindex, std::size_t pos, const rle_array<T,TCount> & c)
298  : Base(i, segindex, pos, c)
299  {}
303  template < typename XRLEArray, typename XIterator >
305  };
306 
307  template < typename T, typename TCount >
308  class rle_array<T,TCount>::iterator : public detail::rle_array_iterator_base<rle_array<T,TCount>,typename Data::iterator>
309  {
310  public: // typedefs
312  typedef typename Base::value_type value_type;
313  typedef typename Base::reference reference;
314  typedef typename Base::pointer pointer;
315  public: // constructors & destructor
316  iterator(const typename Data::iterator & i, TCount segindex, std::size_t pos, rle_array<T,TCount> & c)
317  : Base(i, segindex, pos, c)
318  {}
319 
320 
321  //void operator=(const iterator & other) { this->Base::operator=(other); }
322 
323  };
324 
325 } // namespace til
326 
327 // package include
328 #include "rle_array.tpp"
329 
330 #endif
331 
A Segment is composed of a value and a length.
Definition: rle_array.h:110
rle_array_iterator_base< TRLEArray, TIterator > Self
Definition: rle_array.h:173
const ValueProxy & proxy() const
Definition: rle_array.h:209
void print() const
Definition: rle_array.h:89
Base::reference reference
Definition: rle_array.h:313
rle_array_iterator_base(const rle_array_iterator_base< XRLEArray, XIterator > &b)
Definition: rle_array.h:197
const T * const_pointer
Definition: rle_array.h:44
Base::value_type value_type
Definition: rle_array.h:293
std::pair< TIterator, count_type > index_type
Definition: rle_array.h:176
detail::rle_array_iterator_base< rle_array< T, TCount >, typename Data::iterator > Base
Definition: rle_array.h:311
ValueProxy::const_pointer pointer
Definition: rle_array.h:186
Adds some left-value operations to const_value_proxy.
Definition: value_proxy.h:102
TCount count_type
Definition: rle_array.h:46
const T & value() const
Definition: rle_array.h:126
const T & operator[](std::size_t i) const
Belongs to package Box Do not include directly, include til/Box.h instead.
Definition: Accumulator.h:10
const T & const_reference
Definition: rle_array.h:43
value_proxy< TRLEArray, index_type, policy::VPAccess_Default< container, index_type & > > ValueProxy
Definition: rle_array.h:180
iterator end()
Definition: rle_array.h:71
Base::pointer pointer
Definition: rle_array.h:314
sparse_iterator(const Base &b)
Definition: rle_array.h:157
const_iterator(const typename Data::const_iterator &i, TCount segindex, std::size_t pos, const rle_array< T, TCount > &c)
Definition: rle_array.h:297
Base::value_type value_type
Definition: rle_array.h:312
const TCount & length() const
Definition: rle_array.h:124
const_iterator end() const
Definition: rle_array.h:67
Segment(TCount r, const T &v)
Definition: rle_array.h:118
iterator begin()
Definition: rle_array.h:69
rle_array(std::size_t i, T value=T())
Standard constructor providing a size and an optional fill value.
Definition: rle_array.h:58
std::size_t size() const
Definition: rle_array.h:86
rle_array< T, TCount > Self
Definition: rle_array.h:41
const_iterator begin() const
Definition: rle_array.h:65
rle_array()
Default constructor, yield a zero-size container.
Definition: rle_array.h:51
TRLEArray::count_type count_type
Definition: rle_array.h:175
iterator(const typename Data::iterator &i, TCount segindex, std::size_t pos, rle_array< T, TCount > &c)
Definition: rle_array.h:316
A run-length encoded array.
Definition: rle_array.h:24
ValueProxy reference
Definition: rle_array.h:45
rle_array_iterator_base(const TIterator &i, count_type segindex, std::size_t pos, container &c)
Definition: rle_array.h:190
detail::rle_array_iterator_base< const rle_array< T, TCount >, typename Data::const_iterator > Base
Definition: rle_array.h:292
container::value_type value_type
Definition: rle_array.h:181
std::size_t pos() const
Return the current position of the iterator in the array.
Definition: rle_array.h:206
const_iterator(const detail::rle_array_iterator_base< XRLEArray, XIterator > &b)
This is only to convert from an rle_array<T,TCount>::iterator, so that one can write const_iterator i...
Definition: rle_array.h:304