aimstil  5.0.5
rle_array.tpp
Go to the documentation of this file.
1 
2 namespace til
3 {
4 
5  //---------------------------------------------------------------------------
6 
7  template < typename T, typename TCount >
8  const T &
9  rle_array<T,TCount>::
10  operator[](std::size_t i) const
11  {
12  assert(i <= this->size());
13  std::size_t current_i = 0;
14  typename Data::const_iterator iData = m_data.begin();
15  while (i >= iData->length())
16  {
17  i -= iData->length();
18  ++iData;
19  }
20  return iData->value();
21  }
22 
23  //---------------------------------------------------------------------------
24 
25  template < typename T, typename TCount >
26  typename rle_array<T,TCount>::ValueProxy
27  rle_array<T,TCount>::
28  operator[](std::size_t i)
29  {
30  assert(i <= this->size());
31  typename Data::iterator iData = m_data.begin();
32  while (i >= iData->length())
33  {
34  i -= iData->length();
35  ++iData;
36  }
37  return ValueProxy(std::make_pair(iData, i), *this);
38  }
39 
40  //---------------------------------------------------------------------------
41 
42 
43  template < typename T, typename TCount >
44  void
45  rle_array<T,TCount>::
46  set
47  (
48  std::pair<typename Data::iterator, TCount> & index
49  , const T & value
50  )
51  {
52  // Do nothing if nothing to do
53  if (value == index.first->value()) return;
54 
55  // Is the current segment made of only one element?
56  if (index.first->length() == 1)
57  {
58  assert(index.second == 0);
59 
60  typename Data::iterator iPreviousSegment = index.first;
61  bool atBeginning = (index.first == m_data.begin());
62  if (!atBeginning) --iPreviousSegment;
63  typename Data::iterator iNextSegment = index.first;
64  bool atEnd = (++iNextSegment == m_data.end());
65 
66  if (!atBeginning && iPreviousSegment->value() == value)
67  {
68  index.second = (iPreviousSegment->length())++;
69  if (!atEnd && iNextSegment->value() == value)
70  {
71  iPreviousSegment->length() += iNextSegment->length();
72  m_data.erase(iNextSegment);
73  }
74  m_data.erase(index.first);
75  index.first = iPreviousSegment;
76  }
77  else if (!atEnd && iNextSegment->value() == value)
78  {
79  ++(iNextSegment->length());
80  index.first = m_data.erase(index.first);
81  }
82  // Then we remain a single point : simply update the value.
83  else
84  {
85  // Simply overwrite the value
86  index.first->value() = value;
87  //index.first->setValue(value);
88  }
89  }
90  // Are we at the very first of current repeated value?
91  else if (index.second == 0)
92  {
93  typename Data::iterator iPreviousSegment = index.first;
94  bool atBeginning = (index.first == m_data.begin());
95  if (!atBeginning) --iPreviousSegment;
96 
97  // If so, decrease current length number by one
98  --(index.first->length());
99 
100  // Is the previous value the same?
101  if (!atBeginning && iPreviousSegment->value() == value)
102  {
103  // Then just increase its length number
104  index.second = (iPreviousSegment->length())++;
105  index.first = iPreviousSegment;
106  }
107  else
108  {
109  // else insert a new length value
110  index.first = m_data.insert(index.first, Segment(1, value));
111  index.second = 0;
112  }
113  }
114  // Are we exactly at the end of current segment?
115  else if (index.second == index.first->length()-1)
116  {
117  typename Data::iterator iNextSegment = index.first;
118  bool atEnd = (++iNextSegment == m_data.end());
119 
120  // Then, decrease current length number by one
121  --(index.first->length());
122  index.second = 0;
123 
124  if (!atEnd && iNextSegment->value() == value)
125  {
126  // If the next sequence has the same value, just increase
127  // its length number by one
128  ++(iNextSegment->length());
129  index.first = iNextSegment;
130  }
131  else
132  {
133  // Insert a new length value
134  index.first = m_data.insert(iNextSegment, Segment(1, value));
135  }
136  }
137  // we are in the middle of a repeated value
138  else
139  {
140  assert(index.second > 0);
141  // First half
142  m_data.insert(index.first, Segment(index.second, index.first->value()));
143  // New element
144  m_data.insert(index.first, Segment(1, value));
145  // last half
146  index.first->length() -= index.second+1;
147  --index.first;
148  index.second = 0;
149  }
150  }
151 
152 /*
153  template < typename T, typename TCount >
154  class rle_array<T,TCount>::ValueProxy : public value_proxy<rle_array<T,TCount>, std::pair<typename Data::iterator, TCount> >
155  {
156  public: // typedefs
157  typedef value_proxy<rle_array<T,TCount>, std::pair<typename Data::iterator, TCount> > Base;
158  typedef typename Base::index_type index_type;
159  typedef typename Base::container container;
160  public: // constructors & destructor
161  ValueProxy(index_type i, container * p) : Base(i, p) {}
162  public: // operators
163  // unfortunately we have to redefine this function by hand :(
164  void operator=(typename boost::call_traits<T>::param_type value) { this->Base::operator=(value); }
165  };
166 */
167 
168  //---------------------------------------------------------------------------
169 
170 
171 
172 
173 } // namespace til
174 
175