You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

faults.hpp 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // faults.hpp
  2. //
  3. // Copyright (C) 2004-2020 MicroNeil Research Corporation.
  4. //
  5. // This software is released under the MIT license. See LICENSE.TXT.
  6. //
  7. // Faults and Checks are classes we can use in place of assert() to handle
  8. // unreasonable or necessary conditions in our code. They are constructed with
  9. // friendly descriptions (and optionally error codes) and then used just
  10. // like assert() would be used-- except they are designed to remain in the
  11. // production code. After all, assert() is a C (not C++) concept.
  12. //
  13. // A ...Check(test_expression) activates when the test_expression is not true.
  14. // A ...Fault(text_expression) activates when the test_expression is true.
  15. //
  16. // An Abort...() sends it's description to cerr then aborts (no cleanup).
  17. // An Exit...() sends it's description to cerr then exits with a result code.
  18. // A Runtime...() throws a runtime_error (self) with it's description in what().
  19. // A Logic...() throws a logic_error (self) with it's description in what().
  20. #pragma once
  21. #include <stdexcept>
  22. #include <cstdlib>
  23. #include <iostream>
  24. #include <string>
  25. namespace codedweller {
  26. const int DefaultExitCode = EXIT_FAILURE; // Use this when no code is provided.
  27. class AbortCheck { // If this check is false we will abort.
  28. private:
  29. const std::string myDescription; // This is what I have to say.
  30. public:
  31. AbortCheck(const std::string& Text) : myDescription(Text) {} // I am constructed with a description
  32. void operator()(bool X) const { // Apply me like assert(exp)
  33. if(false == X) { // If the expression is false then we
  34. std::cerr << myDescription << std::endl; // failed the check so we display our
  35. abort(); // description and abort.
  36. }
  37. }
  38. const std::string Description() { return myDescription; } // You can ask for my Description.
  39. };
  40. class AbortFault { // If this fault occurs we will abort.
  41. private:
  42. const std::string myDescription; // This is what I have to say.
  43. public:
  44. AbortFault(const std::string& Text) : myDescription(Text) {} // I am constructed with a description
  45. void operator()(bool X) const { // Apply me like assert(! exp)
  46. if(true == X) { // If the expression is true then we
  47. std::cerr << myDescription << std::endl; // have a fault so we display our fault
  48. abort(); // description and abort.
  49. }
  50. }
  51. const std::string Description() const { return myDescription; } // You can ask for my Description.
  52. };
  53. class ExitCheck { // If this check is false we will exit.
  54. private:
  55. const std::string myDescription; // This is what I have to say.
  56. const int myExitCode; // This is what I send to exit().
  57. public:
  58. ExitCheck(const std::string& Text, int Code=DefaultExitCode) : // I am constructed with a description
  59. myDescription(Text), myExitCode(Code) {} // and (optionlly) an exit code.
  60. void operator()(bool X) const { // Apply me like assert(exp)
  61. if(false == X) { // If the expression is false then we
  62. std::cerr << myDescription << std::endl; // failed the check so we display our
  63. exit(myExitCode); // description and exit with our code.
  64. }
  65. }
  66. const std::string Description() { return myDescription; } // You can ask for my Description.
  67. const int ExitCode() { return myExitCode; } // You can ask for my ExitCode.
  68. };
  69. class ExitFault { // If this fault occurs we will exit.
  70. private:
  71. const std::string myDescription; // This is what I have to say.
  72. const int myExitCode; // This is what I send to exit().
  73. public:
  74. ExitFault(const std::string& Text, int Code=DefaultExitCode) : // I am constructed with a description
  75. myDescription(Text), myExitCode(Code) {} // and (optionlly) an exit code.
  76. void operator()(bool X) const { // Apply me like assert(! exp)
  77. if(true == X) { // If the expression is true then we
  78. std::cerr << myDescription << std::endl; // have a fault so we display our fault
  79. exit(myExitCode); // description and exit with our code.
  80. }
  81. }
  82. const std::string Description() const { return myDescription; } // You can ask for my Description.
  83. const int ExitCode() const { return myExitCode; } // You can ask for my ExitCode.
  84. };
  85. class RuntimeCheck : public std::runtime_error { // Throw if this check fails.
  86. public:
  87. RuntimeCheck(const std::string& Text) : std::runtime_error(Text) {} // Construct me with a description.
  88. void operator()(bool X) const { // Apply me like assert(exp)
  89. if(false == X) { // If the expression is false then we
  90. throw *this; // failed the check so we throw.
  91. }
  92. }
  93. };
  94. class RuntimeFault : public std::runtime_error { // Throw if we find this fault.
  95. public:
  96. RuntimeFault(const std::string& Text) : std::runtime_error(Text) {} // Construct me with a description.
  97. void operator()(bool X) const { // Apply me like assert(exp)
  98. if(true == X) { // If the expression is true then we
  99. throw *this; // found the fault so we throw.
  100. }
  101. }
  102. };
  103. class LogicCheck : public std::logic_error { // Throw if this check fails.
  104. public:
  105. LogicCheck(const std::string& Text) : std::logic_error(Text) {} // Construct me with a description.
  106. void operator()(bool X) const { // Apply me like assert(exp)
  107. if(false == X) { // If the expression is false then we
  108. throw *this; // failed the check so we throw.
  109. }
  110. }
  111. };
  112. class LogicFault : public std::logic_error { // Throw if we find this fault.
  113. public:
  114. LogicFault(const std::string& Text) : std::logic_error(Text) {} // Construct me with a description.
  115. void operator()(bool X) const { // Apply me like assert(exp)
  116. if(true == X) { // If the expression is true then we
  117. throw *this; // found the fault so we throw.
  118. }
  119. }
  120. };
  121. } // End namespace codedweller