path.hpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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
  24. { return m_str[pos]; }
  25. constexpr bool operator==(const string_view& val) const
  26. {
  27. if (m_len != val.m_len)
  28. return false;
  29. for (std::size_t i = 0; i < m_len; ++i) {
  30. if (m_str[i] != val.m_str[i])
  31. return false;
  32. }
  33. return true;
  34. }
  35. constexpr bool operator==(const char* str) const
  36. {
  37. for (std::size_t i = 0; i < m_len; ++i) {
  38. if (m_str[i] != str[i])
  39. return false;
  40. }
  41. return str[m_len] == '\0';
  42. }
  43. constexpr bool operator==(const std::string& str) const
  44. {
  45. if (m_len != str.size())
  46. return false;
  47. return operator==(str.c_str());
  48. }
  49. };
  50. class path_iterator {
  51. private:
  52. string_view m_all;
  53. unsigned m_curlen = 0;
  54. int m_is_absolute;
  55. public:
  56. constexpr path_iterator() = default;
  57. constexpr path_iterator(string_view str): m_all{str}
  58. {
  59. m_is_absolute = !m_all.empty() && m_all[0] == '/';
  60. this->operator++();
  61. }
  62. constexpr path_iterator(const std::string& str): path_iterator{string_view{str}} { }
  63. inline path_iterator(const char* str): path_iterator{string_view{str}} { }
  64. constexpr operator bool() const { return !m_all.empty(); }
  65. constexpr bool is_absolute() const { return m_is_absolute; }
  66. constexpr string_view operator*() const { return string_view{m_all.data(), m_curlen}; }
  67. constexpr path_iterator& operator++()
  68. {
  69. std::size_t start = m_curlen;
  70. while (start < m_all.size() && m_all[start] == '/')
  71. ++start;
  72. m_all = string_view{m_all.data() + start, m_all.size() - start};
  73. if (m_all.empty())
  74. return *this;
  75. m_curlen = 0;
  76. while (m_curlen < m_all.size() && m_all[m_curlen] != '/')
  77. ++m_curlen;
  78. return *this;
  79. }
  80. };
  81. } // namespace types