#pragma once // // This file is distributed under the MIT License. See LICENSE.md for details. // #include #include #include "llvm/ADT/StringRef.h" /// Allows passing strings as template parameters /// /// Objects of this type should only ever be constructed from a string literal. /// Internally, it stores the string (minus the last '\0' character as an array) template struct ConstexprString { public: /// The data members have to be public for a literal type to be usable as /// a template parameter :{ /// /// That being said, please, think of it as a private field and never access /// it directly. std::array String; constexpr ConstexprString(const char (&Value)[N]) noexcept requires(N >= 2) { std::copy(Value, Value + N - 1, String.data()); } constexpr ConstexprString() noexcept requires(N == 1) : String({}) {} constexpr ConstexprString(const ConstexprString &) = default; constexpr ConstexprString(ConstexprString &&) = default; constexpr ConstexprString &operator=(const ConstexprString &) = default; constexpr ConstexprString &operator=(ConstexprString &&) = default; constexpr size_t size() const noexcept { return String.size(); } constexpr const char *begin() const noexcept { return String.begin(); } constexpr const char *end() const noexcept { return String.end(); } constexpr char operator[](size_t Idx) const noexcept { return String[Idx]; } constexpr std::string_view operator*() const noexcept { return operator std::string_view(); } constexpr operator std::string_view() const noexcept { return std::string_view{ String.data(), String.size() }; } constexpr operator llvm::StringRef() const noexcept { return llvm::StringRef{ String.data(), String.size() }; } };