1 // -*- C++ -*-
2 
3 // Copyright (C) 2005-2020 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the terms
7 // of the GNU General Public License as published by the Free Software
8 // Foundation; either version 3, or (at your option) any later
9 // version.
10 
11 // This library is distributed in the hope that it will be useful, but
12 // WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // General Public License for more details.
15 
16 // You should have received a copy of the GNU General Public License
17 // along with this library; see the file COPYING3.  If not see
18 // <http://www.gnu.org/licenses/>.
19 
20 
21 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
22 
23 // Permission to use, copy, modify, sell, and distribute this software
24 // is hereby granted without fee, provided that the above copyright
25 // notice appears in all copies, and that both that copyright notice
26 // and this permission notice appear in supporting documentation. None
27 // of the above authors, nor IBM Haifa Research Laboratories, make any
28 // representation about the suitability of this software for any
29 // purpose. It is provided "as is" without express or implied
30 // warranty.
31 
32 /**
33  * @file container_rand_regression_test.tcc
34  * Contains a random regression test for a specific container type.
35  */
36 
37 #ifndef PB_DS_CONTAINER_RAND_REGRESSION_TEST_TCC
38 #define PB_DS_CONTAINER_RAND_REGRESSION_TEST_TCC
39 
40   // Constructor, copy constructor, assignment and destructor.
41 PB_DS_CLASS_T_DEC
42 PB_DS_CLASS_C_DEC::
container_rand_regression_test(unsigned long seed,size_t n,size_t m,double tp,double ip,double dp,double ep,double cp,double mp,bool disp)43 container_rand_regression_test(unsigned long seed, size_t n, size_t m,
44 			       double tp, double ip, double dp, double ep,
45 			       double cp, double mp, bool disp)
46 : m_seed(seed == 0 ? twister_rand_gen::get_time_determined_seed(): seed),
47   m_n(n), m_m(m), m_tp(tp), m_ip(ip), m_dp(dp), m_ep(ep), m_cp(cp),
48   m_mp(mp), m_disp(disp), m_p_c(0)
49 { }
50 
51 PB_DS_CLASS_T_DEC
52 PB_DS_CLASS_C_DEC::
~container_rand_regression_test()53 ~container_rand_regression_test()
54 { }
55 
56 PB_DS_CLASS_T_DEC
57 bool
58 PB_DS_CLASS_C_DEC::
default_constructor()59 default_constructor()
60 {
61   PB_DS_TRACE("default_constructor");
62   bool done = true;
63   m_alloc.set_probability(m_tp);
64 
65   try
66     {
67       m_p_c = new Cntnr;
68     }
69   catch(__gnu_cxx::forced_error&)
70     {
71       done = false;
72     }
73 
74   if (m_p_c)
75     PB_DS_COND_COMPARE(*m_p_c, m_native_c);
76 
77   return done;
78 }
79 
80 PB_DS_CLASS_T_DEC
81 void
82 PB_DS_CLASS_C_DEC::
swap()83 swap()
84 {
85   PB_DS_TRACE("swap");
86   m_alloc.set_probability(0);
87   Cntnr* p_c = new Cntnr;
88   m_alloc.set_probability(1);
89   p_c->swap(*m_p_c);
90   std::swap(p_c, m_p_c);
91   delete p_c;
92   PB_DS_COND_COMPARE(*m_p_c, m_native_c);
93 }
94 
95 PB_DS_CLASS_T_DEC
96 bool
97 PB_DS_CLASS_C_DEC::
copy_constructor()98 copy_constructor()
99 {
100   PB_DS_TRACE("copy_constructor");
101   bool done = true;
102   Cntnr* p_c = 0;
103   m_alloc.set_probability(m_tp);
104 
105   typedef typename allocator_type::group_adjustor adjustor;
106   adjustor adjust(m_p_c->size());
107 
108   try
109     {
110       p_c = new Cntnr(*m_p_c);
111       std::swap(p_c, m_p_c);
112     }
113   catch(__gnu_cxx::forced_error&)
114     {
115       done = false;
116     }
117 
118   delete p_c;
119   PB_DS_COND_COMPARE(*m_p_c, m_native_c);
120   return done;
121 }
122 
123 PB_DS_CLASS_T_DEC
124 bool
125 PB_DS_CLASS_C_DEC::
assignment_operator()126 assignment_operator()
127 {
128   PB_DS_TRACE("assignment operator");
129   bool done = true;
130   Cntnr* p_c = 0;
131   m_alloc.set_probability(m_tp);
132 
133   typedef typename allocator_type::group_adjustor adjustor;
134   adjustor adjust(m_p_c->size());
135 
136   try
137     {
138       p_c = new Cntnr();
139       *p_c = *m_p_c;
140       std::swap(p_c, m_p_c);
141     }
142   catch(__gnu_cxx::forced_error&)
143     {
144       done = false;
145     }
146 
147   delete p_c;
148   PB_DS_COND_COMPARE(*m_p_c, m_native_c);
149   return done;
150 }
151 
152 PB_DS_CLASS_T_DEC
153 bool
154 PB_DS_CLASS_C_DEC::
it_constructor()155 it_constructor()
156 {
157   bool done = true;
158   Cntnr* p_c = 0;
159   m_alloc.set_probability(m_tp);
160   typedef typename allocator_type::group_adjustor adjustor;
161   adjustor adjust(m_p_c->size());
162 
163   try
164     {
165       switch(get_next_sub_op(3))
166         {
167         case 0:
168 	  p_c = new Cntnr(m_p_c->get_cmp_fn());
169 	  m_native_c.clear();
170 	  break;
171         case 1:
172 	  p_c = new Cntnr(m_p_c->begin(), m_p_c->end());
173 	  break;
174         case 2:
175 	  p_c = new Cntnr(m_p_c->begin(), m_p_c->end(), m_p_c->get_cmp_fn());
176 	  break;
177         default:
178 	  _GLIBCXX_THROW_IF(true, "", m_p_c, &m_native_c);
179         };
180 
181       std::swap(p_c, m_p_c);
182     }
183   catch(__gnu_cxx::forced_error&)
184     {
185       done = false;
186     }
187 
188   delete p_c;
189   PB_DS_COND_COMPARE(*m_p_c, m_native_c);
190   return done;
191 }
192 
193 
194   // Compare.
195 PB_DS_CLASS_T_DEC
196 void
197 PB_DS_CLASS_C_DEC::
cmp(const Cntnr & c,const native_type & native,const std::string & callfn)198 cmp(const Cntnr& c, const native_type& native, const std::string& callfn)
199 {
200   destructor_printer notify(__FUNCTION__);
201 
202   try
203     {
204       m_alloc.set_probability(1);
205 
206       const size_t size = c.size();
207       const size_t native_size = native.size();
208       _GLIBCXX_THROW_IF(size != native_size, size << " " << native_size,
209 			&c, &native);
210 
211       const bool empty = c.empty();
212       const bool native_empty = native.empty();
213       _GLIBCXX_THROW_IF(empty != native_empty, empty << " " << native_empty,
214 			&c, &native);
215 
216       const size_t it_size = std::distance(c.begin(), c.end());
217       _GLIBCXX_THROW_IF(it_size != size, it_size << " " << size, &c, &native);
218 
219       if (!c.empty())
220 	{
221 	  const std::string native_top = native.top();
222 	  const std::string top = test_traits::native_value(c.top());
223 	  const bool top_smaller = std::less<std::string>()(top, native_top);
224 	  const bool top_larger = std::less<std::string>()(native_top, top);
225 
226 	  if (top_smaller || top_larger)
227 	    _GLIBCXX_THROW_IF(true, top << " " << native_top, &c, &native);
228 	}
229     }
230   catch(...)
231     {
232       _GLIBCXX_THROW_IF(true, "call-fn: " + callfn, &c, &native);
233     }
234 
235   notify.cancel();
236 }
237 
238   // Operators.
239 PB_DS_CLASS_T_DEC
240 void
241 PB_DS_CLASS_C_DEC::
operator ()()242 operator()()
243 {
244   typedef xml_result_set_regression_formatter formatter_type;
245   formatter_type* p_fmt = 0;
246   if (m_disp)
247     p_fmt = new formatter_type(string_form<Cntnr>::name(),
248 			       string_form<Cntnr>::desc());
249 
250   m_g.init(m_seed);
251   m_alloc.seed(m_seed);
252 
253   // The __throw_allocator::_S_label defaults to 0, so to make things
254   // easier and more precise when debugging, start at 1.
255   const size_t starting_label(1);
256 
257   try
258     {
259       prog_bar pb(m_n, std::cout, m_disp);
260 
261       for (m_i = starting_label; m_i <= m_n; ++m_i)
262         {
263 	  PB_DS_TRACE("Op #" << m_i);
264 
265 	  // Track allocation from this point only.
266 	  allocator_type::set_label(m_i);
267 	  switch(m_i)
268             {
269             case 1:
270 	      PB_DS_RUN_MTHD(default_constructor);
271 	      break;
272             case 2:
273 	      defs();
274 	      break;
275             case 3:
276 	      policy_access();
277 	      break;
278             case 4:
279 	      it_copy();
280 	      break;
281             case 5:
282 	      it_assign();
283 	      break;
284             default:
285 	      switch(get_next_op())
286                 {
287                 case insert_op:
288 		  PB_DS_RUN_MTHD(push)
289                     break;
290                 case modify_op:
291 		  PB_DS_RUN_MTHD(modify)
292                     break;
293                 case erase_op:
294 		  switch(get_next_sub_op(3))
295                     {
296                     case 0:
297 		      PB_DS_RUN_MTHD(pop)
298                         break;
299                     case 1:
300 		      PB_DS_RUN_MTHD(erase_if)
301                         break;
302                     case 2:
303 		      PB_DS_RUN_MTHD(erase_it)
304                         break;
305                     default:
306 		      _GLIBCXX_THROW_IF(true, "", m_p_c, &m_native_c);
307                     }
308 		  break;
309                 case clear_op:
310 		  PB_DS_RUN_MTHD(clear)
311                     break;
312                 case other_op:
313 		  switch(get_next_sub_op(5))
314                     {
315                     case 0:
316 		      swap();
317 		      break;
318                     case 1:
319 		      PB_DS_RUN_MTHD(copy_constructor)
320                         break;
321                     case 2:
322 		      PB_DS_RUN_MTHD(it_constructor)
323                         break;
324                     case 3:
325 		      PB_DS_RUN_MTHD(assignment_operator)
326                         break;
327                     case 4:
328 		      PB_DS_RUN_MTHD(split_join)
329                         break;
330                     default:
331 		      _GLIBCXX_THROW_IF(true, "", m_p_c, &m_native_c);
332                     }
333 		  break;
334                 default:
335 		  _GLIBCXX_THROW_IF(true, "", m_p_c,  &m_native_c);
336                 };
337             }
338 	  pb.inc();
339         }
340     }
341   catch (...)
342     {
343       std::cerr << "Failed at index " << m_i << std::endl;
344       delete m_p_c;
345       throw;
346     }
347 
348   // Clean up, then check for allocation by special label, set above.
349   allocator_type::set_label(0);
350   delete m_p_c;
351 
352   try
353     {
354       for (size_t n = starting_label; n <= m_n; ++n)
355 	m_alloc.check(n);
356     }
357   catch (std::logic_error& obj)
358     {
359       // On fail, check should throw std::logic_error.
360       std::cerr << obj.what() << std::endl;
361       std::cerr << typeid(Cntnr).name() << std::endl;
362       throw;
363     }
364 
365   // Reset throw probability.
366   m_alloc.set_probability(0);
367 
368   if (m_disp)
369     {
370       std::cout << std::endl;
371       delete p_fmt;
372     }
373 }
374 
375 PB_DS_CLASS_T_DEC
376 typename PB_DS_CLASS_C_DEC::op
377 PB_DS_CLASS_C_DEC::
get_next_op()378 get_next_op()
379 {
380   const double prob = m_g.get_prob();
381 
382   if (prob < m_ip)
383     return insert_op;
384 
385   if (prob < m_ip + m_dp)
386     return modify_op;
387 
388   if (prob < m_ip + m_dp + m_ep)
389     return erase_op;
390 
391   if (prob < m_ip + m_dp + m_ep + m_cp)
392     return clear_op;
393 
394   _GLIBCXX_THROW_IF(prob > 1, prob, m_p_c, &m_native_c);
395   return other_op;
396 }
397 
398 PB_DS_CLASS_T_DEC
399 size_t
400 PB_DS_CLASS_C_DEC::
get_next_sub_op(size_t max)401 get_next_sub_op(size_t max)
402 {
403   const double p = m_g.get_prob();
404   const double delta = 1 / static_cast<double>(max);
405   size_t i = 0;
406   while (true)
407     if (p <= (i + 1) * delta)
408       {
409 	_GLIBCXX_THROW_IF(i >= max, i << " " << max, m_p_c, &m_native_c);
410 	return i;
411       }
412     else
413       ++i;
414 }
415 
416   // Insert.
417 PB_DS_CLASS_T_DEC
418 bool
419 PB_DS_CLASS_C_DEC::
push()420 push()
421 {
422   PB_DS_TRACE("push");
423   bool done = true;
424   destructor_printer notify(__FUNCTION__);
425 
426     try
427       {
428         m_alloc.set_probability(0);
429         value_type v = test_traits::generate_value(m_g, m_m);
430         m_alloc.set_probability(m_tp);
431         const typename cntnr::size_type sz = m_p_c->size();
432         m_p_c->push(v);
433         _GLIBCXX_THROW_IF(sz != m_p_c->size() - 1, sz, m_p_c, &m_native_c);
434         m_native_c.push(test_traits::native_value(v));
435       }
436     catch(__gnu_cxx::forced_error&)
437       {
438         done = false;
439       }
440     catch(...)
441       {
442         _GLIBCXX_THROW_IF(true, "", m_p_c, &m_native_c);
443       }
444 
445   PB_DS_COND_COMPARE(*m_p_c, m_native_c);
446   notify.cancel();
447   return done;
448 }
449 
450 
451   // Modify.
452 PB_DS_CLASS_T_DEC
453 bool
454 PB_DS_CLASS_C_DEC::
modify()455 modify()
456 {
457   PB_DS_TRACE("modify");
458   destructor_printer notify(__FUNCTION__);
459 
460   bool done = true;
461   try
462     {
463       m_alloc.set_probability(0);
464       value_type v = test_traits::generate_value(m_g, m_m);
465 
466       m_alloc.set_probability(m_tp);
467       typename cntnr::iterator it = m_p_c->begin();
468       std::advance(it, m_g.get_unsigned_long(0, m_p_c->size()));
469       if (it != m_p_c->end())
470 	{
471 	  typedef typename test_traits::native_value_type native_value_type;
472 	  native_value_type native_v = test_traits::native_value(*it);
473 	  native_value_type new_native_v = test_traits::native_value(v);
474 	  m_p_c->modify(it, v);
475 	  m_native_c.modify(native_v, new_native_v);
476 	}
477     }
478   catch(__gnu_cxx::forced_error&)
479     {
480       done = false;
481       _GLIBCXX_THROW_IF(true, "", m_p_c, &m_native_c);
482     }
483 
484   PB_DS_COND_COMPARE(*m_p_c, m_native_c);
485   notify.cancel();
486   return done;
487 }
488 
489   // Clear.
490 PB_DS_CLASS_T_DEC
491 bool
492 PB_DS_CLASS_C_DEC::
clear()493 clear()
494 {
495   PB_DS_TRACE("clear");
496   m_p_c->clear();
497   m_native_c.clear();
498   return true;
499 }
500 
501   // Erase.
502 PB_DS_CLASS_T_DEC
503 bool
504 PB_DS_CLASS_C_DEC::
pop()505 pop()
506 {
507   PB_DS_TRACE("pop");
508   destructor_printer notify(__FUNCTION__);
509 
510   bool done = true;
511   try
512     {
513       m_alloc.set_probability(1);
514       if (!m_p_c->empty())
515         {
516 	  m_p_c->pop();
517 	  m_native_c.pop();
518         }
519     }
520   catch(__gnu_cxx::forced_error&)
521     {
522       done = false;
523       _GLIBCXX_THROW_IF(true, "", m_p_c, &m_native_c);
524     }
525 
526   PB_DS_COND_COMPARE(*m_p_c, m_native_c);
527   notify.cancel();
528   return done;
529 }
530 
531 PB_DS_CLASS_T_DEC
532 bool
533 PB_DS_CLASS_C_DEC::
erase_if()534 erase_if()
535 {
536   PB_DS_TRACE("erase_if");
537   destructor_printer notify(__FUNCTION__);
538 
539   bool done = true;
540   try
541     {
542       typedef
543 	typename std::iterator_traits<typename cntnr::iterator>::reference
544 	it_const_reference;
545 
546       m_alloc.set_probability(1);
547 
548       typedef
549 	typename test_traits::template erase_if_fn<value_type>
550 	erase_if_fn_t;
551 
552       const size_t ersd = m_p_c->erase_if(erase_if_fn_t());
553 
554       typedef
555 	typename test_traits::template erase_if_fn<std::string>
556 	native_erase_if_fn_t;
557 
558       const size_t native_ersd = m_native_c.erase_if(native_erase_if_fn_t());
559 
560       _GLIBCXX_THROW_IF(ersd != native_ersd, ersd << " " << native_ersd,
561 			m_p_c, &m_native_c);
562     }
563   catch(__gnu_cxx::forced_error&)
564     {
565       done = false;
566       _GLIBCXX_THROW_IF(true, "", m_p_c, &m_native_c);
567     }
568 
569   PB_DS_COND_COMPARE(*m_p_c, m_native_c);
570   notify.cancel();
571   return done;
572 }
573 
574 PB_DS_CLASS_T_DEC
575 bool
576 PB_DS_CLASS_C_DEC::
erase_it()577 erase_it()
578 {
579   PB_DS_TRACE("erase_it");
580   destructor_printer notify(__FUNCTION__);
581 
582   bool done = true;
583   try
584     {
585       m_alloc.set_probability(1);
586       typename cntnr::iterator it = m_p_c->begin();
587       std::advance(it, m_g.get_unsigned_long(0, m_p_c->size()));
588 
589       if (it != m_p_c->end())
590 	{
591 	  m_native_c.erase(*it);
592 	  m_p_c->erase(it);
593 	}
594     }
595   catch(__gnu_cxx::forced_error&)
596     {
597       done = false;
598       _GLIBCXX_THROW_IF(true, "", m_p_c, &m_native_c);
599     }
600 
601   PB_DS_COND_COMPARE(*m_p_c, m_native_c);
602   notify.cancel();
603   return done;
604 }
605 
606   // Defs.
607 PB_DS_CLASS_T_DEC
608 void
609 PB_DS_CLASS_C_DEC::
defs()610 defs()
611 {
612   // General container types.
613   typedef typename Cntnr::size_type test_size_type;
614   typedef typename Cntnr::difference_type difference_type;
615   value_defs();
616   iterator_defs();
617   policy_defs();
618 }
619 
620 PB_DS_CLASS_T_DEC
621 void
622 PB_DS_CLASS_C_DEC::
value_defs()623 value_defs()
624 {
625   typedef typename Cntnr::value_type test_value_type;
626   typedef typename Cntnr::reference test_reference;
627   typedef typename Cntnr::const_reference test_const_reference;
628   typedef typename Cntnr::pointer test_pointer;
629   typedef typename Cntnr::const_pointer test_const_pointer;
630 }
631 
632 PB_DS_CLASS_T_DEC
633 void
634 PB_DS_CLASS_C_DEC::
ds_defs()635 ds_defs()
636 {
637   typedef typename Cntnr::container_category test_container_category;
638 }
639 
640 PB_DS_CLASS_T_DEC
641 void
642 PB_DS_CLASS_C_DEC::
iterator_defs()643 iterator_defs()
644 {
645   typedef typename Cntnr::point_iterator test_point_iterator;
646   typedef typename Cntnr::point_const_iterator const_test_point_iterator;
647   typedef typename Cntnr::iterator test_iterator;
648   typedef typename Cntnr::const_iterator const_test_iterator;
649 }
650 
651 PB_DS_CLASS_T_DEC
652 void
653 PB_DS_CLASS_C_DEC::
policy_defs()654 policy_defs()
655 {
656   typedef typename Cntnr::allocator_type test_allocator;
657   typedef typename Cntnr::cmp_fn test_cmp_fn;
658 }
659 
660 
661 // Policy access.
662 PB_DS_CLASS_T_DEC
663 void
664 PB_DS_CLASS_C_DEC::
policy_access()665 policy_access()
666 {
667   PB_DS_TRACE("policy_access");
668 
669   {
670     typename Cntnr::cmp_fn& r_t = m_p_c->get_cmp_fn();
671     assert(&r_t);
672   }
673 
674   {
675     const typename Cntnr::cmp_fn& r_t =((const Cntnr& )*m_p_c).get_cmp_fn();
676     assert(&r_t);
677   }
678 }
679 
680 // Split join.
681 PB_DS_CLASS_T_DEC
682 bool
683 PB_DS_CLASS_C_DEC::
split_join()684 split_join()
685 {
686   PB_DS_TRACE("split_join");
687   destructor_printer notify(__FUNCTION__);
688 
689   bool done = true;
690   try
691     {
692       m_alloc.set_probability(0);
693       Cntnr lhs(*m_p_c);
694       Cntnr rhs;
695       native_type native_lhs(m_native_c);
696       m_alloc.set_probability(m_tp);
697 
698       typedef typename test_traits::template erase_if_fn<value_type> split_fn_t;
699       lhs.split(split_fn_t(), rhs);
700 
701       typedef typename test_traits::template erase_if_fn<std::string>
702 	native_split_fn_t;
703 
704       native_type native_rhs;
705       native_lhs.split(native_split_fn_t(), native_rhs);
706       PB_DS_COND_COMPARE(lhs, native_lhs);
707       PB_DS_COND_COMPARE(rhs, native_rhs);
708 
709       m_alloc.set_probability(m_tp);
710 
711       if (m_g.get_prob() < 0.5)
712 	lhs.swap(rhs);
713       lhs.join(rhs);
714 
715       _GLIBCXX_THROW_IF(rhs.size() != 0, rhs.size(), m_p_c, &m_native_c);
716       _GLIBCXX_THROW_IF(!rhs.empty(), rhs.size(), m_p_c, &m_native_c);
717     }
718   catch(__gnu_cxx::forced_error&)
719     {
720       done = false;
721       const bool b = __gnu_pbds::container_traits<cntnr>::split_join_can_throw;
722       _GLIBCXX_THROW_IF(!b, b, m_p_c, &m_native_c);
723     }
724 
725   PB_DS_COND_COMPARE(*m_p_c, m_native_c);
726   notify.cancel();
727   return done;
728 }
729 
730 // Iterator conversions.
731 PB_DS_CLASS_T_DEC
732 void
733 PB_DS_CLASS_C_DEC::
it_copy()734 it_copy()
735 {
736   PB_DS_TRACE("it_copy");
737 
738   {
739     typename cntnr::iterator it = m_p_c->end();
740     typename cntnr::const_iterator const_it(it);
741     _GLIBCXX_THROW_IF(const_it != it, "", m_p_c, &m_native_c);
742     _GLIBCXX_THROW_IF(!(const_it == it), "", m_p_c, &m_native_c);
743   }
744 
745   {
746     typename cntnr::const_iterator const_it = m_p_c->end();
747     typename cntnr::point_const_iterator const_find_it(const_it);
748     _GLIBCXX_THROW_IF(const_find_it != const_it, "", m_p_c, &m_native_c);
749     _GLIBCXX_THROW_IF(!(const_find_it == const_it), "", m_p_c, &m_native_c);
750   }
751 
752   {
753     typename cntnr::iterator it = m_p_c->end();
754     typename cntnr::point_const_iterator const_find_it1(it);
755     _GLIBCXX_THROW_IF(const_find_it1 != it, "", m_p_c, &m_native_c);
756     _GLIBCXX_THROW_IF(!(const_find_it1 == it), "", m_p_c, &m_native_c);
757 
758     typename cntnr::point_iterator find_it1(it);
759     _GLIBCXX_THROW_IF(find_it1 != it, "", m_p_c, &m_native_c);
760     _GLIBCXX_THROW_IF(!(find_it1 == it), "", m_p_c, &m_native_c);
761 
762     typename cntnr::point_iterator find_it = m_p_c->end();
763     typename cntnr::point_const_iterator const_find_it(find_it);
764     _GLIBCXX_THROW_IF(find_it != const_find_it, "", m_p_c, &m_native_c);
765     _GLIBCXX_THROW_IF(!(find_it == const_find_it), "", m_p_c, &m_native_c);
766   }
767 }
768 
769 PB_DS_CLASS_T_DEC
770 void
771 PB_DS_CLASS_C_DEC::
it_assign()772 it_assign()
773 {
774   PB_DS_TRACE("it_assign");
775 
776   {
777     typename cntnr::iterator it = m_p_c->end();
778     typename cntnr::const_iterator const_it;
779     const_it = it;
780     _GLIBCXX_THROW_IF(const_it != it, "", m_p_c, &m_native_c);
781     _GLIBCXX_THROW_IF(!(const_it == it), "", m_p_c, &m_native_c);
782 
783     typename cntnr::point_const_iterator const_find_it;
784     const_find_it = it;
785     _GLIBCXX_THROW_IF(const_find_it != it, "", m_p_c, &m_native_c);
786     _GLIBCXX_THROW_IF(!(const_find_it == it), "", m_p_c, &m_native_c);
787 
788     typename cntnr::point_iterator find_it;
789     find_it = it;
790     _GLIBCXX_THROW_IF(find_it != it, "", m_p_c, &m_native_c);
791     _GLIBCXX_THROW_IF(!(find_it == it), "", m_p_c, &m_native_c);
792   }
793 
794   {
795     typename cntnr::const_iterator const_it = m_p_c->end();
796     typename cntnr::point_const_iterator const_find_it;
797     const_find_it = const_it;
798     _GLIBCXX_THROW_IF(const_find_it != const_it, "", m_p_c, &m_native_c);
799     _GLIBCXX_THROW_IF(!(const_find_it == const_it), "", m_p_c, &m_native_c);
800   }
801 
802   {
803     typename cntnr::point_iterator find_it = m_p_c->end();
804     typename cntnr::point_const_iterator const_find_it;
805     const_find_it = find_it;
806     _GLIBCXX_THROW_IF(find_it != const_find_it, "", m_p_c, &m_native_c);
807     _GLIBCXX_THROW_IF(!(find_it == const_find_it), "", m_p_c, &m_native_c);
808   }
809 }
810 
811 
812 // Diagnostics.
813 PB_DS_CLASS_T_DEC
814 void
815 PB_DS_CLASS_C_DEC::
print_container(const native_type & cnt,std::ostream & os) const816 print_container(const native_type& cnt, std::ostream& os) const
817 {
818   m_alloc.set_probability(0);
819   native_type cpy(cnt);
820   while (!cpy.empty())
821     {
822       os << cpy.top() << std::endl;
823       cpy.pop();
824     }
825 }
826 
827 PB_DS_CLASS_T_DEC
828 void
829 PB_DS_CLASS_C_DEC::
print_container(const cntnr & cnt,std::ostream & os) const830 print_container(const cntnr& cnt, std::ostream& os) const
831 {
832   typedef typename cntnr::const_iterator const_iterator;
833   m_alloc.set_probability(0);
834   for (const_iterator it = cnt.begin(); it != cnt.end(); ++it)
835     os << *it << std::endl;
836 }
837 
838 #endif
839