- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
#define SWITCH(str) switch(str_hash_for_switch(str))
#define CASE(str) static_assert(str_is_correct(str) && (str_len(str) <= MAX_LEN),\
"CASE string contains wrong characters, or its length is greater than 9");\
case str_hash(str, str_len(str))
#define DEFAULT default
typedef unsigned char uchar;
typedef unsigned long long ullong;
const uchar MAX_LEN = 9;
const ullong N_HASH = static_cast<ullong>(-1);
constexpr ullong raise_128_to(const uchar power)
{
return 1ULL << 7 * power;
}
constexpr bool str_is_correct(const char* const str)
{
return (static_cast<signed char>(*str) > 0) ? str_is_correct(str + 1) : (*str ? false : true);
}
constexpr uchar str_len(const char* const str)
{
return *str ? (1 + str_len(str + 1)) : 0;
}
constexpr ullong str_hash(const char* const str, const uchar current_len)
{
return *str ? (raise_128_to(current_len - 1) * static_cast<uchar>(*str) + str_hash(str + 1, current_len - 1)) : 0;
}
inline ullong str_hash_for_switch(const char* const str)
{
return (str_is_correct(str) && (str_len(str) <= MAX_LEN)) ? str_hash(str, str_len(str)) : N_HASH;
}
inline ullong str_hash_for_switch(const std::string& str)
{
return (str_is_correct(str.c_str()) && (str.length() <= MAX_LEN)) ? str_hash(str.c_str(), str.length()) : N_HASH;
}
Запостил из-за ошибки на некоторых платформах и компиляторах.
И они обрамлялись одинарными кавычками?
И фильтроблумить. То бишь проверять отсутствие.
Да, походу затупил, и действительно надо или uint64_t или выражать MAX_LEN через длину long long.
char <= short <= int <= long <= long long
http://en.cppreference.com/w/cpp/language/types
В стандарте ее что-то найти не могу.
Хрен знает. Судя по всему какой-то умник статистику по самым популярным платформам собрал.
Судя по этой фразе автор как бы намекает нам, что стандарт с++ гарантирует не только те самые неравенства, но и минимальный размер типов в битах. Может быть в драфте они не описаны? Только в полноценной версии?
Это возможно его заблуждение. Дамой с прогулки вернусь - посмотрю стандарт
Сначала прочитал "С дамой, с прогулки вернусь". Потом понял что это фантастика.
А ты не задумывался, а может я ею всегда был? Ты почему мой возраст не знаешь? Потому что этот вопрос задавать мне не принято.
Действительно. Может и был.
>мой возраст не знаешь
Да тут это вроде все знают - школьных лет.
сишный стандарт требует, чтобы значения целых типов включали минимальные границы
с теми границами unsigned long long может быть больше 64 битов, но не меньше
— minimum value for an object of type long long int
LLONG_MIN -9223372036854775807 // −(2^63−1)
— maximum value for an object of type long long int
LLONG_MAX +9223372036854775807 // 2^63−1
— maximum value for an object of typeunsigned long long int
ULLONG_MAX 18446744073709551615 // 2^64−1
в крестоблядском стандарте все мутно
он импортирует <climits>, но не говорит ничего
а в драфте с++11 вообще написано, что мнение автора может не совпадать с его точкой зрения
The contents are the same as the Standard C library header <limits.h>. [ Note: The types of the constants defined by macros in <climits> are not required to match the types to which the macros refer. —end note ]
А в С99 как раз описаны минимальные ограничения для каждого типа.
> А в С99 как раз описаны минимальные ограничения для каждого типа.
Так, это уже интереснее. В С89 требование к минимуму на тип описано? С89 первый же стандарт сишки? Если в первом стандарте С89 описан минимум на тип, то гарантии наверное есть. Или нет... На каком-нибудь Арме может в limits.h лежать с вырвиглазыми размерами типов, тогда и в крестовом компиляторе все посыпется...
http://www.youtube.com/watch?v=LxHdzGDazXg