#include #include #include #include // ----- Fixed string NTTP (chapter 19) ----- // A tiny compile‑time string wrapper used as a non‑type template parameter. // The implementation follows the recipe shown in chapter 19. template struct fixed_string { char data[N + 1]{}; constexpr fixed_string() = default; constexpr fixed_string(const char (&s)[N + 1]) { for (std::size_t i = 0; i < N; ++i) data[i] = s[i]; data[N] = '\0'; } constexpr const char* c_str() const { return data; } }; // ----- Schema ----- // A table row is a plain aggregate struct (chapter 3). struct Row { int id; int value; }; constexpr Row table[] = { {1, 10}, {2, 20}, {3, 30}, }; // ----- Query representation ----- struct Query { fixed_string<16> select; // column after SELECT fixed_string<16> where; // column after WHERE char op; // only '>' supported for now int rhs; // right‑hand side constant }; // ----- Helper utilities ----- consteval const char* skip_ws(const char* p) { while (*p == ' ' || *p == '\t' || *p == '\n') ++p; return p; } consteval std::size_t read_ident(const char* p, char* out) { std::size_t i = 0; while (*p && *p != ' ' && *p != '\t' && *p != '\n' && *p != ',' && *p != ';') { out[i++] = *p++; } out[i] = '\0'; return i; } consteval int read_number(const char* p, const char*& end) { int value = 0; while (*p >= '0' && *p <= '9') { value = value * 10 + (*p - '0'); ++p; } end = p; return value; } // ----- Compile‑time parser ----- // Parses a very small subset of SQL: SELECT FROM WHERE > consteval Query parse_query(const char* qs) { const char* p = qs; p = skip_ws(p); // SELECT keyword (assumed present) p += 6; // skip "SELECT" p = skip_ws(p); char sel[17]{}; read_ident(p, sel); p += std::char_traits::length(sel); p = skip_ws(p); // FROM keyword (ignored, table name is fixed) p += 4; // skip "FROM" p = skip_ws(p); while (*p && *p != ' ') ++p; // skip table identifier p = skip_ws(p); // WHERE keyword p += 5; // skip "WHERE" p = skip_ws(p); char wh[17]{}; read_ident(p, wh); p += std::char_traits::length(wh); p = skip_ws(p); // operator – only '>' is accepted char op = *p; ++p; p = skip_ws(p); const char* num_end = nullptr; int rhs = read_number(p, num_end); Query q{}; q.select = fixed_string<16>{sel}; q.where = fixed_string<16>{wh}; q.op = op; q.rhs = rhs; return q; } // ----- Evaluation ----- // Walks the constexpr table and collects matching rows into a fixed‑size std::array. consteval std::array eval(const Query& q) { std::array out{{0, 0, 0}}; std::size_t idx = 0; for (const Row& r : table) { int lhs = (std::string_view(q.where.c_str()) == "value") ? r.value : 0; bool ok = false; if (q.op == '>') ok = lhs > q.rhs; if (ok) { out[idx++] = (std::string_view(q.select.c_str()) == "id") ? r.id : r.value; } } return out; } int main() { // The query is parsed at compile time; any syntax error aborts compilation. constexpr auto q = parse_query("SELECT id FROM table WHERE value > 15"); static_assert(std::string_view(q.select.c_str()) == "id", "wrong SELECT column"); static_assert(std::string_view(q.where.c_str()) == "value", "wrong WHERE column"); static_assert(q.rhs == 15, "wrong constant"); constexpr auto result = eval(q); static_assert(result[0] == 2, "first matching id"); static_assert(result[1] == 3, "second matching id"); std::cout << "constexpr‑SQL capstone OK" << '\n'; }