You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

string.h 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * Frozen
  3. * Copyright 2016 QuarksLab
  4. *
  5. * Licensed to the Apache Software Foundation (ASF) under one
  6. * or more contributor license agreements. See the NOTICE file
  7. * distributed with this work for additional information
  8. * regarding copyright ownership. The ASF licenses this file
  9. * to you under the Apache License, Version 2.0 (the
  10. * "License"); you may not use this file except in compliance
  11. * with the License. You may obtain a copy of the License at
  12. *
  13. * http://www.apache.org/licenses/LICENSE-2.0
  14. *
  15. * Unless required by applicable law or agreed to in writing,
  16. * software distributed under the License is distributed on an
  17. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  18. * KIND, either express or implied. See the License for the
  19. * specific language governing permissions and limitations
  20. * under the License.
  21. */
  22. #ifndef FROZEN_LETITGO_STRING_H
  23. #define FROZEN_LETITGO_STRING_H
  24. #include "frozen/bits/elsa.h"
  25. #include "frozen/bits/version.h"
  26. #include "frozen/bits/defines.h"
  27. #include <functional>
  28. #ifdef FROZEN_LETITGO_HAS_STRING_VIEW
  29. #include <string_view>
  30. #endif
  31. namespace frozen {
  32. template <typename _CharT>
  33. class basic_string {
  34. using chr_t = _CharT;
  35. chr_t const *data_;
  36. std::size_t size_;
  37. public:
  38. template <std::size_t N>
  39. constexpr basic_string(chr_t const (&data)[N])
  40. : data_(data), size_(N - 1) {}
  41. constexpr basic_string(chr_t const *data, std::size_t size)
  42. : data_(data), size_(size) {}
  43. #ifdef FROZEN_LETITGO_HAS_STRING_VIEW
  44. constexpr basic_string(std::basic_string_view<chr_t> data)
  45. : data_(data.data()), size_(data.size()) {}
  46. #endif
  47. constexpr basic_string(const basic_string &) noexcept = default;
  48. constexpr basic_string &operator=(const basic_string &) noexcept = default;
  49. constexpr std::size_t size() const { return size_; }
  50. constexpr chr_t operator[](std::size_t i) const { return data_[i]; }
  51. constexpr bool operator==(basic_string other) const {
  52. if (size_ != other.size_)
  53. return false;
  54. for (std::size_t i = 0; i < size_; ++i)
  55. if (data_[i] != other.data_[i])
  56. return false;
  57. return true;
  58. }
  59. constexpr bool operator<(const basic_string &other) const {
  60. unsigned i = 0;
  61. while (i < size() && i < other.size()) {
  62. if ((*this)[i] < other[i]) {
  63. return true;
  64. }
  65. if ((*this)[i] > other[i]) {
  66. return false;
  67. }
  68. ++i;
  69. }
  70. return size() < other.size();
  71. }
  72. constexpr const chr_t *data() const { return data_; }
  73. };
  74. template <typename _CharT> struct elsa<basic_string<_CharT>> {
  75. constexpr std::size_t operator()(basic_string<_CharT> value) const {
  76. std::size_t d = 5381;
  77. for (std::size_t i = 0; i < value.size(); ++i)
  78. d = d * 33 + value[i];
  79. return d;
  80. }
  81. // https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
  82. // With the lowest bits removed, based on experimental setup.
  83. constexpr std::size_t operator()(basic_string<_CharT> value, std::size_t seed) const {
  84. std::size_t d = (0x811c9dc5 ^ seed) * 0x01000193;
  85. for (std::size_t i = 0; i < value.size(); ++i)
  86. d = (d ^ value[i]) * 0x01000193;
  87. return d >> 8 ;
  88. }
  89. };
  90. using string = basic_string<char>;
  91. using wstring = basic_string<wchar_t>;
  92. using u16string = basic_string<char16_t>;
  93. using u32string = basic_string<char32_t>;
  94. #ifdef FROZEN_LETITGO_HAS_CHAR8T
  95. using u8string = basic_string<char8_t>;
  96. #endif
  97. namespace string_literals {
  98. constexpr string operator"" _s(const char *data, std::size_t size) {
  99. return {data, size};
  100. }
  101. constexpr wstring operator"" _s(const wchar_t *data, std::size_t size) {
  102. return {data, size};
  103. }
  104. constexpr u16string operator"" _s(const char16_t *data, std::size_t size) {
  105. return {data, size};
  106. }
  107. constexpr u32string operator"" _s(const char32_t *data, std::size_t size) {
  108. return {data, size};
  109. }
  110. #ifdef FROZEN_LETITGO_HAS_CHAR8T
  111. constexpr u8string operator"" _s(const char8_t *data, std::size_t size) {
  112. return {data, size};
  113. }
  114. #endif
  115. } // namespace string_literals
  116. } // namespace frozen
  117. namespace std {
  118. template <typename _CharT> struct hash<frozen::basic_string<_CharT>> {
  119. size_t operator()(frozen::basic_string<_CharT> s) const {
  120. return frozen::elsa<frozen::basic_string<_CharT>>{}(s);
  121. }
  122. };
  123. } // namespace std
  124. #endif