Added path views for abs and rel paths
This commit is contained in:
@@ -0,0 +1,219 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user