fork download
  1. #include <iostream>
  2. #include <array>
  3. #include <algorithm>
  4. #include <cstring>
  5.  
  6. using namespace std;
  7.  
  8. const unsigned int long_enough = 512;
  9. class my_exception : public exception {
  10. std::array<char, long_enough> err;
  11. std::array<char, long_enough>::iterator insertion_point;
  12. public:
  13. template <typename Iter>
  14. void append(Iter first, Iter last) noexcept {
  15. //Remember null terminator!
  16. auto space_left = std::distance(insertion_point, err.end());
  17. if (std::distance(first, last)>=space_left){
  18. last = first + (space_left - 1);
  19. }
  20. insertion_point = copy(first, last, insertion_point); //TODO: bounds, start
  21. }
  22. void append(const char msg[]) noexcept {
  23. append(msg, msg+strlen(msg));
  24. }
  25. my_exception(const char msg[]) noexcept {
  26. insertion_point = err.begin();
  27. append(msg, msg+strlen(msg));
  28. }
  29. virtual const char* what() const noexcept override{
  30. return err.data();
  31. }
  32. };
  33.  
  34. void i_will_throw() {
  35. throw my_exception("i_will_throw: demonstrating exception propagation mechanism");
  36. }
  37.  
  38. void i_will_rethrow() {
  39. try {
  40. i_will_throw();
  41. } catch (my_exception& e) {
  42. e.append("\n<<--via: i_will_rethrow");
  43. throw;
  44. }
  45. }
  46.  
  47. void recurse_and_throw(char how_deep) {
  48. std::string name_with_depth = "\n<<--via: recurse_and_throw(";
  49. name_with_depth += how_deep; name_with_depth += ")";
  50. try {
  51. if (how_deep!='A') {
  52. recurse_and_throw(how_deep - 1);
  53. } else {
  54. i_will_throw();
  55. return;
  56. }
  57. } catch (my_exception& e) {
  58. e.append(name_with_depth.begin(), name_with_depth.end());
  59. throw;
  60. }
  61. }
  62.  
  63. int main() {
  64. cout << "-------Simple--------" << endl;
  65. try {
  66. i_will_throw();
  67. } catch (exception& e) {
  68. cout << e.what()<<endl;
  69. }
  70. cout << "--------Rethrown-------" << endl;
  71. try {
  72. i_will_rethrow();
  73. } catch (exception& e) {
  74. cout << e.what()<<endl;
  75. }
  76. cout << "--------Recursive-------" << endl;
  77. try {
  78. recurse_and_throw('F');
  79. } catch (exception& e) {
  80. cout << e.what()<<endl;
  81. }
  82. cout << "--------Recursive long-------" << endl;
  83. try {
  84. recurse_and_throw('U');
  85. } catch (exception& e) {
  86. cout << e.what() <<endl;
  87. }
  88. return 0;
  89. }
Success #stdin #stdout 0s 3432KB
stdin
Standard input is empty
stdout
-------Simple--------
i_will_throw: demonstrating exception propagation mechanism
--------Rethrown-------
i_will_throw: demonstrating exception propagation mechanism
<<--via: i_will_rethrow
--------Recursive-------
i_will_throw: demonstrating exception propagation mechanism
<<--via: recurse_and_throw(A)
<<--via: recurse_and_throw(B)
<<--via: recurse_and_throw(C)
<<--via: recurse_and_throw(D)
<<--via: recurse_and_throw(E)
<<--via: recurse_and_throw(F)
--------Recursive long-------
i_will_throw: demonstrating exception propagation mechanism
<<--via: recurse_and_throw(A)
<<--via: recurse_and_throw(B)
<<--via: recurse_and_throw(C)
<<--via: recurse_and_throw(D)
<<--via: recurse_and_throw(E)
<<--via: recurse_and_throw(F)
<<--via: recurse_and_throw(G)
<<--via: recurse_and_throw(H)
<<--via: recurse_and_throw(I)
<<--via: recurse_and_throw(J)
<<--via: recurse_and_throw(K)
<<--via: recurse_and_throw(L)
<<--via: recurse_and_throw(M)
<<--via: recurse_and_throw(N)
<<--via: recurse_and_throw(O)
<