Playing around with parsing a data buffer I wrote a small search function to find the first complete match out of a set of (string) arguments.
The (simplified) buffer class with the find function:
// buffer_simple.hpp
#pragma once
#include <cstddef>
#include <utility>
template <typename T, size_t S>
class buffer {
public:
constexpr buffer() {}
template <size_t Si>
constexpr buffer(const T (&arr)[Si]) {
for (size_t i = 0, l = (S < Si ? S : Si); i < l; ++i) {
values[i] = arr[i];
}
}
/**
* Find the first matching array in a larger array and return the argument index and buffer end index of the match.
* @param str One or many strings to search for
* @returns std::pair<argument index, end of match index in buffer>
*/
template <size_t... SS>
constexpr std::pair<int, size_t> find_first(const T (&...str)[SS]) const {
size_t matching[] { (SS - 1)... }; // Amount of remaining 'characters to match'
for (size_t i = 0; i < S; ++i) { // Loop over the dataset
int mi = 0;
((matching[mi++] = (str[(SS - 1) - matching[mi]] == values[i]) ? (matching[mi] - 1) : ((str[0] == values[i]) ? (SS - 2) : (SS - 1) )), ...); // Nasty pseudo loop for width first search
for (mi = 0; mi < sizeof...(SS); ++mi) { // See if we have any full matches
if (matching[mi] == 0) return { mi, i };
}
}
return { -1, 0 };
}
constexpr T& operator[](const size_t i) { return values[i]; }
constexpr const T& operator[](const size_t i) const { return values[i]; }
private:
T values[S] {0};
};
An example use case:
#include <iostream>
#include "buffer_simple.hpp"
buffer<char, 256> b { "find mefind me:gehoehgioewghowieanother string:" };
int main () {
const auto result = b.find_first("find me:", "bla", "another string:");
// switch (result.first) {
// case 0:
// break;
// case 1:
// break;
// case 2:
// break;
// }
std::cout << "Result index: " << result.first << ", offset: " << result.second << std::endl;
}
This will return:
Result index: 0, offset: 14
Despite the extremely nasty fold expression this actually works. During runtime that is. As a test I tried declaring the buffer and search result constexpr and things blew up with GCC reporting an Array out of bounds
error. I'm curious to see which other pitfalls might be lurking.