Update cx::string to be more level with string_view
This commit is contained in:
parent
e5d8c0f567
commit
00355a64c6
@ -201,6 +201,40 @@ namespace rexy{
|
|||||||
return l = (l + r);
|
return l = (l + r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T, class Char, std::enable_if_t<is_string<T>::value, int> = 0>
|
||||||
|
constexpr std::size_t find_first_of(T&& t, const Char* c, std::size_t start, std::size_t size){
|
||||||
|
if(start > t.length()){
|
||||||
|
return rexy::npos;
|
||||||
|
}
|
||||||
|
for(auto it = t.cbegin() + start;it != t.cend();++it){
|
||||||
|
for(std::size_t i = 0;i < size;++i){
|
||||||
|
if(*it == c[i]){
|
||||||
|
return it - t.cbegin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rexy::npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class Char, std::enable_if_t<is_string<T>::value, int> = 0>
|
||||||
|
constexpr std::size_t find_last_of(T&& t, const Char* c, std::size_t start, std::size_t size){
|
||||||
|
if(start > t.length()){
|
||||||
|
return rexy::npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto b = t.cend() - 1;
|
||||||
|
const auto e = t.cbegin() - 1 - start;
|
||||||
|
|
||||||
|
for(auto it = b;it != e;--it){
|
||||||
|
for(std::size_t i = 0;i < size;++i){
|
||||||
|
if(*it == c[i]){
|
||||||
|
return it - t.cbegin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rexy::npos;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -21,50 +21,13 @@
|
|||||||
|
|
||||||
#include "../../string_base.hpp"
|
#include "../../string_base.hpp"
|
||||||
|
|
||||||
#include <concepts> //convertible_to
|
#include <utility> //forward
|
||||||
#include <utility> //forward, as_const
|
|
||||||
#include <type_traits> //decay, is_nothrow_assignable
|
#include <type_traits> //decay, is_nothrow_assignable
|
||||||
|
|
||||||
|
#include "../../concepts/string.hpp"
|
||||||
|
|
||||||
namespace rexy{
|
namespace rexy{
|
||||||
|
|
||||||
template<class T>
|
|
||||||
concept BasicString = requires(const T& a){
|
|
||||||
{std::as_const(a).length()} -> std::convertible_to<typename std::decay_t<T>::size_type>;
|
|
||||||
{std::as_const(a).c_str()} -> std::convertible_to<typename std::decay_t<T>::const_pointer>;
|
|
||||||
{std::as_const(a)[0]} -> std::convertible_to<typename std::decay_t<T>::const_reference>;
|
|
||||||
{std::as_const(a).begin()} -> std::convertible_to<typename std::decay_t<T>::const_iterator>;
|
|
||||||
{std::as_const(a).end()} -> std::convertible_to<typename std::decay_t<T>::const_iterator>;
|
|
||||||
};
|
|
||||||
template<class T>
|
|
||||||
concept StringExpr = rexy::is_template_type<T,string_cat_expr>::value;
|
|
||||||
template<class T>
|
|
||||||
concept String = BasicString<T> || StringExpr<T>;
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct is_string{
|
|
||||||
static constexpr bool value = BasicString<T>;
|
|
||||||
};
|
|
||||||
template<class T>
|
|
||||||
static constexpr bool is_string_v = is_string<T>::value;
|
|
||||||
template<class... Ts>
|
|
||||||
struct are_strings{
|
|
||||||
static constexpr bool value = (BasicString<Ts> && ...);
|
|
||||||
};
|
|
||||||
template<class... Ts>
|
|
||||||
static constexpr bool are_strings_v = are_strings<Ts...>::value;
|
|
||||||
template<class T>
|
|
||||||
struct is_string_expr{
|
|
||||||
static constexpr bool value = StringExpr<T>;
|
|
||||||
};
|
|
||||||
template<class T>
|
|
||||||
static constexpr bool is_string_expr_v = is_string_expr<T>::value;
|
|
||||||
template<class... Ts>
|
|
||||||
struct are_string_expr{
|
|
||||||
static constexpr bool value = (StringExpr<Ts> && ...);
|
|
||||||
};
|
|
||||||
template<class... Ts>
|
|
||||||
static constexpr bool are_string_expr_v = are_string_expr<Ts...>::value;
|
|
||||||
|
|
||||||
//Compare
|
//Compare
|
||||||
template<BasicString Str1, BasicString Str2>
|
template<BasicString Str1, BasicString Str2>
|
||||||
constexpr bool operator==(Str1&& left, Str2&& right){
|
constexpr bool operator==(Str1&& left, Str2&& right){
|
||||||
@ -145,6 +108,40 @@ namespace rexy{
|
|||||||
return l = (l + r);
|
return l = (l + r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<BasicString T, class Char>
|
||||||
|
constexpr std::size_t find_first_of(T&& t, const Char* c, std::size_t start, std::size_t size){
|
||||||
|
if(start > t.length()){
|
||||||
|
return rexy::npos;
|
||||||
|
}
|
||||||
|
for(auto it = t.cbegin() + start;it != t.cend();++it){
|
||||||
|
for(std::size_t i = 0;i < size;++i){
|
||||||
|
if(*it == c[i]){
|
||||||
|
return it - t.cbegin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rexy::npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<BasicString T, class Char>
|
||||||
|
constexpr std::size_t find_last_of(T&& t, const Char* c, std::size_t start, std::size_t size){
|
||||||
|
if(start > t.length()){
|
||||||
|
return rexy::npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto b = t.cend() - 1;
|
||||||
|
const auto e = t.cbegin() - 1 - start;
|
||||||
|
|
||||||
|
for(auto it = b;it != e;--it){
|
||||||
|
for(std::size_t i = 0;i < size;++i){
|
||||||
|
if(*it == c[i]){
|
||||||
|
return it - t.cbegin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rexy::npos;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
34
include/rexy/compat/string_base.hpp
Normal file
34
include/rexy/compat/string_base.hpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
This file is a part of rexy's general purpose library
|
||||||
|
Copyright (C) 2022 rexy712
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef REXY_COMPAT_STRING_BASE_HPP
|
||||||
|
#define REXY_COMPAT_STRING_BASE_HPP
|
||||||
|
|
||||||
|
#include <cstddef> //size_t
|
||||||
|
|
||||||
|
namespace rexy{
|
||||||
|
static constexpr std::size_t npos = std::size_t{-1};
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cpp_concepts
|
||||||
|
#include "cpp20/string_base.hpp"
|
||||||
|
#else
|
||||||
|
#include "cpp20/string_base.tpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
73
include/rexy/concepts/string.hpp
Normal file
73
include/rexy/concepts/string.hpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/**
|
||||||
|
This file is a part of rexy's general purpose library
|
||||||
|
Copyright (C) 2022 rexy712
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef REXY_CONCEPTS_STRING_HPP
|
||||||
|
#define REXY_CONCEPTS_STRING_HPP
|
||||||
|
|
||||||
|
#include <type_traits> //decay
|
||||||
|
#include <concepts> //convertible_to
|
||||||
|
#include <utility> //as_const
|
||||||
|
|
||||||
|
#include "../traits.hpp"
|
||||||
|
|
||||||
|
namespace rexy{
|
||||||
|
|
||||||
|
template<class Left, class Right>
|
||||||
|
class string_cat_expr;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
concept BasicString = requires(const T& a){
|
||||||
|
{std::as_const(a).length()} -> std::convertible_to<typename std::decay_t<T>::size_type>;
|
||||||
|
{std::as_const(a).c_str()} -> std::convertible_to<typename std::decay_t<T>::const_pointer>;
|
||||||
|
{std::as_const(a)[0]} -> std::convertible_to<typename std::decay_t<T>::const_reference>;
|
||||||
|
{std::as_const(a).begin()} -> std::convertible_to<typename std::decay_t<T>::const_iterator>;
|
||||||
|
{std::as_const(a).end()} -> std::convertible_to<typename std::decay_t<T>::const_iterator>;
|
||||||
|
};
|
||||||
|
template<class T>
|
||||||
|
concept StringExpr = rexy::is_template_type<T,string_cat_expr>::value;
|
||||||
|
template<class T>
|
||||||
|
concept String = BasicString<T> || StringExpr<T>;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct is_string{
|
||||||
|
static constexpr bool value = BasicString<T>;
|
||||||
|
};
|
||||||
|
template<class T>
|
||||||
|
static constexpr bool is_string_v = is_string<T>::value;
|
||||||
|
template<class... Ts>
|
||||||
|
struct are_strings{
|
||||||
|
static constexpr bool value = (BasicString<Ts> && ...);
|
||||||
|
};
|
||||||
|
template<class... Ts>
|
||||||
|
static constexpr bool are_strings_v = are_strings<Ts...>::value;
|
||||||
|
template<class T>
|
||||||
|
struct is_string_expr{
|
||||||
|
static constexpr bool value = StringExpr<T>;
|
||||||
|
};
|
||||||
|
template<class T>
|
||||||
|
static constexpr bool is_string_expr_v = is_string_expr<T>::value;
|
||||||
|
template<class... Ts>
|
||||||
|
struct are_string_expr{
|
||||||
|
static constexpr bool value = (StringExpr<Ts> && ...);
|
||||||
|
};
|
||||||
|
template<class... Ts>
|
||||||
|
static constexpr bool are_string_expr_v = are_string_expr<Ts...>::value;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -27,11 +27,14 @@ namespace rexy::cx{
|
|||||||
}
|
}
|
||||||
|
|
||||||
#include "../string_base.hpp" //string_cat_expr
|
#include "../string_base.hpp" //string_cat_expr
|
||||||
#include "../utility.hpp" //strlen
|
#include "../string_view.hpp"
|
||||||
|
#include "../utility.hpp" //strlen, strcmp
|
||||||
#include "../detail/string_appender.hpp"
|
#include "../detail/string_appender.hpp"
|
||||||
#include <type_traits> //nothrow_invocable, integral_constant, declval, remove_cvref_t
|
#include <type_traits> //nothrow_invocable, integral_constant, declval, remove_cvref_t
|
||||||
|
#include <iterator> //reverse_iterator
|
||||||
|
|
||||||
#include "../compat/standard.hpp"
|
#include "../compat/standard.hpp"
|
||||||
|
#include "../compat/string_base.hpp"
|
||||||
|
|
||||||
//This is different from rexy::string_view in that this doesn't hold a pointer to a constant string array.
|
//This is different from rexy::string_view in that this doesn't hold a pointer to a constant string array.
|
||||||
//This holds a mutable array of data which can be modified during compile time. string_view is
|
//This holds a mutable array of data which can be modified during compile time. string_view is
|
||||||
@ -52,9 +55,13 @@ namespace rexy::cx{
|
|||||||
using const_reference = const value_type&;
|
using const_reference = const value_type&;
|
||||||
using iterator = pointer;
|
using iterator = pointer;
|
||||||
using const_iterator = const_pointer;
|
using const_iterator = const_pointer;
|
||||||
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||||
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static constexpr std::size_t max_size = N;
|
static constexpr size_type max_size = N;
|
||||||
|
static constexpr size_type npos = size_type{-1};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
value_type m_data[N] = {};
|
value_type m_data[N] = {};
|
||||||
size_type m_length = 0;
|
size_type m_length = 0;
|
||||||
@ -117,43 +124,59 @@ namespace rexy::cx{
|
|||||||
constexpr string& operator=(const string&)noexcept = default;
|
constexpr string& operator=(const string&)noexcept = default;
|
||||||
constexpr string& operator=(string&&)noexcept = default;
|
constexpr string& operator=(string&&)noexcept = default;
|
||||||
|
|
||||||
|
constexpr bool operator==(const string& s)noexcept{return !rexy::strcmp(m_data, s.m_data);}
|
||||||
|
constexpr bool operator!=(const string& s)noexcept{return rexy::strcmp(m_data, s.m_data);}
|
||||||
|
|
||||||
constexpr size_type length(void)const noexcept
|
constexpr size_type length(void)const noexcept{return m_length;}
|
||||||
{return m_length;}
|
constexpr size_type size(void)const noexcept{return m_length;}
|
||||||
constexpr size_type capacity(void)const noexcept
|
constexpr size_type capacity(void)const noexcept{return max_size;}
|
||||||
{return max_size;}
|
constexpr bool empty(void)const noexcept{return m_length == 0;}
|
||||||
constexpr pointer c_str(void)noexcept
|
|
||||||
{return m_data;}
|
|
||||||
constexpr const_pointer c_str(void)const noexcept
|
|
||||||
{return m_data;}
|
|
||||||
constexpr pointer get(void)noexcept
|
|
||||||
{return m_data;}
|
|
||||||
constexpr const_pointer get(void)const noexcept
|
|
||||||
{return m_data;}
|
|
||||||
constexpr operator pointer(void)noexcept
|
|
||||||
{return m_data;}
|
|
||||||
constexpr operator const_pointer(void)const noexcept
|
|
||||||
{return m_data;}
|
|
||||||
|
|
||||||
constexpr iterator begin(void)noexcept
|
constexpr pointer c_str(void)noexcept{return m_data;}
|
||||||
{return m_data;}
|
constexpr const_pointer c_str(void)const noexcept{return m_data;}
|
||||||
constexpr const_iterator begin(void)const noexcept
|
constexpr pointer get(void)noexcept{return m_data;}
|
||||||
{return m_data;}
|
constexpr const_pointer get(void)const noexcept{return m_data;}
|
||||||
constexpr const_iterator cbegin(void)const noexcept
|
constexpr operator pointer(void)noexcept{return m_data;}
|
||||||
{return m_data;}
|
constexpr operator const_pointer(void)const noexcept{return m_data;}
|
||||||
constexpr iterator end(void)noexcept
|
|
||||||
{return m_data+m_length;}
|
|
||||||
constexpr const_iterator end(void)const noexcept
|
|
||||||
{return m_data+m_length;}
|
|
||||||
constexpr const_iterator cend(void)const noexcept
|
|
||||||
{return m_data+m_length;}
|
|
||||||
|
|
||||||
constexpr bool valid(void)const noexcept
|
constexpr reference operator[](size_type i)noexcept{return m_data[i];}
|
||||||
{return m_length > 0;}
|
constexpr const_reference operator[](size_type i)const noexcept{return m_data[i];}
|
||||||
constexpr reference operator[](size_type i)noexcept
|
constexpr reference at(size_type i)noexcept{return m_data[i];}
|
||||||
{return m_data[i];}
|
constexpr const_reference at(size_type i)const noexcept{return m_data[i];}
|
||||||
constexpr const_reference operator[](size_type i)const noexcept
|
constexpr const_reference front(size_type i)const noexcept{return m_data[0];}
|
||||||
{return m_data[i];}
|
constexpr const_reference back(size_type i)const noexcept{return m_data[m_length-1];}
|
||||||
|
|
||||||
|
constexpr const_iterator search(const basic_string_view<value_type>& s)const{
|
||||||
|
return two_way_search(cbegin(), cend(), s.cbegin(), s.cend());
|
||||||
|
}
|
||||||
|
constexpr const_iterator search(const_pointer c)const{
|
||||||
|
return search(basic_string_view<value_type>{c});
|
||||||
|
}
|
||||||
|
template<class Searcher>
|
||||||
|
constexpr const_iterator search(const basic_string_view<value_type>& s, Searcher&& searcher)const{
|
||||||
|
return searcher(cbegin(), cend(), s.cbegin(), s.cend());
|
||||||
|
}
|
||||||
|
template<class Searcher>
|
||||||
|
constexpr const_iterator search(const_pointer c, Searcher&& searcher)const{
|
||||||
|
return search(basic_string_view<value_type>{c}, searcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr iterator begin(void)noexcept{return m_data;}
|
||||||
|
constexpr const_iterator begin(void)const noexcept{return m_data;}
|
||||||
|
constexpr const_iterator cbegin(void)const noexcept{return m_data;}
|
||||||
|
constexpr iterator end(void)noexcept{return m_data+m_length;}
|
||||||
|
constexpr const_iterator end(void)const noexcept{return m_data+m_length;}
|
||||||
|
constexpr const_iterator cend(void)const noexcept{return m_data+m_length;}
|
||||||
|
|
||||||
|
constexpr const_reverse_iterator rbegin(void)const{return const_reverse_iterator(m_data+m_length);}
|
||||||
|
constexpr const_reverse_iterator rend(void)const{return const_reverse_iterator(m_data-1);}
|
||||||
|
constexpr const_reverse_iterator crbegin(void)const{return rbegin();}
|
||||||
|
constexpr const_reverse_iterator crend(void)const{return rend();}
|
||||||
|
|
||||||
|
constexpr bool valid(void)const noexcept{return m_length > 0;}
|
||||||
|
|
||||||
|
constexpr bool compare(const string& s)const{return *this == s;}
|
||||||
|
constexpr bool compare(const_pointer c)const{return *this == c;}
|
||||||
|
|
||||||
constexpr bool resize(size_type i)noexcept{
|
constexpr bool resize(size_type i)noexcept{
|
||||||
if(i >= capacity()){
|
if(i >= capacity()){
|
||||||
@ -169,12 +192,29 @@ namespace rexy::cx{
|
|||||||
m_data[m_length++] = data[i];
|
m_data[m_length++] = data[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
constexpr void append(const_pointer data)noexcept
|
constexpr void append(const_pointer data)noexcept{append(data, rexy::strlen(data));}
|
||||||
{append(data, rexy::strlen(data));}
|
constexpr void append(const string& s)noexcept{append(s.get(), s.length());}
|
||||||
constexpr void append(const string& s)noexcept
|
constexpr void append(const rexy::basic_string_view<value_type>& s)noexcept{append(s.get(), s.length());}
|
||||||
{append(s.get(), s.length());}
|
|
||||||
constexpr void append(const rexy::basic_string_view<value_type>& s)noexcept
|
constexpr size_type find_first_of(value_type v, size_type start = 0)const{
|
||||||
{append(s.get(), s.length());}
|
return rexy::find_first_of(*this, &v, start, 1);
|
||||||
|
}
|
||||||
|
constexpr size_type find_first_of(const_pointer c, size_type pos = 0)const{
|
||||||
|
return rexy::find_first_of(*this, c, pos, rexy::strlen(c));
|
||||||
|
}
|
||||||
|
constexpr size_type find_first_of(const_pointer c, size_type start, size_type size)const{
|
||||||
|
return rexy::find_first_of(*this, c, start, size);
|
||||||
|
}
|
||||||
|
constexpr size_type find_last_of(value_type v, size_type start = 0)const{
|
||||||
|
return rexy::find_last_of(*this, &v, start, 1);
|
||||||
|
}
|
||||||
|
constexpr size_type find_last_of(const_pointer c, size_type start = 0)const{
|
||||||
|
return rexy::find_last_of(*this, c, start, rexy::strlen(c));
|
||||||
|
}
|
||||||
|
constexpr size_type find_last_of(const_pointer c, size_type start, size_type size)const{
|
||||||
|
return rexy::find_last_of(*this, c, start, size);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
template<class Char, std::size_t N>
|
template<class Char, std::size_t N>
|
||||||
string(const Char(&data)[N]) -> string<N, Char>;
|
string(const Char(&data)[N]) -> string<N, Char>;
|
||||||
|
|||||||
@ -28,11 +28,7 @@
|
|||||||
#include "compat/to_address.hpp"
|
#include "compat/to_address.hpp"
|
||||||
#include "string_view.hpp"
|
#include "string_view.hpp"
|
||||||
|
|
||||||
#ifdef __cpp_concepts
|
#include "compat/string_base.hpp"
|
||||||
#include "compat/cpp20/string_base.hpp"
|
|
||||||
#else
|
|
||||||
#include "compat/cpp17/string_base.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace rexy{
|
namespace rexy{
|
||||||
|
|
||||||
|
|||||||
@ -67,7 +67,6 @@ namespace rexy{
|
|||||||
constexpr basic_string_view& operator=(const basic_string_view& s)noexcept = default;
|
constexpr basic_string_view& operator=(const basic_string_view& s)noexcept = default;
|
||||||
constexpr basic_string_view& operator=(basic_string_view&&)noexcept = default;
|
constexpr basic_string_view& operator=(basic_string_view&&)noexcept = default;
|
||||||
|
|
||||||
|
|
||||||
//Length of string not including null terminator
|
//Length of string not including null terminator
|
||||||
constexpr size_type length(void)const noexcept{return m_length;}
|
constexpr size_type length(void)const noexcept{return m_length;}
|
||||||
constexpr size_type size(void)const noexcept{return m_length;}
|
constexpr size_type size(void)const noexcept{return m_length;}
|
||||||
|
|||||||
@ -23,6 +23,8 @@
|
|||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
#include "string_base.hpp"
|
#include "string_base.hpp"
|
||||||
|
|
||||||
|
#include "compat/string_base.hpp"
|
||||||
|
|
||||||
namespace rexy{
|
namespace rexy{
|
||||||
|
|
||||||
template<class Char>
|
template<class Char>
|
||||||
@ -93,70 +95,27 @@ namespace rexy{
|
|||||||
}
|
}
|
||||||
template<class Char>
|
template<class Char>
|
||||||
constexpr auto basic_string_view<Char>::find_first_of(value_type v, size_type start)const -> size_type{
|
constexpr auto basic_string_view<Char>::find_first_of(value_type v, size_type start)const -> size_type{
|
||||||
if(start >= m_length){
|
return rexy::find_first_of(*this, &v, start, 1);
|
||||||
return npos;
|
|
||||||
}
|
|
||||||
for(auto it = begin() + start;it != end();++it){
|
|
||||||
if(*it == v){
|
|
||||||
return it - begin();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return npos;
|
|
||||||
}
|
}
|
||||||
template<class Char>
|
template<class Char>
|
||||||
constexpr auto basic_string_view<Char>::find_first_of(const_pointer c, size_type start)const -> size_type{
|
constexpr auto basic_string_view<Char>::find_first_of(const_pointer c, size_type start)const -> size_type{
|
||||||
return find_first_of(c, start, ::rexy::strlen(c));
|
return rexy::find_first_of(*this, c, start, rexy::strlen(c));
|
||||||
}
|
}
|
||||||
template<class Char>
|
template<class Char>
|
||||||
constexpr auto basic_string_view<Char>::find_first_of(const_pointer c, size_type start, size_type size)const -> size_type{
|
constexpr auto basic_string_view<Char>::find_first_of(const_pointer c, size_type start, size_type size)const -> size_type{
|
||||||
if(start > m_length){
|
return rexy::find_first_of(*this, c, start, size);
|
||||||
return npos;
|
|
||||||
}
|
|
||||||
for(auto it = begin() + start;it != end();++it){
|
|
||||||
for(size_type i = 0;i < size;++i){
|
|
||||||
if(*it == c[i]){
|
|
||||||
return it - begin();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return npos;
|
|
||||||
}
|
}
|
||||||
template<class Char>
|
template<class Char>
|
||||||
constexpr auto basic_string_view<Char>::find_last_of(value_type v, size_type start)const -> size_type{
|
constexpr auto basic_string_view<Char>::find_last_of(value_type v, size_type start)const -> size_type{
|
||||||
if(start >= m_length){
|
return rexy::find_last_of(*this, &v, start, 1);
|
||||||
return npos;
|
|
||||||
}
|
|
||||||
const auto b = end() - 1;
|
|
||||||
const auto e = begin() - 1 - start;
|
|
||||||
|
|
||||||
for(auto it = b;it != e;--it){
|
|
||||||
if(*it == v){
|
|
||||||
return it - begin();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return npos;
|
|
||||||
}
|
}
|
||||||
template<class Char>
|
template<class Char>
|
||||||
constexpr auto basic_string_view<Char>::find_last_of(const_pointer c, size_type start)const -> size_type{
|
constexpr auto basic_string_view<Char>::find_last_of(const_pointer c, size_type start)const -> size_type{
|
||||||
return find_last_of(c, start, ::rexy::strlen(c));
|
return rexy::find_last_of(*this, c, start, rexy::strlen(c));
|
||||||
}
|
}
|
||||||
template<class Char>
|
template<class Char>
|
||||||
constexpr auto basic_string_view<Char>::find_last_of(const_pointer c, size_type start, size_type size)const -> size_type{
|
constexpr auto basic_string_view<Char>::find_last_of(const_pointer c, size_type start, size_type size)const -> size_type{
|
||||||
if(start > m_length){
|
return rexy::find_last_of(*this, c, start, size);
|
||||||
return npos;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto b = end() - 1;
|
|
||||||
const auto e = begin() - 1 - start;
|
|
||||||
|
|
||||||
for(auto it = b;it != e;--it){
|
|
||||||
for(size_type i = 0;i < size;++i){
|
|
||||||
if(*it == c[i]){
|
|
||||||
return it - begin();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return npos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user