00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #pragma once
00018
00019 #include "AITypes.h"
00020
00021 #include <cstddef>
00022 #include <stdexcept>
00023 #include <cstring>
00024
00025 namespace ai
00026 {
00051 namespace details
00052 {
00053 constexpr bool compare_less(const char* str1, std::size_t len1, const char* str2, std::size_t len2) AINOEXCEPT
00054 {
00055 return (len2 == 0) ? false :
00056 (len1 == 0) ? true :
00057 (*str1 != *str2) ? (*str1 < *str2) :
00058 compare_less(str1 + 1, len1 - 1, str2 + 1, len2 - 1);
00059 }
00060
00061 constexpr bool compare_equal(const char* str1, std::size_t len1, const char* str2, std::size_t len2) AINOEXCEPT
00062 {
00063 return (len1 == 0 && len2 == 0) ? true :
00064 (len1 == 0 || len2 == 0) ? false :
00065 (*str1 != *str2) ? false :
00066 compare_equal(str1 + 1, len1 - 1, str2 + 1, len2 - 1);
00067 }
00068
00069 }
00070
00071
00072 class LiteralString
00073 {
00074 public:
00075 using const_iterator = const char*;
00076
00077 template<std::size_t N>
00078 constexpr LiteralString(const char(&arr)[N]) AINOEXCEPT : str{arr}, len{N - 1}
00079 {
00080 static_assert(N >= 1, "not a string literal");
00081 }
00082
00083 constexpr char operator[](std::size_t i) const
00084 {
00085 return i < len ? str[i] : throw std::out_of_range{""};
00086 }
00087
00088 constexpr std::size_t size() const AINOEXCEPT { return len; }
00089
00092 constexpr operator const char*() const AINOEXCEPT { return str; }
00093
00097 constexpr const char* c_str() const AINOEXCEPT { return str; }
00098
00101 constexpr const_iterator begin() const AINOEXCEPT { return str; }
00102
00105 constexpr const_iterator end() const AINOEXCEPT { return str + len; }
00106
00107 private:
00108 const char* const str;
00109 const std::size_t len;
00110 };
00111
00114 inline constexpr bool operator<(ai::LiteralString lhs, ai::LiteralString rhs) AINOEXCEPT
00115 {
00116 return details::compare_less(lhs, lhs.size(), rhs, rhs.size());
00117 }
00118
00121 inline constexpr bool operator>(ai::LiteralString lhs, ai::LiteralString rhs) AINOEXCEPT
00122 {
00123 return (rhs < lhs);
00124 }
00125
00126 inline constexpr bool operator==(ai::LiteralString lhs, ai::LiteralString rhs) AINOEXCEPT
00127 {
00128 return details::compare_equal(lhs, lhs.size(), rhs, rhs.size());
00129 }
00130
00131 inline bool operator==(ai::LiteralString lhs, const char* rhs)
00132 {
00133 return (std::strcmp(lhs.c_str(), rhs) == 0);
00134 }
00135
00136 inline bool operator==(const char* lhs, ai::LiteralString rhs)
00137 {
00138 return (rhs == lhs);
00139 }
00140
00141 constexpr ai::LiteralString kEmptyLiteralString { "" };
00142
00143 }