path.hpp 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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. };
  46. class path_iterator {
  47. private:
  48. string_view m_all;
  49. unsigned m_curlen = 0;
  50. int m_is_absolute;
  51. public:
  52. constexpr path_iterator() = default;
  53. constexpr path_iterator(string_view str) : m_all{str} {
  54. m_is_absolute = !m_all.empty() && m_all[0] == '/';
  55. this->operator++();
  56. }
  57. constexpr path_iterator(const std::string& str)
  58. : path_iterator{string_view{str}} {}
  59. inline path_iterator(const char* str) : path_iterator{string_view{str}} {}
  60. constexpr operator bool() const { return !m_all.empty(); }
  61. constexpr bool is_absolute() const { return m_is_absolute; }
  62. constexpr string_view operator*() const {
  63. return string_view{m_all.data(), m_curlen};
  64. }
  65. constexpr path_iterator& operator++() {
  66. std::size_t start = m_curlen;
  67. while (start < m_all.size() && m_all[start] == '/')
  68. ++start;
  69. m_all = string_view{m_all.data() + start, m_all.size() - start};
  70. if (m_all.empty())
  71. return *this;
  72. m_curlen = 0;
  73. while (m_curlen < m_all.size() && m_all[m_curlen] != '/')
  74. ++m_curlen;
  75. return *this;
  76. }
  77. };
  78. } // namespace types