123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- #pragma once
- #include <types/string.hpp>
- #include <vector>
- #include <cstddef>
- namespace types {
- class path {
- public:
- using item_string = types::string<>;
- using item_vector = std::vector<item_string>;
- using string_type = types::string<>;
- using size_type = std::size_t;
- using iterator = item_vector::const_iterator;
- private:
- item_vector m_vec;
- public:
- constexpr path() = default;
- constexpr path(const path& val) = default;
- constexpr path(path&& val) = default;
- constexpr path(const char* str, size_type len = -1U)
- { append(str, len); }
- constexpr path& operator=(const path& val) = default;
- constexpr path& operator=(path&& val) = default;
- constexpr path& operator=(const char* str)
- {
- m_vec.clear();
- append(str);
- return *this;
- }
- constexpr string_type full_path() const
- {
- string_type str;
- for (auto iter = m_vec.begin(); iter != m_vec.end(); ++iter) {
- if (iter != m_vec.begin()
- || (m_vec.front().empty() && m_vec.size() == 1))
- str += '/';
- str += *iter;
- }
- return str;
- }
- constexpr item_string last_name() const
- { return m_vec.empty() ? item_string {} : m_vec.back(); }
- constexpr bool empty() const
- { return m_vec.empty(); }
- constexpr bool is_absolute() const { return !empty() && !m_vec[0][0]; }
- constexpr bool is_relative() const { return !empty() && !is_absolute(); }
- constexpr path& append(const char* str, size_type len = -1U)
- {
- const char* start = str;
- while (len-- && *str) {
- if (*str == '/') {
- if (m_vec.empty() || str != start)
- m_vec.emplace_back(start, str - start);
- start = str + 1;
- }
- ++str;
- }
- if (str != start || m_vec.size() != 1 || !m_vec.front().empty())
- m_vec.emplace_back(start, str - start);
- return *this;
- }
- constexpr path& append(const path& val)
- {
- m_vec.insert(m_vec.end(), val.m_vec.begin(), val.m_vec.end());
- return *this;
- }
- constexpr void clear() { m_vec.clear(); }
- constexpr void remove_last()
- {
- if (m_vec.size() > 1)
- m_vec.pop_back();
- }
- constexpr path& operator+=(const char* str)
- { return append(str); }
- constexpr path& operator+=(const path& val)
- { return append(val); }
- constexpr bool operator==(const char* str) const
- {
- return full_path() == str;
- }
- constexpr iterator begin() const { return m_vec.cbegin(); }
- constexpr iterator end() const { return m_vec.cend(); }
- };
- constexpr path make_path(const char* pathstr, const char* pwd)
- {
- if (*pathstr && pathstr[0] == '/')
- return pathstr;
- else
- return path { pwd }.append(pathstr);
- }
- constexpr path make_path(const char* pathstr, const path& pwd)
- {
- if (*pathstr && pathstr[0] == '/')
- return pathstr;
- else
- return path{pwd}.append(pathstr);
- }
- } // namespace types
|