5 #ifndef __NODAMUSHI_SVD_PATH_HPP__ 6 #define __NODAMUSHI_SVD_PATH_HPP__ 16 template<
typename STR>
struct path;
18 namespace path_details {
22 const int a1 = a <=
'Z'?(int)a-(
int)
'A':(int)a -(
int)
'a';
23 const int b1 = b <=
'Z'?(int)b-(
int)
'A':(int)b -(
int)
'a';
29 constexpr
int num(
char c){
30 return (
'0'<=c && c <=
'9')? c-
'0': -1;
33 template<
typename S1,
typename S2>
34 constexpr
int compare(
const S1& s1,
const S2& s2)
36 const size_t ss1 = s1.size(),ss2 = s2.size();
39 for(;i1 < ss1 && i2 < ss2;i1++,i2++){
40 const char c1 = s1[i1],c2 = s2[i2];
41 const int n1 =
num(c1);
42 const int n2 =
num(c2);
45 constexpr
size_t OVER_FLOW = ((size_t)~0) / 10;
46 size_t num1=n1,count1=0;
47 for(;i1+1<ss1;i1++,count1++){
48 const int n =
num(s1[i1+1]);
50 if(num1 >= OVER_FLOW)
break;
51 num1 = num1 * 10 + (size_t)n;
54 size_t num2=n2,count2=0;
55 for(;i2+1<ss2;i2++,count2++){
56 const int n =
num(s2[i2+1]);
58 if(num2 >= OVER_FLOW)
break;
59 num2 = num2 * 10 + (size_t)n;
61 if(num1 < num2)
return -1;
62 else if(num1 > num2)
return 1;
65 same = count1 < count2? -2: 2;
78 size_t rest1 = ss1-i1 , rest2 = ss2-i2;
79 return same != 0&&rest1==0 && rest2==0? (same>>1):
112 template<
typename STR=sub
string>
struct path
114 template<
typename STR2>
friend class path;
123 names.reserve(count);
125 auto from = s.cbegin();
143 names.reserve(a.names.size()+b.names.size());
144 for(
const auto& e:a)names.push_back(e);
145 for(
const auto& e:b)names.push_back(e);
149 names.reserve(a.names.size()+b.names.size());
150 for(
const auto& e:a)names.push_back(e);
151 for(
auto&& e:b)names.push_back(std::move(e));
154 path(path<STR>&&) =
default;
155 template<
typename STR2>
158 names.reserve(p.size());
159 for(
const auto& s:p){
164 path(
const path<STR>&) =
default;
165 path<STR>&
operator=(path<STR>&&)=
default;
166 path<STR>&
operator=(
const path<STR>&)=
default;
167 template<
typename STR2>
171 names.reserve(p.size());
172 for(
const auto& s:p){
182 # if __cplusplus >= 201703 190 size_t s = names.size();
191 size_t s2 = s + p.size();
193 for(
const auto& e:p.names)
199 size_t s = names.size();
200 size_t s2 = s + p.size();
202 for(
auto&& e:p.names)
203 names.push_back(std::move(e));
218 size_t size()const noexcept{
return names.size();}
219 bool single()const noexcept{
return names.size()==1;}
220 bool empty()const noexcept{
return names.size()==0;}
221 operator bool()const noexcept{
return names.size()!=0;}
224 return {*
this,from,s};
227 auto begin()
const{
return names.begin();}
228 auto end()
const{
return names.end();}
229 auto cbegin()
const{
return names.cbegin();}
230 auto cend()
const{
return names.cend();}
232 auto end(){
return names.end();}
237 if((
void*)
this == (
void*)&s)
return true;
238 if(s.size() !=
size())
return false;
239 for(
size_t i = 0,e =
size();i < e;i++){
240 if(names[i] != s.names[i]){
292 if(
this == &s)
return 0;
293 const size_t st =
size(),s1 = s.size();
294 const size_t size = st<s1? st:s1;
295 for(
size_t i = 0;i<
size;i++){
300 return st == s1 ? 0: st < s1? -1:1;
309 std::vector<STR> names;
315 static constexpr
bool set(
const std::string& src,
path<STR>& dst){dst = src;
return true;}
316 # if __cplusplus >= 201703 317 static constexpr
bool set(
const std::string_view& src,
path<STR>& dst){dst = src;
return true;}
329 ostream&
operator <<(ostream& o,const ::nodamushi::svd::path<S>& p)
331 for(
size_t i = 0,n=p.size();i<n;i++){
339 #endif // __NODAMUSHI_SVD_PATH_HPP__
path< STR > & operator=(path< STR > &&)=default
path< STR > & operator=(const path< STR2 > &p)
ostream & operator<<(std::ostream &os, const ::nodamushi::svd::Access &value)
size_t size() const noexcept
bool empty() const noexcept
int compare(const path< S > &s) const noexcept
static constexpr bool set(const std::string &src, path< STR > &dst)
bool operator<(const path< S > &s) const noexcept
bool operator!=(string_ref s) const
path< STR > & add(path< STR > &&p)
path< STR > & add_name(string_ref p)
const std::string & string_ref
path< STR > subpath(size_t from, size_t end=0) const
path< STR > add(path< STR > &&a) const
bool single() const noexcept
path< STR > append(const path< STR > &a) const
path(const path< STR2 > &p)
bool equals(const path< S > &s) const
bool operator==(const path< S > &s) const
path< STR > add(const path< STR > &a) const
bool operator>=(const path< S > &s) const noexcept
constexpr int compare(char a, char b)
This class reperesents SVD(xml) element / attribute.
constexpr int num(char c)
path< STR > append(path< STR > &&a) const
path< STR > & operator=(const std::string &s)
string_ref operator[](size_t i) const
path(const path< STR > &a, const path< STR > &b)
bool operator<=(const path< S > &s) const noexcept
path(const path< STR > &a, path< STR > &&b)
bool operator>(const path< S > &s) const noexcept
bool operator==(string_ref s) const
void emplace_back_string(std::vector< std::string > &v, ITR itr, ITR_END end)
path< STR > & add(const path< STR > &p)
path(const path< STR > &p, size_t from, size_t size)
bool operator!=(const path< S > &s) const