Skip to content

Instantly share code, notes, and snippets.

@lemire
Created September 12, 2024 20:38
Show Gist options
  • Save lemire/49e6cbf5cc12c4eb14c868618a1d6492 to your computer and use it in GitHub Desktop.
Save lemire/49e6cbf5cc12c4eb14c868618a1d6492 to your computer and use it in GitHub Desktop.
find_all_constexpr
#include <array>
#include <algorithm>
#include <string_view>
#include <utility>
#include <iostream>
#include <cstdint>
// Helper to get the first character of a string_view
consteval uint8_t get_first_char(std::string_view sv) {
if(sv.empty()) { return 0; }
return sv[0];
}
// Helper to find the range of strings starting with a given character
template<size_t N>
consteval std::pair<int, int> find_char_range(std::array<std::string_view, N>&arr, uint8_t c) {
auto it = std::lower_bound(arr.data(), arr.data() + N, c,
[](const auto& sv, char ch) { return get_first_char(sv) < ch; });
if (it == arr.data() + N || get_first_char(*it) != c) return {-1, -1};
auto end = std::upper_bound(it, arr.data() + N, c,
[](char ch, const auto& sv) { return ch < get_first_char(sv); });
return {static_cast<int>(it - arr.data()), static_cast<int>(end - arr.data() - 1)};
}
// Main function to sort and find ranges
template<size_t N>
consteval std::pair<std::array<std::pair<int, int>, 256>,std::array<std::string_view, N>> sort_and_range(const std::array<std::string_view, N>& arr) {
// Create a copy of the array to sort
std::array<std::string_view, N> sorted_arr = arr;
std::sort(sorted_arr.begin(), sorted_arr.end(),
[](const auto& a, const auto& b) { return get_first_char(a) < get_first_char(b); });
// Find ranges for each character
std::array<std::pair<int, int>, 256> result = {std::make_pair(-1, -1)};
for (int c = 0; c < 256; ++c) {
result[c] = find_char_range(sorted_arr, c);
}
return {result, sorted_arr};
}
bool ping(std::string_view v) {
static constexpr std::array<std::string_view, 5> otest_array = {
"banana", "apple", "cherry", "date", "elderberry"
};
static constexpr auto c = sort_and_range(otest_array);
static constexpr auto result = c.first;
static constexpr auto test_array = c.second;
auto [start, end] = result[uint8_t(v[0])];
if(start == -1) { return false; }
for(int s = start; s <= end; s++) {
if(v == test_array[s]) { return true; }
}
return false;
}
bool get(std::string_view x) {
return ping(x);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment