Added path views for abs and rel paths
This commit is contained in:
@@ -28,36 +28,38 @@ public:
|
||||
using key_less = path_key_less<PathSystems>;
|
||||
using value_type = std::string;
|
||||
|
||||
//checked indexing
|
||||
const string& at(size_t index) const noexcept;
|
||||
//both have checked indexing
|
||||
const string& operator[](size_t index) const noexcept;
|
||||
string& operator[](size_t index) noexcept;
|
||||
const string& at(size_t index) const noexcept;
|
||||
string& at(size_t index) noexcept;
|
||||
|
||||
void shrink(size_t size) noexcept;
|
||||
|
||||
bool empty() const noexcept;
|
||||
size_t size() const noexcept;
|
||||
size_t size() const noexcept;
|
||||
void reserve(size_t capacity) noexcept;
|
||||
|
||||
// if the path is empty, these operations have no effect. They return the removed element as a string.
|
||||
string pop_back() noexcept;
|
||||
virtual bool push_back(string element) noexcept;
|
||||
string pop_back() noexcept;
|
||||
virtual bool push_back(string element) noexcept;
|
||||
|
||||
virtual void take_elements(tl::vector<string>&& elements) noexcept;
|
||||
virtual void take_elements(tl::vector<string>&& elements) noexcept;
|
||||
|
||||
iterator begin() noexcept;
|
||||
iterator end() noexcept;
|
||||
iterator begin() noexcept;
|
||||
iterator end() noexcept;
|
||||
const_iterator begin() const noexcept;
|
||||
const_iterator end() const noexcept;
|
||||
const_reverse_iterator rbegin() const noexcept;
|
||||
const_reverse_iterator rend() const noexcept;
|
||||
|
||||
uint32_t hash() const noexcept;
|
||||
uint32_t hash() const noexcept;
|
||||
|
||||
protected:
|
||||
bool validate_element(const string& element) noexcept;
|
||||
void push_element(string element) noexcept;
|
||||
void push_element(string element) noexcept;
|
||||
|
||||
tl::vector<string> m_elements;
|
||||
mutable uint32_t m_hash = 0;
|
||||
mutable uint32_t m_hash = 0;
|
||||
|
||||
friend bool path_key_less<PathSystems>::operator()(const path_base<PathSystems>& a1, const path_base<PathSystems>& a2) const noexcept;
|
||||
};
|
||||
@@ -87,9 +89,43 @@ namespace path_system
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename PathSystems>
|
||||
const string& path_base<PathSystems>::operator[](size_t index) const noexcept
|
||||
{
|
||||
if (index >= m_elements.size())
|
||||
TL_PLAIN_CRASH("Illegal access");
|
||||
return m_elements[index];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename PathSystems>
|
||||
string& path_base<PathSystems>::operator[](size_t index) noexcept
|
||||
{
|
||||
if (index >= m_elements.size())
|
||||
TL_PLAIN_CRASH("Illegal access");
|
||||
m_hash = 0;
|
||||
return m_elements[index];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename PathSystems>
|
||||
const string& path_base<PathSystems>::at(size_t index) const noexcept
|
||||
{
|
||||
if (index >= m_elements.size())
|
||||
TL_PLAIN_CRASH("Illegal access");
|
||||
return m_elements[index];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename PathSystems>
|
||||
string& path_base<PathSystems>::at(size_t index) noexcept
|
||||
{
|
||||
if (index >= m_elements.size())
|
||||
TL_PLAIN_CRASH("Illegal access");
|
||||
m_hash = 0;
|
||||
return m_elements[index];
|
||||
}
|
||||
|
||||
@@ -164,25 +200,7 @@ string path_base<PathSystems>::pop_back() noexcept
|
||||
template <typename PathSystems>
|
||||
bool path_base<PathSystems>::push_back(string element) noexcept
|
||||
{
|
||||
if (!validate_element(element))
|
||||
{
|
||||
TL_PLAIN_FAIL("Pushed an invalid path element.");
|
||||
return false;
|
||||
}
|
||||
|
||||
push_element(std::move(element));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename PathSystems>
|
||||
bool path_base<PathSystems>::validate_element(const string& /*element*/) noexcept
|
||||
{
|
||||
// validate element to be added here
|
||||
// if not return false
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <EASTL/fixed_string.h>
|
||||
|
||||
#include "tl/detail/prologue.h"
|
||||
#include <EASTL/fixed_vector.h>
|
||||
#include "tl/string.h"
|
||||
@@ -15,9 +17,9 @@ namespace path_system
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename T>
|
||||
void simple_format_rel_path(T& o_buffer, const tl::vector<string>& members, const char* separator) noexcept;
|
||||
void simple_format_rel_path(T& o_buffer, tl::span<const string> members, const char* separator) noexcept;
|
||||
template<typename T>
|
||||
void simple_format_abs_path(T& o_buffer, const tl::vector<string>& members, const char* root_tag, const char* separator) noexcept;
|
||||
void simple_format_abs_path(T& o_buffer, tl::span<const string> members, const char* root_tag, const char* separator) noexcept;
|
||||
|
||||
inline bool find_next_separator(const char* const* separators_begin, const char* const* separators_end, const char*& io_startIt, const char* end, const char*& io_endIt) noexcept;
|
||||
|
||||
@@ -31,10 +33,10 @@ template<int Index, typename... Tail>
|
||||
struct path_system_getter
|
||||
{
|
||||
template<typename T>
|
||||
static T format_absolute(int type_idx, const tl::vector<string>& members) noexcept;
|
||||
static void parse_absolute(tl::vector<string>& o_elements, int type_idx, const char* path, size_t size) noexcept;
|
||||
static T format_abs(int type_idx, tl::span<const string> members) noexcept;
|
||||
static void parse_abs(tl::vector<string>& o_elements, int type_idx, const char* path, size_t size) noexcept;
|
||||
static int deduce_system_type(const char* path, size_t size) noexcept;
|
||||
static bool validate_abs_path(int type_idx, const tl::vector<string>& members) noexcept;
|
||||
static bool validate_abs_path(int type_idx, tl::span<const string> members) noexcept;
|
||||
};
|
||||
|
||||
// specialization if Head element exists
|
||||
@@ -42,10 +44,10 @@ template<int Index, typename Head, typename... Tail>
|
||||
struct path_system_getter<Index, Head, Tail...>
|
||||
{
|
||||
template<typename T>
|
||||
static T format_absolute(int type_idx, const tl::vector<string>& members) noexcept;
|
||||
static void parse_absolute(tl::vector<string>& o_elements, int type_idx, const char* path, size_t size) noexcept;
|
||||
static T format_abs(int type_idx, tl::span<const string> members) noexcept;
|
||||
static void parse_abs(tl::vector<string>& o_elements, int type_idx, const char* path, size_t size) noexcept;
|
||||
static int deduce_system_type(const char* path, size_t size) noexcept;
|
||||
static bool validate_abs_path(int type_idx, const tl::vector<string>& members) noexcept;
|
||||
static bool validate_abs_path(int type_idx, tl::span<const string> members) noexcept;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -85,7 +87,8 @@ struct base_path_system
|
||||
static const tl::vector<const char*>& get_parse_separators() noexcept;
|
||||
static const char* get_format_separator() noexcept;
|
||||
|
||||
static string format_relative(const tl::vector<string>& members) noexcept;
|
||||
template<typename T>
|
||||
static T format_rel(tl::span<const string> members) noexcept;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -110,7 +113,7 @@ namespace path_system
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename T>
|
||||
void simple_format_rel_path(T& o_buffer, const tl::vector<string>& members, const char* separator) noexcept
|
||||
void simple_format_rel_path(T& o_buffer, tl::span<const string> members, const char* separator) noexcept
|
||||
{
|
||||
//calculate the size to reserve
|
||||
size_t totalSize = 0;
|
||||
@@ -133,8 +136,18 @@ void simple_format_rel_path(T& o_buffer, const tl::vector<string>& members, cons
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<>
|
||||
inline void simple_format_rel_path(string& o_buffer, tl::span<const string> members, const char* separator) noexcept
|
||||
{
|
||||
tl::fixed_string<char, 1024> temp;
|
||||
simple_format_rel_path(temp, members, separator);
|
||||
o_buffer = string(temp);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename T>
|
||||
void simple_format_abs_path(T& o_buffer, const tl::vector<string>& members, const char* root_tag, const char* separator) noexcept
|
||||
void simple_format_abs_path(T& o_buffer, tl::span<const string> members, const char* root_tag, const char* separator) noexcept
|
||||
{
|
||||
o_buffer.append(root_tag);
|
||||
detail::path_system::simple_format_rel_path(o_buffer, members, separator);
|
||||
@@ -246,16 +259,16 @@ inline bool simple_match_prefix(const char* path, size_t size, const char* prefi
|
||||
|
||||
template<int Index, typename... Tail>
|
||||
template<typename T>
|
||||
T path_system_getter<Index, Tail...>::format_absolute(int /*type_idx*/, const tl::vector<string>& /*members*/) noexcept
|
||||
T path_system_getter<Index, Tail...>::format_abs(int /*type_idx*/, tl::span<const string> /*members*/) noexcept
|
||||
{
|
||||
TL_PLAIN_FAIL("Failed to format path. Invalid type.");
|
||||
return {};
|
||||
}
|
||||
|
||||
template<int Index, typename... Tail>
|
||||
void path_system_getter<Index, Tail...>::parse_absolute(tl::vector<string>& /*o_elements*/, int /*type_idx*/, const char* /*path*/, size_t /* size */) noexcept
|
||||
void path_system_getter<Index, Tail...>::parse_abs(tl::vector<string>& /*o_elements*/, int /*type_idx*/, const char* /*path*/, size_t /* size */) noexcept
|
||||
{
|
||||
TL_PLAIN_FAIL("Failed parsing absolute path. Invalid type.");
|
||||
TL_PLAIN_FAIL("Failed parsing abs path. Invalid type.");
|
||||
}
|
||||
|
||||
template<int Index, typename... Tail>
|
||||
@@ -265,7 +278,7 @@ int path_system_getter<Index, Tail...>::deduce_system_type(const char* /*path*/,
|
||||
}
|
||||
|
||||
template<int Index, typename... Tail>
|
||||
bool path_system_getter<Index, Tail...>::validate_abs_path(int /*type_idx*/, const tl::vector<string>& /*members*/) noexcept
|
||||
bool path_system_getter<Index, Tail...>::validate_abs_path(int /*type_idx*/, tl::span<const string> /*members*/) noexcept
|
||||
{
|
||||
TL_PLAIN_FAIL("Failed validating path system. Invalid type.");
|
||||
return false;
|
||||
@@ -275,23 +288,23 @@ bool path_system_getter<Index, Tail...>::validate_abs_path(int /*type_idx*/, con
|
||||
|
||||
template<int Index, typename Head, typename... Tail>
|
||||
template<typename T>
|
||||
T path_system_getter<Index, Head, Tail...>::format_absolute(int type_idx, const tl::vector<string>& members) noexcept
|
||||
T path_system_getter<Index, Head, Tail...>::format_abs(int type_idx, tl::span<const string> members) noexcept
|
||||
{
|
||||
if (type_idx == Index)
|
||||
return Head::template format_absolute<T>(members);
|
||||
return Head::template format_abs<T>(members);
|
||||
|
||||
return path_system_getter<Index + 1, Tail...>::template format_absolute<T>(type_idx, members);
|
||||
return path_system_getter<Index + 1, Tail...>::template format_abs<T>(type_idx, members);
|
||||
}
|
||||
|
||||
template<int Index, typename Head, typename... Tail>
|
||||
void path_system_getter<Index, Head, Tail...>::parse_absolute(tl::vector<string>& o_elements, int type_idx, const char* path, size_t size) noexcept
|
||||
void path_system_getter<Index, Head, Tail...>::parse_abs(tl::vector<string>& o_elements, int type_idx, const char* path, size_t size) noexcept
|
||||
{
|
||||
if (type_idx == Index)
|
||||
{
|
||||
Head::parse_absolute(o_elements, path, size);
|
||||
Head::parse_abs(o_elements, path, size);
|
||||
return;
|
||||
}
|
||||
path_system_getter<Index + 1, Tail...>::parse_absolute(o_elements, type_idx, path, size);
|
||||
path_system_getter<Index + 1, Tail...>::parse_abs(o_elements, type_idx, path, size);
|
||||
}
|
||||
|
||||
|
||||
@@ -305,7 +318,7 @@ int path_system_getter<Index, Head, Tail...>::deduce_system_type(const char* pat
|
||||
}
|
||||
|
||||
template<int Index, typename Head, typename... Tail>
|
||||
bool path_system_getter<Index, Head, Tail...>::validate_abs_path(int type_idx, const tl::vector<string>& members) noexcept
|
||||
bool path_system_getter<Index, Head, Tail...>::validate_abs_path(int type_idx, tl::span<const string> members) noexcept
|
||||
{
|
||||
if (type_idx == Index)
|
||||
return Head::validate_abs_path(members);
|
||||
@@ -365,15 +378,12 @@ const tl::vector<const char*>& base_path_system<parse_separators, format_separat
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename parse_separators, typename format_separator>
|
||||
string base_path_system<parse_separators, format_separator>::format_relative(const tl::vector<string>& members) noexcept
|
||||
template<typename T>
|
||||
T base_path_system<parse_separators, format_separator>::format_rel(tl::span<const string> members) noexcept
|
||||
{
|
||||
eastl::string buffer;
|
||||
buffer.reserve(8192);
|
||||
detail::path_system::simple_format_rel_path(buffer, members, format_separator::value());
|
||||
if (buffer.data())
|
||||
return string(buffer.data(), buffer.size());
|
||||
|
||||
return string();
|
||||
T string;
|
||||
detail::path_system::simple_format_rel_path(string, members, format_separator::value());
|
||||
return string;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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