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_ASSOC_RAND_REGRESSION_TEST_HPP 38 #define PB_DS_ASSOC_RAND_REGRESSION_TEST_HPP 39 40 #include <iostream> 41 #include <vector> 42 #include <regression/rand/assoc/container_rand_regression_test.h> 43 #include <io/verified_cmd_line_input.hpp> 44 #include <common_type/assoc/common_type.hpp> 45 #include <regression/basic_type.hpp> 46 #include <regression/common_type.hpp> 47 48 namespace __gnu_pbds 49 { 50 namespace test 51 { 52 namespace detail 53 { 54 #ifndef PB_DS_REGRESSION 55 #error "Must define PB_DS_REGRESSION" 56 #endif 57 58 struct rand_reg_test 59 { 60 public: rand_reg_test__gnu_pbds::test::detail::rand_reg_test61 rand_reg_test(size_t seed, size_t n, size_t m, double tp, double ip, 62 double ep, double cp, double mp, bool d) 63 : m_sd(seed), m_n(n), m_m(m), m_tp(tp), m_ip(ip), m_ep(ep), m_cp(cp), 64 m_mp(mp), m_disp(d) 65 { 66 if (m_disp) 67 xml_test_rand_regression_formatter(seed, n, m, tp, ip, ep, cp, mp); 68 } 69 70 template<typename Cntnr> 71 void operator ()__gnu_pbds::test::detail::rand_reg_test72 operator()(Cntnr) 73 { 74 unsigned long ul = static_cast<unsigned long>(m_sd); 75 container_rand_regression_test<Cntnr> t(ul, m_n, m_n, m_tp, m_ip, 76 m_ep, m_cp, m_mp, m_disp); 77 t(); 78 } 79 80 private: 81 const size_t m_sd; 82 const size_t m_n; 83 const size_t m_m; 84 const double m_tp; 85 const double m_ip; 86 const double m_ep; 87 const double m_cp; 88 const double m_mp; 89 const bool m_disp; 90 }; 91 92 void 93 usage(const std::string& r_name); 94 95 void 96 verify_params(size_t&, size_t&, size_t&, 97 double&, double&, double&, double&, double&, bool&); 98 } // namespace detail 99 100 template<typename TL> 101 int rand_regression_test(size_t iter,size_t keys,const std::string name,TL tl)102 rand_regression_test(size_t iter, size_t keys, const std::string name, TL tl) 103 { 104 // Sane defaults. 105 size_t n = iter; 106 size_t m = keys; 107 size_t sd = twister_rand_gen::get_time_determined_seed(); 108 double tp = 0.2; 109 double ip = 0.6; 110 double ep = 0.2; 111 double cp = 0.001; 112 double mp = 0.25; 113 bool disp = true; // show progress 114 115 try 116 { 117 detail::verify_params(sd, n, m, tp, ip, 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, 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 150 << " <sd> <n> <m> <tp> <ip> <ep> <cp> <mp> ['t' | 'f']" 151 << endl << endl; 152 153 cerr << "This test performs basic regression tests on various associative containers." 154 "For each container, it performs a sequence of operations. At each iteration, it does " 155 "the following: " << endl; 156 cerr << "* Performs an operation on the container " << endl; 157 cerr << "* Performs the same operation on an cntnr object" << endl; 158 cerr << "* Possibly compares the container to the cntnr object" << endl; 159 cerr << "* Checks that exceptions (thrown by an allocator) " 160 "do not violate exception guarantees"; 161 162 cerr << endl << endl; 163 164 cerr << "sd = seed for random-number generator; " 165 "0 = time determined value" << endl; 166 cerr << "n = number of iterations" << endl; 167 cerr << "m = number of distinct values" << endl; 168 cerr << "tp = probability that an exception will be actively thrown" << endl; 169 cerr << "ip = probability that an operation will be insert" << 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 + 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_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_ep, 180 double& r_cp, double& r_mp, bool& r_d) 181 { 182 verify_prob(r_tp); 183 verify_prob(r_ip); 184 verify_prob(r_ep); 185 verify_prob(r_cp); 186 verify_prob(r_mp); 187 verify_prob(r_ip + r_ep + r_cp); 188 } 189 } // namespace detail 190 } // namespace test 191 } // namespace __gnu_pbds 192 193 #endif 194