00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef __AXIOMS_HH
00019 # define __AXIOMS_HH
00020
00023
00024 # include <string>
00025 # include <sstream>
00026 # include <catsfoot-config.hh>
00027 # include <iostream>
00028 # include "../type_traits/always_false.hh"
00029
00030 namespace catsfoot {
00032 struct axiom_failure {
00033 private:
00034 std::string _msg;
00035
00036 public:
00038 const std::string& msg() const { return _msg; }
00039
00040 axiom_failure(const std::string& _msg):
00041 _msg(_msg) {}
00042
00043 axiom_failure(std::string&& _msg):
00044 _msg(std::move(_msg)) {}
00045
00046 axiom_failure(std::string&& func,
00047 std::string&& file,
00048 unsigned line,
00049 std::string&& expr):
00050 _msg() {
00051 std::stringstream ss;
00052 ss << std::move(file) << ":" << line << ":";
00053 ss << " Axiom " << std::move(func) << " failed.";
00054 ss << std::endl << std::endl;
00055 ss << "Expression was: " << std::move(expr) << std::endl;
00056 _msg = ss.str();
00057 }
00058
00060 axiom_failure(const axiom_failure&) = default;
00061
00063 axiom_failure(axiom_failure&& other): _msg(std::move(other._msg)) {}
00064
00066 axiom_failure& operator=(axiom_failure&& other) {
00067 std::swap(_msg, other._msg);
00068 return *this;
00069 }
00070
00072 axiom_failure& operator=(const axiom_failure& other) {
00073 return *this = axiom_failure(other);
00074 }
00075 };
00076
00077 # ifdef __CATSFOOT_ENABLE_TESTING_RT
00078 # include "../extern_decl.hh"
00079
00080 namespace details {
00082 EXTERN
00083 void reached_function(std::string&& func,
00084 std::string&& file,
00085 unsigned line);
00086
00088 EXTERN
00089 void register_function(std::string&& func,
00090 std::string&& file,
00091 unsigned line);
00092 }
00093
00095 EXTERN
00096 bool check_unverified(std::ostream& s = std::cerr);
00097 # else
00098 namespace details {
00099 template <typename T = std::string>
00100 extern
00101 void reached_function(T&&,
00102 std::string&&,
00103 unsigned) {
00104 static_assert(details::always_false<T>::value,
00105 "You probably called a functionality that is available "
00106 "only if you link with the runtime library. In this case "
00107 "include catsfoot_testing.hh instead of catsfoot.hh");
00108 }
00109
00110 template <typename T = std::string>
00111 extern
00112 void register_function(T&&,
00113 std::string&&,
00114 unsigned) {
00115 static_assert(details::always_false<T>::value,
00116 "You probably called a functionality that is available "
00117 "only if you link with the runtime library. In this case "
00118 "include catsfoot_testing.hh instead of catsfoot.hh");
00119 }
00120 }
00121
00122 template <typename T = std::ostream>
00123 extern
00124 bool check_unverified(T& = std::cerr) {
00125 static_assert(details::always_false<T>::value,
00126 "You probably called a functionality that is available "
00127 "only if you link with the runtime library. In this case "
00128 "include catsfoot_testing.hh instead of catsfoot.hh");
00129 return false;
00130 }
00131 # endif
00132 }
00133
00135 # define _catsfoot__test_axiom(FUN, FILE, LINE, EXPR) \
00136 { ::catsfoot::details::reached_function(FUN, FILE, LINE); \
00137 if (!(EXPR)) \
00138 throw ::catsfoot::axiom_failure(FUN, \
00139 FILE, LINE, #EXPR); } \
00140 ::catsfoot::details::register_function(FUN, FILE, LINE);
00141
00142 # if defined(DEFINE___PRETTY_FUNCTION__) && \
00143 defined(DEFINE___FILE__) && \
00144 defined(DEFINE___LINE__)
00145 # define axiom_assert(expr) _catsfoot__test_axiom(__PRETTY_FUNCTION__, \
00146 __FILE__, \
00147 __LINE__, \
00148 expr)
00149 # elif defined(DEFINE___func__) && \
00150 defined(DEFINE___FILE__) && \
00151 defined(DEFINE___LINE__)
00152 # define axiom_assert(expr) _catsfoot__test_axiom(__func__, \
00153 __FILE__, \
00154 __LINE__, \
00155 expr)
00156 # else
00157
00158
00159 # define axiom_assert(expr) _catsfoot__test_axiom("<unknown>", \
00160 "<unknown>", \
00161 0, \
00162 expr)
00163 # endif
00164
00165 #endif