#include <climits>
#include <cstring>
#include <exception>
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::exception;
using std::string;
class CastException: public exception {
protected:
string message;
public:
virtual ~CastException () throw() {}
virtual const char* what() const throw() {
return message.c_str();
}
CastException& operator<< (const char* str) {
message.append(str);
return *this;
}
CastException& operator<< (const string str) {
message += str;
return *this;
}
};
class TooBigStringException: public CastException {
public:
TooBigStringException() {
message.append("Too big string!");
}
};
class TooBigCharTypeException: public CastException {
public:
TooBigCharTypeException() {
message.append("Too big CharType!");
}
};
class IncorrectSymbolException: public CastException {
public:
IncorrectSymbolException() {
message.append("Incorrect symbol!");
}
};
class OverflowException: public CastException {
public:
OverflowException() {
message.append("Overflow!");
}
};
class InvalidValueException: public CastException {
public:
InvalidValueException() {
message.append("Invalid value!");
}
};
template <typename CharType>
inline char CharFromString(const CharType* data, size_t len) {
if (len > 1) {
throw TooBigStringException();
}
if (sizeof(CharType) > sizeof(char)) {
throw TooBigCharTypeException();
}
return static_cast<char>(*data);
}
bool addition_is_safe(int a, int b) {
return INT_MAX - b >= a;
}
bool multiplication_is_safe(int a, int b) {
return INT_MAX / b >= a;
}
template <typename CharType>
inline int IntFromString(const CharType* data, size_t len) {
int res = 0;
for (size_t i = 0; i < len; ++i) {
if (static_cast<char>(data[i]) < '0' || static_cast<char>(data[i]) > '9') {
throw IncorrectSymbolException();
}
if (!multiplication_is_safe(res, 10)) {
throw OverflowException();
}
res *= 10;
if (!addition_is_safe(res, static_cast<char>(data[i]) - '0')) {
throw OverflowException();
}
res += static_cast<char>(data[i]) - '0';
}
return res;
}
bool addition_is_safe(long long a, long long b) {
return LLONG_MAX - b >= a;
}
bool multiplication_is_safe(long long a, long long b) {
return LLONG_MAX / b >= a;
}
template <typename CharType>
inline long long LongLongFromString(const CharType* data, size_t len) {
long long res = 0;
for (size_t i = 0; i < len; ++i) {
if (static_cast<char>(data[i]) < '0' || static_cast<char>(data[i]) > '9') {
throw IncorrectSymbolException();
}
if (!multiplication_is_safe(res, 10LL)) {
throw OverflowException();
}
res *= 10;
if (!addition_is_safe(res, static_cast<long long>(data[i]) - '0')) {
throw OverflowException();
}
res += static_cast<long long>(data[i]) - '0';
}
return res;
}
template <typename CharType>
inline bool BoolFromString(const CharType* data, size_t len) {
if (len == 1) {
if (*data == '0') {
return false;
} else if (*data == '1') {
return true;
} else {
throw IncorrectSymbolException();
}
} else if (len == 4 && strncmp(data, "true", 4) == 0) {
return true;
} else if (len == 5 && strncmp(data, "false", 5) == 0) {
return false;
} else {
throw InvalidValueException();
}
}
int main() {
cout << "From \"a\" to char: ";
try {
cout << CharFromString<char>("a", 1) << endl;
} catch (CastException& ex) {
cout << ex.what() << endl;
}
cout << "From \"ab\" to char: ";
try {
cout << CharFromString<char>("ab", 2) << endl;
} catch (CastException& ex) {
cout << ex.what() << endl;
}
cout << "From 42 to int: ";
try {
cout << IntFromString<char>("42", 2) << endl;
} catch (CastException& ex) {
cout << ex.what() << endl;
}
cout << "From 2147483648 (INT_MAX + 1) to int: ";
try {
cout << IntFromString<char>("2147483648", 10) << endl;
} catch (CastException& ex) {
cout << ex.what() << endl;
}
cout << "From 7500 to long long: ";
try {
cout << LongLongFromString<char>("7500", 4) << endl;
} catch (CastException& ex) {
cout << ex.what() << endl;
}
cout << "From \"STR_NOT_NUM\" to long long: ";
try {
cout << LongLongFromString<char>("STR_NOT_NUM", 11) << endl;
} catch (CastException& ex) {
cout << ex.what() << endl;
}
cout << "From \"true\" to bool: ";
try {
cout << BoolFromString<char>("true", 4) << endl;
} catch (CastException& ex) {
cout << ex.what() << endl;
}
cout << "From \"1234\" to bool: ";
try {
cout << BoolFromString<char>("1234", 4) << endl;
} catch (CastException& ex) {
cout << ex.what() << endl;
}
return 0;
}
понедельник, 27 июня 2011 г.
Исключения
Собственный класс исключения CastException с перегруженным оператором << для записи в объект исключения и несколько примеров его использования.
Подписаться на:
Комментарии к сообщению (Atom)
Комментариев нет:
Отправить комментарий