Proton  1.1.1
Make porting easy from Python to C++11
list.hpp
1 #ifndef PROTON_LIST_HEADER
2 #define PROTON_LIST_HEADER
3 
4 #include <list>
5 #include <iterator>
6 #include <algorithm>
7 #include <iostream>
8 
9 namespace proton{
10 
11 template <typename T, typename allocT, typename V >
12 bool has(const std::list<T,allocT>& x, V&& val)
13 {
14  return std::find(x.begin(), x.end(), val)!=x.end();
15 }
16 
17 template <typename T, typename A, typename V>
18 std::list<T,A>& operator<<(std::list<T,A>& x, V&& val)
19 {
20  x.push_back(val);
21  return x;
22 }
23 
24 template <typename T, typename A, typename V>
25 std::list<T,A>& operator>>(std::list<T,A>& x, V& val)
26 {
27  PROTON_THROW_IF(x.empty(), "want to pop an empty list.");
28  val=x.back();
29  x.pop_back();
30  return x;
31 }
32 
33 template <typename T, typename A>
34 std::ostream& operator<<(std::ostream& s, std::list<T,A>& x)
35 {
36  s << "[";
37  bool first=true;
38  for(auto& i:x){
39  if(first)
40  first=false;
41  else
42  s <<", ";
43  s << i;
44  }
45  s << "]";
46  return s;
47 }
48 
49 /*
50 template <typename T, typename A>
51 bool operator==(const std::list<T,A>& x, const std::list<T,A>& y)
52 {
53  if(x.size()!=y.size())
54  return false;
55  auto it_y=y.begin();
56  each(it_x,x){
57  if(*it_x!=*it_y)
58  return false;
59  ++it_y;
60  }
61  return true;
62 }
63 
64 template <typename T, typename A>
65 bool operator!=(const std::list<T,A>& x, const std::list<T,A>& y)
66 {
67  if(x.size()!=y.size())
68  return true;
69  auto it_y=y.begin();
70  each(it_x,x){
71  if(*it_x!=*it_y)
72  return true;
73  ++it_y;
74  }
75  return false;
76 }
77 */
78 
79 template <typename T, typename A>
80 void sort(std::list<T,A>& x)
81 {
82  x.sort();
83 }
84 
85 template <typename T, typename A>
86 T& get(std::list<T,A>& x, long i)
87 {
88  if(i>=0){
89  long j=0;
90  auto it=x.begin(),end=x.end();
91  for(; j<i; j++,++it){
92  if(it==end){
93  break;
94  }
95  }
96  if(it==end){
97  PROTON_ERR("out of range: look up "<<i<<" in a list whose size is " << j);
98  }
99  return *it;
100  }
101  else{
102  long j=0;
103  auto it=x.end(),begin=x.begin();
104  for(; j>i; --j,--it){
105  if(it==begin){
106  PROTON_ERR("out of range: look up "<<-j+i<<" in a list whose size is " << -j);
107  }
108  }
109  return *it;
110  }
111 }
112 
113 template <typename T, typename A>
114 const T& get(const std::list<T,A>& x, long i)
115 {
116  if(i>=0){
117  long j=0;
118  auto it=x.begin(),end=x.end();
119  for(; j<i; j++,++it){
120  if(it==end){
121  break;
122  }
123  }
124  if(it==end){
125  PROTON_ERR("out of range: look up "<<i<<" in a list whose size is " << j);
126  }
127  return *it;
128  }
129  else{
130  long j=0;
131  auto it=x.end(),begin=x.begin();
132  for(; j>i; --j,--it){
133  if(it==begin){
134  PROTON_ERR("out of range: look up "<<-j+i<<" in a list whose size is " << -j);
135  }
136  }
137  return *it;
138  }
139 }
140 
141 
142 template <typename T, typename A>
143 std::list<T,A> sub(const std::list<T,A>& x, long i)
144 {
145  typename std::list<T,A>::const_iterator it;
146  if(i>=0){
147  long j=0;
148  it=x.begin();
149  auto end=x.end();
150  for(; j<i; j++,++it){
151  if(it==end){
152  return {};
153  }
154  }
155  if(it==end){
156  return {};
157  }
158  // it points to the first item
159  }
160  else{
161  long j=0;
162  it=x.end();
163  auto begin=x.begin();
164  for(; j>i; --j,--it){
165  if(it==begin){
166  return x;
167  }
168  }
169  }
170 
171  std::list<T,A> r;
172  std::copy(it, x.end(), std::back_inserter(r));
173  return r;
174 }
175 
176 template <typename T, typename A>
177 std::list<T,A> sub(const std::list<T,A>& x, long first, long last)
178 {
179  bool diff_sign=true;
180  if(first>=0 && last>=0){
181  if(first>=last)
182  return {};
183  diff_sign=false;
184  }
185  if(first<0 && last<0){
186  if(first>=last)
187  return {};
188  diff_sign=false;
189  }
190 
191  auto end=x.end(), begin=x.begin();
192  typename std::list<T,A>::const_iterator it;
193  long i=first;
194  long size=-1;
195  if(i>=0){
196  long j=0;
197  it=begin;
198  for(; j<i; j++,++it){
199  if(it==end){
200  return {};
201  }
202  }
203  if(it==end){
204  return {};
205  }
206  // it points to the first item
207  }
208  else{
209  long j=0;
210  it=end;
211  for(; j>i; --j,--it){
212  if(it==begin){
213  size=-j;
214  break;
215  }
216  }
217  }
218 
219  std::list<T,A> r;
220  if(!diff_sign){
221  if(first<0 && size>=0){
222  last=last+size;
223  if(last<=0)
224  return r;
225  first=first+size;
226  if(first<0)
227  first=0;
228  }
229  for(long i=last-first;i>0;--i,++it){
230  if(it!=end)
231  r << *it;
232  else
233  break;
234  }
235  return r;
236  }
237 
238  typename std::list<T,A>::const_iterator it1;
239  i=last;
240  if(i>=0){
241  bool pass=false;
242  long j=0;
243  it1=begin;
244  for(; j<i; j++,++it1){
245  if(it1==it)
246  pass=true;
247  if(it1==end){
248  break;
249  }
250  }
251  if(!pass)
252  return r;
253  // it1 points to the last item
254  }
255  else{
256  long j=0;
257  it1=end;
258  for(; j>i; --j,--it1){
259  if(it1==it)
260  return r;
261  }
262  // it1 points to the first item
263  }
264 
265  std::copy(it,it1, std::back_inserter(r));
266  return r;
267 }
268 
269 }
270 
271 #endif // PROTON_LIST_HEADER