LINUX.ORG.RU

Непонятная ошибка хеширования string_view

 ,


0

2

Пытаюсь сделать простенький парсер входных данных из string_view, разбирая токены через хеш-функцию:

#include <string_view>
#include <format>
#include <iostream>
#include <ranges>

/******************************************************************************/
inline constexpr size_t _hash (const char *str, size_t n=0) {
	// FNV-1a
	size_t res{0xcbf29ce484222325}, prime{0x00000100000001b3};
//	                  vvvvvvvvvvvvvvv здесь была ошибка
//	for (size_t i{0}; i < n or str[i]; ++i) {
	for (size_t i{0}; (i < n) or (n == 0 and str[i]); ++i) { // *fixed* FTGJ
		res = res ^ str[i];
		res = res * prime;
	}
	return res;
}

inline constexpr size_t operator ""_hash (const char *str, size_t n) {
	return _hash (str, n);
};

inline constexpr size_t _hash (const std::string_view &strv) {
	return _hash (strv.data(), strv.size());
};
auto to_string_view = [] (auto &&r) -> std::string_view {
	return std::string_view(&*r.begin(), std::ranges::distance(r));
};

auto not_empty = [](auto x) -> bool {
	return not x.empty();
};
void parse_key_flags(std::string_view input) {

	std::cout<<std::format("\"TOKEN\"_hash = {}\n", "TOKEN"_hash);

	for (auto entry : input
	                | std::views::split(' ')
	                | std::views::filter(not_empty)
	                
	) {
		
		auto row = entry | std::views::split(':')
		                 | std::views::filter(not_empty)
		                 | std::views::transform(to_string_view);
		
		auto key = row.front();
		std::cout<<std::format("key = \"{}\", tokens:\n", key);

		for (auto flag : row
		               | std::views::drop(1)
		               | std::views::transform(to_string_view)
		) {
			std::cout<<std::format("\t\"{}\" (hash = {})",flag, _hash(flag));
			switch (_hash(flag)) {
				default:
					std::cout<<" -> [FAIL]\n";
					continue;
				case "TOKEN"_hash:
					std::cout<<" -> [TOKEN]\n";
			}
		}
	}
}

Пытаюсь парсить строку

int main() {
	std::string_view input = "KEY1:TOKEN KEY2:TOKEN:FAIL";
	parse_key_flags(input);

}
И получаю ерунду
"TOKEN"_hash = 15101299456084321266 // ok
key = "KEY1", tokens:
	"TOKEN" (hash = 10353157926286166668) -> [FAIL] // WAT?
key = "KEY2", tokens:
	"TOKEN" (hash = 5196937941191725884) -> [FAIL] // WUT!?
	"FAIL" (hash = 3215402482899151853) -> [FAIL]
В чём тут дело?

★★★★★

Последнее исправление: thunar (всего исправлений: 2)
Ответ на: комментарий от bugfixer

в твоём примере тут не хватает квадратных скобок и названия функции алгоритма что бы это стало моим примером — при этом ты явно не написал внешний «накопитель», которого не нужно заводить в случае с тем что я предлагал)

safocl ★★
()
Ответ на: комментарий от safocl

ниже c++23 вообще не стоит делать проги — пожалуй теперь уже ниже c++26.

Это пока Вам в ТЗ не пропишут явно с++17, и то это ещё повезло.

Но меня умиляет Ваш юношеский задор.

AntonI ★★★★★
()
Ответ на: комментарий от AntonI

Но меня умиляет Ваш юношеский задор.

Как выяснилось у вьюноши перлов вообще предостаточно. Вот например, или вот, и особо шедевральное. Жаль что раньше не увидел, столько времени можно было бы сэкономить…

bugfixer ★★★★★
()
Ответ на: комментарий от AntonI

Это пока Вам в ТЗ не пропишут явно с++17, и то это ещё повезло.

это означает лишь некомпетентность работодателя (тимлида), либо отсутсвтие компилятора поддерживающего определённый стандарт выше... никаких иных валидных причин не может существовать.

Но меня умиляет Ваш юношеский задор.

да ну — как раз таковой «задор» это городить дублирование кода, который уже имеется в стандартной либе.

safocl ★★
()
Последнее исправление: safocl (всего исправлений: 1)
Ответ на: комментарий от safocl

это означает лишь некомпетентность работодателя

Нет, это означает что как тимлид/работодатель Вы абсолютно некомпетентны - Вы не осознаете что Ваш код не самоцель,Ваш код не более чем инструмент, небольшой кусочек мозаики в стеке самых разных технологий, от ИТ до прокатных станов. И ситуации бывают очень разные, ограничения на стандарт могут быть связаны с туевой хучей как независящих от тимлида/работодателя причин, так и вполне осознанным оптимальным выбором работодателя/тимлида связанным с внутренними факторами которые Вы в силу своей некомпетентности просто не осознаете.

Но с лямбдой головного мозга это понять слишком сложно. Не хватает лямбд, нужно больше лямбд!

Ещё я мальчиком всё думал: заведу себе зверька, а то их вона
сколько скачет по полям-то!
Возьму в товарищи разумного жирафа, муравьеда или просто кенгуру,
я даже имя подыскал:
Лямбда! Я назову его Лямбда!
...Так думал я, но детство кончилось, а бедный муравьед и по сегодня
остаётся не востребован и скачет, где скакал...

(с) Михаил Щербаков.

Но детство, как мы тут видим, кончилось не у всех:-)

AntonI ★★★★★
()
Последнее исправление: AntonI (всего исправлений: 2)