throw_allocator.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026
  1. // -*- C++ -*-
  2. // Copyright (C) 2005-2023 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the terms
  6. // of the GNU General Public License as published by the Free Software
  7. // Foundation; either version 3, or (at your option) any later
  8. // version.
  9. // This library is distributed in the hope that it will be useful, but
  10. // WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. // General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
  21. // Permission to use, copy, modify, sell, and distribute this software
  22. // is hereby granted without fee, provided that the above copyright
  23. // notice appears in all copies, and that both that copyright notice
  24. // and this permission notice appear in supporting documentation. None
  25. // of the above authors, nor IBM Haifa Research Laboratories, make any
  26. // representation about the suitability of this software for any
  27. // purpose. It is provided "as is" without express or implied
  28. // warranty.
  29. /** @file ext/throw_allocator.h
  30. * This file is a GNU extension to the Standard C++ Library.
  31. *
  32. * Contains two exception-generating types (throw_value, throw_allocator)
  33. * intended to be used as value and allocator types while testing
  34. * exception safety in templatized containers and algorithms. The
  35. * allocator has additional log and debug features. The exception
  36. * generated is of type forced_exception_error.
  37. */
  38. #ifndef _THROW_ALLOCATOR_H
  39. #define _THROW_ALLOCATOR_H 1
  40. #include <bits/requires_hosted.h> // GNU extensions are currently omitted
  41. #include <cmath>
  42. #include <ctime>
  43. #include <map>
  44. #include <string>
  45. #include <ostream>
  46. #include <stdexcept>
  47. #include <utility>
  48. #include <bits/functexcept.h>
  49. #include <bits/move.h>
  50. #if __cplusplus >= 201103L
  51. # include <functional>
  52. # include <random>
  53. #else
  54. # include <tr1/functional>
  55. # include <tr1/random>
  56. #endif
  57. #include <ext/alloc_traits.h>
  58. #if !__has_builtin(__builtin_sprintf)
  59. # include <cstdio>
  60. #endif
  61. namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
  62. {
  63. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  64. /**
  65. * @brief Thrown by utilities for testing exception safety.
  66. * @ingroup exceptions
  67. */
  68. struct forced_error : public std::exception
  69. { };
  70. // Substitute for forced_error object when -fno-exceptions.
  71. inline void
  72. __throw_forced_error()
  73. { _GLIBCXX_THROW_OR_ABORT(forced_error()); }
  74. /**
  75. * @brief Base class for checking address and label information
  76. * about allocations. Create a std::map between the allocated
  77. * address (void*) and a datum for annotations, which are a pair of
  78. * numbers corresponding to label and allocated size.
  79. */
  80. struct annotate_base
  81. {
  82. private:
  83. typedef std::pair<size_t, size_t> data_type;
  84. typedef std::map<void*, data_type> map_alloc_type;
  85. typedef map_alloc_type::value_type entry_type;
  86. typedef map_alloc_type::const_iterator const_iterator;
  87. typedef map_alloc_type::const_reference const_reference;
  88. #if __cplusplus >= 201103L
  89. typedef std::map<void*, size_t> map_construct_type;
  90. #endif
  91. public:
  92. annotate_base()
  93. {
  94. label();
  95. map_alloc();
  96. }
  97. static void
  98. set_label(size_t l)
  99. { label() = l; }
  100. static size_t
  101. get_label()
  102. { return label(); }
  103. void
  104. insert(void* p, size_t size)
  105. {
  106. entry_type entry = make_entry(p, size);
  107. if (!p)
  108. {
  109. std::string error("annotate_base::insert null insert!\n");
  110. log_to_string(error, entry);
  111. std::__throw_logic_error(error.c_str());
  112. }
  113. std::pair<map_alloc_type::iterator, bool> inserted
  114. = map_alloc().insert(entry);
  115. if (!inserted.second)
  116. {
  117. std::string error("annotate_base::insert double insert!\n");
  118. log_to_string(error, entry);
  119. log_to_string(error, *inserted.first);
  120. std::__throw_logic_error(error.c_str());
  121. }
  122. }
  123. void
  124. erase(void* p, size_t size)
  125. { map_alloc().erase(check_allocated(p, size)); }
  126. #if __cplusplus >= 201103L
  127. void
  128. insert_construct(void* p)
  129. {
  130. if (!p)
  131. {
  132. std::string error("annotate_base::insert_construct null!\n");
  133. std::__throw_logic_error(error.c_str());
  134. }
  135. auto inserted = map_construct().insert(std::make_pair(p, get_label()));
  136. if (!inserted.second)
  137. {
  138. std::string error("annotate_base::insert_construct double insert!\n");
  139. log_to_string(error, std::make_pair(p, get_label()));
  140. log_to_string(error, *inserted.first);
  141. std::__throw_logic_error(error.c_str());
  142. }
  143. }
  144. void
  145. erase_construct(void* p)
  146. { map_construct().erase(check_constructed(p)); }
  147. #endif
  148. // See if a particular address and allocation size has been saved.
  149. inline map_alloc_type::iterator
  150. check_allocated(void* p, size_t size)
  151. {
  152. map_alloc_type::iterator found = map_alloc().find(p);
  153. if (found == map_alloc().end())
  154. {
  155. std::string error("annotate_base::check_allocated by value "
  156. "null erase!\n");
  157. log_to_string(error, make_entry(p, size));
  158. std::__throw_logic_error(error.c_str());
  159. }
  160. if (found->second.second != size)
  161. {
  162. std::string error("annotate_base::check_allocated by value "
  163. "wrong-size erase!\n");
  164. log_to_string(error, make_entry(p, size));
  165. log_to_string(error, *found);
  166. std::__throw_logic_error(error.c_str());
  167. }
  168. return found;
  169. }
  170. // See if a given label has been allocated.
  171. inline void
  172. check(size_t label)
  173. {
  174. std::string found;
  175. {
  176. const_iterator beg = map_alloc().begin();
  177. const_iterator end = map_alloc().end();
  178. while (beg != end)
  179. {
  180. if (beg->second.first == label)
  181. log_to_string(found, *beg);
  182. ++beg;
  183. }
  184. }
  185. #if __cplusplus >= 201103L
  186. {
  187. auto beg = map_construct().begin();
  188. auto end = map_construct().end();
  189. while (beg != end)
  190. {
  191. if (beg->second == label)
  192. log_to_string(found, *beg);
  193. ++beg;
  194. }
  195. }
  196. #endif
  197. if (!found.empty())
  198. {
  199. std::string error("annotate_base::check by label\n");
  200. error += found;
  201. std::__throw_logic_error(error.c_str());
  202. }
  203. }
  204. // See if there is anything left allocated or constructed.
  205. inline static void
  206. check()
  207. {
  208. std::string found;
  209. {
  210. const_iterator beg = map_alloc().begin();
  211. const_iterator end = map_alloc().end();
  212. while (beg != end)
  213. {
  214. log_to_string(found, *beg);
  215. ++beg;
  216. }
  217. }
  218. #if __cplusplus >= 201103L
  219. {
  220. auto beg = map_construct().begin();
  221. auto end = map_construct().end();
  222. while (beg != end)
  223. {
  224. log_to_string(found, *beg);
  225. ++beg;
  226. }
  227. }
  228. #endif
  229. if (!found.empty())
  230. {
  231. std::string error("annotate_base::check \n");
  232. error += found;
  233. std::__throw_logic_error(error.c_str());
  234. }
  235. }
  236. #if __cplusplus >= 201103L
  237. inline map_construct_type::iterator
  238. check_constructed(void* p)
  239. {
  240. auto found = map_construct().find(p);
  241. if (found == map_construct().end())
  242. {
  243. std::string error("annotate_base::check_constructed not "
  244. "constructed!\n");
  245. log_to_string(error, std::make_pair(p, get_label()));
  246. std::__throw_logic_error(error.c_str());
  247. }
  248. return found;
  249. }
  250. inline void
  251. check_constructed(size_t label)
  252. {
  253. auto beg = map_construct().begin();
  254. auto end = map_construct().end();
  255. std::string found;
  256. while (beg != end)
  257. {
  258. if (beg->second == label)
  259. log_to_string(found, *beg);
  260. ++beg;
  261. }
  262. if (!found.empty())
  263. {
  264. std::string error("annotate_base::check_constructed by label\n");
  265. error += found;
  266. std::__throw_logic_error(error.c_str());
  267. }
  268. }
  269. #endif
  270. private:
  271. friend std::ostream&
  272. operator<<(std::ostream&, const annotate_base&);
  273. entry_type
  274. make_entry(void* p, size_t size)
  275. { return std::make_pair(p, data_type(get_label(), size)); }
  276. static void
  277. log_to_string(std::string& s, const_reference ref)
  278. {
  279. #if ! __has_builtin(__builtin_sprintf)
  280. __typeof__(&std::sprintf) __builtin_sprintf = &std::sprintf;
  281. #endif
  282. char buf[40];
  283. const char tab('\t');
  284. s += "label: ";
  285. unsigned long l = static_cast<unsigned long>(ref.second.first);
  286. __builtin_sprintf(buf, "%lu", l);
  287. s += buf;
  288. s += tab;
  289. s += "size: ";
  290. l = static_cast<unsigned long>(ref.second.second);
  291. __builtin_sprintf(buf, "%lu", l);
  292. s += buf;
  293. s += tab;
  294. s += "address: ";
  295. __builtin_sprintf(buf, "%p", ref.first);
  296. s += buf;
  297. s += '\n';
  298. }
  299. #if __cplusplus >= 201103L
  300. static void
  301. log_to_string(std::string& s, const std::pair<const void*, size_t>& ref)
  302. {
  303. #if ! __has_builtin(__builtin_sprintf)
  304. auto __builtin_sprintf = &std::sprintf;
  305. #endif
  306. char buf[40];
  307. const char tab('\t');
  308. s += "label: ";
  309. unsigned long l = static_cast<unsigned long>(ref.second);
  310. __builtin_sprintf(buf, "%lu", l);
  311. s += buf;
  312. s += tab;
  313. s += "address: ";
  314. __builtin_sprintf(buf, "%p", ref.first);
  315. s += buf;
  316. s += '\n';
  317. }
  318. #endif
  319. static size_t&
  320. label()
  321. {
  322. static size_t _S_label(std::numeric_limits<size_t>::max());
  323. return _S_label;
  324. }
  325. static map_alloc_type&
  326. map_alloc()
  327. {
  328. static map_alloc_type _S_map;
  329. return _S_map;
  330. }
  331. #if __cplusplus >= 201103L
  332. static map_construct_type&
  333. map_construct()
  334. {
  335. static map_construct_type _S_map;
  336. return _S_map;
  337. }
  338. #endif
  339. };
  340. inline std::ostream&
  341. operator<<(std::ostream& os, const annotate_base& __b)
  342. {
  343. std::string error;
  344. typedef annotate_base base_type;
  345. {
  346. base_type::const_iterator beg = __b.map_alloc().begin();
  347. base_type::const_iterator end = __b.map_alloc().end();
  348. for (; beg != end; ++beg)
  349. __b.log_to_string(error, *beg);
  350. }
  351. #if __cplusplus >= 201103L
  352. {
  353. auto beg = __b.map_construct().begin();
  354. auto end = __b.map_construct().end();
  355. for (; beg != end; ++beg)
  356. __b.log_to_string(error, *beg);
  357. }
  358. #endif
  359. return os << error;
  360. }
  361. /**
  362. * @brief Base struct for condition policy.
  363. *
  364. * Requires a public member function with the signature
  365. * void throw_conditionally()
  366. */
  367. struct condition_base
  368. {
  369. #if __cplusplus >= 201103L
  370. condition_base() = default;
  371. condition_base(const condition_base&) = default;
  372. condition_base& operator=(const condition_base&) = default;
  373. #endif
  374. virtual ~condition_base() { };
  375. };
  376. /**
  377. * @brief Base class for incremental control and throw.
  378. */
  379. struct limit_condition : public condition_base
  380. {
  381. // Scope-level adjustor objects: set limit for throw at the
  382. // beginning of a scope block, and restores to previous limit when
  383. // object is destroyed on exiting the block.
  384. struct adjustor_base
  385. {
  386. private:
  387. const size_t _M_orig;
  388. public:
  389. adjustor_base() : _M_orig(limit()) { }
  390. virtual
  391. ~adjustor_base() { set_limit(_M_orig); }
  392. };
  393. /// Never enter the condition.
  394. struct never_adjustor : public adjustor_base
  395. {
  396. never_adjustor() { set_limit(std::numeric_limits<size_t>::max()); }
  397. };
  398. /// Always enter the condition.
  399. struct always_adjustor : public adjustor_base
  400. {
  401. always_adjustor() { set_limit(count()); }
  402. };
  403. /// Enter the nth condition.
  404. struct limit_adjustor : public adjustor_base
  405. {
  406. limit_adjustor(const size_t __l) { set_limit(__l); }
  407. };
  408. // Increment _S_count every time called.
  409. // If _S_count matches the limit count, throw.
  410. static void
  411. throw_conditionally()
  412. {
  413. if (count() == limit())
  414. __throw_forced_error();
  415. ++count();
  416. }
  417. static size_t&
  418. count()
  419. {
  420. static size_t _S_count(0);
  421. return _S_count;
  422. }
  423. static size_t&
  424. limit()
  425. {
  426. static size_t _S_limit(std::numeric_limits<size_t>::max());
  427. return _S_limit;
  428. }
  429. // Zero the throw counter, set limit to argument.
  430. static void
  431. set_limit(const size_t __l)
  432. {
  433. limit() = __l;
  434. count() = 0;
  435. }
  436. };
  437. #ifdef _GLIBCXX_USE_C99_STDINT_TR1
  438. /**
  439. * @brief Base class for random probability control and throw.
  440. */
  441. struct random_condition : public condition_base
  442. {
  443. // Scope-level adjustor objects: set probability for throw at the
  444. // beginning of a scope block, and restores to previous
  445. // probability when object is destroyed on exiting the block.
  446. struct adjustor_base
  447. {
  448. private:
  449. const double _M_orig;
  450. public:
  451. adjustor_base() : _M_orig(probability()) { }
  452. virtual ~adjustor_base()
  453. { set_probability(_M_orig); }
  454. };
  455. /// Group condition.
  456. struct group_adjustor : public adjustor_base
  457. {
  458. group_adjustor(size_t size)
  459. { set_probability(1 - std::pow(double(1 - probability()),
  460. double(0.5 / (size + 1))));
  461. }
  462. };
  463. /// Never enter the condition.
  464. struct never_adjustor : public adjustor_base
  465. {
  466. never_adjustor() { set_probability(0); }
  467. };
  468. /// Always enter the condition.
  469. struct always_adjustor : public adjustor_base
  470. {
  471. always_adjustor() { set_probability(1); }
  472. };
  473. random_condition()
  474. {
  475. probability();
  476. engine();
  477. }
  478. static void
  479. set_probability(double __p)
  480. { probability() = __p; }
  481. static void
  482. throw_conditionally()
  483. {
  484. if (generate() < probability())
  485. __throw_forced_error();
  486. }
  487. void
  488. seed(unsigned long __s)
  489. { engine().seed(__s); }
  490. private:
  491. #if __cplusplus >= 201103L
  492. typedef std::uniform_real_distribution<double> distribution_type;
  493. typedef std::mt19937 engine_type;
  494. #else
  495. typedef std::tr1::uniform_real<double> distribution_type;
  496. typedef std::tr1::mt19937 engine_type;
  497. #endif
  498. static double
  499. generate()
  500. {
  501. #if __cplusplus >= 201103L
  502. const distribution_type distribution(0, 1);
  503. static auto generator = std::bind(distribution, engine());
  504. #else
  505. // Use variate_generator to get normalized results.
  506. typedef std::tr1::variate_generator<engine_type, distribution_type> gen_t;
  507. distribution_type distribution(0, 1);
  508. static gen_t generator(engine(), distribution);
  509. #endif
  510. #if ! __has_builtin(__builtin_sprintf)
  511. __typeof__(&std::sprintf) __builtin_sprintf = &std::sprintf;
  512. #endif
  513. double random = generator();
  514. if (random < distribution.min() || random > distribution.max())
  515. {
  516. std::string __s("random_condition::generate");
  517. __s += "\n";
  518. __s += "random number generated is: ";
  519. char buf[40];
  520. __builtin_sprintf(buf, "%f", random);
  521. __s += buf;
  522. std::__throw_out_of_range(__s.c_str());
  523. }
  524. return random;
  525. }
  526. static double&
  527. probability()
  528. {
  529. static double _S_p;
  530. return _S_p;
  531. }
  532. static engine_type&
  533. engine()
  534. {
  535. static engine_type _S_e;
  536. return _S_e;
  537. }
  538. };
  539. #endif // _GLIBCXX_USE_C99_STDINT_TR1
  540. /**
  541. * @brief Class with exception generation control. Intended to be
  542. * used as a value_type in templatized code.
  543. *
  544. * Note: Destructor not allowed to throw.
  545. */
  546. template<typename _Cond>
  547. struct throw_value_base : public _Cond
  548. {
  549. typedef _Cond condition_type;
  550. using condition_type::throw_conditionally;
  551. std::size_t _M_i;
  552. #ifndef _GLIBCXX_IS_AGGREGATE
  553. throw_value_base() : _M_i(0)
  554. { throw_conditionally(); }
  555. throw_value_base(const throw_value_base& __v) : _M_i(__v._M_i)
  556. { throw_conditionally(); }
  557. #if __cplusplus >= 201103L
  558. // Shall not throw.
  559. throw_value_base(throw_value_base&&) = default;
  560. #endif
  561. explicit throw_value_base(const std::size_t __i) : _M_i(__i)
  562. { throw_conditionally(); }
  563. #endif
  564. throw_value_base&
  565. operator=(const throw_value_base& __v)
  566. {
  567. throw_conditionally();
  568. _M_i = __v._M_i;
  569. return *this;
  570. }
  571. #if __cplusplus >= 201103L
  572. // Shall not throw.
  573. throw_value_base&
  574. operator=(throw_value_base&&) = default;
  575. #endif
  576. throw_value_base&
  577. operator++()
  578. {
  579. throw_conditionally();
  580. ++_M_i;
  581. return *this;
  582. }
  583. };
  584. template<typename _Cond>
  585. inline void
  586. swap(throw_value_base<_Cond>& __a, throw_value_base<_Cond>& __b)
  587. {
  588. typedef throw_value_base<_Cond> throw_value;
  589. throw_value::throw_conditionally();
  590. throw_value orig(__a);
  591. __a = __b;
  592. __b = orig;
  593. }
  594. // General instantiable types requirements.
  595. template<typename _Cond>
  596. inline bool
  597. operator==(const throw_value_base<_Cond>& __a,
  598. const throw_value_base<_Cond>& __b)
  599. {
  600. typedef throw_value_base<_Cond> throw_value;
  601. throw_value::throw_conditionally();
  602. bool __ret = __a._M_i == __b._M_i;
  603. return __ret;
  604. }
  605. template<typename _Cond>
  606. inline bool
  607. operator<(const throw_value_base<_Cond>& __a,
  608. const throw_value_base<_Cond>& __b)
  609. {
  610. typedef throw_value_base<_Cond> throw_value;
  611. throw_value::throw_conditionally();
  612. bool __ret = __a._M_i < __b._M_i;
  613. return __ret;
  614. }
  615. // Numeric algorithms instantiable types requirements.
  616. template<typename _Cond>
  617. inline throw_value_base<_Cond>
  618. operator+(const throw_value_base<_Cond>& __a,
  619. const throw_value_base<_Cond>& __b)
  620. {
  621. typedef throw_value_base<_Cond> throw_value;
  622. throw_value::throw_conditionally();
  623. throw_value __ret(__a._M_i + __b._M_i);
  624. return __ret;
  625. }
  626. template<typename _Cond>
  627. inline throw_value_base<_Cond>
  628. operator-(const throw_value_base<_Cond>& __a,
  629. const throw_value_base<_Cond>& __b)
  630. {
  631. typedef throw_value_base<_Cond> throw_value;
  632. throw_value::throw_conditionally();
  633. throw_value __ret(__a._M_i - __b._M_i);
  634. return __ret;
  635. }
  636. template<typename _Cond>
  637. inline throw_value_base<_Cond>
  638. operator*(const throw_value_base<_Cond>& __a,
  639. const throw_value_base<_Cond>& __b)
  640. {
  641. typedef throw_value_base<_Cond> throw_value;
  642. throw_value::throw_conditionally();
  643. throw_value __ret(__a._M_i * __b._M_i);
  644. return __ret;
  645. }
  646. /// Type throwing via limit condition.
  647. struct throw_value_limit : public throw_value_base<limit_condition>
  648. {
  649. typedef throw_value_base<limit_condition> base_type;
  650. #ifndef _GLIBCXX_IS_AGGREGATE
  651. throw_value_limit() { }
  652. throw_value_limit(const throw_value_limit& __other)
  653. : base_type(__other._M_i) { }
  654. #if __cplusplus >= 201103L
  655. throw_value_limit(throw_value_limit&&) = default;
  656. #endif
  657. explicit throw_value_limit(const std::size_t __i) : base_type(__i) { }
  658. #endif
  659. throw_value_limit&
  660. operator=(const throw_value_limit& __other)
  661. {
  662. base_type::operator=(__other);
  663. return *this;
  664. }
  665. #if __cplusplus >= 201103L
  666. throw_value_limit&
  667. operator=(throw_value_limit&&) = default;
  668. #endif
  669. };
  670. #ifdef _GLIBCXX_USE_C99_STDINT_TR1
  671. /// Type throwing via random condition.
  672. struct throw_value_random : public throw_value_base<random_condition>
  673. {
  674. typedef throw_value_base<random_condition> base_type;
  675. #ifndef _GLIBCXX_IS_AGGREGATE
  676. throw_value_random() { }
  677. throw_value_random(const throw_value_random& __other)
  678. : base_type(__other._M_i) { }
  679. #if __cplusplus >= 201103L
  680. throw_value_random(throw_value_random&&) = default;
  681. #endif
  682. explicit throw_value_random(const std::size_t __i) : base_type(__i) { }
  683. #endif
  684. throw_value_random&
  685. operator=(const throw_value_random& __other)
  686. {
  687. base_type::operator=(__other);
  688. return *this;
  689. }
  690. #if __cplusplus >= 201103L
  691. throw_value_random&
  692. operator=(throw_value_random&&) = default;
  693. #endif
  694. };
  695. #endif // _GLIBCXX_USE_C99_STDINT_TR1
  696. /**
  697. * @brief Allocator class with logging and exception generation control.
  698. * Intended to be used as an allocator_type in templatized code.
  699. * @ingroup allocators
  700. *
  701. * Note: Deallocate not allowed to throw.
  702. */
  703. template<typename _Tp, typename _Cond>
  704. class throw_allocator_base
  705. : public annotate_base, public _Cond
  706. {
  707. public:
  708. typedef std::size_t size_type;
  709. typedef std::ptrdiff_t difference_type;
  710. typedef _Tp value_type;
  711. typedef value_type* pointer;
  712. typedef const value_type* const_pointer;
  713. typedef value_type& reference;
  714. typedef const value_type& const_reference;
  715. #if __cplusplus >= 201103L
  716. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  717. // 2103. std::allocator propagate_on_container_move_assignment
  718. typedef std::true_type propagate_on_container_move_assignment;
  719. #endif
  720. private:
  721. typedef _Cond condition_type;
  722. std::allocator<value_type> _M_allocator;
  723. typedef __gnu_cxx::__alloc_traits<std::allocator<value_type> > traits;
  724. using condition_type::throw_conditionally;
  725. public:
  726. size_type
  727. max_size() const _GLIBCXX_USE_NOEXCEPT
  728. { return traits::max_size(_M_allocator); }
  729. pointer
  730. address(reference __x) const _GLIBCXX_NOEXCEPT
  731. { return std::__addressof(__x); }
  732. const_pointer
  733. address(const_reference __x) const _GLIBCXX_NOEXCEPT
  734. { return std::__addressof(__x); }
  735. _GLIBCXX_NODISCARD pointer
  736. allocate(size_type __n, const void* __hint = 0)
  737. {
  738. if (__n > this->max_size())
  739. std::__throw_bad_alloc();
  740. throw_conditionally();
  741. pointer const a = traits::allocate(_M_allocator, __n, __hint);
  742. insert(a, sizeof(value_type) * __n);
  743. return a;
  744. }
  745. #if __cplusplus >= 201103L
  746. template<typename _Up, typename... _Args>
  747. void
  748. construct(_Up* __p, _Args&&... __args)
  749. {
  750. traits::construct(_M_allocator, __p, std::forward<_Args>(__args)...);
  751. insert_construct(__p);
  752. }
  753. template<typename _Up>
  754. void
  755. destroy(_Up* __p)
  756. {
  757. erase_construct(__p);
  758. traits::destroy(_M_allocator, __p);
  759. }
  760. #else
  761. void
  762. construct(pointer __p, const value_type& __val)
  763. { return _M_allocator.construct(__p, __val); }
  764. void
  765. destroy(pointer __p)
  766. { _M_allocator.destroy(__p); }
  767. #endif
  768. void
  769. deallocate(pointer __p, size_type __n)
  770. {
  771. erase(__p, sizeof(value_type) * __n);
  772. _M_allocator.deallocate(__p, __n);
  773. }
  774. void
  775. check_allocated(pointer __p, size_type __n)
  776. {
  777. size_type __t = sizeof(value_type) * __n;
  778. annotate_base::check_allocated(__p, __t);
  779. }
  780. void
  781. check(size_type __n)
  782. { annotate_base::check(__n); }
  783. };
  784. template<typename _Tp, typename _Cond>
  785. inline bool
  786. operator==(const throw_allocator_base<_Tp, _Cond>&,
  787. const throw_allocator_base<_Tp, _Cond>&)
  788. { return true; }
  789. #if __cpp_impl_three_way_comparison < 201907L
  790. template<typename _Tp, typename _Cond>
  791. inline bool
  792. operator!=(const throw_allocator_base<_Tp, _Cond>&,
  793. const throw_allocator_base<_Tp, _Cond>&)
  794. { return false; }
  795. #endif
  796. /// Allocator throwing via limit condition.
  797. template<typename _Tp>
  798. struct throw_allocator_limit
  799. : public throw_allocator_base<_Tp, limit_condition>
  800. {
  801. template<typename _Tp1>
  802. struct rebind
  803. { typedef throw_allocator_limit<_Tp1> other; };
  804. throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { }
  805. throw_allocator_limit(const throw_allocator_limit&)
  806. _GLIBCXX_USE_NOEXCEPT { }
  807. template<typename _Tp1>
  808. throw_allocator_limit(const throw_allocator_limit<_Tp1>&)
  809. _GLIBCXX_USE_NOEXCEPT { }
  810. ~throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { }
  811. #if __cplusplus >= 201103L
  812. throw_allocator_limit&
  813. operator=(const throw_allocator_limit&) = default;
  814. #endif
  815. };
  816. #ifdef _GLIBCXX_USE_C99_STDINT_TR1
  817. /// Allocator throwing via random condition.
  818. template<typename _Tp>
  819. struct throw_allocator_random
  820. : public throw_allocator_base<_Tp, random_condition>
  821. {
  822. template<typename _Tp1>
  823. struct rebind
  824. { typedef throw_allocator_random<_Tp1> other; };
  825. throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { }
  826. throw_allocator_random(const throw_allocator_random&)
  827. _GLIBCXX_USE_NOEXCEPT { }
  828. template<typename _Tp1>
  829. throw_allocator_random(const throw_allocator_random<_Tp1>&)
  830. _GLIBCXX_USE_NOEXCEPT { }
  831. ~throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { }
  832. #if __cplusplus >= 201103L
  833. throw_allocator_random&
  834. operator=(const throw_allocator_random&) = default;
  835. #endif
  836. };
  837. #endif // _GLIBCXX_USE_C99_STDINT_TR1
  838. _GLIBCXX_END_NAMESPACE_VERSION
  839. } // namespace
  840. #if __cplusplus >= 201103L
  841. # include <bits/functional_hash.h>
  842. namespace std _GLIBCXX_VISIBILITY(default)
  843. {
  844. #pragma GCC diagnostic push
  845. #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  846. /// Explicit specialization of std::hash for __gnu_cxx::throw_value_limit.
  847. template<>
  848. struct hash<__gnu_cxx::throw_value_limit>
  849. : public std::unary_function<__gnu_cxx::throw_value_limit, size_t>
  850. {
  851. size_t
  852. operator()(const __gnu_cxx::throw_value_limit& __val) const
  853. {
  854. __gnu_cxx::throw_value_limit::throw_conditionally();
  855. std::hash<std::size_t> __h;
  856. size_t __result = __h(__val._M_i);
  857. return __result;
  858. }
  859. };
  860. #ifdef _GLIBCXX_USE_C99_STDINT_TR1
  861. /// Explicit specialization of std::hash for __gnu_cxx::throw_value_random.
  862. template<>
  863. struct hash<__gnu_cxx::throw_value_random>
  864. : public std::unary_function<__gnu_cxx::throw_value_random, size_t>
  865. {
  866. size_t
  867. operator()(const __gnu_cxx::throw_value_random& __val) const
  868. {
  869. __gnu_cxx::throw_value_random::throw_conditionally();
  870. std::hash<std::size_t> __h;
  871. size_t __result = __h(__val._M_i);
  872. return __result;
  873. }
  874. };
  875. #endif
  876. #pragma GCC diagnostic pop
  877. } // end namespace std
  878. #endif
  879. #endif