1 // -*- C++ -*- 2 3 // Copyright (C) 2005-2019 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 rand_regression_test.hpp 34 * Contains a random-operation test. 35 */ 36 37 #ifndef PB_DS_PQ_RAND_REGRESSION_TEST_HPP 38 #define PB_DS_PQ_RAND_REGRESSION_TEST_HPP 39 40 #include <iostream> 41 #include <vector> 42 #include <io/verified_cmd_line_input.hpp> 43 #include <regression/common_type.hpp> 44 #include <regression/rand/priority_queue/container_rand_regression_test.h> 45 46 namespace __gnu_pbds 47 { 48 namespace test 49 { 50 namespace detail 51 { 52 #ifndef PB_DS_REGRESSION 53 #error "Must define PB_DS_REGRESSION" 54 #endif 55 56 struct rand_reg_test 57 { 58 public: rand_reg_test__gnu_pbds::test::detail::rand_reg_test59 rand_reg_test(size_t seed, size_t n, size_t m, double tp, double ip, 60 double dp, double ep, double cp, double mp, bool d) 61 : m_sd(seed), m_n(n), m_m(m), m_tp(tp), m_ip(ip), m_dp(dp), m_ep(ep), 62 m_cp(cp), m_mp(mp), m_disp(d) 63 { 64 if (m_disp) 65 xml_test_rand_regression_formatter(seed, n, m, tp, ip, ep, cp, mp); 66 } 67 68 template<typename Cntnr> 69 void operator ()__gnu_pbds::test::detail::rand_reg_test70 operator()(Cntnr) 71 { 72 unsigned long ul = static_cast<unsigned long>(m_sd); 73 container_rand_regression_test<Cntnr> t(ul, m_n, m_n, m_tp, m_ip, m_dp, 74 m_ep, m_cp, m_mp, m_disp); 75 t(); 76 } 77 78 private: 79 const size_t m_sd; 80 const size_t m_n; 81 const size_t m_m; 82 const double m_tp; 83 const double m_ip; 84 const double m_dp; 85 const double m_ep; 86 const double m_cp; 87 const double m_mp; 88 const bool m_disp; 89 }; 90 91 void 92 usage(const std::string& r_name); 93 94 void 95 verify_params(size_t&, size_t&, size_t&, 96 double&, double&, double&, double&, double&, double&, bool&); 97 } // namespace detail 98 99 template<typename TL> 100 int rand_regression_test(size_t iter,size_t keys,const std::string name,TL tl)101 rand_regression_test(size_t iter, size_t keys, const std::string name, TL tl) 102 { 103 // Sane defaults. 104 size_t n = iter; 105 size_t m = keys; 106 size_t sd = twister_rand_gen::get_time_determined_seed(); 107 double tp = 0.2; 108 double ip = 0.6; 109 double dp = 0.1; 110 double ep = 0.2; 111 double cp = 0.001; 112 double mp = 1; 113 bool disp = true; // show progress 114 115 try 116 { 117 detail::verify_params(sd, n, m, tp, ip, dp, ep, cp, mp, disp); 118 } 119 catch(__gnu_pbds::test::illegal_input_error&) 120 { 121 detail::usage(name); 122 return -1; 123 } 124 catch(...) 125 { 126 return -2; 127 }; 128 129 try 130 { 131 detail::rand_reg_test tst(sd, n, m, tp, ip, dp, ep, cp, mp, disp); 132 __gnu_cxx::typelist::apply(tst, tl); 133 } 134 catch(...) 135 { 136 std::cerr << "Test failed with seed " << sd << std::endl; 137 throw; 138 } 139 140 return 0; 141 } 142 143 namespace detail 144 { 145 inline void usage(const std::string & name)146 usage(const std::string& name) 147 { 148 using namespace std; 149 cerr << "usage: " << name << " <sd> <n> <m> <tp> <ip> <dp> <ep> <cp> <mp> ['t' | 'f']" << 150 endl << endl; 151 152 cerr << "This test performs basic regression tests on various priority queues." 153 "For each container, it performs a sequence of operations. At each iteration, it does " 154 "the following: " << endl; 155 cerr << "* Performs an operation on the container " << endl; 156 cerr << "* Performs the same operation on an cntnr object" << endl; 157 cerr << "* Possibly compares the container to the cntnr object" << endl; 158 cerr << "* Checks that exceptions (thrown by an allocator) " 159 "do not violate exception guarantees"; 160 161 cerr << endl << endl; 162 163 cerr << "sd = seed for random-number generator; 0 = " 164 "time determined value" << endl; 165 cerr << "n = number of iterations" << endl; 166 cerr << "m = number of distinct values" << endl; 167 cerr << "tp = probability that an exception will be actively thrown" << endl; 168 cerr << "ip = probability that an operation will be insert" << endl; 169 cerr << "dp = probability that an operation will be modify" << endl; 170 cerr << "ep = probability that an operation will be erase" << endl; 171 cerr << "cp = probability that an operation will be clear" << endl; 172 cerr << "(therefore, 1 - (ip + dp + ep + cp) = probability of any other operation)" << endl; 173 cerr << "mp = probability that the container will be compared to the cntnr object" << endl; 174 cerr << "'t' or 'f' determine whether progress will be displayed" << endl; 175 } 176 177 inline void verify_params(size_t & r_seed,size_t & r_n,size_t & r_m,double & r_tp,double & r_ip,double & r_dp,double & r_ep,double & r_cp,double & r_mp,bool & r_d)178 verify_params(size_t& r_seed, size_t& r_n, 179 size_t& r_m, double& r_tp, double& r_ip, double& r_dp, 180 double& r_ep, double& r_cp, double& r_mp, bool& r_d) 181 { 182 verify_prob(r_tp); 183 verify_prob(r_ip); 184 verify_prob(r_dp); 185 verify_prob(r_ep); 186 verify_prob(r_cp); 187 verify_prob(r_mp); 188 verify_prob(r_ip + r_dp + r_ep + r_cp); 189 } 190 } // namespace detail 191 } // namespace test 192 } // namespace __gnu_pbds 193 194 #endif 195