throw_allocator.h 25 KB

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