path.hpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #pragma once
  2. #include <cstddef>
  3. #include <string>
  4. #include <vector>
  5. namespace types {
  6. class string_view {
  7. private:
  8. const char* m_str;
  9. std::size_t m_len;
  10. public:
  11. constexpr string_view() : m_str(nullptr), m_len(0) {}
  12. constexpr string_view(const char* str, std::size_t len)
  13. : m_str(str), m_len(len) {}
  14. constexpr string_view(const std::string& str)
  15. : m_str(str.c_str()), m_len(str.size()) {}
  16. inline string_view(const char* str)
  17. : m_str(str), m_len(std::char_traits<char>::length(str)) {}
  18. constexpr const char* data() const { return m_str; }
  19. constexpr std::size_t size() const { return m_len; }
  20. constexpr bool empty() const { return m_len == 0; }
  21. constexpr const char* begin() const { return m_str; }
  22. constexpr const char* end() const { return m_str + m_len; }
  23. constexpr char operator[](std::size_t pos) const { return m_str[pos]; }
  24. constexpr bool operator==(const string_view& val) const {
  25. if (m_len != val.m_len)
  26. return false;
  27. for (std::size_t i = 0; i < m_len; ++i) {
  28. if (m_str[i] != val.m_str[i])
  29. return false;
  30. }
  31. return true;
  32. }
  33. constexpr bool operator==(const char* str) const {
  34. for (std::size_t i = 0; i < m_len; ++i) {
  35. if (m_str[i] != str[i])
  36. return false;
  37. }
  38. return str[m_len] == '\0';
  39. }
  40. constexpr bool operator==(const std::string& str) const {
  41. if (m_len != str.size())
  42. return false;
  43. return operator==(str.c_str());
  44. }
  45. constexpr bool operator<(const string_view& val) const {
  46. for (std::size_t i = 0; i < m_len && i < val.m_len; ++i) {
  47. if (m_str[i] < val.m_str[i])
  48. return true;
  49. if (m_str[i] > val.m_str[i])
  50. return false;
  51. }
  52. return m_len < val.m_len;
  53. }
  54. };
  55. class path_iterator {
  56. private:
  57. string_view m_all;
  58. unsigned m_curlen = 0;
  59. int m_is_absolute;
  60. public:
  61. constexpr path_iterator() = default;
  62. constexpr path_iterator(string_view str) : m_all{str} {
  63. m_is_absolute = !m_all.empty() && m_all[0] == '/';
  64. this->operator++();
  65. }
  66. constexpr path_iterator(const std::string& str)
  67. : path_iterator{string_view{str}} {}
  68. inline path_iterator(const char* str) : path_iterator{string_view{str}} {}
  69. constexpr operator bool() const { return !m_all.empty(); }
  70. constexpr bool is_absolute() const { return m_is_absolute; }
  71. constexpr string_view operator*() const {
  72. return string_view{m_all.data(), m_curlen};
  73. }
  74. constexpr path_iterator& operator++() {
  75. std::size_t start = m_curlen;
  76. while (start < m_all.size() && m_all[start] == '/')
  77. ++start;
  78. m_all = string_view{m_all.data() + start, m_all.size() - start};
  79. if (m_all.empty())
  80. return *this;
  81. m_curlen = 0;
  82. while (m_curlen < m_all.size() && m_all[m_curlen] != '/')
  83. ++m_curlen;
  84. return *this;
  85. }
  86. };
  87. } // namespace types