.. _program_listing_file_include_ct_string.inl: Program Listing for File ct_string.inl ====================================== |exhale_lsh| :ref:`Return to documentation for file ` (``include/ct_string.inl``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #pragma once #include #include #include // std::invoke #include #include // std::move, std::index_sequence_for namespace ctql { template struct ct_string { std::array data{}; constexpr ct_string() = default; constexpr ct_string(const char (&str)[N + 1]) { for (std::size_t i = 0; i < N + 1; ++i) data[i] = str[i]; } constexpr const char* c_str() const { return data.data(); } constexpr std::size_t size() const { return N; } constexpr operator std::string_view() const { return {data.data(), N}; } }; template ct_string(const char (&)[N]) -> ct_string; template constexpr auto operator+(const ct_string& lhs, const ct_string& rhs) { ct_string result; for (std::size_t i = 0; i < N1; ++i) result.data[i] = lhs.data[i]; for (std::size_t i = 0; i < N2; ++i) result.data[N1 + i] = rhs.data[i]; result.data[N1 + N2] = '\0'; return result; } template constexpr bool operator==(const ct_string& lhs, const ct_string& rhs) { if constexpr (N1 != N2) return false; else { for (std::size_t i = 0; i < N1; ++i) { if (lhs.data[i] != rhs.data[i]) return false; } return true; } } consteval std::size_t count_digits(std::size_t n) { std::size_t digits = 1; while (n /= 10) ++digits; return digits; } template consteval auto to_ct_string() { constexpr std::size_t digits = count_digits(N); ct_string result; std::size_t n = N; for (std::size_t i = 0; i < digits; ++i) result.data[digits - 1 - i] = char('0' + (n % 10)), n /= 10; result.data[digits] = '\0'; return result; } template constexpr auto operator""_ct() { return str; } template struct match : Lambda_t... { using Lambda_t::operator()...; constexpr match(Lambda_t... lambda) : Lambda_t(std::move(lambda))... {} }; #define $match(arg, ...) std::invoke(ctql::match{__VA_ARGS__}, arg) template constexpr void foreach_indexed(Fn&& fn) { [&](std::index_sequence) { (std::forward(fn).template operator()(), ...); }(std::index_sequence_for{}); } }