iutest  1.17.99.14
iutest_list.hpp
[詳解]
1 //======================================================================
2 //-----------------------------------------------------------------------
13 //-----------------------------------------------------------------------
14 //======================================================================
15 #ifndef INCG_IRIS_IUTEST_LIST_HPP_CB5AECEA_6147_4A89_BB97_236338CA177E_
16 #define INCG_IRIS_IUTEST_LIST_HPP_CB5AECEA_6147_4A89_BB97_236338CA177E_
17 
18 //======================================================================
19 // include
20 #if IUTEST_USE_OWN_LIST
21 # ifdef _IUTEST_DEBUG
22 # include <assert.h>
23 # endif
24 #else
25 # include <list>
26 #endif
27 
28 namespace iutest {
29 namespace detail
30 {
31 
32 #if IUTEST_USE_OWN_LIST
33 
34 //======================================================================
35 // class
40 template<typename TN>
41 class iu_list_node
42 {
43  typedef TN *value_ptr;
44  typedef iu_list_node<TN> _Myt;
45 public:
46  value_ptr next;
47  value_ptr prev;
48 
49 protected:
50  iu_list_node() IUTEST_CXX_NOEXCEPT_SPEC : next(NULL)
51  , prev(NULL)
52  {}
53 };
54 
59 template<typename NODE, typename NODE_PTR, typename NODE_REF>
60 class iu_list_iterator
61 {
62  typedef iu_list_iterator<NODE, NODE_PTR, NODE_REF> _Myt;
63 public:
64  typedef NODE value_type;
65  typedef NODE_PTR value_ptr;
66  typedef NODE_REF value_ref;
67  typedef value_ptr pointer;
68  typedef value_ref reference;
69  typedef int distance_type;
70  typedef int difference_type;
71 public:
72  value_ptr m_node;
73 public:
74  iu_list_iterator(value_ptr p=NULL) IUTEST_CXX_NOEXCEPT_SPEC : m_node(p) {} // NOLINT
75  iu_list_iterator(const iu_list_iterator& rhs) IUTEST_CXX_NOEXCEPT_SPEC : m_node(rhs.m_node) {}
76  iu_list_iterator& operator = (const iu_list_iterator& rhs) IUTEST_CXX_NOEXCEPT_SPEC
77  {
78  m_node = rhs.m_node;
79  return *this;
80  }
81 
82 public:
83  bool operator == (const _Myt& it) const { return this->m_node == it.m_node; }
84  bool operator != (const _Myt& it) const { return this->m_node != it.m_node; }
85 
86  _Myt& operator ++ () { m_node = m_node->next; return *this; }
87  _Myt& operator -- () { m_node = m_node->prev; return *this; }
88  value_ptr operator -> () IUTEST_CXX_NOEXCEPT_SPEC { return ptr(); }
89  value_ptr operator * () IUTEST_CXX_NOEXCEPT_SPEC { return m_node; }
90  value_ptr ptr() const IUTEST_CXX_NOEXCEPT_SPEC { return m_node; }
91 
92  operator value_ptr () { return ptr(); }
93 
94  _Myt operator + (int n)
95  {
96  if( n == 0 )
97  {
98  return *this;
99  }
100  if( n > 0 )
101  {
102  return this->operator +(static_cast<unsigned int>(n));
103  }
104  _Myt ret(*this);
105  n = -n;
106  for( int i=0; i < n && ret.m_node != NULL; ++i )
107  {
108  ret.m_node = ret.m_node->prev;
109  }
110  return ret;
111  }
112 
113  _Myt operator + (unsigned int n)
114  {
115  _Myt ret(*this);
116  for( unsigned int i=0; i < n && ret.m_node != NULL; ++i )
117  {
118  ret.m_node = ret.m_node->next;
119  }
120  return ret;
121  }
122 };
123 
129 template<typename NODE>
130 class iu_list
131 {
132  typedef NODE *node_ptr;
133  typedef iu_list<NODE> _Myt;
134 protected:
135  node_ptr m_node;
136 
137 public:
138  typedef iu_list_iterator<NODE, NODE*, NODE&> iterator;
139  typedef iu_list_iterator<NODE, const NODE*, const NODE&> const_iterator;
140 public:
141  explicit iu_list(node_ptr p=NULL) IUTEST_CXX_NOEXCEPT_SPEC : m_node(p) {}
142 
143 public:
144  // リストの総数取得
145  size_t count() const IUTEST_CXX_NOEXCEPT_SPEC
146  {
147  size_t cnt = 0;
148  node_ptr cur = m_node;
149  while(cur != NULL)
150  {
151  ++cnt;
152  cur = cur->next;
153  }
154  return cnt;
155  }
156  size_t size() const IUTEST_CXX_NOEXCEPT_SPEC
157  {
158  return count();
159  }
160  bool empty() const IUTEST_CXX_NOEXCEPT_SPEC
161  {
162  return m_node == NULL;
163  }
164 public:
165  // ソートして挿入
166  void sort_insert(node_ptr p)
167  {
168  if( p == NULL )
169  {
170  return;
171  }
172 
173  if( m_node == NULL )
174  {
175  m_node = p;
176  return;
177  }
178 
179  if( *p < *m_node )
180  {
181  // 入れ替え
182  node_ptr next = m_node;
183  m_node = p;
184  p->next = next;
185  next->prev = p;
186  }
187  else
188  {
189  node_ptr prev = m_node;
190  node_ptr cur = m_node->next;
191  while(cur != NULL)
192  {
193  if( *p < *cur )
194  {
195  break;
196  }
197  prev = cur;
198  cur = prev->next;
199  }
200  prev->next = p;
201  p->prev = prev;
202  p->next = cur;
203  if( cur != NULL )
204  {
205  cur->prev = p;
206  }
207  }
208  }
209  // 追加
210  void push_back(node_ptr p)
211  {
212  if( p == NULL )
213  {
214  return;
215  }
216 
217  if( m_node == NULL )
218  {
219  m_node = p;
220  return;
221  }
222 
223  node_ptr prev = m_node;
224  node_ptr cur = m_node->next;
225  while(cur != NULL)
226  {
227  if( prev == p )
228  {
229  return;
230  }
231  prev = cur;
232  cur = prev->next;
233  }
234  prev->next = p;
235  p->prev = prev;
236  }
237  // 削除
238  void remove(node_ptr p)
239  {
240  if( p == NULL )
241  {
242  return;
243  }
244  if( m_node == NULL )
245  {
246  return;
247  }
248  if( p->prev == NULL )
249  {
250  m_node = p->next;
251  if( m_node != NULL )
252  {
253  m_node->prev = NULL;
254  }
255  }
256  else
257  {
258  p->prev->next = p->next;
259  if( p->next != NULL )
260  {
261  p->next->prev = p->prev;
262  }
263  }
264  p->prev = p->next = NULL;
265  }
266  void erase(iterator it)
267  {
268  remove(it.ptr());
269  }
270 public:
275  template<typename F>
276  void shuffle(F& r)
277  {
278  for( unsigned int i=2, n=count(); i<n; ++i )
279  {
280  swap(begin() + (i-2), begin() + r(i) % i );
281  }
282  }
283 
284 public:
285  void swap(iterator a, iterator b)
286  {
287  if( a == b )
288  {
289  return;
290  }
291  if( a.ptr() == m_node )
292  {
293  m_node = b.ptr();
294  }
295  else if( b.ptr() == m_node )
296  {
297  m_node = a.ptr();
298  }
299 
300  if( a->next == b.ptr() )
301  {
302  a->next = b->next;
303  b->next = a.ptr();
304  b->prev = a->prev;
305  a->prev = b.ptr();
306  if( a->next != NULL )
307  {
308  a->next->prev = a.ptr();
309  }
310  if( b->prev != NULL )
311  {
312  b->prev->next = b.ptr();
313  }
314  }
315  else if( a->prev == b.ptr() )
316  {
317  b->next = a->next;
318  a->next = b.ptr();
319  a->prev = b->prev;
320  b->prev = a.ptr();
321  if( b->next != NULL )
322  {
323  b->next->prev = b.ptr();
324  }
325  if( a->prev != NULL )
326  {
327  a->prev->next = a.ptr();
328  }
329  }
330  else
331  {
332  node_ptr tmp = a->next;
333  a->next = b->next;
334  b->next = tmp;
335  tmp = a->prev;
336  a->prev = b->prev;
337  b->prev = tmp;
338  if( a->next != NULL )
339  {
340  a->next->prev = a.ptr();
341  }
342  if( b->next != NULL )
343  {
344  b->next->prev = b.ptr();
345  }
346  if( a->prev != NULL )
347  {
348  a->prev->next = a.ptr();
349  }
350  if( b->prev != NULL )
351  {
352  b->prev->next = b.ptr();
353  }
354  }
355  }
356 
357 public:
358  iterator begin() IUTEST_CXX_NOEXCEPT_SPEC
359  {
360  return m_node;
361  }
362  iterator end() IUTEST_CXX_NOEXCEPT_SPEC
363  {
364  return iterator(NULL);
365  }
366  const_iterator begin() const IUTEST_CXX_NOEXCEPT_SPEC
367  {
368  return m_node;
369  }
370  const_iterator end() const IUTEST_CXX_NOEXCEPT_SPEC
371  {
372  return const_iterator(NULL);
373  }
374 
375 
376 public:
377  struct EqualOp
378  {
379  template<typename T>
380  bool operator () (const T* lhs, const T* rhs) const { return *lhs == *rhs; }
381  };
382 public:
383  template<typename FUNC>
384  node_ptr find(node_ptr p, FUNC& f) const
385  {
386  node_ptr cur = m_node;
387  while( cur != NULL )
388  {
389  if( f(cur, p) )
390  {
391  return cur;
392  }
393  cur = cur->next;
394  }
395  return NULL;
396  }
397  template<typename FUNC>
398  node_ptr find(FUNC& f) const
399  {
400  node_ptr cur = m_node;
401  while( cur != NULL )
402  {
403  if( f(cur) )
404  {
405  return cur;
406  }
407  cur = cur->next;
408  }
409  return NULL;
410  }
411 
412 public:
413  node_ptr operator -> () { return m_node; }
414  node_ptr operator & () { return m_node; } // NOLINT
415  NODE& operator * () { return *m_node; }
416 
417  node_ptr operator [] (int index) const
418  {
419  node_ptr cur = m_node;
420  for( int i=0; i < index; ++i )
421  {
422  cur = cur->next;
423  if( cur == NULL )
424  {
425  break;
426  }
427  }
428  return cur;
429  }
430 
431  bool operator == (node_ptr p) const { return m_node == p; }
432  bool operator != (node_ptr p) const { return m_node != p; }
433 
434 private:
435 #ifdef _IUTEST_DEBUG
436  // ノードの状態チェック
437  bool check_node()
438  {
439  if( m_node == NULL )
440  {
441  return true;
442  }
443  node_ptr prev = m_node;
444  node_ptr curr = prev->next;
445  while( curr != NULL )
446  {
447  assert( prev->next == curr );
448  assert( curr->prev == prev );
449  prev = curr;
450  curr = prev->next;
451  }
452  return true;
453  }
454 #endif
455 };
456 
457 #endif
458 
459 
460 IUTEST_PRAGMA_WARN_PUSH()
461 IUTEST_PRAGMA_WARN_DISABLE_NOEXCEPT_TPYE()
462 
466 template<typename It>
467 void RandomShuffle(It begin, It last, iuRandom& r)
468 {
469  r.shuffle(begin, last);
470 }
471 #if IUTEST_USE_OWN_LIST
472 template<typename Node, typename Fn>
473 void RandomShuffle(iu_list<Node>& list, Fn& r)
474 {
475  list.shuffle(r);
476 }
477 #endif
478 template<typename T, typename Fn>
479 void RandomShuffle(::std::vector<T>& list, Fn& r)
480 {
481  RandomShuffle(list.begin(), list.end(), r);
482 }
483 
484 #if IUTEST_USE_OWN_LIST
485 template<typename Node, typename Fn>
486 Node* FindList(const iu_list<Node>& list, Fn& f)
487 {
488  return list.find(f);
489 }
490 #else
491 template<typename T, typename Fn>
492 T FindList(const ::std::vector<T>& list, Fn& f)
493 {
494  for(typename ::std::vector<T>::const_iterator it = list.begin(), end = list.end(); it != end; ++it)
495  {
496  if(f(*it))
497  {
498  return *it;
499  }
500  }
501  return NULL;
502 }
503 #endif
504 
505 
509 #if IUTEST_USE_OWN_LIST
510 
511 template<typename Node, typename Fn>
512 int CountIf(const iu_list<Node>& list, Fn f)
513 {
514  int count = 0;
515  for( typename iu_list<Node>::const_iterator it = list.begin(), end=list.end(); it != end; ++it )
516  {
517  if( f(*it) )
518  {
519  ++count;
520  }
521  }
522  return count;
523 }
524 
525 #else
526 
527 template<typename T, typename Fn>
528 int CountIf(const ::std::vector<T>& list, Fn f)
529 {
530  int count = 0;
531  for(typename ::std::vector<T>::const_iterator it = list.begin(), end = list.end(); it != end; ++it)
532  {
533  if(f(*it))
534  {
535  ++count;
536  }
537  }
538  return count;
539 }
540 
541 #endif
542 
543 
547 #if IUTEST_USE_OWN_LIST
548 
549 template<typename Node, typename Fn>
550 int SumOverList(const iu_list<Node>& list, Fn f)
551 {
552  int count = 0;
553  for( typename iu_list<Node>::const_iterator it = list.begin(), end=list.end(); it != end; ++it )
554  {
555  count += ((*it)->*f)();
556  }
557  return count;
558 }
559 
560 #else
561 
562 template<typename T, typename Fn>
563 int SumOverList(const ::std::vector<T>& list, Fn f)
564 {
565  int count = 0;
566  for(typename ::std::vector<T>::const_iterator it = list.begin(), end = list.end(); it != end; ++it)
567  {
568  count += ((*it)->*f)();
569  }
570  return count;
571 }
572 
573 #endif
574 
575 
579 #if IUTEST_USE_OWN_LIST
580 
581 template<typename Node, typename Fn>
582 int CountIfOverList(const iu_list<Node>& list, Fn f)
583 {
584  int count = 0;
585  for( typename iu_list<Node>::const_iterator it = list.begin(), end=list.end(); it != end; ++it )
586  {
587  if( ((*it)->*f)() )
588  {
589  ++count;
590  }
591  }
592  return count;
593 }
594 
595 #else
596 
597 template<typename T, typename Fn>
598 int CountIfOverList(const ::std::vector<T>& list, Fn f)
599 {
600  int count = 0;
601  for(typename ::std::vector<T>::const_iterator it = list.begin(), end = list.end(); it != end; ++it)
602  {
603  if(((*it)->*f)())
604  {
605  ++count;
606  }
607  }
608  return count;
609 }
610 
611 #endif
612 
616 #if IUTEST_USE_OWN_LIST
617 
618 template<typename Node, typename Fn>
619 bool AnyOverList(const iu_list<Node>& list, Fn f)
620 {
621  for( typename iu_list<Node>::const_iterator it = list.begin(), end=list.end(); it != end; ++it )
622  {
623  if( ((*it)->*f)() )
624  {
625  return true;
626  }
627  }
628  return false;
629 }
630 
631 #else
632 
633 template<typename T, typename Fn>
634 bool AnyOverList(const ::std::vector<T>& list, Fn f)
635 {
636  for(typename ::std::vector<T>::const_iterator it = list.begin(), end = list.end(); it != end; ++it)
637  {
638  if(((*it)->*f)())
639  {
640  return true;
641  }
642  }
643  return false;
644 }
645 
646 #endif
647 
648 IUTEST_PRAGMA_WARN_POP()
649 
650 } // end of namespace detail
651 } // end of namespace iutest
652 
653 
654 #endif // INCG_IRIS_IUTEST_LIST_HPP_CB5AECEA_6147_4A89_BB97_236338CA177E_
#define IUTEST_CXX_NOEXCEPT_SPEC
noexcept specification definition
Definition: iutest_compiler.hpp:811
iutest root namespace
Definition: iutest_charcode.hpp:33