// -*- C++ -*- // Copyright (C) 2005, 2006, 2008, 2009 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the terms // of the GNU General Public License as published by the Free Software // Foundation; either version 3, or (at your option) any later // version. // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // You should have received a copy of the GNU General Public License // along with this library; see the file COPYING3. If not see // . // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL. // Permission to use, copy, modify, sell, and distribute this software // is hereby granted without fee, provided that the above copyright // notice appears in all copies, and that both that copyright notice // and this permission notice appear in supporting documentation. None // of the above authors, nor IBM Haifa Research Laboratories, make any // representation about the suitability of this software for any // purpose. It is provided "as is" without express or implied // warranty. /** * @file container_rand_regression_test.h * Contains a random regression test for a specific container type. */ #ifndef PB_DS_CONTAINER_RAND_REGRESSION_TEST_H #define PB_DS_CONTAINER_RAND_REGRESSION_TEST_H #include #include #include #include #include #include #include #include #include #include #include #include namespace __gnu_pbds { namespace test { namespace detail { // Rand test specialized for a specific container. template class container_rand_regression_test { private: typedef Cntnr cntnr; typedef typename cntnr::allocator_type allocator_type; typedef typename cntnr::size_type size_type; typedef twister_rand_gen gen; typedef basic_type value_type; typedef native_priority_queue native_type; typedef regression_test_traits test_traits; enum op { insert_op, modify_op, erase_op, clear_op, other_op }; op get_next_op(); size_t get_next_sub_op(size_t max); static void defs(); static void value_defs(); static void ds_defs(); static void iterator_defs(); static void policy_defs(); void policy_access(); void it_copy(); void it_assign(); bool default_constructor(); void swap(); bool copy_constructor(); bool assignment_operator(); bool it_constructor(); bool push(); bool modify(); bool pop(); bool erase_if(); bool erase_it(); bool clear(); bool split_join(); void cmp(const Cntnr& r_container, const native_type& r_native_c, const std::string& r_call_fn); void print_container(const native_type& r_cnt, std::ostream& r_os = std::cerr) const; void print_container(const cntnr& r_cnt, std::ostream& r_os = std::cerr) const; struct destructor_printer { destructor_printer(const std::string& r_msg) : m_msg(r_msg), m_print(true) { } void cancel() { m_print = false; } ~destructor_printer() { if (m_print) { std::cerr << std::endl << "Uncaught exception: " << std::endl << m_msg << std::endl; } } const std::string m_msg; bool m_print; }; const unsigned long m_seed; const size_t m_n; const size_t m_m; const double m_tp; const double m_ip; const double m_dp; const double m_ep; const double m_cp; const double m_mp; const bool m_disp; twister_rand_gen m_g; Cntnr* m_p_c; native_type m_native_c; allocator_type m_alloc; size_t m_i; public: 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); virtual ~container_rand_regression_test(); void operator()(); }; #ifdef PB_DS_REGRESSION_TRACE # define PB_DS_TRACE(X) std::cerr << X << std::endl #else # define PB_DS_TRACE(X) #endif #define PB_DS_CLASS_T_DEC \ template #define PB_DS_CLASS_C_DEC \ container_rand_regression_test #define PB_DS_COND_COMPARE(L, R) \ if (m_g.get_prob() < m_mp) \ cmp(L, R, __FUNCTION__); #define PB_DS_RUN_MTHD(MTHD) \ { \ bool done = false; \ while (!done) \ done = MTHD(); \ } #define _GLIBCXX_THROW_IF_(PRED, MORE, P_C, P_NC, F, L) \ if (PRED) \ { \ std::cerr << "Failure at " << F << ": " << L << std::endl; \ std::cerr << MORE << std::endl; \ std::cerr << "container:" << std::endl; \ print_container(*(P_C)); \ std::cerr << std::endl; \ std::cerr << "native container:" << std::endl; \ print_container(*(P_NC)); \ std::cerr << std::endl; \ throw std::logic_error("pbds throw if failed"); \ } #define _GLIBCXX_THROW_IF(PRED, MORE, P_C, P_NC) \ _GLIBCXX_THROW_IF_(PRED, MORE, P_C, P_NC, __FILE__, __LINE__) #include #undef PB_DS_COND_COMPARE #undef PB_DS_RUN_MTHD #undef PB_DS_CLASS_T_DEC #undef PB_DS_CLASS_C_DEC #undef _GLIBCXX_THROW_IF_ #undef _GLIBCXX_THROW_IF #undef PB_DS_TRACE } // namespace detail } // namespace test } // namespace __gnu_pbds #endif