mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-14 16:09:06 +07:00
remove string_view backport
This commit is contained in:
@@ -11,5 +11,4 @@
|
||||
#include "configs.hpp"
|
||||
#include "macros.hpp"
|
||||
#include "main.hpp"
|
||||
#include "stdex.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
@@ -1,367 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "Enduro2D"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "macros.hpp"
|
||||
|
||||
//
|
||||
// basic_string_view
|
||||
//
|
||||
|
||||
namespace e2d { namespace stdex
|
||||
{
|
||||
template < typename Char, typename Traits = std::char_traits<Char> >
|
||||
class basic_string_view {
|
||||
public:
|
||||
using value_type = Char;
|
||||
using traits_type = Traits;
|
||||
|
||||
using pointer = const Char*;
|
||||
using const_pointer = const Char*;
|
||||
|
||||
using reference = const Char&;
|
||||
using const_reference = const Char&;
|
||||
|
||||
using const_iterator = const_pointer;
|
||||
using iterator = const_iterator;
|
||||
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
using reverse_iterator = const_reverse_iterator;
|
||||
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
static const size_type npos = size_type(-1);
|
||||
|
||||
static_assert(
|
||||
std::is_pod<value_type>::value,
|
||||
"value_type must be a POD");
|
||||
static_assert(
|
||||
std::is_same<value_type, typename traits_type::char_type>::value,
|
||||
"traits_type::char_type must be the same type as value_type");
|
||||
public:
|
||||
basic_string_view() noexcept = default;
|
||||
basic_string_view(const basic_string_view&) noexcept = default;
|
||||
basic_string_view& operator=(const basic_string_view&) noexcept = default;
|
||||
|
||||
basic_string_view(std::nullptr_t) noexcept = delete;
|
||||
basic_string_view(std::nullptr_t, size_type) noexcept = delete;
|
||||
|
||||
basic_string_view(const Char* str) noexcept {
|
||||
E2D_ASSERT(str);
|
||||
data_ = str;
|
||||
size_ = Traits::length(str);
|
||||
}
|
||||
|
||||
basic_string_view(const Char* str, size_type size) noexcept {
|
||||
E2D_ASSERT(!size || str);
|
||||
data_ = str;
|
||||
size_ = size;
|
||||
}
|
||||
|
||||
template < typename Alloc >
|
||||
basic_string_view(const std::basic_string<Char, Traits, Alloc>& str) noexcept
|
||||
: data_(str.data())
|
||||
, size_(str.size()) {}
|
||||
|
||||
template < typename Alloc >
|
||||
operator std::basic_string<Char, Traits, Alloc>() const {
|
||||
return {cbegin(), cend()};
|
||||
}
|
||||
|
||||
const_iterator begin() const noexcept {
|
||||
return data_;
|
||||
}
|
||||
|
||||
const_iterator cbegin() const noexcept {
|
||||
return data_;
|
||||
}
|
||||
|
||||
const_iterator end() const noexcept {
|
||||
return data_ + size_;
|
||||
}
|
||||
|
||||
const_iterator cend() const noexcept {
|
||||
return data_ + size_;
|
||||
}
|
||||
|
||||
const_reverse_iterator rbegin() const noexcept {
|
||||
return const_reverse_iterator(end());
|
||||
}
|
||||
|
||||
const_reverse_iterator crbegin() const noexcept {
|
||||
return const_reverse_iterator(cend());
|
||||
}
|
||||
|
||||
const_reverse_iterator rend() const noexcept {
|
||||
return const_reverse_iterator(begin());
|
||||
}
|
||||
|
||||
const_reverse_iterator crend() const noexcept {
|
||||
return const_reverse_iterator(cbegin());
|
||||
}
|
||||
|
||||
size_type size() const noexcept {
|
||||
return size_;
|
||||
}
|
||||
|
||||
size_type length() const noexcept {
|
||||
return size_;
|
||||
}
|
||||
|
||||
size_type max_size() const noexcept {
|
||||
return std::numeric_limits<size_type>::max();
|
||||
}
|
||||
|
||||
bool empty() const noexcept {
|
||||
return size_ == 0;
|
||||
}
|
||||
|
||||
const_reference operator[](size_type index) const noexcept {
|
||||
E2D_ASSERT(index < size_);
|
||||
return data_[index];
|
||||
}
|
||||
|
||||
const_reference at(size_type index) const {
|
||||
if ( index < size_ ) {
|
||||
return data_[index];
|
||||
}
|
||||
throw std::out_of_range("basic_string_view::at");
|
||||
}
|
||||
|
||||
const_reference front() const noexcept {
|
||||
E2D_ASSERT(size_ > 0);
|
||||
return data_[0];
|
||||
}
|
||||
|
||||
const_reference back() const noexcept {
|
||||
E2D_ASSERT(size_ > 0);
|
||||
return data_[size_ - 1];
|
||||
}
|
||||
|
||||
const_pointer data() const noexcept {
|
||||
return data_;
|
||||
}
|
||||
|
||||
void swap(basic_string_view& other) noexcept {
|
||||
std::swap(data_, other.data_);
|
||||
std::swap(size_, other.size_);
|
||||
}
|
||||
|
||||
void remove_prefix(size_type n) noexcept {
|
||||
E2D_ASSERT(n <= size_);
|
||||
data_ += n;
|
||||
size_ -= n;
|
||||
}
|
||||
|
||||
void remove_suffix(size_type n) noexcept {
|
||||
E2D_ASSERT(n <= size_);
|
||||
size_ -= n;
|
||||
}
|
||||
|
||||
int compare(basic_string_view str) const noexcept {
|
||||
const auto ms = std::min(size(), str.size());
|
||||
const auto cr = Traits::compare(data(), str.data(), ms);
|
||||
return cr == 0
|
||||
? (size() == str.size()
|
||||
? 0
|
||||
: (size() < str.size() ? -1 : 1))
|
||||
: cr;
|
||||
}
|
||||
|
||||
int compare(size_type pos1, size_type n1, basic_string_view other) const noexcept {
|
||||
return substr(pos1, n1).compare(other);
|
||||
}
|
||||
|
||||
int compare(size_type pos1, size_type n1, basic_string_view other, size_type pos2, size_type n2) const noexcept {
|
||||
return substr(pos1, n1).compare(other.substr(pos2, n2));
|
||||
}
|
||||
|
||||
int compare(const Char* other) const noexcept {
|
||||
return compare(basic_string_view(other));
|
||||
}
|
||||
|
||||
int compare(size_type pos1, size_type n1, const Char* other) const noexcept {
|
||||
return substr(pos1, n1).compare(basic_string_view(other));
|
||||
}
|
||||
|
||||
int compare(size_type pos1, size_type n1, const Char* other, size_type n2) const noexcept {
|
||||
return substr(pos1, n1).compare(basic_string_view(other, n2));
|
||||
}
|
||||
|
||||
bool starts_with(basic_string_view other) const noexcept {
|
||||
return size() >= other.size() && 0 == compare(0, other.size(), other);
|
||||
}
|
||||
|
||||
bool starts_with(Char other) const noexcept {
|
||||
return starts_with(basic_string_view(&other, 1));
|
||||
}
|
||||
|
||||
bool starts_with(const Char* other) const noexcept {
|
||||
return starts_with(basic_string_view(other));
|
||||
}
|
||||
|
||||
bool ends_with(basic_string_view other) const noexcept {
|
||||
return size() >= other.size() && 0 == compare(size() - other.size(), npos, other);
|
||||
}
|
||||
|
||||
bool ends_with(Char other) const noexcept {
|
||||
return ends_with(basic_string_view(&other, 1));
|
||||
}
|
||||
|
||||
bool ends_with(const Char* other) const noexcept {
|
||||
return ends_with(basic_string_view(other));
|
||||
}
|
||||
|
||||
size_type copy(Char* dst, size_type size, size_type index = 0) const {
|
||||
if ( index > size_ ) {
|
||||
throw std::out_of_range("basic_string_view::copy");
|
||||
}
|
||||
size_type ms = std::min(size, size_ - index);
|
||||
Traits::copy(dst, data_ + index, ms);
|
||||
return ms;
|
||||
}
|
||||
|
||||
basic_string_view substr(size_type index = 0, size_type size = npos) const {
|
||||
if ( index <= size_ ) {
|
||||
return basic_string_view(
|
||||
data_ + index,
|
||||
std::min(size, size_ - index));
|
||||
}
|
||||
throw std::out_of_range("basic_string_view::substr");
|
||||
}
|
||||
private:
|
||||
const Char* data_ = nullptr;
|
||||
size_type size_ = 0;
|
||||
};
|
||||
|
||||
template < typename Char, typename Traits >
|
||||
const typename basic_string_view<Char, Traits>::size_type
|
||||
basic_string_view<Char, Traits>::npos;
|
||||
|
||||
template < typename Char, typename Traits >
|
||||
bool operator<(
|
||||
basic_string_view<Char, Traits> l,
|
||||
basic_string_view<Char, Traits> r) noexcept
|
||||
{
|
||||
return l.compare(r) < 0;
|
||||
}
|
||||
|
||||
template < typename Char, typename Traits >
|
||||
bool operator<(
|
||||
basic_string_view<Char, Traits> l,
|
||||
const char* r) noexcept
|
||||
{
|
||||
return l.compare(basic_string_view<Char, Traits>(r)) < 0;
|
||||
}
|
||||
|
||||
template < typename Char, typename Traits >
|
||||
bool operator<(
|
||||
basic_string_view<Char, Traits> l,
|
||||
const std::basic_string<Char, Traits>& r) noexcept
|
||||
{
|
||||
return l.compare(basic_string_view<Char, Traits>(r)) < 0;
|
||||
}
|
||||
|
||||
template < typename Char, typename Traits >
|
||||
bool operator<(
|
||||
const char* l,
|
||||
basic_string_view<Char, Traits> r) noexcept
|
||||
{
|
||||
return basic_string_view<Char, Traits>(l).compare(r) < 0;
|
||||
}
|
||||
|
||||
template < typename Char, typename Traits >
|
||||
bool operator<(
|
||||
const std::basic_string<Char, Traits>& l,
|
||||
basic_string_view<Char, Traits> r) noexcept
|
||||
{
|
||||
return basic_string_view<Char, Traits>(l).compare(r) < 0;
|
||||
}
|
||||
|
||||
template < typename Char, typename Traits >
|
||||
bool operator==(
|
||||
basic_string_view<Char, Traits> l,
|
||||
basic_string_view<Char, Traits> r) noexcept
|
||||
{
|
||||
const auto ls = l.size();
|
||||
const auto rs = r.size();
|
||||
return ls == rs && Traits::compare(l.data(), r.data(), ls) == 0;
|
||||
}
|
||||
|
||||
template < typename Char, typename Traits >
|
||||
bool operator==(
|
||||
basic_string_view<Char, Traits> l,
|
||||
const char* r) noexcept
|
||||
{
|
||||
return l.compare(basic_string_view<Char, Traits>(r)) == 0;
|
||||
}
|
||||
|
||||
template < typename Char, typename Traits >
|
||||
bool operator==(
|
||||
basic_string_view<Char, Traits> l,
|
||||
const std::basic_string<Char, Traits>& r) noexcept
|
||||
{
|
||||
return l.compare(basic_string_view<Char, Traits>(r)) == 0;
|
||||
}
|
||||
|
||||
template < typename Char, typename Traits >
|
||||
bool operator==(
|
||||
const char* l,
|
||||
basic_string_view<Char, Traits> r) noexcept
|
||||
{
|
||||
return basic_string_view<Char, Traits>(l).compare(r) == 0;
|
||||
}
|
||||
|
||||
template < typename Char, typename Traits >
|
||||
bool operator==(
|
||||
const std::basic_string<Char, Traits>& l,
|
||||
basic_string_view<Char, Traits> r) noexcept
|
||||
{
|
||||
return basic_string_view<Char, Traits>(l).compare(r) == 0;
|
||||
}
|
||||
|
||||
template < typename Char, typename Traits >
|
||||
bool operator!=(
|
||||
basic_string_view<Char, Traits> l,
|
||||
basic_string_view<Char, Traits> r) noexcept
|
||||
{
|
||||
return !(l == r);
|
||||
}
|
||||
|
||||
template < typename Char, typename Traits >
|
||||
bool operator!=(
|
||||
basic_string_view<Char, Traits> l,
|
||||
const char* r) noexcept
|
||||
{
|
||||
return !(l == r);
|
||||
}
|
||||
|
||||
template < typename Char, typename Traits >
|
||||
bool operator!=(
|
||||
basic_string_view<Char, Traits> l,
|
||||
const std::basic_string<Char, Traits>& r) noexcept
|
||||
{
|
||||
return !(l == r);
|
||||
}
|
||||
|
||||
template < typename Char, typename Traits >
|
||||
bool operator!=(
|
||||
const char* l,
|
||||
basic_string_view<Char, Traits> r) noexcept
|
||||
{
|
||||
return !(l == r);
|
||||
}
|
||||
|
||||
template < typename Char, typename Traits >
|
||||
bool operator!=(
|
||||
const std::basic_string<Char, Traits>& l,
|
||||
basic_string_view<Char, Traits> r) noexcept
|
||||
{
|
||||
return !(l == r);
|
||||
}
|
||||
}}
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "stdex.hpp"
|
||||
#include "_base.hpp"
|
||||
|
||||
namespace e2d
|
||||
{
|
||||
@@ -41,26 +41,26 @@ namespace e2d
|
||||
using vector = std::vector<Value, Allocator>;
|
||||
|
||||
template < typename Key
|
||||
, typename Comp = std::less<Key>
|
||||
, typename Comp = std::less<>
|
||||
, typename Allocator = std::allocator<Key> >
|
||||
using set = std::set<Key, Comp, Allocator>;
|
||||
|
||||
template < typename Key
|
||||
, typename Value
|
||||
, typename Comp = std::less<Key>
|
||||
, typename Comp = std::less<>
|
||||
, typename Allocator = std::allocator<std::pair<const Key, Value>> >
|
||||
using map = std::map<Key, Value, Comp, Allocator>;
|
||||
|
||||
template < typename Value
|
||||
, typename Hash = std::hash<Value>
|
||||
, typename Pred = std::equal_to<Value>
|
||||
, typename Pred = std::equal_to<>
|
||||
, typename Allocator = std::allocator<Value> >
|
||||
using hash_set = std::unordered_set<Value, Hash, Pred, Allocator>;
|
||||
|
||||
template < typename Key
|
||||
, typename Value
|
||||
, typename Hash = std::hash<Key>
|
||||
, typename Pred = std::equal_to<Key>
|
||||
, typename Pred = std::equal_to<>
|
||||
, typename Allocator = std::allocator<std::pair<const Key, Value>> >
|
||||
using hash_map = std::unordered_map<Key, Value, Hash, Pred, Allocator>;
|
||||
|
||||
@@ -71,5 +71,5 @@ namespace e2d
|
||||
|
||||
template < typename Char
|
||||
, typename Traits = std::char_traits<Char> >
|
||||
using basic_string_view = stdex::basic_string_view<Char, Traits>;
|
||||
using basic_string_view = std::basic_string_view<Char, Traits>;
|
||||
}
|
||||
|
||||
@@ -118,6 +118,9 @@ namespace e2d
|
||||
str_view fmt, Args&&... args) noexcept;
|
||||
|
||||
bool wildcard_match(str_view string, str_view pattern);
|
||||
|
||||
bool starts_with(str_view input, str_view test) noexcept;
|
||||
bool ends_with(str_view input, str_view test) noexcept;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,8 +80,8 @@ namespace e2d
|
||||
public:
|
||||
std::mutex mutex;
|
||||
stdex::jobber worker{1};
|
||||
hash_map<str, url> aliases;
|
||||
hash_map<str, file_source_uptr> schemes;
|
||||
map<str, url> aliases;
|
||||
map<str, file_source_uptr> schemes;
|
||||
public:
|
||||
url resolve_url(const url& url, u8 level = 0) const {
|
||||
if ( level > 32 ) {
|
||||
@@ -121,7 +121,10 @@ namespace e2d
|
||||
|
||||
bool vfs::unregister_scheme(str_view scheme) {
|
||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||
return state_->schemes.erase(scheme) > 0;
|
||||
const auto iter = state_->schemes.find(scheme);
|
||||
return iter != state_->schemes.end()
|
||||
? (state_->schemes.erase(iter), true)
|
||||
: false;
|
||||
}
|
||||
|
||||
bool vfs::register_scheme_alias(str_view scheme, url alias) {
|
||||
@@ -132,7 +135,10 @@ namespace e2d
|
||||
|
||||
bool vfs::unregister_scheme_alias(str_view scheme) {
|
||||
std::lock_guard<std::mutex> guard(state_->mutex);
|
||||
return state_->aliases.erase(scheme) > 0;
|
||||
const auto iter = state_->aliases.find(scheme);
|
||||
return iter != state_->aliases.end()
|
||||
? (state_->aliases.erase(iter), true)
|
||||
: false;
|
||||
}
|
||||
|
||||
bool vfs::exists(const url& url) const {
|
||||
@@ -326,7 +332,7 @@ namespace e2d
|
||||
mz_zip_archive_file_stat file_stat;
|
||||
if ( mz_zip_reader_file_stat(state_->archive.get(), i, &file_stat) ) {
|
||||
const str_view filename{file_stat.m_filename};
|
||||
if ( filename.length() > parent.length() && filename.starts_with(parent) ) {
|
||||
if ( filename.length() > parent.length() && strings::starts_with(filename, parent) ) {
|
||||
func(file_stat.m_filename, !!file_stat.m_is_directory);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,10 +22,10 @@ namespace e2d { namespace address
|
||||
str parent(str_view address) {
|
||||
const auto sep_e = str_view_search(address, address_separator);
|
||||
if ( sep_e == address.end() ) {
|
||||
return address;
|
||||
return str(address);
|
||||
}
|
||||
const auto sep_d = std::distance(address.begin(), sep_e);
|
||||
return address.substr(0, static_cast<std::size_t>(sep_d));
|
||||
return str(address.substr(0, static_cast<std::size_t>(sep_d)));
|
||||
}
|
||||
|
||||
str nested(str_view address) {
|
||||
@@ -34,6 +34,6 @@ namespace e2d { namespace address
|
||||
return str();
|
||||
}
|
||||
const auto sep_d = std::distance(address.begin(), sep_e);
|
||||
return address.substr(static_cast<std::size_t>(sep_d) + address_separator.size());
|
||||
return str(address.substr(static_cast<std::size_t>(sep_d) + address_separator.size()));
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace
|
||||
}
|
||||
{
|
||||
factory_loader<>::collect_context ctx(
|
||||
parent_address,
|
||||
str(parent_address),
|
||||
component_root->value);
|
||||
bool success = the<factory>().collect_dependencies(
|
||||
component_root->name.GetString(),
|
||||
@@ -151,7 +151,7 @@ namespace
|
||||
++component_root )
|
||||
{
|
||||
factory_loader<>::fill_context ctx(
|
||||
parent_address,
|
||||
str(parent_address),
|
||||
component_root->value,
|
||||
dependencies);
|
||||
bool success = the<factory>().fill_prototype(
|
||||
|
||||
@@ -187,7 +187,7 @@ namespace e2d { namespace impl
|
||||
{
|
||||
read_file_uptr make_read_file(str_view path) noexcept {
|
||||
try {
|
||||
return std::make_unique<read_file_posix>(path);
|
||||
return std::make_unique<read_file_posix>(str(path));
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -195,7 +195,7 @@ namespace e2d { namespace impl
|
||||
|
||||
write_file_uptr make_write_file(str_view path, bool append) noexcept {
|
||||
try {
|
||||
return std::make_unique<write_file_posix>(path, append);
|
||||
return std::make_unique<write_file_posix>(str(path), append);
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ namespace e2d { namespace impl
|
||||
{
|
||||
read_file_uptr make_read_file(str_view path) noexcept {
|
||||
try {
|
||||
return std::make_unique<read_file_winapi>(path);
|
||||
return std::make_unique<read_file_winapi>(str(path));
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -234,7 +234,7 @@ namespace e2d { namespace impl
|
||||
|
||||
write_file_uptr make_write_file(str_view path, bool append) noexcept {
|
||||
try {
|
||||
return std::make_unique<write_file_winapi>(path, append);
|
||||
return std::make_unique<write_file_winapi>(str(path), append);
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -41,10 +41,10 @@ namespace e2d { namespace path
|
||||
{
|
||||
str combine(str_view lhs, str_view rhs) {
|
||||
if ( lhs.empty() || is_absolute(rhs) ) {
|
||||
return rhs;
|
||||
return str(rhs);
|
||||
}
|
||||
if ( rhs.empty() ) {
|
||||
return lhs;
|
||||
return str(lhs);
|
||||
}
|
||||
return is_directory_separator(lhs.back())
|
||||
? str_view_concat(lhs, rhs)
|
||||
@@ -54,15 +54,15 @@ namespace e2d { namespace path
|
||||
str remove_filename(str_view path) {
|
||||
const str name = filename(path);
|
||||
return name.empty()
|
||||
? path
|
||||
: path.substr(0, path.length() - name.length());
|
||||
? str(path)
|
||||
: str(path.substr(0, path.length() - name.length()));
|
||||
}
|
||||
|
||||
str remove_extension(str_view path) {
|
||||
const str ext = extension(path);
|
||||
return ext.empty()
|
||||
? path
|
||||
: path.substr(0, path.length() - ext.length());
|
||||
? str(path)
|
||||
: str(path.substr(0, path.length() - ext.length()));
|
||||
}
|
||||
|
||||
str replace_filename(str_view path, str_view filename) {
|
||||
@@ -94,7 +94,7 @@ namespace e2d { namespace path
|
||||
const auto sep_e = std::find_if(
|
||||
path.crbegin(), path.crend(), &is_directory_separator);
|
||||
const auto sep_d = std::distance(sep_e, path.crend());
|
||||
return path.substr(static_cast<std::size_t>(sep_d));
|
||||
return str(path.substr(static_cast<std::size_t>(sep_d)));
|
||||
}
|
||||
|
||||
str extension(str_view path) {
|
||||
@@ -120,7 +120,7 @@ namespace e2d { namespace path
|
||||
return str();
|
||||
}
|
||||
const auto sep_d = std::distance(sep_b, path.crend());
|
||||
return path.substr(0, static_cast<std::size_t>(sep_d));
|
||||
return str(path.substr(0, static_cast<std::size_t>(sep_d)));
|
||||
}
|
||||
|
||||
bool is_absolute(str_view path) noexcept {
|
||||
|
||||
@@ -327,4 +327,14 @@ namespace e2d { namespace strings
|
||||
utf8_iter(si, si, se), utf8_iter(se, si, se),
|
||||
utf8_iter(pi, pi, pe), utf8_iter(pe, pi, pe));
|
||||
}
|
||||
|
||||
bool starts_with(str_view input, str_view test) noexcept {
|
||||
return input.length() >= test.length()
|
||||
&& 0 == input.compare(0, test.length(), test);
|
||||
}
|
||||
|
||||
bool ends_with(str_view input, str_view test) noexcept {
|
||||
return input.length() >= test.length()
|
||||
&& 0 == input.compare(input.length() - test.length(), test.length(), test);
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -42,11 +42,11 @@ namespace
|
||||
const str_view::size_type sep_pos =
|
||||
str_view_search(schemepath, scheme_separator, 0);
|
||||
if ( str_view::npos == sep_pos ) {
|
||||
return std::make_pair(str(), schemepath);
|
||||
return std::make_pair(str(), str(schemepath));
|
||||
}
|
||||
return std::make_pair(
|
||||
schemepath.substr(0, sep_pos),
|
||||
schemepath.substr(sep_pos + scheme_separator.length()));
|
||||
str(schemepath.substr(0, sep_pos)),
|
||||
str(schemepath.substr(sep_pos + scheme_separator.length())));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -254,6 +254,25 @@ TEST_CASE("strings") {
|
||||
REQUIRE(wildcard_match(mark_string("abc"), mark_pattern("********a********b********b********")) == false);
|
||||
REQUIRE(wildcard_match(mark_string("*abc*"), mark_pattern("***a*b*c***")) == true);
|
||||
}
|
||||
{
|
||||
REQUIRE(strings::starts_with("", ""));
|
||||
REQUIRE(strings::starts_with("hello_world", ""));
|
||||
REQUIRE(strings::starts_with("hello_world", "hello"));
|
||||
REQUIRE(strings::starts_with("hello_world", "hello_world"));
|
||||
REQUIRE_FALSE(strings::starts_with("", "a"));
|
||||
REQUIRE_FALSE(strings::starts_with("hello_world", "world"));
|
||||
REQUIRE_FALSE(strings::starts_with("hello_world", "hello_world_42"));
|
||||
REQUIRE_FALSE(strings::starts_with("hello_world", "42_hello_world"));
|
||||
|
||||
REQUIRE(strings::ends_with("", ""));
|
||||
REQUIRE(strings::ends_with("hello_world", ""));
|
||||
REQUIRE(strings::ends_with("hello_world", "world"));
|
||||
REQUIRE(strings::ends_with("hello_world", "hello_world"));
|
||||
REQUIRE_FALSE(strings::ends_with("", "a"));
|
||||
REQUIRE_FALSE(strings::ends_with("hello_world", "hello"));
|
||||
REQUIRE_FALSE(strings::ends_with("hello_world", "hello_world_42"));
|
||||
REQUIRE_FALSE(strings::ends_with("hello_world", "42_hello_world"));
|
||||
}
|
||||
{
|
||||
char buf[6];
|
||||
REQUIRE_THROWS_AS(strings::format(buf, 0, "hello"), strings::bad_format_buffer);
|
||||
|
||||
Reference in New Issue
Block a user