iutest  1.17.1.0
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 public:
161  // ソートして挿入
162  void sort_insert(node_ptr p)
163  {
164  if( p == NULL )
165  {
166  return;
167  }
168 
169  if( m_node == NULL )
170  {
171  m_node = p;
172  return;
173  }
174 
175  if( *p < *m_node )
176  {
177  // 入れ替え
178  node_ptr next = m_node;
179  m_node = p;
180  p->next = next;
181  next->prev = p;
182  }
183  else
184  {
185  node_ptr prev = m_node;
186  node_ptr cur = m_node->next;
187  while(cur != NULL)
188  {
189  if( *p < *cur )
190  {
191  break;
192  }
193  prev = cur;
194  cur = prev->next;
195  }
196  prev->next = p;
197  p->prev = prev;
198  p->next = cur;
199  if( cur != NULL )
200  {
201  cur->prev = p;
202  }
203  }
204  }
205  // 追加
206  void push_back(node_ptr p)
207  {
208  if( p == NULL )
209  {
210  return;
211  }
212 
213  if( m_node == NULL )
214  {
215  m_node = p;
216  return;
217  }
218 
219  node_ptr prev = m_node;
220  node_ptr cur = m_node->next;
221  while(cur != NULL)
222  {
223  if( prev == p )
224  {
225  return;
226  }
227  prev = cur;
228  cur = prev->next;
229  }
230  prev->next = p;
231  p->prev = prev;
232  }
233  // 削除
234  void remove(node_ptr p)
235  {
236  if( p == NULL )
237  {
238  return;
239  }
240  if( m_node == NULL )
241  {
242  return;
243  }
244  if( p->prev == NULL )
245  {
246  m_node = p->next;
247  if( m_node != NULL )
248  {
249  m_node->prev = NULL;
250  }
251  }
252  else
253  {
254  p->prev->next = p->next;
255  if( p->next != NULL )
256  {
257  p->next->prev = p->prev;
258  }
259  }
260  p->prev = p->next = NULL;
261  }
262  void erase(iterator it)
263  {
264  remove(it.ptr());
265  }
266 public:
271  template<typename F>
272  void shuffle(F& r)
273  {
274  for( unsigned int i=2, n=count(); i<n; ++i )
275  {
276  swap(begin() + (i-2), begin() + r(i) % i );
277  }
278  }
279 
280 public:
281  void swap(iterator a, iterator b)
282  {
283  if( a == b )
284  {
285  return;
286  }
287  if( a.ptr() == m_node )
288  {
289  m_node = b.ptr();
290  }
291  else if( b.ptr() == m_node )
292  {
293  m_node = a.ptr();
294  }
295 
296  if( a->next == b.ptr() )
297  {
298  a->next = b->next;
299  b->next = a.ptr();
300  b->prev = a->prev;
301  a->prev = b.ptr();
302  if( a->next != NULL )
303  {
304  a->next->prev = a.ptr();
305  }
306  if( b->prev != NULL )
307  {
308  b->prev->next = b.ptr();
309  }
310  }
311  else if( a->prev == b.ptr() )
312  {
313  b->next = a->next;
314  a->next = b.ptr();
315  a->prev = b->prev;
316  b->prev = a.ptr();
317  if( b->next != NULL )
318  {
319  b->next->prev = b.ptr();
320  }
321  if( a->prev != NULL )
322  {
323  a->prev->next = a.ptr();
324  }
325  }
326  else
327  {
328  node_ptr tmp = a->next;
329  a->next = b->next;
330  b->next = tmp;
331  tmp = a->prev;
332  a->prev = b->prev;
333  b->prev = tmp;
334  if( a->next != NULL )
335  {
336  a->next->prev = a.ptr();
337  }
338  if( b->next != NULL )
339  {
340  b->next->prev = b.ptr();
341  }
342  if( a->prev != NULL )
343  {
344  a->prev->next = a.ptr();
345  }
346  if( b->prev != NULL )
347  {
348  b->prev->next = b.ptr();
349  }
350  }
351  }
352 
353 public:
354  iterator begin() IUTEST_CXX_NOEXCEPT_SPEC
355  {
356  return m_node;
357  }
358  iterator end() IUTEST_CXX_NOEXCEPT_SPEC
359  {
360  return iterator(NULL);
361  }
362  const_iterator begin() const IUTEST_CXX_NOEXCEPT_SPEC
363  {
364  return m_node;
365  }
366  const_iterator end() const IUTEST_CXX_NOEXCEPT_SPEC
367  {
368  return const_iterator(NULL);
369  }
370 
371 
372 public:
373  struct EqualOp
374  {
375  template<typename T>
376  bool operator () (const T* lhs, const T* rhs) const { return *lhs == *rhs; }
377  };
378 public:
379  template<typename FUNC>
380  node_ptr find(node_ptr p, FUNC& f) const
381  {
382  node_ptr cur = m_node;
383  while( cur != NULL )
384  {
385  if( f(cur, p) )
386  {
387  return cur;
388  }
389  cur = cur->next;
390  }
391  return NULL;
392  }
393  template<typename FUNC>
394  node_ptr find(FUNC& f) const
395  {
396  node_ptr cur = m_node;
397  while( cur != NULL )
398  {
399  if( f(cur) )
400  {
401  return cur;
402  }
403  cur = cur->next;
404  }
405  return NULL;
406  }
407 
408 public:
409  node_ptr operator -> () { return m_node; }
410  node_ptr operator & () { return m_node; } // NOLINT
411  NODE& operator * () { return *m_node; }
412 
413  node_ptr operator [] (int index) const
414  {
415  node_ptr cur = m_node;
416  for( int i=0; i < index; ++i )
417  {
418  cur = cur->next;
419  if( cur == NULL )
420  {
421  break;
422  }
423  }
424  return cur;
425  }
426 
427  bool operator == (node_ptr p) const { return m_node == p; }
428  bool operator != (node_ptr p) const { return m_node != p; }
429 
430 private:
431 #ifdef _IUTEST_DEBUG
432  // ノードの状態チェック
433  bool check_node()
434  {
435  if( m_node == NULL )
436  {
437  return true;
438  }
439  node_ptr prev = m_node;
440  node_ptr curr = prev->next;
441  while( curr != NULL )
442  {
443  assert( prev->next == curr );
444  assert( curr->prev == prev );
445  prev = curr;
446  curr = prev->next;
447  }
448  return true;
449  }
450 #endif
451 };
452 
453 #endif
454 
455 
456 IUTEST_PRAGMA_WARN_PUSH()
457 IUTEST_PRAGMA_WARN_DISABLE_NOEXCEPT_TPYE()
458 
462 template<typename It>
463 void RandomShuffle(It begin, It last, iuRandom& r)
464 {
465  r.shuffle(begin, last);
466 }
467 #if IUTEST_USE_OWN_LIST
468 template<typename Node, typename Fn>
469 void RandomShuffle(iu_list<Node>& list, Fn& r)
470 {
471  list.shuffle(r);
472 }
473 #endif
474 template<typename T, typename Fn>
475 void RandomShuffle(::std::vector<T>& list, Fn& r)
476 {
477  RandomShuffle(list.begin(), list.end(), r);
478 }
479 
480 #if IUTEST_USE_OWN_LIST
481 template<typename Node, typename Fn>
482 Node* FindList(const iu_list<Node>& list, Fn& f)
483 {
484  return list.find(f);
485 }
486 #else
487 template<typename T, typename Fn>
488 T FindList(const ::std::vector<T>& list, Fn& f)
489 {
490  for(typename ::std::vector<T>::const_iterator it = list.begin(), end = list.end(); it != end; ++it)
491  {
492  if(f(*it))
493  {
494  return *it;
495  }
496  }
497  return NULL;
498 }
499 #endif
500 
501 
505 #if IUTEST_USE_OWN_LIST
506 
507 template<typename Node, typename Fn>
508 int CountIf(const iu_list<Node>& list, Fn f)
509 {
510  int count = 0;
511  for( typename iu_list<Node>::const_iterator it = list.begin(), end=list.end(); it != end; ++it )
512  {
513  if( f(*it) )
514  {
515  ++count;
516  }
517  }
518  return count;
519 }
520 
521 #else
522 
523 template<typename T, typename Fn>
524 int CountIf(const ::std::vector<T>& list, Fn f)
525 {
526  int count = 0;
527  for(typename ::std::vector<T>::const_iterator it = list.begin(), end = list.end(); it != end; ++it)
528  {
529  if(f(*it))
530  {
531  ++count;
532  }
533  }
534  return count;
535 }
536 
537 #endif
538 
539 
543 #if IUTEST_USE_OWN_LIST
544 
545 template<typename Node, typename Fn>
546 int SumOverList(const iu_list<Node>& list, Fn f)
547 {
548  int count = 0;
549  for( typename iu_list<Node>::const_iterator it = list.begin(), end=list.end(); it != end; ++it )
550  {
551  count += ((*it)->*f)();
552  }
553  return count;
554 }
555 
556 #else
557 
558 template<typename T, typename Fn>
559 int SumOverList(const ::std::vector<T>& list, Fn f)
560 {
561  int count = 0;
562  for(typename ::std::vector<T>::const_iterator it = list.begin(), end = list.end(); it != end; ++it)
563  {
564  count += ((*it)->*f)();
565  }
566  return count;
567 }
568 
569 #endif
570 
571 
575 #if IUTEST_USE_OWN_LIST
576 
577 template<typename Node, typename Fn>
578 int CountIfOverList(const iu_list<Node>& list, Fn f)
579 {
580  int count = 0;
581  for( typename iu_list<Node>::const_iterator it = list.begin(), end=list.end(); it != end; ++it )
582  {
583  if( ((*it)->*f)() )
584  {
585  ++count;
586  }
587  }
588  return count;
589 }
590 
591 #else
592 
593 template<typename T, typename Fn>
594 int CountIfOverList(const ::std::vector<T>& list, Fn f)
595 {
596  int count = 0;
597  for(typename ::std::vector<T>::const_iterator it = list.begin(), end = list.end(); it != end; ++it)
598  {
599  if(((*it)->*f)())
600  {
601  ++count;
602  }
603  }
604  return count;
605 }
606 
607 #endif
608 
612 #if IUTEST_USE_OWN_LIST
613 
614 template<typename Node, typename Fn>
615 bool AnyOverList(const iu_list<Node>& list, Fn f)
616 {
617  for( typename iu_list<Node>::const_iterator it = list.begin(), end=list.end(); it != end; ++it )
618  {
619  if( ((*it)->*f)() )
620  {
621  return true;
622  }
623  }
624  return false;
625 }
626 
627 #else
628 
629 template<typename T, typename Fn>
630 bool AnyOverList(const ::std::vector<T>& list, Fn f)
631 {
632  for(typename ::std::vector<T>::const_iterator it = list.begin(), end = list.end(); it != end; ++it)
633  {
634  if(((*it)->*f)())
635  {
636  return true;
637  }
638  }
639  return false;
640 }
641 
642 #endif
643 
644 IUTEST_PRAGMA_WARN_POP()
645 
646 } // end of namespace detail
647 } // end of namespace iutest
648 
649 
650 #endif // INCG_IRIS_IUTEST_LIST_HPP_CB5AECEA_6147_4A89_BB97_236338CA177E_
iutest_config.hpp
iris unit test config
IUTEST_CXX_NOEXCEPT_SPEC
#define IUTEST_CXX_NOEXCEPT_SPEC
noexcept specification definition
Definition: iutest_compiler.hpp:734
iutest
iutest root namespace
Definition: iutest_charcode.hpp:31