220 lines
5.0 KiB
C++
220 lines
5.0 KiB
C++
#pragma once
|
|
|
|
#include "tl/detail/prologue.h"
|
|
#include "tl/span.h"
|
|
#include "tl/string.h"
|
|
#include "tl/hash_and_combine.h"
|
|
|
|
namespace tl
|
|
{
|
|
namespace detail
|
|
{
|
|
namespace path_system
|
|
{
|
|
|
|
class path_view_base;
|
|
|
|
struct path_view_key_less
|
|
{
|
|
bool operator()(const path_view_base& a1, const path_view_base& a2) const noexcept;
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// inner path_view_base definition
|
|
class path_view_base
|
|
{
|
|
public:
|
|
path_view_base() noexcept;
|
|
path_view_base(tl::span<const string> elements) noexcept;
|
|
virtual ~path_view_base() noexcept = default;
|
|
using iterator = tl::span<const string>::iterator;
|
|
using const_iterator = tl::span<const string>::const_iterator;
|
|
using const_reverse_iterator = tl::span<const string>::const_reverse_iterator;
|
|
using key_less = path_view_key_less;
|
|
using value_type = std::string;
|
|
|
|
//both have checked indexing
|
|
const string& at(size_t index) const noexcept;
|
|
const string& operator[](size_t index) const noexcept;
|
|
|
|
void shrink(size_t size) noexcept;
|
|
|
|
bool empty() const noexcept;
|
|
size_t size() const noexcept;
|
|
|
|
void pop_back() noexcept;
|
|
|
|
iterator begin() noexcept;
|
|
iterator end() noexcept;
|
|
const_iterator begin() const noexcept;
|
|
const_iterator end() const noexcept;
|
|
|
|
const string& front() const noexcept;
|
|
const string& back() const noexcept;
|
|
|
|
uint32_t hash() const noexcept;
|
|
|
|
protected:
|
|
tl::span<const string> m_elements;
|
|
mutable uint32_t m_hash = 0;
|
|
|
|
friend bool path_view_key_less::operator()(const path_view_base& a1, const path_view_base& a2) const noexcept;
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
namespace tl
|
|
{
|
|
namespace detail
|
|
{
|
|
namespace path_system
|
|
{
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
inline path_view_base::path_view_base() noexcept
|
|
{
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
inline path_view_base::path_view_base(tl::span<const string> elements) noexcept
|
|
: m_elements(elements)
|
|
{
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
inline const string& path_view_base::operator[](size_t index) const noexcept
|
|
{
|
|
if (index >= m_elements.size())
|
|
TL_PLAIN_CRASH("Illegal access");
|
|
return m_elements[index];
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
inline const string& path_view_base::at(size_t index) const noexcept
|
|
{
|
|
if (index >= m_elements.size())
|
|
TL_PLAIN_CRASH("Illegal access");
|
|
return m_elements[index];
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
inline void path_view_base::shrink(size_t size) noexcept
|
|
{
|
|
if (size < this->size())
|
|
{
|
|
m_elements = tl::span<const string>(m_elements.data(), size);
|
|
m_hash = 0;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
inline uint32_t path_view_base::hash() const noexcept
|
|
{
|
|
if (m_hash == 0)
|
|
{
|
|
for (const string& e : *this)
|
|
hash_and_combine(m_hash, e);
|
|
}
|
|
return m_hash;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
inline size_t path_view_base::size() const noexcept
|
|
{
|
|
return m_elements.size();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
inline bool path_view_base::empty() const noexcept
|
|
{
|
|
return m_elements.empty();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
inline void path_view_base::pop_back() noexcept
|
|
{
|
|
if (empty())
|
|
{
|
|
TL_PLAIN_FAIL();
|
|
return;
|
|
}
|
|
|
|
m_hash = 0;
|
|
m_elements = tl::span<const string>(m_elements.data(), m_elements.size() - 1);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
inline path_view_base::iterator path_view_base::begin() noexcept
|
|
{
|
|
return m_elements.begin();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
inline path_view_base::iterator path_view_base::end() noexcept
|
|
{
|
|
return m_elements.end();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
inline path_view_base::const_iterator path_view_base::begin() const noexcept
|
|
{
|
|
return m_elements.cbegin();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
inline path_view_base::const_iterator path_view_base::end() const noexcept
|
|
{
|
|
return m_elements.cend();
|
|
}
|
|
|
|
inline const string& path_view_base::front() const noexcept
|
|
{
|
|
return m_elements.front();
|
|
}
|
|
inline const string& path_view_base::back() const noexcept
|
|
{
|
|
return m_elements.back();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
inline bool path_view_key_less::operator()(const path_view_base& a1, const path_view_base& a2) const noexcept
|
|
{
|
|
const size_t sz1 = a1.size();
|
|
const size_t sz2 = a2.size();
|
|
for (size_t i = 0; i < sz1 && i < sz2; ++i)
|
|
{
|
|
if (a1[i] != a2[i])
|
|
return a1[i].unique_key() < a2[i].unique_key();
|
|
}
|
|
return sz1 < sz2;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|