flatten 20260225
This commit is contained in:
90
tjp/core/string/Dictionary.h
Normal file
90
tjp/core/string/Dictionary.h
Normal file
@@ -0,0 +1,90 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "../threads/Lock.hpp"
|
||||
#include "../ptr/Ptr.hpp"
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace string_dictionary {
|
||||
|
||||
struct Instance;
|
||||
struct Entry;
|
||||
struct Dictionary;
|
||||
|
||||
struct Reference
|
||||
{
|
||||
StrongPtr<Entry> entry;
|
||||
|
||||
operator const std::string &() const;
|
||||
operator const std::string_view () const;
|
||||
} ;
|
||||
|
||||
struct Entry
|
||||
{
|
||||
StrongPtr<Dictionary> container;
|
||||
const std::string value;
|
||||
|
||||
Entry(const StrongPtr<Dictionary> &container, std::string &&string);
|
||||
|
||||
~Entry ();
|
||||
} ;
|
||||
|
||||
bool operator ==(const Reference &lhs, const Reference &rhs);
|
||||
bool operator ==(const Reference &lhs, const std::string &r);
|
||||
bool operator ==(const Reference &lhs, const std::string_view &r);
|
||||
bool operator ==(const Reference &lhs, const char *r);
|
||||
|
||||
bool operator ==(const std::string &l, const Reference &rhs);
|
||||
bool operator ==(const std::string_view &l, const Reference &rhs);
|
||||
bool operator ==(const char *l, const Reference &rhs);
|
||||
|
||||
bool operator !=(const Reference &lhs, const Reference &rhs);
|
||||
bool operator !=(const Reference &lhs, const std::string &r);
|
||||
bool operator !=(const Reference &lhs, const std::string_view &r);
|
||||
bool operator !=(const Reference &lhs, const char *r);
|
||||
|
||||
bool operator !=(const std::string &l, const Reference &rhs);
|
||||
bool operator !=(const std::string_view &l, const Reference &rhs);
|
||||
bool operator !=(const char *l, const Reference &rhs);
|
||||
|
||||
bool operator <(const Reference &lhs, const Reference &rhs);
|
||||
bool operator <(const Reference &lhs, const std::string &r);
|
||||
bool operator <(const Reference &lhs, const std::string_view &r);
|
||||
bool operator <(const Reference &lhs, const char *r);
|
||||
|
||||
bool operator <(const std::string &l, const Reference &rhs);
|
||||
bool operator <(const std::string_view &l, const Reference &rhs);
|
||||
bool operator <(const char *l, const Reference &rhs);
|
||||
|
||||
// ----
|
||||
|
||||
struct Dictionary : StrongThis<Dictionary>
|
||||
{
|
||||
Mutex mutex;
|
||||
std::map<std::string_view, WeakPtr<Entry>> entries;
|
||||
|
||||
void remove(Entry *entry);
|
||||
|
||||
Reference get(const std::string_view &value);
|
||||
Reference get(const std::string &value);
|
||||
Reference get(std::string &&value);
|
||||
Reference get(const char *value);
|
||||
} ;
|
||||
|
||||
} // namespace
|
||||
|
||||
using StringDictionary = string_dictionary::Dictionary;
|
||||
using StringRef = string_dictionary::Reference;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
#include "Dictionary.inl"
|
||||
233
tjp/core/string/Dictionary.inl
Normal file
233
tjp/core/string/Dictionary.inl
Normal file
@@ -0,0 +1,233 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace string_dictionary {
|
||||
|
||||
// ----
|
||||
|
||||
inline
|
||||
Entry::Entry(const StrongPtr<Dictionary> &container_, std::string &&value_) :
|
||||
container(container_),
|
||||
value(std::move(value_))
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
Entry::~Entry ()
|
||||
{
|
||||
if (container)
|
||||
container->remove(this);
|
||||
}
|
||||
|
||||
// ----
|
||||
|
||||
inline
|
||||
Reference::operator const std::string &() const
|
||||
{
|
||||
return entry->value;
|
||||
}
|
||||
|
||||
inline
|
||||
Reference::operator const std::string_view () const
|
||||
{
|
||||
return entry->value;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator ==(const Reference &lhs, const Reference &rhs)
|
||||
{
|
||||
return (const std::string &)lhs == (const std::string &)rhs;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator ==(const Reference &lhs, const std::string &r)
|
||||
{
|
||||
return (const std::string &)lhs == r;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator ==(const Reference &lhs, const std::string_view &r)
|
||||
{
|
||||
return (const std::string &)lhs == r;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator ==(const Reference &lhs, const char *r)
|
||||
{
|
||||
return (const std::string &)lhs == r;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator ==(const std::string &l, const Reference &rhs)
|
||||
{
|
||||
return l == (const std::string &)rhs;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator ==(const std::string_view &l, const Reference &rhs)
|
||||
{
|
||||
return l == (const std::string &)rhs;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator ==(const char *l, const Reference &rhs)
|
||||
{
|
||||
return l == (const std::string &)rhs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline
|
||||
bool operator !=(const Reference &lhs, const Reference &rhs)
|
||||
{
|
||||
return (const std::string &)lhs != (const std::string &)rhs;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator !=(const Reference &lhs, const std::string &r)
|
||||
{
|
||||
return (const std::string &)lhs != r;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator !=(const Reference &lhs, const std::string_view &r)
|
||||
{
|
||||
return (const std::string &)lhs != r;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator !=(const Reference &lhs, const char *r)
|
||||
{
|
||||
return (const std::string &)lhs != r;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator !=(const std::string &l, const Reference &rhs)
|
||||
{
|
||||
return l != (const std::string &)rhs;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator !=(const std::string_view &l, const Reference &rhs)
|
||||
{
|
||||
return l != (const std::string &)rhs;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator !=(const char *l, const Reference &rhs)
|
||||
{
|
||||
return l != (const std::string &)rhs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline
|
||||
bool operator <(const Reference &lhs, const Reference &rhs)
|
||||
{
|
||||
return (const std::string &)lhs < (const std::string &)rhs;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator <(const Reference &lhs, const std::string &r)
|
||||
{
|
||||
return (const std::string &)lhs < r;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator <(const Reference &lhs, const std::string_view &r)
|
||||
{
|
||||
return (const std::string &)lhs < r;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator <(const Reference &lhs, const char *r)
|
||||
{
|
||||
return (const std::string &)lhs < r;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator <(const std::string &l, const Reference &rhs)
|
||||
{
|
||||
return l < (const std::string &)rhs;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator <(const std::string_view &l, const Reference &rhs)
|
||||
{
|
||||
return l < (const std::string &)rhs;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator <(const char *l, const Reference &rhs)
|
||||
{
|
||||
return l < (const std::string &)rhs;
|
||||
}
|
||||
|
||||
|
||||
// ----
|
||||
|
||||
inline
|
||||
void Dictionary::remove(Entry *entry)
|
||||
{
|
||||
auto i = entries.find(entry->value);
|
||||
if (i != entries.end())
|
||||
entries.erase(i);
|
||||
}
|
||||
|
||||
inline
|
||||
Reference Dictionary::get(const std::string_view &value)
|
||||
{
|
||||
auto i = entries.find(value);
|
||||
if (i != entries.end())
|
||||
return { strong(i->second) };
|
||||
|
||||
auto entry = strong<Entry>(Entry { strong_this(this), std::string(value) });
|
||||
entries.emplace(entry->value, entry);
|
||||
return { std::move(entry) };
|
||||
}
|
||||
|
||||
inline
|
||||
Reference Dictionary::get(const std::string &value)
|
||||
{
|
||||
auto i = entries.find(value);
|
||||
if (i != entries.end())
|
||||
return { strong(i->second) };
|
||||
|
||||
auto entry = strong<Entry>(strong_this(this), std::string(value));
|
||||
entries.emplace(entry->value, entry);
|
||||
return { std::move(entry) };
|
||||
}
|
||||
|
||||
inline
|
||||
Reference Dictionary::get(std::string &&value)
|
||||
{
|
||||
auto i = entries.find(value);
|
||||
if (i != entries.end())
|
||||
return { strong(i->second) };
|
||||
|
||||
auto entry = strong<Entry>(strong_this(this), std::move(value));
|
||||
entries.emplace(entry->value, entry);
|
||||
return { std::move(entry) };
|
||||
}
|
||||
|
||||
inline
|
||||
Reference Dictionary::get(const char *value)
|
||||
{
|
||||
auto i = entries.find(value);
|
||||
if (i != entries.end())
|
||||
return { strong(i->second) };
|
||||
|
||||
auto entry = strong<Entry>(strong_this(this), std::string(value));
|
||||
entries.emplace(entry->value, entry);
|
||||
return { std::move(entry) };
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
40
tjp/core/string/Str+IO.h
Executable file
40
tjp/core/string/Str+IO.h
Executable file
@@ -0,0 +1,40 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Str.h"
|
||||
#include <iosfwd>
|
||||
#include "from_string.h"
|
||||
|
||||
namespace tjp::core::str {
|
||||
|
||||
#ifdef TJP_STR_USE_TEMPLATES
|
||||
|
||||
template<typename IO, int N1>
|
||||
void io_(IO &io, TJP_STR &v)
|
||||
{
|
||||
io.intrinsic_string(v);
|
||||
}
|
||||
|
||||
#else
|
||||
template<typename IO>
|
||||
void io_(IO &io, TJP_STR &v)
|
||||
{
|
||||
io.intrinsic_string(v);
|
||||
}
|
||||
#endif
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
std::ostream &operator <<(std::ostream &o, const TJP_STR &v);
|
||||
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
void from_string(str::TJP_STR &v, const std::string_view &s);
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "Str+IO.inl"
|
||||
26
tjp/core/string/Str+IO.inl
Executable file
26
tjp/core/string/Str+IO.inl
Executable file
@@ -0,0 +1,26 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#include "Str+IO.h"
|
||||
#include "Str.hpp"
|
||||
#include "from_string.h"
|
||||
|
||||
namespace tjp::core::str {
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
std::ostream &operator <<(std::ostream &o, const TJP_STR &v)
|
||||
{
|
||||
return o << (std::string_view)v;
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
void from_string(str::TJP_STR &v, const std::string_view &s)
|
||||
{
|
||||
v = s;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
10
tjp/core/string/Str.cpp
Normal file
10
tjp/core/string/Str.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#include "Str.hpp"
|
||||
|
||||
#ifndef TJP_STR_INLINE
|
||||
#define TJP_STR_INLINE
|
||||
#include "Str.inl"
|
||||
#endif
|
||||
150
tjp/core/string/Str.h
Executable file
150
tjp/core/string/Str.h
Executable file
@@ -0,0 +1,150 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "String.h"
|
||||
#include "StringView.h"
|
||||
|
||||
#include "../rtti/TypeName+custom.hpp"
|
||||
|
||||
namespace tjp::core {
|
||||
namespace str {
|
||||
|
||||
#define TJP_STR_INLINE inline
|
||||
|
||||
#define TJP_STR_USE_TEMPLATES
|
||||
#ifdef TJP_STR_USE_TEMPLATES
|
||||
constexpr int Str_DefaultN = 48;
|
||||
|
||||
template<int N=Str_DefaultN>
|
||||
struct Str;
|
||||
|
||||
#define TJP_STR_TEMPLATE template<int N1>
|
||||
#define TJP_STR_TEMPLATE2 template<int N2>
|
||||
|
||||
#define TJP_STR_TEMPLATE12 template<int N1, int N2>
|
||||
#define CONST_TEMPLATE_N1 N1
|
||||
|
||||
#define TJP_STR Str<N1>
|
||||
#define TJP_STR2 Str<N2>
|
||||
#define TJP_STR_TYPENAME typename TJP_STR
|
||||
|
||||
#define TJP_STR_DEFAULT Str<Str_DefaultN>
|
||||
#else
|
||||
struct Str;
|
||||
|
||||
#define TJP_STR_TEMPLATE
|
||||
#define TJP_STR_TEMPLATE12
|
||||
#define TJP_STR_TEMPLATE2
|
||||
#define CONST_TEMPLATE_N1 48
|
||||
|
||||
#define TJP_STR Str
|
||||
#define TJP_STR2 Str
|
||||
#define TJP_STR_TYPENAME TJP_STR
|
||||
|
||||
#define TJP_STR_DEFAULT Str
|
||||
#endif
|
||||
|
||||
|
||||
TJP_STR_TEMPLATE12
|
||||
bool operator ==(const TJP_STR &lhs, const TJP_STR2 &rhs);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
bool operator ==(const TJP_STR &lhs, const String &r);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
bool operator ==(const TJP_STR &lhs, const StringView &r);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
bool operator ==(const TJP_STR &lhs, const char *r);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
bool operator ==(const String &l, const TJP_STR &rhs);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
bool operator ==(const StringView &l, const TJP_STR &rhs);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
bool operator ==(const char *l, const TJP_STR &rhs);
|
||||
|
||||
TJP_STR_TEMPLATE12
|
||||
bool operator !=(const TJP_STR &lhs, const TJP_STR2 &rhs);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
bool operator !=(const TJP_STR &lhs, const String &r);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
bool operator !=(const TJP_STR &lhs, const StringView &r);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
bool operator !=(const TJP_STR &lhs, const char *r);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
bool operator !=(const String &l, const TJP_STR &rhs);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
bool operator !=(const StringView &l, const TJP_STR &rhs);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
bool operator !=(const char *l, const TJP_STR &rhs);
|
||||
|
||||
TJP_STR_TEMPLATE12
|
||||
bool operator <(const TJP_STR &lhs, const TJP_STR2 &rhs);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
bool operator <(const TJP_STR &lhs, const String &r);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
bool operator <(const TJP_STR &lhs, const StringView &r);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
bool operator <(const TJP_STR &lhs, const char *r);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
bool operator <(const String &l, const TJP_STR &rhs);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
bool operator <(const StringView &l, const TJP_STR &rhs);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
bool operator <(const char *l, const TJP_STR &rhs);
|
||||
|
||||
TJP_STR_TEMPLATE12
|
||||
TJP_STR operator+(const TJP_STR &lhs, const TJP_STR2 &rhs);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR operator+(const String &lhs, const TJP_STR &rhs);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR operator+(const StringView &lhs, const TJP_STR &rhs);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR operator+(const char *lhs, const TJP_STR &rhs);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR operator+(const TJP_STR &lhs, const String &rhs);
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR operator+(const TJP_STR &lhs, const StringView &rhs);
|
||||
|
||||
TJP_STR_DEFAULT operator+(const char *lhs, const StringView &rhs);
|
||||
|
||||
} // namespace
|
||||
|
||||
#ifdef TJP_STR_USE_TEMPLATES
|
||||
template<int N1=str::Str_DefaultN>
|
||||
using StrN = str::TJP_STR;
|
||||
|
||||
using Str = StrN<str::Str_DefaultN>;
|
||||
using Str = Str;
|
||||
#else
|
||||
using Str = str::TJP_STR;
|
||||
using Str = Str;
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
TIMPREPSCIUS_CORE_RTTI_REPLACE_TYPENAME(tjp::core::Str);
|
||||
|
||||
58
tjp/core/string/Str.hpp
Executable file
58
tjp/core/string/Str.hpp
Executable file
@@ -0,0 +1,58 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Str.h"
|
||||
#include "../containers/StackArray.hpp"
|
||||
|
||||
namespace tjp::core::str {
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
struct Str
|
||||
{
|
||||
static constexpr int N = CONST_TEMPLATE_N1;
|
||||
using Internal = StackArray<char, N>;
|
||||
using value_type = typename Internal::value_type;
|
||||
using const_iterator_ = typename Internal::const_iterator;
|
||||
|
||||
Internal string;
|
||||
|
||||
Str();
|
||||
Str(size_t size, char initializer);
|
||||
Str(const String &rhs);
|
||||
Str(const StringView &rhs);
|
||||
Str(const char *rhs);
|
||||
Str(const char *begin, const char *end);
|
||||
Str(const StringView &v0, const StringView &v1);
|
||||
|
||||
TJP_STR_TEMPLATE2
|
||||
Str(const TJP_STR2 &rhs);
|
||||
|
||||
explicit Str(const Vector<char> &v);
|
||||
|
||||
operator const StringView () const;
|
||||
bool empty() const;
|
||||
|
||||
void clear();
|
||||
|
||||
const value_type *data() const;
|
||||
const_iterator_ begin() const;
|
||||
const_iterator_ end() const;
|
||||
size_t size () const;
|
||||
|
||||
char front() const;
|
||||
char back() const;
|
||||
|
||||
|
||||
const char *c_str() const;
|
||||
const char *c_str();
|
||||
String toString() const;
|
||||
} ;
|
||||
|
||||
} // namespace
|
||||
|
||||
#ifdef TJP_STR_INLINE
|
||||
#include "Str.inl"
|
||||
#endif
|
||||
464
tjp/core/string/Str.inl
Normal file
464
tjp/core/string/Str.inl
Normal file
@@ -0,0 +1,464 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Str.hpp"
|
||||
#include "../algorithm/small_cmp.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
namespace str {
|
||||
|
||||
typedef StringView compare_type;
|
||||
|
||||
TJP_STR_INLINE
|
||||
auto cmp (const compare_type &l, const compare_type &r)
|
||||
{
|
||||
return small_cmp(l.data(), l.size(), r.data(), r.size());
|
||||
}
|
||||
|
||||
TJP_STR_INLINE
|
||||
auto cmp (const compare_type &l, const char *r)
|
||||
{
|
||||
return small_cmp(l.data(), l.size(), r);
|
||||
}
|
||||
|
||||
TJP_STR_INLINE
|
||||
auto cmp (const char *l, const compare_type &r)
|
||||
{
|
||||
return -cmp(r, l);
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE12
|
||||
TJP_STR_INLINE
|
||||
auto cmp(const TJP_STR &lhs, const TJP_STR2 &rhs)
|
||||
{
|
||||
return small_cmp(lhs.data(), lhs.size(), rhs.data(), rhs.size());
|
||||
}
|
||||
|
||||
TJP_STR_INLINE
|
||||
auto add(const compare_type &l, const compare_type &r)
|
||||
{
|
||||
return Str(l, r);
|
||||
}
|
||||
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
TJP_STR::Str()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
TJP_STR::Str(size_t size, char c)
|
||||
{
|
||||
for (auto i=0; i<size; ++i)
|
||||
string.push_back(c);
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
TJP_STR::Str(const String &rhs) :
|
||||
string(rhs.data(), rhs.data() + rhs.size())
|
||||
{
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
TJP_STR::Str(const Vector<char> &rhs) :
|
||||
string(rhs.data(), rhs.data() + rhs.size())
|
||||
{
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
TJP_STR::Str(const StringView &rhs) :
|
||||
string(rhs.data(), rhs.data() + rhs.size())
|
||||
{
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_TEMPLATE2
|
||||
TJP_STR_INLINE
|
||||
TJP_STR::Str(const TJP_STR2 &rhs) :
|
||||
string(rhs.string)
|
||||
{
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
TJP_STR::Str(const char *begin, const char *end) :
|
||||
string(begin, end)
|
||||
{
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
TJP_STR::Str(const char *rhs)
|
||||
{
|
||||
debug_assert(rhs);
|
||||
if (!rhs)
|
||||
return;
|
||||
|
||||
auto MAX = 16384;
|
||||
for (auto i=0; i<MAX; ++i)
|
||||
{
|
||||
if (*rhs == 0)
|
||||
break;
|
||||
|
||||
string.push_back(*rhs++);
|
||||
}
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
TJP_STR::Str(const StringView &v0, const StringView &v1)
|
||||
{
|
||||
string.size_to(v0.size() + v1.size());
|
||||
|
||||
string.append(v0.data(), v0.data() + v0.size());
|
||||
string.append(v1.data(), v1.data() + v1.size());
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
String TJP_STR::toString() const
|
||||
{
|
||||
return String(string.begin(), string.size());
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
TJP_STR::operator const StringView () const
|
||||
{
|
||||
return StringView(string.begin(), string.size());
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
bool TJP_STR::empty() const
|
||||
{
|
||||
return string.empty();
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
void TJP_STR::clear()
|
||||
{
|
||||
return string.clear();
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
char TJP_STR::front() const
|
||||
{
|
||||
return string.front();
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
char TJP_STR::back() const
|
||||
{
|
||||
return string.back();
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
const TJP_STR_TYPENAME::value_type *TJP_STR::data() const
|
||||
{
|
||||
return string.data();
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
TJP_STR_TYPENAME::const_iterator_ TJP_STR::begin() const
|
||||
{
|
||||
return string.begin();
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
TJP_STR_TYPENAME::const_iterator_ TJP_STR::end() const
|
||||
{
|
||||
return string.end();
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
size_t TJP_STR::size() const
|
||||
{
|
||||
return string.size();
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
const char *TJP_STR::c_str()
|
||||
{
|
||||
string.push_back(0);
|
||||
string.pop_back();
|
||||
return string.data();
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
const char *TJP_STR::c_str() const
|
||||
{
|
||||
return const_cast<TJP_STR *>(this)->c_str();
|
||||
}
|
||||
|
||||
TJP_STR_INLINE
|
||||
bool operator ==(const compare_type &lhs, const char *rhs)
|
||||
{
|
||||
return cmp(lhs, rhs) == 0;
|
||||
}
|
||||
|
||||
|
||||
TJP_STR_INLINE
|
||||
bool operator ==(const char *lhs, const compare_type &rhs)
|
||||
{
|
||||
return rhs == lhs;
|
||||
}
|
||||
|
||||
TJP_STR_INLINE
|
||||
bool operator !=(const compare_type &lhs, const char *rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
TJP_STR_INLINE
|
||||
bool operator !=(const char *lhs, const compare_type &rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
TJP_STR_INLINE
|
||||
bool operator <(const compare_type &lhs, const char *rhs)
|
||||
{
|
||||
return cmp(lhs, rhs) < 0;
|
||||
}
|
||||
|
||||
|
||||
TJP_STR_INLINE
|
||||
bool operator <(const char *lhs, const compare_type &rhs)
|
||||
{
|
||||
return cmp(lhs, rhs) < 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
TJP_STR_TEMPLATE12
|
||||
TJP_STR_INLINE
|
||||
bool operator ==(const TJP_STR &lhs, const TJP_STR2 &rhs)
|
||||
{
|
||||
return cmp(lhs, rhs) == 0;
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
bool operator ==(const TJP_STR &lhs, const String &r)
|
||||
{
|
||||
return cmp((const compare_type &)lhs, compare_type(r)) == 0;
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
bool operator ==(const TJP_STR &lhs, const StringView &r)
|
||||
{
|
||||
return cmp((const compare_type &)lhs, r) == 0;
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
bool operator ==(const TJP_STR &lhs, const char *r)
|
||||
{
|
||||
return cmp((const compare_type &)lhs, r) == 0;
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
bool operator ==(const String &l, const TJP_STR &rhs)
|
||||
{
|
||||
return cmp(compare_type(l), (const compare_type &)rhs) == 0;
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
bool operator ==(const StringView &l, const TJP_STR &rhs)
|
||||
{
|
||||
return cmp(l, (const compare_type &)rhs) == 0;
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
bool operator ==(const char *l, const TJP_STR &rhs)
|
||||
{
|
||||
return cmp(l, (const compare_type &)rhs) == 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
TJP_STR_TEMPLATE12
|
||||
TJP_STR_INLINE
|
||||
bool operator !=(const TJP_STR &lhs, const TJP_STR2 &rhs)
|
||||
{
|
||||
return cmp(lhs, rhs) != 0;
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
bool operator !=(const TJP_STR &lhs, const String &r)
|
||||
{
|
||||
return cmp((const compare_type &)lhs, compare_type(r)) != 0;
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
bool operator !=(const TJP_STR &lhs, const StringView &r)
|
||||
{
|
||||
return cmp((const compare_type &)lhs, r) != 0;
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
bool operator !=(const TJP_STR &lhs, const char *r)
|
||||
{
|
||||
return cmp((const compare_type &)lhs, r) != 0;
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
bool operator !=(const String &l, const TJP_STR &rhs)
|
||||
{
|
||||
return cmp(compare_type(l), (const compare_type &)rhs) != 0;
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
bool operator !=(const StringView &l, const TJP_STR &rhs)
|
||||
{
|
||||
return cmp(compare_type(l), (const compare_type &)rhs) != 0;
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
bool operator !=(const char *l, const TJP_STR &rhs)
|
||||
{
|
||||
return cmp(l, (const compare_type &)rhs) != 0;
|
||||
}
|
||||
|
||||
|
||||
TJP_STR_TEMPLATE12
|
||||
TJP_STR_INLINE
|
||||
bool operator <(const TJP_STR &lhs, const TJP_STR2 &rhs)
|
||||
{
|
||||
return cmp(lhs, rhs) < 0;
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
bool operator <(const TJP_STR &lhs, const String &r)
|
||||
{
|
||||
return cmp((const compare_type &)lhs, compare_type(r)) < 0;
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
bool operator <(const TJP_STR &lhs, const StringView &r)
|
||||
{
|
||||
return cmp((const compare_type &)lhs, r) < 0;
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
bool operator <(const TJP_STR &lhs, const char *r)
|
||||
{
|
||||
return cmp((const compare_type &)lhs, r) < 0;
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
bool operator <(const String &l, const TJP_STR &rhs)
|
||||
{
|
||||
return cmp(compare_type(l), (const compare_type &)rhs) < 0;
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
bool operator <(const StringView &l, const TJP_STR &rhs)
|
||||
{
|
||||
return cmp(l, (const compare_type &)rhs) < 0;
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
bool operator <(const char *l, const TJP_STR &rhs)
|
||||
{
|
||||
return cmp(l, (const compare_type &)rhs) < 0;
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE12
|
||||
TJP_STR_INLINE
|
||||
TJP_STR operator+(const TJP_STR &lhs, const TJP_STR2 &rhs)
|
||||
{
|
||||
return add(lhs, rhs);
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
TJP_STR operator+(const String &lhs, const TJP_STR &rhs)
|
||||
{
|
||||
return add(lhs, rhs);
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
TJP_STR operator+(const StringView &lhs, const TJP_STR &rhs)
|
||||
{
|
||||
return add(lhs, rhs);
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
TJP_STR operator+(const char *lhs, const TJP_STR &rhs)
|
||||
{
|
||||
return add(lhs, rhs);
|
||||
}
|
||||
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
TJP_STR operator+(const TJP_STR &lhs, const String &rhs)
|
||||
{
|
||||
return add(lhs, rhs);
|
||||
}
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
TJP_STR operator+(const TJP_STR &lhs, const StringView &rhs)
|
||||
{
|
||||
return add(lhs, rhs);
|
||||
}
|
||||
|
||||
|
||||
TJP_STR_TEMPLATE
|
||||
TJP_STR_INLINE
|
||||
TJP_STR operator+(const TJP_STR &lhs, const char *rhs)
|
||||
{
|
||||
return add(lhs, rhs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
13
tjp/core/string/String.h
Executable file
13
tjp/core/string/String.h
Executable file
@@ -0,0 +1,13 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
// TODO: this header should be String+RTTI.hpp, and String_.h should be String.h
|
||||
|
||||
#include "String_.h"
|
||||
|
||||
#include "../rtti/TypeName.hpp"
|
||||
|
||||
TIMPREPSCIUS_CORE_RTTI_REPLACE_TYPENAME(tjp::core::String);
|
||||
7
tjp/core/string/String.hpp
Executable file
7
tjp/core/string/String.hpp
Executable file
@@ -0,0 +1,7 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "String.h"
|
||||
81
tjp/core/string/StringView+concat.hpp
Executable file
81
tjp/core/string/StringView+concat.hpp
Executable file
@@ -0,0 +1,81 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "String.h"
|
||||
#include "StringView.h"
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
template<typename ... Args>
|
||||
size_t concat_size(const StringView &s)
|
||||
{
|
||||
return s.size();
|
||||
}
|
||||
|
||||
template<typename ... Args>
|
||||
size_t concat_size(const StringView &s, Args && ...args)
|
||||
{
|
||||
return concat_size(s) + concat_size(args...);
|
||||
}
|
||||
|
||||
template<typename ... Args>
|
||||
void concat_ (String &s, const StringView &v)
|
||||
{
|
||||
s.insert(s.end(), v.begin(), v.end());
|
||||
}
|
||||
|
||||
template<typename ... Args>
|
||||
void concat_ (String &s, const StringView &v, Args && ...args)
|
||||
{
|
||||
s.insert(s.end(), v.begin(), v.end());
|
||||
concat_(s, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename ... Args>
|
||||
String concat (Args && ...args)
|
||||
{
|
||||
String s;
|
||||
s.reserve(concat_size(args...));
|
||||
concat_(s, std::forward<Args>(args)...);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace std {
|
||||
|
||||
inline
|
||||
std::string operator +(const std::string &lhs, const std::string_view &rhs)
|
||||
{
|
||||
return tjp::core::concat(lhs, rhs);
|
||||
}
|
||||
|
||||
inline
|
||||
std::string operator +(const std::string_view &lhs, const std::string &rhs)
|
||||
{
|
||||
return tjp::core::concat(lhs, rhs);
|
||||
}
|
||||
|
||||
inline
|
||||
std::string operator +(const std::string_view &lhs, const std::string_view &rhs)
|
||||
{
|
||||
return tjp::core::concat(lhs, rhs);
|
||||
}
|
||||
|
||||
inline
|
||||
std::string operator +(const char *lhs, const std::string_view &rhs)
|
||||
{
|
||||
return tjp::core::concat(lhs, rhs);
|
||||
}
|
||||
|
||||
inline
|
||||
std::string operator +(const std::string_view &lhs, const char *rhs)
|
||||
{
|
||||
return tjp::core::concat(lhs, rhs);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
25
tjp/core/string/StringView+less.hpp
Executable file
25
tjp/core/string/StringView+less.hpp
Executable file
@@ -0,0 +1,25 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "String.h"
|
||||
#include "StringView.h"
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
inline
|
||||
bool operator <(const String &lhs, const StringView &rhs)
|
||||
{
|
||||
return (StringView)lhs < rhs;
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator <(const StringView &lhs, const String &rhs)
|
||||
{
|
||||
return lhs < (StringView)rhs;
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
13
tjp/core/string/StringView.h
Executable file
13
tjp/core/string/StringView.h
Executable file
@@ -0,0 +1,13 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
using StringView = std::string_view;
|
||||
|
||||
} // namespace
|
||||
7
tjp/core/string/StringView.hpp
Executable file
7
tjp/core/string/StringView.hpp
Executable file
@@ -0,0 +1,7 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "StringView.h"
|
||||
13
tjp/core/string/String_.h
Executable file
13
tjp/core/string/String_.h
Executable file
@@ -0,0 +1,13 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
using String = std::string;
|
||||
|
||||
} // namespace
|
||||
40
tjp/core/string/ToString.hpp
Normal file
40
tjp/core/string/ToString.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "String.hpp"
|
||||
#include "StringView.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
struct ToString
|
||||
{
|
||||
struct End_ {};
|
||||
static constexpr End_ End{};
|
||||
|
||||
std::stringstream o;
|
||||
|
||||
template<typename T>
|
||||
ToString &operator <<(T &&t)
|
||||
{
|
||||
o << t;
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator String()
|
||||
{
|
||||
return o.str();
|
||||
}
|
||||
} ;
|
||||
|
||||
inline
|
||||
String operator <<(std::stringstream &o, ToString::End_)
|
||||
{
|
||||
return o.str();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
17
tjp/core/string/Tokenizer.h
Normal file
17
tjp/core/string/Tokenizer.h
Normal file
@@ -0,0 +1,17 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
|
||||
struct TokenVector;
|
||||
struct TokenStringView;
|
||||
|
||||
template<typename string, typename token_type>
|
||||
class Tokenizer;
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
132
tjp/core/string/Tokenizer.hpp
Normal file
132
tjp/core/string/Tokenizer.hpp
Normal file
@@ -0,0 +1,132 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Tokenizer.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "str_find.h"
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
|
||||
struct TokenVector
|
||||
{
|
||||
typedef std::vector<unsigned char> Tokens;
|
||||
Tokens tokens;
|
||||
|
||||
TokenVector(const std::string &_del) :
|
||||
tokens(255, false)
|
||||
{
|
||||
const unsigned char *begin = (const unsigned char *)_del.c_str();
|
||||
const unsigned char *end = begin + _del.size();
|
||||
for (const unsigned char *c=begin; c!=end;++c)
|
||||
tokens[*c] = true;
|
||||
}
|
||||
|
||||
size_t find(const unsigned char *s, size_t left, char &t, size_t size) const
|
||||
{
|
||||
return str_find(s, tokens.data(), left, t, size);
|
||||
}
|
||||
} ;
|
||||
|
||||
struct TokenStringView
|
||||
{
|
||||
typedef std::string_view Tokens;
|
||||
Tokens tokens;
|
||||
|
||||
TokenStringView(const std::string_view &_del) :
|
||||
tokens(_del)
|
||||
{
|
||||
}
|
||||
|
||||
size_t find(const unsigned char *s, size_t left, char &t, size_t size) const
|
||||
{
|
||||
return str_find(s, tokens, left, t, size);
|
||||
}
|
||||
} ;
|
||||
|
||||
template<typename string, typename token_type>
|
||||
class Tokenizer
|
||||
{
|
||||
public:
|
||||
typedef token_type Tokens;
|
||||
typedef size_t index;
|
||||
|
||||
protected:
|
||||
const unsigned char *s;
|
||||
const Tokens *tokens;
|
||||
|
||||
index size;
|
||||
index left;
|
||||
index right;
|
||||
char t;
|
||||
|
||||
public:
|
||||
|
||||
Tokenizer (const char *_s, index _size, const token_type &tokens_) :
|
||||
s((const unsigned char *)_s),
|
||||
left(0),
|
||||
tokens(&tokens_),
|
||||
size(_size)
|
||||
{
|
||||
right = tokens->find(s, left, t, size);
|
||||
}
|
||||
|
||||
Tokenizer () :
|
||||
s(nullptr),
|
||||
tokens(nullptr),
|
||||
left(0),
|
||||
right(0),
|
||||
size(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool next (string &_s, char &_t)
|
||||
{
|
||||
index _left,_size;
|
||||
|
||||
bool result = next(_left, _size, _t);
|
||||
if (result)
|
||||
_s = string((const char *)s+_left, _size);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool next (index &_left, index &_size, char &_t)
|
||||
{
|
||||
if (left != -1)
|
||||
{
|
||||
_t = t;
|
||||
|
||||
if (right == -1)
|
||||
{
|
||||
_left = left;
|
||||
_size = size - left;
|
||||
left = right;
|
||||
}
|
||||
else
|
||||
{
|
||||
_left = left;
|
||||
_size = right-left;
|
||||
|
||||
left = right + 1;
|
||||
if (left < size)
|
||||
right = tokens->find(s, left, t, size);
|
||||
else
|
||||
left = -1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
41
tjp/core/string/_tests/Dictionary.cpp
Normal file
41
tjp/core/string/_tests/Dictionary.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#include <tjp/core/string/Dictionary.h>
|
||||
#include <tjp/core/testing/catch.hpp>
|
||||
|
||||
namespace tjp::core::string_dictionary {
|
||||
namespace {
|
||||
|
||||
SCENARIO("core::string::string_dictionary")
|
||||
{
|
||||
GIVEN("a dictionary")
|
||||
{
|
||||
auto dictionary = strong<Dictionary>();
|
||||
auto hi_cstr = "hi";
|
||||
auto hi_str = std::string("hi");
|
||||
auto hi_str_view = std::string_view(hi_str);
|
||||
|
||||
auto hi0 = dictionary->get(hi_cstr);
|
||||
auto hi1 = dictionary->get(hi_str);
|
||||
auto hi2 = dictionary->get(hi_str_view);
|
||||
|
||||
REQUIRE(hi2 == hi1);
|
||||
REQUIRE(hi0 == hi1);
|
||||
REQUIRE(hi0 == hi_cstr);
|
||||
REQUIRE(hi0 == hi_str);
|
||||
REQUIRE(hi0 == hi_str_view);
|
||||
|
||||
REQUIRE(hi0.entry == hi1.entry);
|
||||
REQUIRE(hi1.entry == hi2.entry);
|
||||
|
||||
auto bye = dictionary->get("bye");
|
||||
|
||||
REQUIRE(hi0 != "bye");
|
||||
REQUIRE(hi0 != bye);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
54
tjp/core/string/_tests/Str.cpp
Executable file
54
tjp/core/string/_tests/Str.cpp
Executable file
@@ -0,0 +1,54 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#include <tjp/core/string/Str.hpp>
|
||||
|
||||
#include <tjp/core/testing/catch.hpp>
|
||||
|
||||
#include <tjp/core/log/Log.h>
|
||||
#include <tjp/core/log/LogOf.h>
|
||||
|
||||
namespace tjp::core {
|
||||
namespace {
|
||||
|
||||
struct AB {
|
||||
Str a, b;
|
||||
};
|
||||
|
||||
SCENARIO("core::string::str")
|
||||
{
|
||||
GIVEN("sizeof")
|
||||
{
|
||||
Str a;
|
||||
|
||||
sLogTest("testing", logVar(sizeof(Str)) << logVar(sizeof(Str::Internal)) << logVar(sizeof(a)) << logVar(sizeof(AB)));
|
||||
}
|
||||
|
||||
GIVEN("a const string")
|
||||
{
|
||||
Str one("1");
|
||||
Str one_again("1");
|
||||
Str two("2");
|
||||
|
||||
StrN<12> small("S");
|
||||
Str bigger = small;
|
||||
|
||||
std::string v;
|
||||
for (auto i=0;i<256;++i)
|
||||
v += "a";
|
||||
|
||||
Str longString(v);
|
||||
|
||||
REQUIRE(one == one);
|
||||
REQUIRE(one == "1");
|
||||
REQUIRE(one != "2");
|
||||
REQUIRE(one != two);
|
||||
REQUIRE(one == one_again);
|
||||
REQUIRE(longString == longString);
|
||||
REQUIRE(longString != one);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
59
tjp/core/string/_tests/cmp_case.cpp
Executable file
59
tjp/core/string/_tests/cmp_case.cpp
Executable file
@@ -0,0 +1,59 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#include <tjp/core/string/cmp_case.hpp>
|
||||
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#include <tjp/core/string/strncasecmp.h>
|
||||
#include <tjp/core/string/String.hpp>
|
||||
#include <tjp/core/containers/Vector.hpp>
|
||||
|
||||
#include <tjp/core/testing/catch.hpp>
|
||||
|
||||
#include <tjp/core/log/Log.h>
|
||||
#include <tjp/core/log/LogOf.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace tjp::core {
|
||||
namespace {
|
||||
|
||||
int positivenegativeone(int v)
|
||||
{
|
||||
return v > 0 ? 1 : (v<0) ? -1 : 0;
|
||||
}
|
||||
|
||||
SCENARIO("core::string::cmp_case")
|
||||
{
|
||||
GIVEN("a const string")
|
||||
{
|
||||
Vector<String> strings {
|
||||
"one",
|
||||
"two",
|
||||
"onewithmore",
|
||||
"three",
|
||||
"thre",
|
||||
""
|
||||
} ;
|
||||
|
||||
for (auto &l: strings)
|
||||
{
|
||||
for (auto &r: strings)
|
||||
{
|
||||
auto a = positivenegativeone(strcasecmp(l.c_str(), r.c_str()));
|
||||
auto b = positivenegativeone(strncasecmp(l.c_str(), l.size(), r.c_str(), r.size()));
|
||||
auto c = positivenegativeone(cmp_case(l, r));
|
||||
|
||||
REQUIRE(a == b);
|
||||
REQUIRE(b == c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
53
tjp/core/string/_tests/join.cpp
Executable file
53
tjp/core/string/_tests/join.cpp
Executable file
@@ -0,0 +1,53 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#include <tjp/core/string/join.hpp>
|
||||
#include <tjp/core/string/String.hpp>
|
||||
#include <tjp/core/containers/Vector.hpp>
|
||||
|
||||
#include <tjp/core/testing/catch.hpp>
|
||||
|
||||
#include <tjp/core/log/Log.h>
|
||||
#include <tjp/core/log/LogOf.h>
|
||||
|
||||
namespace tjp::core {
|
||||
namespace {
|
||||
|
||||
SCENARIO("core::string::join")
|
||||
{
|
||||
GIVEN("string")
|
||||
{
|
||||
String s = join_values(
|
||||
',',
|
||||
Vector<String>{"a", "b", "c", "d"}
|
||||
);
|
||||
|
||||
REQUIRE(s == "a,b,c,d");
|
||||
}
|
||||
|
||||
GIVEN("strings")
|
||||
{
|
||||
String s = join_values(
|
||||
',',
|
||||
Vector<String>{"a", "b", "c", "d"},
|
||||
Vector<String>{"e", "f", "g", "h"}
|
||||
);
|
||||
|
||||
REQUIRE(s == "a,b,c,d,e,f,g,h");
|
||||
}
|
||||
|
||||
GIVEN("string and integers")
|
||||
{
|
||||
String s = join_values(
|
||||
',',
|
||||
Vector<String>{"a", "b", "c", "d"},
|
||||
Vector<int>{0, 1, 2, 3}
|
||||
);
|
||||
|
||||
REQUIRE(s == "a,b,c,d,0,1,2,3");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
58
tjp/core/string/_tests/replace.cpp
Executable file
58
tjp/core/string/_tests/replace.cpp
Executable file
@@ -0,0 +1,58 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#include <tjp/core/string/replace.h>
|
||||
|
||||
#include <tjp/core/testing/catch.hpp>
|
||||
|
||||
#include <tjp/core/log/Log.h>
|
||||
#include <tjp/core/log/LogOf.h>
|
||||
|
||||
namespace tjp::core {
|
||||
namespace {
|
||||
|
||||
SCENARIO("core::string::replace")
|
||||
{
|
||||
GIVEN("string")
|
||||
{
|
||||
String s = "abc";
|
||||
|
||||
WHEN("begin")
|
||||
{
|
||||
auto replaced = replace(s, "a", "xyz");
|
||||
REQUIRE(replaced == true);
|
||||
|
||||
REQUIRE(s == "xyzbc");
|
||||
}
|
||||
|
||||
WHEN("end")
|
||||
{
|
||||
bool replaced = replace(s, "c", "xyz");
|
||||
REQUIRE(replaced == true);
|
||||
|
||||
REQUIRE(s == "abxyz");
|
||||
}
|
||||
|
||||
WHEN("middle")
|
||||
{
|
||||
bool replaced = replace(s, "b", "xyz");
|
||||
REQUIRE(replaced == true);
|
||||
|
||||
REQUIRE(s == "axyzc");
|
||||
}
|
||||
|
||||
WHEN("missing")
|
||||
{
|
||||
bool replaced = replace(s, "d", "xyz");
|
||||
REQUIRE(replaced == false);
|
||||
|
||||
REQUIRE(s == "abc");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
48
tjp/core/string/_tests/split_once.cpp
Executable file
48
tjp/core/string/_tests/split_once.cpp
Executable file
@@ -0,0 +1,48 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#include <tjp/core/string/split_once.hpp>
|
||||
#include <tjp/core/string/String.hpp>
|
||||
#include <tjp/core/containers/Vector.hpp>
|
||||
|
||||
#include <tjp/core/testing/catch.hpp>
|
||||
|
||||
#include <tjp/core/log/Log.h>
|
||||
#include <tjp/core/log/LogOf.h>
|
||||
|
||||
namespace tjp::core {
|
||||
namespace {
|
||||
|
||||
SCENARIO("core::string::split_once")
|
||||
{
|
||||
GIVEN("strings")
|
||||
{
|
||||
Vector<Tuple<String, String, bool, String, String>> strings {
|
||||
{ "asdf:1234", ":", true, "asdf", "1234" },
|
||||
{ ":asdf1234", ":", true, "", "asdf1234" },
|
||||
{ "asdf1234:", ":", true, "asdf1234", "" },
|
||||
{ "asdf1234", ":", false, "", "" },
|
||||
{ ":asdf:1234", ":", true, "", "asdf:1234" },
|
||||
{ "asdf::1234", ":", true, "asdf", ":1234" },
|
||||
} ;
|
||||
|
||||
for (auto &ss : strings)
|
||||
{
|
||||
auto &[s, c, has_value, l, r] = ss;
|
||||
|
||||
auto split = split_once(s, c);
|
||||
REQUIRE(split.has_value() == has_value);
|
||||
|
||||
if (has_value)
|
||||
{
|
||||
auto &[lv, rv] = *split;
|
||||
REQUIRE(lv == l);
|
||||
REQUIRE(rv == r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
50
tjp/core/string/_tests/strncasecmp.cpp
Executable file
50
tjp/core/string/_tests/strncasecmp.cpp
Executable file
@@ -0,0 +1,50 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#include <tjp/core/string/strncasecmp.h>
|
||||
#include <tjp/core/string/String.hpp>
|
||||
#include <tjp/core/containers/Vector.hpp>
|
||||
|
||||
#include <tjp/core/testing/catch.hpp>
|
||||
|
||||
#include <tjp/core/log/Log.h>
|
||||
#include <tjp/core/log/LogOf.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace tjp::core {
|
||||
namespace {
|
||||
|
||||
int positivenegativeone(int v)
|
||||
{
|
||||
return v > 0 ? 1 : (v<0) ? -1 : 0;
|
||||
}
|
||||
|
||||
|
||||
SCENARIO("core::string::strncasecmp")
|
||||
{
|
||||
GIVEN("a const string")
|
||||
{
|
||||
Vector<String> strings {
|
||||
"one",
|
||||
"two",
|
||||
"three",
|
||||
""
|
||||
} ;
|
||||
|
||||
for (auto &l: strings)
|
||||
{
|
||||
for (auto &r: strings)
|
||||
{
|
||||
auto a = positivenegativeone(strcasecmp(l.c_str(), r.c_str()));
|
||||
auto b = positivenegativeone(strncasecmp(l.c_str(), l.size(), r.c_str(), r.size()));
|
||||
|
||||
REQUIRE(a == b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
50
tjp/core/string/_tests/strncmp.cpp
Executable file
50
tjp/core/string/_tests/strncmp.cpp
Executable file
@@ -0,0 +1,50 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#include <tjp/core/string/strncmp.h>
|
||||
#include <tjp/core/string/String.hpp>
|
||||
#include <tjp/core/containers/Vector.hpp>
|
||||
|
||||
#include <tjp/core/testing/catch.hpp>
|
||||
|
||||
#include <tjp/core/log/Log.h>
|
||||
#include <tjp/core/log/LogOf.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace tjp::core {
|
||||
namespace {
|
||||
|
||||
int positivenegativeone(int v)
|
||||
{
|
||||
return v > 0 ? 1 : (v<0) ? -1 : 0;
|
||||
}
|
||||
|
||||
|
||||
SCENARIO("core::string::strncmp")
|
||||
{
|
||||
GIVEN("a const string")
|
||||
{
|
||||
Vector<String> strings {
|
||||
"one",
|
||||
"two",
|
||||
"three",
|
||||
""
|
||||
} ;
|
||||
|
||||
for (auto &l: strings)
|
||||
{
|
||||
for (auto &r: strings)
|
||||
{
|
||||
auto a = positivenegativeone(strcmp(l.c_str(), r.c_str()));
|
||||
auto b = positivenegativeone(strncmp(l.c_str(), l.size(), r.c_str(), r.size()));
|
||||
|
||||
REQUIRE(a == b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
57
tjp/core/string/_tests/trim.cpp
Executable file
57
tjp/core/string/_tests/trim.cpp
Executable file
@@ -0,0 +1,57 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#include <tjp/core/string/trim.h>
|
||||
|
||||
#include <tjp/core/testing/catch.hpp>
|
||||
|
||||
#include <tjp/core/log/Log.h>
|
||||
#include <tjp/core/log/LogOf.h>
|
||||
|
||||
namespace tjp::core {
|
||||
namespace {
|
||||
|
||||
SCENARIO("core::string::trim")
|
||||
{
|
||||
GIVEN("string")
|
||||
{
|
||||
String s = "abc";
|
||||
|
||||
auto trimmed_left = trim_left_copy(s, "a");
|
||||
auto trimmed_right = trim_right_copy(s, "c");
|
||||
auto trimmed = trim_copy(s, "ac");
|
||||
|
||||
REQUIRE(trimmed_left == "bc");
|
||||
REQUIRE(trimmed_right == "ab");
|
||||
REQUIRE(trimmed == "b");
|
||||
}
|
||||
|
||||
GIVEN("string view")
|
||||
{
|
||||
String s_ = "abc";
|
||||
StringView s = s_;
|
||||
|
||||
auto trimmed_left = trim_left_copy(s, "a");
|
||||
auto trimmed_right = trim_right_copy(s, "c");
|
||||
auto trimmed = trim_copy(s, "ac");
|
||||
|
||||
REQUIRE(trimmed_left == "bc");
|
||||
REQUIRE(trimmed_right == "ab");
|
||||
REQUIRE(trimmed == "b");
|
||||
}
|
||||
|
||||
GIVEN("string view from string on stack")
|
||||
{
|
||||
auto trimmed_left = trim_left_copy<StringView>(String("abc"), "a");
|
||||
auto trimmed_right = trim_right_copy<StringView>(String("abc"), "c");
|
||||
auto trimmed = trim_copy<StringView>(String("abc"), "ac");
|
||||
|
||||
REQUIRE(trimmed_left == "bc");
|
||||
REQUIRE(trimmed_right == "ab");
|
||||
REQUIRE(trimmed == "b");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
25
tjp/core/string/as_string.hpp
Executable file
25
tjp/core/string/as_string.hpp
Executable file
@@ -0,0 +1,25 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "String.h"
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
template<typename T>
|
||||
String as_string(const T &s)
|
||||
{
|
||||
return String((char *)s.data(), s.size() * sizeof(s.front()));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline
|
||||
String as_string(const String &s)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
17
tjp/core/string/as_string_view.hpp
Executable file
17
tjp/core/string/as_string_view.hpp
Executable file
@@ -0,0 +1,17 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "String.h"
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
template<typename T>
|
||||
StringView as_string_view(const T &s)
|
||||
{
|
||||
return StringView((char *)s.data(), s.size() * sizeof(s.front()));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
37
tjp/core/string/as_vector.hpp
Executable file
37
tjp/core/string/as_vector.hpp
Executable file
@@ -0,0 +1,37 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "String.h"
|
||||
#include "StringView.h"
|
||||
#include "../containers/Vector.h"
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
template<typename T=char, typename U>
|
||||
Vector<T> as_vector(const U &s)
|
||||
{
|
||||
return Vector<T>((T *)s.data(), (T *)(s.data() + s.size()));
|
||||
}
|
||||
|
||||
template<typename T=char>
|
||||
Vector<T> as_vector(const String &s)
|
||||
{
|
||||
return Vector<T>((T *)s.data(), (T *)(s.data() + s.size()));
|
||||
}
|
||||
|
||||
template<typename T=char>
|
||||
Vector<T> as_vector(const StringView &s)
|
||||
{
|
||||
return Vector<T>((T *)s.data(), (T *)(s.data() + s.size()));
|
||||
}
|
||||
|
||||
template<typename T=char>
|
||||
Vector<T> as_vector(const char *s)
|
||||
{
|
||||
return as_vector(StringView(s));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
25
tjp/core/string/auto_to_string.hpp
Normal file
25
tjp/core/string/auto_to_string.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ToString.hpp"
|
||||
|
||||
// this is questionable
|
||||
|
||||
namespace std {
|
||||
|
||||
template<typename T>
|
||||
auto operator <<(const std::string &s, T &&t)
|
||||
{
|
||||
return tjp::core::ToString() << s << std::forward<T>(t);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto operator <<(const std::string_view &s, T &&t)
|
||||
{
|
||||
return tjp::core::ToString() << s << std::forward<T>(t);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
50
tjp/core/string/cmp.cpp
Executable file
50
tjp/core/string/cmp.cpp
Executable file
@@ -0,0 +1,50 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
#ifdef TJP_CORE_HEADER_ONLY
|
||||
#pragma once
|
||||
#endif
|
||||
#include "../header_only/compile.h"
|
||||
|
||||
#include "cmp.hpp"
|
||||
#include "strncmp.h"
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
TJP_CORE_HEADER_ONLY_INLINE
|
||||
int cmp(const String &l, const String &r)
|
||||
{
|
||||
return strncmp(l.c_str(), l.size(), r.c_str(), r.size());
|
||||
}
|
||||
|
||||
TJP_CORE_HEADER_ONLY_INLINE
|
||||
bool less(const String &l, const String &r)
|
||||
{
|
||||
return l < r;
|
||||
}
|
||||
|
||||
TJP_CORE_HEADER_ONLY_INLINE
|
||||
bool equal(const String &l, String &r)
|
||||
{
|
||||
return l == r;
|
||||
}
|
||||
|
||||
TJP_CORE_HEADER_ONLY_INLINE
|
||||
int cmp(const StringView &l, const StringView &r)
|
||||
{
|
||||
return strncmp(l.data(), l.size(), r.data(), r.size());
|
||||
}
|
||||
|
||||
TJP_CORE_HEADER_ONLY_INLINE
|
||||
bool less(const StringView &l, const StringView &r)
|
||||
{
|
||||
return l < r;
|
||||
}
|
||||
|
||||
TJP_CORE_HEADER_ONLY_INLINE
|
||||
bool equal(const StringView &l, const StringView &r)
|
||||
{
|
||||
return l == r;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
20
tjp/core/string/cmp.hpp
Executable file
20
tjp/core/string/cmp.hpp
Executable file
@@ -0,0 +1,20 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "String.h"
|
||||
#include "StringView.h"
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
int cmp(const String &l, const String &r);
|
||||
bool less(const String &l, const String &r);
|
||||
bool equal(const String &l, const String &r);
|
||||
|
||||
int cmp(const StringView &l, const StringView &r);
|
||||
bool less(const StringView &l, const StringView &r);
|
||||
bool equal(const StringView &l, const StringView &r);
|
||||
|
||||
} // namespace
|
||||
52
tjp/core/string/cmp_case.cpp
Executable file
52
tjp/core/string/cmp_case.cpp
Executable file
@@ -0,0 +1,52 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#ifdef TJP_CORE_HEADER_ONLY
|
||||
#pragma once
|
||||
#endif
|
||||
#include "../header_only/compile.h"
|
||||
|
||||
#include "cmp_case.hpp"
|
||||
#include "strncasecmp.h"
|
||||
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
TJP_CORE_HEADER_ONLY_INLINE
|
||||
int cmp_case(const String &l, const String &r)
|
||||
{
|
||||
return strncasecmp(l.c_str(), l.size(), r.c_str(), r.size());
|
||||
}
|
||||
|
||||
TJP_CORE_HEADER_ONLY_INLINE
|
||||
bool less_case(const String &l, const String &r)
|
||||
{
|
||||
return cmp_case(l,r) < 0;
|
||||
}
|
||||
|
||||
TJP_CORE_HEADER_ONLY_INLINE
|
||||
bool equal_case(const String &l, const String &r)
|
||||
{
|
||||
return cmp_case(l,r) == 0;
|
||||
}
|
||||
|
||||
TJP_CORE_HEADER_ONLY_INLINE
|
||||
int cmp_case(const StringView &l, const StringView &r)
|
||||
{
|
||||
return strncasecmp(l.data(), l.size(), r.data(), r.size());
|
||||
}
|
||||
|
||||
TJP_CORE_HEADER_ONLY_INLINE
|
||||
bool less_case(const StringView &l, const StringView &r)
|
||||
{
|
||||
return cmp_case(l, r) < 0;
|
||||
}
|
||||
|
||||
TJP_CORE_HEADER_ONLY_INLINE
|
||||
bool equal_case(const StringView &l, const StringView &r)
|
||||
{
|
||||
return cmp_case(l,r) == 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
25
tjp/core/string/cmp_case.hpp
Executable file
25
tjp/core/string/cmp_case.hpp
Executable file
@@ -0,0 +1,25 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "String.h"
|
||||
#include "StringView.h"
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
int cmp_case(const String &l, const String &r);
|
||||
int cmp_case(const StringView &l, const StringView &r);
|
||||
|
||||
bool less_case(const String &l, const String &r);
|
||||
bool less_case(const StringView &l, const StringView &r);
|
||||
|
||||
bool equal_case(const String &l, const String &r);
|
||||
bool equal_case(const StringView &l, const StringView &r);
|
||||
|
||||
} // namespace
|
||||
|
||||
#ifdef TJP_CORE_HEADER_ONLY
|
||||
#include "cmp_case.cpp"
|
||||
#endif
|
||||
7
tjp/core/string/ends_with.hpp
Executable file
7
tjp/core/string/ends_with.hpp
Executable file
@@ -0,0 +1,7 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../algorithm/ends_with.hpp"
|
||||
26
tjp/core/string/find_after.hpp
Executable file
26
tjp/core/string/find_after.hpp
Executable file
@@ -0,0 +1,26 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../containers/Optional.hpp"
|
||||
|
||||
#include "StringView.hpp"
|
||||
|
||||
namespace tjp::core::string {
|
||||
|
||||
inline
|
||||
Optional<StringView::pos> find_after(const StringView &s, const StringView &find, StringView::pos pos=0)
|
||||
{
|
||||
if (pos + find.size() > s.size())
|
||||
return {};
|
||||
|
||||
auto f = s.find(find, pos);
|
||||
if (f == s.npos)
|
||||
return {};
|
||||
|
||||
return f + find.size();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
23
tjp/core/string/find_if.hpp
Executable file
23
tjp/core/string/find_if.hpp
Executable file
@@ -0,0 +1,23 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../containers/Optional.hpp"
|
||||
|
||||
#include "StringView.hpp"
|
||||
|
||||
namespace tjp::core::string {
|
||||
|
||||
inline
|
||||
Optional<size_t> find_if(const StringView &s, const StringView &find, size_t pos=0)
|
||||
{
|
||||
auto f = s.find(find, pos);
|
||||
if (f == s.npos)
|
||||
return {};
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
69
tjp/core/string/from_string.cpp
Executable file
69
tjp/core/string/from_string.cpp
Executable file
@@ -0,0 +1,69 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#ifdef TJP_CORE_HEADER_ONLY
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "../header_only/compile.h"
|
||||
|
||||
#include "from_string.hpp"
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
TJP_CORE_HEADER_ONLY_INLINE
|
||||
void from_string(std::string_view &v, const std::string_view &s)
|
||||
{
|
||||
v = s;
|
||||
}
|
||||
|
||||
TJP_CORE_HEADER_ONLY_INLINE
|
||||
void from_string(std::string &v, const std::string_view &s)
|
||||
{
|
||||
v = s;
|
||||
}
|
||||
|
||||
TJP_CORE_HEADER_ONLY_INLINE
|
||||
void from_string(bool &v, const std::string_view &s)
|
||||
{
|
||||
v = (s == "true");
|
||||
}
|
||||
|
||||
|
||||
TJP_CORE_HEADER_ONLY_INLINE
|
||||
int naive_atoi(const std::string_view &s)
|
||||
{
|
||||
// Taken from http://tinodidriksen.com/uploads/code/cpp/speed-string-to-int.cpp
|
||||
|
||||
int x = 0;
|
||||
bool neg = false;
|
||||
auto *p = s.data();
|
||||
auto *e = p + s.size();
|
||||
|
||||
if (p < e && *p == '-') {
|
||||
neg = true;
|
||||
++p;
|
||||
}
|
||||
|
||||
while (p < e && *p >= '0' && *p <= '9') {
|
||||
x = (x*10) + (*p - '0');
|
||||
++p;
|
||||
}
|
||||
|
||||
if (neg) {
|
||||
x = -x;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
TJP_CORE_HEADER_ONLY_INLINE
|
||||
void from_string(int &v, const std::string_view &s)
|
||||
{
|
||||
v = naive_atoi(s);
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
25
tjp/core/string/from_string.h
Executable file
25
tjp/core/string/from_string.h
Executable file
@@ -0,0 +1,25 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
template<typename T>
|
||||
void from_string(T &t, const std::string_view &s);
|
||||
|
||||
template<typename T>
|
||||
T from_string(const std::string_view &s);
|
||||
|
||||
template<typename T>
|
||||
T from_string(const std::string_view &s, const T &defaultValue);
|
||||
|
||||
void from_string(std::string_view &v, const std::string_view &s);
|
||||
void from_string(std::string &, const std::string_view &s);
|
||||
void from_string(bool &v, const std::string_view &s);
|
||||
void from_string(int &v, const std::string_view &s);
|
||||
|
||||
} // namespace
|
||||
14
tjp/core/string/from_string.hpp
Executable file
14
tjp/core/string/from_string.hpp
Executable file
@@ -0,0 +1,14 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../header_only/compile.h"
|
||||
|
||||
#include "from_string.h"
|
||||
#include "from_string.inl"
|
||||
|
||||
#ifdef TJP_CORE_HEADER_ONLY
|
||||
#include "from_string.cpp"
|
||||
#endif
|
||||
44
tjp/core/string/from_string.inl
Executable file
44
tjp/core/string/from_string.inl
Executable file
@@ -0,0 +1,44 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "from_string.h"
|
||||
#include "../io/memstream.hpp"
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
template<typename T>
|
||||
void from_string(T &t, const std::string_view &s)
|
||||
{
|
||||
io::imemstream in(s.data(), s.size());
|
||||
in >> t;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T from_string(const std::string_view &s, const T &defaultValue)
|
||||
{
|
||||
T t = defaultValue;
|
||||
from_string(t, s);
|
||||
return t;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T from_string(const std::string_view &s)
|
||||
{
|
||||
T t;
|
||||
from_string(t, s);
|
||||
return t;
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
T from_string_using(const U &s)
|
||||
{
|
||||
T t;
|
||||
io::imemstream in(s.data(), s.size());
|
||||
in >> t;
|
||||
return t;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
17
tjp/core/string/has.hpp
Executable file
17
tjp/core/string/has.hpp
Executable file
@@ -0,0 +1,17 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../algorithm/has_sequence.hpp"
|
||||
#include "StringView.hpp"
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
bool has(const StringView &lhs, const StringView &rhs)
|
||||
{
|
||||
return has_sequence(lhs, rhs);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
17
tjp/core/string/has_prefix.hpp
Executable file
17
tjp/core/string/has_prefix.hpp
Executable file
@@ -0,0 +1,17 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "starts_with.hpp"
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
inline
|
||||
bool has_prefix(const std::string_view &s, const std::string_view &prefix)
|
||||
{
|
||||
return starts_with(s, prefix);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
72
tjp/core/string/join.hpp
Executable file
72
tjp/core/string/join.hpp
Executable file
@@ -0,0 +1,72 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../iterators/is_first.hpp"
|
||||
#include "to_string.hpp"
|
||||
#include <string>
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
template <typename V, typename T>
|
||||
void join_(std::string &result, is_first &first, const V &delimiter, const T & sv)
|
||||
{
|
||||
for (auto &s : sv)
|
||||
{
|
||||
if (!first.check())
|
||||
result += delimiter;
|
||||
|
||||
result.insert(result.end(), s.begin(), s.end());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename V, typename U, typename T>
|
||||
void join_(std::string &result, is_first &first, const V &delimiter, const U &u, const T & sv)
|
||||
{
|
||||
for (auto &s_ : sv)
|
||||
{
|
||||
auto s = u(s_);
|
||||
if (!first.check())
|
||||
result += delimiter;
|
||||
|
||||
result.insert(result.end(), s.begin(), s.end());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename V, typename ... T>
|
||||
std::string join(const V &delimiter, T&& ... t)
|
||||
{
|
||||
std::string result;
|
||||
is_first first;
|
||||
|
||||
((join_(result, first, delimiter, t)),...) ;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename V, typename ... T>
|
||||
std::string join_values(const V &delimiter, T&& ... t)
|
||||
{
|
||||
std::string result;
|
||||
is_first first;
|
||||
|
||||
auto u = [](auto &v) { return to_string(v); };
|
||||
((join_(result, first, delimiter, u, t)),...) ;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename V, typename U, typename ... T>
|
||||
std::string join_with(const V &delimiter, U &&u, T&& ... t)
|
||||
{
|
||||
std::string result;
|
||||
is_first first;
|
||||
|
||||
((join_(result, first, delimiter, u, t)),...) ;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
37
tjp/core/string/replace.cpp
Executable file
37
tjp/core/string/replace.cpp
Executable file
@@ -0,0 +1,37 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#if defined(TJP_CORE_HEADER_ONLY)
|
||||
#pragma once
|
||||
#endif
|
||||
#include "../header_only/compile.h"
|
||||
|
||||
#include "replace.h"
|
||||
#include <string>
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
TJP_CORE_HEADER_ONLY_INLINE
|
||||
bool replace(String& str, const StringView& from, const StringView& to)
|
||||
{
|
||||
size_t start_pos = str.find(from);
|
||||
if(start_pos == std::string::npos)
|
||||
return false;
|
||||
str.replace(start_pos, from.length(), to);
|
||||
return true;
|
||||
}
|
||||
|
||||
TJP_CORE_HEADER_ONLY_INLINE
|
||||
void replaceAll(String& str, const StringView& from, const StringView& to)
|
||||
{
|
||||
if(from.empty())
|
||||
return;
|
||||
size_t start_pos = 0;
|
||||
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
|
||||
str.replace(start_pos, from.length(), to);
|
||||
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
19
tjp/core/string/replace.h
Executable file
19
tjp/core/string/replace.h
Executable file
@@ -0,0 +1,19 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "String.hpp"
|
||||
#include "StringView.hpp"
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
bool replace(String & str, const StringView& from, const StringView& to);
|
||||
void replaceAll(String& str, const StringView& from, const StringView& to);
|
||||
|
||||
} // namespace
|
||||
|
||||
#ifdef TJP_CORE_HEADER_ONLY
|
||||
#include "replace.cpp"
|
||||
#endif
|
||||
23
tjp/core/string/replaced.cpp
Executable file
23
tjp/core/string/replaced.cpp
Executable file
@@ -0,0 +1,23 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#include "replace.h"
|
||||
#include "replaced.h"
|
||||
#include <string>
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
String replacedFirst(const StringView & str, const StringView& from, const StringView& to) {
|
||||
auto s = String(str);
|
||||
replace(s, from, to);
|
||||
return s;
|
||||
}
|
||||
|
||||
String replaced(const StringView & str, const StringView& from, const StringView& to) {
|
||||
auto s = String(str);
|
||||
replaceAll(s, from, to);
|
||||
return s;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
15
tjp/core/string/replaced.h
Executable file
15
tjp/core/string/replaced.h
Executable file
@@ -0,0 +1,15 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "String.hpp"
|
||||
#include "StringView.hpp"
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
String replaceFirst(const StringView & str, const StringView& from, const StringView& to);
|
||||
String replaced(const StringView & str, const StringView& from, const StringView& to);
|
||||
|
||||
} // namespace
|
||||
16
tjp/core/string/split.hpp
Executable file
16
tjp/core/string/split.hpp
Executable file
@@ -0,0 +1,16 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> split(const T &s, const T &delimiter);
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "split.inl"
|
||||
49
tjp/core/string/split.inl
Executable file
49
tjp/core/string/split.inl
Executable file
@@ -0,0 +1,49 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> split(const T &s, const T &delimiter)
|
||||
{
|
||||
std::vector<T> result;
|
||||
|
||||
size_t last = 0; size_t next = 0;
|
||||
while ((next = s.find(delimiter, last)) != T::npos)
|
||||
{
|
||||
if (last < next)
|
||||
result.push_back(s.substr(last, next-last));
|
||||
|
||||
last = next + std::max(delimiter.size(), (size_t)1);
|
||||
}
|
||||
|
||||
if (last < s.size())
|
||||
result.push_back(s.substr(last));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> split(const T &s, char delimiter)
|
||||
{
|
||||
std::vector<T> result;
|
||||
|
||||
size_t last = 0; size_t next = 0;
|
||||
while ((next = s.find(delimiter, last)) != T::npos)
|
||||
{
|
||||
if (last < next)
|
||||
result.push_back(s.substr(last, next-last));
|
||||
|
||||
last = next + 1;
|
||||
}
|
||||
|
||||
if (last < s.size())
|
||||
result.push_back(s.substr(last));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
26
tjp/core/string/split_once.hpp
Executable file
26
tjp/core/string/split_once.hpp
Executable file
@@ -0,0 +1,26 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../containers/Tuple.hpp"
|
||||
#include "../containers/Optional.hpp"
|
||||
#include "StringView.hpp"
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
template <typename T>
|
||||
Optional<Tuple<T, T>> split_once(const T &s, const StringView &delimiter)
|
||||
{
|
||||
auto v = s.find(delimiter);
|
||||
if (v == s.npos)
|
||||
return {};
|
||||
|
||||
return Tuple<T, T> {
|
||||
s.substr(0, v),
|
||||
s.substr(v+delimiter.size())
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
7
tjp/core/string/starts_with.hpp
Executable file
7
tjp/core/string/starts_with.hpp
Executable file
@@ -0,0 +1,7 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../algorithm/starts_with.hpp"
|
||||
62
tjp/core/string/str_find.cpp
Executable file
62
tjp/core/string/str_find.cpp
Executable file
@@ -0,0 +1,62 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#include "str_find.h"
|
||||
#include <cstring>
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
size_t str_find(const char *s, char del, size_t offset)
|
||||
{
|
||||
const char *result = strchr(s+offset, del);
|
||||
if (result == NULL)
|
||||
return -1;
|
||||
return (size_t)(result - s);
|
||||
}
|
||||
|
||||
size_t str_find(const unsigned char *s, const unsigned char *tokens, size_t offset, char &t, size_t size)
|
||||
{
|
||||
t = 0;
|
||||
|
||||
bool found = false;
|
||||
const unsigned char *r = (const unsigned char *)s+offset;
|
||||
const unsigned char *e = s + size;
|
||||
for (;r < e && *r!=0; r++)
|
||||
{
|
||||
if (*(tokens + *r))
|
||||
{
|
||||
t = *r;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return -1;
|
||||
|
||||
return (int)(r - s);
|
||||
}
|
||||
|
||||
size_t str_find(const unsigned char *s, const std::string_view &tokens, size_t offset, char &t, size_t size)
|
||||
{
|
||||
t = 0;
|
||||
|
||||
const unsigned char *r = (const unsigned char *)s+offset;
|
||||
const unsigned char *e = s + size;
|
||||
for (;r < e && *r!=0; r++)
|
||||
{
|
||||
for (auto &t_ : tokens)
|
||||
{
|
||||
if (t_ == *r)
|
||||
{
|
||||
t = t_;
|
||||
return (int)(r - s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
16
tjp/core/string/str_find.h
Executable file
16
tjp/core/string/str_find.h
Executable file
@@ -0,0 +1,16 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
size_t str_find(const char *s, char del, size_t offset=0);
|
||||
size_t str_find(const unsigned char *s, const unsigned char *tokens, size_t offset, char &t, size_t size);
|
||||
size_t str_find(const unsigned char *s, const std::string_view &tokens, size_t offset, char &t, size_t size);
|
||||
|
||||
|
||||
} // namespace
|
||||
32
tjp/core/string/strncasecmp.cpp
Executable file
32
tjp/core/string/strncasecmp.cpp
Executable file
@@ -0,0 +1,32 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#ifdef TJP_CORE_HEADER_ONLY
|
||||
#pragma once
|
||||
#endif
|
||||
#include "../header_only/compile.h"
|
||||
|
||||
#include "strncasecmp.h"
|
||||
|
||||
#include <strings.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
TJP_CORE_HEADER_ONLY_INLINE
|
||||
int strncasecmp(const char *l, size_t ls, const char *r, size_t rs)
|
||||
{
|
||||
auto v = ::strncasecmp(l, r, std::min(ls, rs));
|
||||
if (v != 0)
|
||||
return v;
|
||||
|
||||
if (ls > rs)
|
||||
return 1;
|
||||
if (ls < rs)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
17
tjp/core/string/strncasecmp.h
Executable file
17
tjp/core/string/strncasecmp.h
Executable file
@@ -0,0 +1,17 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
int strncasecmp(const char *l, size_t ls, const char *r, size_t rs);
|
||||
|
||||
} // namespace
|
||||
|
||||
#ifdef TJP_CORE_HEADER_ONLY
|
||||
#include "strncasecmp.cpp"
|
||||
#endif
|
||||
28
tjp/core/string/strncmp.cpp
Executable file
28
tjp/core/string/strncmp.cpp
Executable file
@@ -0,0 +1,28 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#include "strncmp.h"
|
||||
|
||||
#include <strings.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
int strncmp(const char *l, size_t ls, const char *r, size_t rs)
|
||||
{
|
||||
auto v = ::strncmp(l, r, std::min(ls, rs));
|
||||
if (v != 0)
|
||||
return v;
|
||||
|
||||
if (ls > rs)
|
||||
return 1;
|
||||
if (ls < rs)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
13
tjp/core/string/strncmp.h
Executable file
13
tjp/core/string/strncmp.h
Executable file
@@ -0,0 +1,13 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
int strncmp(const char *l, size_t ls, const char *r, size_t rs);
|
||||
|
||||
} // namespace
|
||||
21
tjp/core/string/sxprintf.h
Executable file
21
tjp/core/string/sxprintf.h
Executable file
@@ -0,0 +1,21 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdio>
|
||||
#include <type_traits>
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
template<typename T, typename ... Args>
|
||||
void sxprintf(T &t, const char *format, Args &&... args)
|
||||
{
|
||||
static_assert(std::is_array<T>::value, "T must be an array");
|
||||
static_assert(std::is_same<typename std::remove_all_extents<T>::type, char>::value, "T must be an array of char");
|
||||
|
||||
snprintf(t, std::size(t), format, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
27
tjp/core/string/to_lower.hpp
Executable file
27
tjp/core/string/to_lower.hpp
Executable file
@@ -0,0 +1,27 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "String.h"
|
||||
#include "StringView.h"
|
||||
#include <cctype>
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
inline
|
||||
String to_lower(const StringView &s_)
|
||||
{
|
||||
String s(s_);
|
||||
|
||||
std::transform(
|
||||
s.begin(), s.end(), s.begin(),
|
||||
[](unsigned char c){ return std::tolower(c); }
|
||||
);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
23
tjp/core/string/to_string.h
Executable file
23
tjp/core/string/to_string.h
Executable file
@@ -0,0 +1,23 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace std {
|
||||
|
||||
inline
|
||||
std::string to_string(const std::string_view &s);
|
||||
|
||||
}
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
|
||||
template<typename T>
|
||||
std::string to_string(const T &t);
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
40
tjp/core/string/to_string.hpp
Executable file
40
tjp/core/string/to_string.hpp
Executable file
@@ -0,0 +1,40 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "to_string.h"
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace std {
|
||||
|
||||
inline
|
||||
std::string to_string(const std::string_view &s)
|
||||
{
|
||||
return std::string(s.data(), s.size());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
|
||||
template<typename T>
|
||||
std::string to_string(const T &t)
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << t;
|
||||
return s.str();
|
||||
}
|
||||
|
||||
inline
|
||||
std::string to_string(const std::string_view &s)
|
||||
{
|
||||
return std::to_string(s);
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
32
tjp/core/string/trim.h
Executable file
32
tjp/core/string/trim.h
Executable file
@@ -0,0 +1,32 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "String.hpp"
|
||||
#include "StringView.hpp"
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
template<typename T>
|
||||
T trim_right_copy(
|
||||
const T &s,
|
||||
const StringView &delimiters = " \f\n\r\t\v"
|
||||
);
|
||||
|
||||
template<typename T>
|
||||
T trim_left_copy(
|
||||
const T &s,
|
||||
const StringView &delimiters = " \f\n\r\t\v"
|
||||
);
|
||||
|
||||
template<typename T>
|
||||
T trim_copy(
|
||||
const T &s,
|
||||
const StringView & delimiters = " \f\n\r\t\v"
|
||||
);
|
||||
|
||||
} // namespace
|
||||
|
||||
#include "trim.inl"
|
||||
49
tjp/core/string/trim.inl
Executable file
49
tjp/core/string/trim.inl
Executable file
@@ -0,0 +1,49 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "trim.h"
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
template<typename T>
|
||||
T trim_right_copy(
|
||||
const T &s,
|
||||
const StringView &delimiters)
|
||||
{
|
||||
if (s.empty())
|
||||
return {};
|
||||
|
||||
return s.substr( 0, s.find_last_not_of( delimiters ) + 1 );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T trim_left_copy(
|
||||
const T &s,
|
||||
const StringView &delimiters)
|
||||
{
|
||||
if (s.empty())
|
||||
return {};
|
||||
|
||||
return s.substr( s.find_first_not_of( delimiters ) );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T trim_copy(
|
||||
const T &s,
|
||||
const StringView &delimiters)
|
||||
{
|
||||
if (s.empty())
|
||||
return {};
|
||||
|
||||
return
|
||||
trim_left_copy(
|
||||
trim_right_copy(s, delimiters),
|
||||
delimiters
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
21
tjp/core/string/unprefix.hpp
Executable file
21
tjp/core/string/unprefix.hpp
Executable file
@@ -0,0 +1,21 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../containers/Optional.hpp"
|
||||
#include "starts_with.hpp"
|
||||
|
||||
namespace tjp::core {
|
||||
|
||||
inline
|
||||
Optional<std::string_view> unprefix(const std::string_view &s, const std::string_view &prefix)
|
||||
{
|
||||
if (starts_with(s, prefix))
|
||||
return s.substr(prefix.size());
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user