00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00031 #ifdef _MSC_VER
00032 # pragma once
00033 # pragma warning( push )
00034 # pragma warning( disable : 4100 4267 4714 4786 )
00035 #endif // _MSC_VER
00036
00037 #ifndef _EXMAT_ERRORCHECK_H
00038 #define _EXMAT_ERRORCHECK_H
00039
00040 #include <stdexcept>
00041 #include <sstream>
00042 #include <string>
00043 #include "Tags.h"
00044 #include "Metaprogramming.h"
00045
00046 namespace exmat {
00047
00048 const char InternalErrMsg[] = "Internal error! Please contact exmat developers.";
00049 const char OutOfBoundsErrMsg[] = "Index out of bounds!";
00050 const char SizeNotPosIntErrMsg[] = "Size should be positive non-zero!";
00051 const char SizeNotMatchErrMsg[] = "Size not match!";
00052 const char IncompatibleErrMsg[] = "Incompatible operation!";
00053 const char CommaInitOutOfBoundErrMsg[] = "Index out of bounds during comma initialization!";
00054
00055 #define THROWMSG(condition, msg, file) if(!(condition)) \
00056 throw(std::runtime_error(std::string(msg) + " At " + file));
00057
00059
00062 template<typename INDEX=NullTag>
00063 class out_of_bound_error : public std::runtime_error {
00064 public:
00065 EXMAT_INLINE2 explicit out_of_bound_error(const char* str)
00066 : std::runtime_error(str) {}
00067 EXMAT_INLINE2 out_of_bound_error(const char* str, INDEX min, INDEX max, INDEX i)
00068 : std::runtime_error(str), minI(min), maxI(max), index(i) {}
00069 EXMAT_INLINE2 virtual ~out_of_bound_error() throw()
00070 {}
00071 INDEX minI, maxI, index;
00072 };
00073
00075
00078 class compatibility_error : public std::runtime_error {
00079 public:
00080 EXMAT_INLINE2 explicit compatibility_error(const char* str)
00081 : std::runtime_error(str) {}
00082 EXMAT_INLINE2 virtual ~compatibility_error() throw()
00083 {}
00084 };
00085
00087
00090 class mem_align_error : public std::runtime_error {
00091 public:
00092 EXMAT_INLINE2 explicit mem_align_error(const char* str)
00093 : std::runtime_error(str) {}
00094 virtual ~mem_align_error() throw()
00095 {}
00096 };
00097
00098
00099 namespace PNS {
00100
00101 static EXMAT_INLINE2 void EmptyAssert_(bool condtion, const char* msg) {
00102 }
00103 static EXMAT_INLINE2 void Assert_(bool condtion, const char* msg) {
00104 if(!condtion)
00105 throw std::runtime_error(msg);
00106 }
00107 static EXMAT_INLINE2 void EmptyAssertBounds_(bool condtion) {
00108 }
00109 template<typename INDEX>
00110 static EXMAT_INLINE2 void AssertBounds_(INDEX min, INDEX max, INDEX i) {
00111 if(i < min || i > max) {
00112 std::ostringstream out(std::ios_base::out);
00113 out << OutOfBoundsErrMsg << " Accessing index: " << i << ", with Min: " << min << ", Max: " << max;
00114 throw out_of_bound_error<INDEX>( out.str().c_str() );
00115 }
00116 }
00117 static EXMAT_INLINE2 void AssertBounds_(bool condtion) {
00118 if(!condtion)
00119 throw out_of_bound_error<>(OutOfBoundsErrMsg);
00120 }
00121 static EXMAT_INLINE2 void EmptyAssertCompat_(bool condtion) {
00122 }
00123 static EXMAT_INLINE2 void AssertCompat_(bool condtion) {
00124 if(!condtion)
00125 throw compatibility_error(IncompatibleErrMsg);
00126 }
00127
00128 }
00129
00130
00132
00135 struct EmptyErrorChecker
00136 {
00137 static EXMAT_INLINE2 void Assert(bool condtion, const char* msg) {
00138 }
00139 template<typename INDEX>
00140 static EXMAT_INLINE2 void AssertBounds(INDEX min, INDEX max, INDEX i) {
00141 }
00142 static EXMAT_INLINE2 void AssertBounds(bool condtion) {
00143 }
00144 static EXMAT_INLINE2 void AssertCompat(bool condtion) {
00145 }
00146 };
00147
00149
00152 struct DefaultErrorChecker
00153 {
00154 static EXMAT_INLINE2 void Assert(bool condtion, const char* msg) {
00155 PNS::Assert_(condtion, msg);
00156 }
00157 template<typename INDEX>
00158 static EXMAT_INLINE2 void AssertBounds(INDEX min, INDEX max, INDEX i) {
00159 }
00160 static EXMAT_INLINE2 void AssertBounds(bool condtion) {
00161 }
00162 static EXMAT_INLINE2 void AssertCompat(bool condtion) {
00163 PNS::AssertCompat_(condtion);
00164 }
00165 };
00166
00168
00171 struct FullErrorChecker
00172 {
00173 static EXMAT_INLINE2 void Assert(bool condtion, const char* msg) {
00174 exmat::PNS::Assert_(condtion, msg);
00175 }
00176 template<typename INDEX>
00177 static EXMAT_INLINE2 void AssertBounds(INDEX min, INDEX max, INDEX i) {
00178 exmat::PNS::AssertBounds_(min, max, i);
00179 }
00180 static EXMAT_INLINE2 void AssertBounds(bool condtion) {
00181 exmat::PNS::AssertBounds_(condtion);
00182 }
00183 static EXMAT_INLINE2 void AssertCompat(bool condtion) {
00184 exmat::PNS::AssertCompat_(condtion);
00185 }
00186 };
00187
00189
00193 template<class CHK1, class CHK2>
00194 struct ResultantChecker {
00195 typedef typename
00196 IF<
00197 OR_bool<
00198 ISSAMETYPE<CHK1, FullErrorChecker>::RET,
00199 ISSAMETYPE<CHK2, FullErrorChecker>::RET
00200 >::RET,
00201 FullErrorChecker,
00202 typename
00203 IF<
00204 AND_bool<
00205 ISSAMETYPE<CHK1, EmptyErrorChecker>::RET,
00206 ISSAMETYPE<CHK2, EmptyErrorChecker>::RET
00207 >::RET,
00208 EmptyErrorChecker,
00209 DefaultErrorChecker
00210 >::RET>::RET RET;
00211 };
00212
00213 }
00214
00215 #ifdef _MSC_VER
00216 # pragma warning( pop )
00217 #endif // _MSC_VER
00218
00219 #endif // _EXMAT_ERRORCHECK_H