准备新增字符串的增强结构,包括编译期字符串
This commit is contained in:
1
CP.hpp
1
CP.hpp
@@ -12,5 +12,6 @@
|
||||
#include "detail/CP/MaxMin.hpp"
|
||||
#include "detail/CP/Arithmetic.hpp"
|
||||
#include "detail/CP/Typen.hpp"
|
||||
#include "detail\CP\CPString.hpp"
|
||||
|
||||
#endif // __FILE_Operator_Hpp
|
||||
|
1
Core.hpp
1
Core.hpp
@@ -3,5 +3,6 @@
|
||||
#define __FILE_Core_Hpp
|
||||
|
||||
#include "detail/Core/Object.hpp"
|
||||
#include "detail\Core\String.hpp"
|
||||
|
||||
#endif // !__FILE_Core_Hpp
|
||||
|
@@ -46,6 +46,20 @@ inline uint32_t Hash(const int64_t A)
|
||||
return (uint32_t)A + ((uint32_t)(A >> 32) * 23);
|
||||
}
|
||||
|
||||
uint32_t Hash(const char* str, uint32_t hash = 5381)
|
||||
{
|
||||
return *str == '\0' ? hash : Hash(str + 1, ((hash << 5) + hash) + *str);
|
||||
}
|
||||
|
||||
uint32_t Hash(std::string_view str, uint32_t hash = 5381)
|
||||
{
|
||||
for (size_t i = 0; i < str.length(); ++i)
|
||||
{
|
||||
hash = ((hash << 5) + hash) + str[i];
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
constexpr uint32_t CHash(const uint8_t A)
|
||||
{
|
||||
return A;
|
||||
|
7
detail/CP/CPString.hpp
Normal file
7
detail/CP/CPString.hpp
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
#ifndef __FILE_Detail_CP_CPString_H
|
||||
#define __FILE_Detail_CP_CPString_H
|
||||
|
||||
|
||||
|
||||
#endif // !__FILE_Detail_CP_CPString_H
|
174
detail/Core/String.hpp
Normal file
174
detail/Core/String.hpp
Normal file
@@ -0,0 +1,174 @@
|
||||
#pragma once
|
||||
#ifndef __FILE_Detail_Core_String_H
|
||||
#define __FILE_Detail_Core_String_H
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
template<typename Char>
|
||||
class PrefixStringTree
|
||||
{
|
||||
public:
|
||||
PrefixStringTree<Char>* parent;
|
||||
PrefixStringTree<Char>* child_head;
|
||||
PrefixStringTree<Char>* child_end;
|
||||
PrefixStringTree<Char>* next;
|
||||
|
||||
using my_string_view = std::basic_string_view<Char>;
|
||||
private:
|
||||
Char mine;
|
||||
Char* data;
|
||||
my_string_view rdata;
|
||||
public:
|
||||
my_string_view ReadValue() const
|
||||
{
|
||||
return rdata;
|
||||
}
|
||||
|
||||
constexpr operator my_string_view() const
|
||||
{
|
||||
return rdata;
|
||||
}
|
||||
|
||||
PrefixStringTree<Char>& PopBack()
|
||||
{
|
||||
if (parent)
|
||||
return *parent;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
void RegetDataFromChild(PrefixStringTree<Char>* target)
|
||||
{
|
||||
auto size = this->rdata.size();
|
||||
if (data)
|
||||
{
|
||||
delete this->data;
|
||||
this->data = target->data;
|
||||
}
|
||||
this->rdata = target->rdata.substr(0, size);
|
||||
if (parent)
|
||||
parent->RegetDataFromChild(target);
|
||||
}
|
||||
PrefixStringTree<Char>* AddChild(Char ch)
|
||||
{
|
||||
auto next = child_head;
|
||||
child_head = new PrefixStringTree<Char>();
|
||||
if (next == nullptr)
|
||||
{
|
||||
child_end = child_head;
|
||||
}
|
||||
child_head->mine = ch;
|
||||
const auto size = rdata.size();
|
||||
child_head->data = new Char[size + 1];
|
||||
::strcpy_s(child_head->data, size, data);
|
||||
child_head->data[size] = ch;
|
||||
child_head->rdata = child_head->data;
|
||||
child_head->next = next;
|
||||
RegetDataFromChild(child_head);
|
||||
return child_head;
|
||||
}
|
||||
PrefixStringTree<Char>* FindChild(Char ch)
|
||||
{
|
||||
for (auto head = child_head; head; head = head->next)
|
||||
{
|
||||
if (head->mine)
|
||||
return head;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
public:
|
||||
PrefixStringTree<Char>& operator+(Char ch)
|
||||
{
|
||||
if (ch == 0)
|
||||
return *this;
|
||||
auto result = FindChild(ch);
|
||||
if (result)
|
||||
return *result;
|
||||
return *AddChild(ch);
|
||||
}
|
||||
|
||||
PrefixStringTree<Char>& operator+(my_string_view view)
|
||||
{
|
||||
if (view.size() == 0 || view.front() == 0)
|
||||
return *this;
|
||||
return this->operator+(view.front()).operator+(view.substr(1));
|
||||
}
|
||||
|
||||
bool operator==(my_string_view str)
|
||||
{
|
||||
return rdata == str;
|
||||
}
|
||||
bool operator!=(my_string_view str)
|
||||
{
|
||||
return rdata != str;
|
||||
}
|
||||
|
||||
static PrefixStringTree<Char>& GetRoot()
|
||||
{
|
||||
static PrefixStringTree<Char> root;
|
||||
return root;
|
||||
}
|
||||
|
||||
decltype(auto) GetSize()
|
||||
{
|
||||
return rdata.size();
|
||||
}
|
||||
|
||||
PrefixStringTree<Char>& GetPrefix(size_t size = -1)
|
||||
{
|
||||
if (size >= rdata.size())
|
||||
return *this;
|
||||
return parent->GetPrefix(size);
|
||||
}
|
||||
|
||||
PrefixStringTree<Char>& GetSamePrefix(PrefixStringTree<Char>& other)
|
||||
{
|
||||
if (rdata.front() != other.rdata.front())
|
||||
return GetRoot();
|
||||
auto i = 0;
|
||||
for (auto e = std::min<size_t>(rdata.size(), other, rdata.size()); i <= e; i++)
|
||||
{
|
||||
if (rdata[i] != other.rdata[i])
|
||||
break;
|
||||
}
|
||||
return this->GetPrefix(i);
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
for (auto head = child_head; head; head = head->next)
|
||||
{
|
||||
head->Clear();
|
||||
}
|
||||
if (data)
|
||||
{
|
||||
delete data;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
class PrefixString
|
||||
{
|
||||
using _Mychar = Char;
|
||||
using my_string_view = std::basic_string_view<Char>;
|
||||
Internal::PrefixStringTree<Char>& str;
|
||||
public:
|
||||
PrefixString() :str(Internal::PrefixStringTree<Char>::GetRoot()) {};
|
||||
PrefixString(my_string_view view) :str(Internal::PrefixStringTree<Char>::GetRoot() + view) {};
|
||||
PrefixString(const PrefixString& other) :str(other.str) {};
|
||||
|
||||
my_string_view ReadValue() const
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
operator my_string_view() const
|
||||
{
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !__FILE_Detail_Core_String_H
|
Reference in New Issue
Block a user