NSVD Reader  0.0.1
path.hpp
Go to the documentation of this file.
1 
5 #ifndef __NODAMUSHI_SVD_PATH_HPP__
6 #define __NODAMUSHI_SVD_PATH_HPP__
7 
8 # include <vector>
9 # include <iterator>
10 # include <algorithm>
11 # include "nodamushi/string_type.hpp"
13 namespace nodamushi{
14 namespace svd {
15 
16 template<typename STR>struct path;
17 
18 namespace path_details {
19 constexpr int compare(char a,char b)
20 {
21  if(a == b) return 0;
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';
24  return (a1 < b1)?-1:
25  (a1 > b1)? 1:
26  (a < b )?-2:2;
27 }
28 
29 constexpr int num(char c){
30  return ('0'<=c && c <='9')? c-'0': -1;
31 }
32 
33 template<typename S1,typename S2>
34 constexpr int compare(const S1& s1,const S2& s2)
35 {
36  const size_t ss1 = s1.size(),ss2 = s2.size();
37  int same = 0;
38  size_t i1=0,i2=0;
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);
43 
44  if(n1!=-1 && n2!=-1){
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]);
49  if(n==-1)break;
50  if(num1 >= OVER_FLOW)break; //TODO: big integer
51  num1 = num1 * 10 + (size_t)n;
52  }
53 
54  size_t num2=n2,count2=0;
55  for(;i2+1<ss2;i2++,count2++){
56  const int n = num(s2[i2+1]);
57  if(n==-1)break;
58  if(num2 >= OVER_FLOW)break; //TODO: big integer
59  num2 = num2 * 10 + (size_t)n;
60  }
61  if(num1 < num2) return -1;
62  else if(num1 > num2) return 1;
63 
64  if(count1!=count2)
65  same = count1 < count2? -2: 2;
66 
67  }else if(n1!=-1){
68  return -1;
69  }else if(n2!=-1){
70  return 1;
71  }else{
72  const int v = compare(c1,c2);
73  if(v & 1) return v;
74  if(v!=0)same = v;
75  }
76  }
77 
78  size_t rest1 = ss1-i1 , rest2 = ss2-i2;
79  return same != 0&&rest1==0 && rest2==0? (same>>1):
80  rest1 < rest2? -1:
81  rest1 ==rest2? 0: 1;
82 }
83 }// namespace path_details------------------
84 
112 template<typename STR=substring>struct path
113 {
114  template<typename STR2> friend class path;
115 
116  path():names{}{};
117  path(string_ref s):names(0)
118  {
119  size_t count =1;
120  for(auto c :s)
121  if(c == '.')
122  count++;
123  names.reserve(count);
124 
125  auto from = s.cbegin();
126  auto i = from;
127  auto end = s.cend();
128  while(i!=end){
129  auto c = *i;
130  if(c == '.'){
131  emplace_back_string(names,from,i);
132  from = i+1;
133  }
134  ++i;
135  }
136  if(i != from)
137  emplace_back_string(names,from,i);
138  }
139  path(const path<STR>& p,size_t from,size_t size):
140  names(p.names.begin()+from,p.names.begin()+from+size){}
141  path(const path<STR>& a,const path<STR>& b):names{}
142  {
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);
146  }
147  path(const path<STR>& a,path<STR>&& b):names{}
148  {
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));
152  b.names.clear();
153  }
154  path(path<STR>&&) = default;
155  template<typename STR2>
156  path(const path<STR2>&p):names{}
157  {
158  names.reserve(p.size());
159  for(const auto& s:p){
160  names.push_back(s);
161  }
162  }
163 
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>
169  {
170  names.clear();
171  names.reserve(p.size());
172  for(const auto& s:p){
173  names.push_back(s);
174  }
175  return *this;
176  }
177  path<STR>& operator=(const std::string& s){
178  operator=(path<STR>(s));
179  return *this;
180  }
181 
182 # if __cplusplus >= 201703
183  path<STR>& operator=(const std::string_view s){
184  operator=(path<STR>(s));
185  return *this;
186  }
187 # endif
189  {
190  size_t s = names.size();
191  size_t s2 = s + p.size();
192  names.reserve(s2);
193  for(const auto& e:p.names)
194  names.push_back(e);
195  return *this;
196  }
198  {
199  size_t s = names.size();
200  size_t s2 = s + p.size();
201  names.reserve(s2);
202  for(auto&& e:p.names)
203  names.push_back(std::move(e));
204  return *this;
205  }
207  {
208  names.push_back(p);
209  return *this;
210  }
211 
212  path<STR> append(const path<STR>& a)const{return {*this,a};}
213  path<STR> append(path<STR>&& a)const{return {*this,a};}
214  path<STR> add(const path<STR>& a)const{return {*this,a};}
215  path<STR> add(path<STR>&& a)const{return {*this,a};}
216 
217  string_ref operator[](size_t i)const{return names[i];}
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;}
222  path<STR> subpath(size_t from,size_t end=0)const{
223  size_t s = (end==0) ? size() - from:end-from;
224  return {*this,from,s};
225  }
226 
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();}
231  auto begin(){return names.begin();}
232  auto end(){return names.end();}
233 
234  template<typename S>
235  bool equals(const path<S>& s)const
236  {
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]){
241  return false;
242  }
243  }
244  return true;
245  }
246 
247  template<typename S>
248  bool operator!=(const path<S>& s)const
249  {
250  return !equals(s);
251  }
252  template<typename S>
253  bool operator==(const path<S>& s)const
254  {
255  return equals(s);
256  }
257 
258  bool operator==(string_ref s)const
259  {
260  path<> p(s);
261  return equals(p);
262  }
263  bool operator!=(string_ref s)const
264  {
265  path<> p(s);
266  return !equals(p);
267  }
268 
291  template<typename S>int compare(const path<S>& s)const noexcept{
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++){
296  const int n = path_details::compare(names[i],s.names[i]);
297  if(n!=0)
298  return n;
299  }
300  return st == s1 ? 0: st < s1? -1:1;
301  }
302 
303  template<typename S>bool operator<(const path<S>& s)const noexcept{return compare(s) < 0;}
304  template<typename S>bool operator>(const path<S>& s)const noexcept{return compare(s) > 0;}
305  template<typename S>bool operator<=(const path<S>& s)const noexcept{return compare(s) <= 0;}
306  template<typename S>bool operator>=(const path<S>& s)const noexcept{return compare(s) >= 0;}
307 
308  private:
309  std::vector<STR> names;
310 };
311 
312 template<typename STR>struct value_setter_helper<path<STR>>
313 {
314  static constexpr bool value=true;
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;}
318 # endif
319 };
320 
321 
322 } // svd
323 }// end namespace nodamushi
324 
325 # include <ostream>
326 
327 namespace std{
328 template<typename S>
329 ostream& operator <<(ostream& o,const ::nodamushi::svd::path<S>& p)
330 {
331  for(size_t i = 0,n=p.size();i<n;i++){
332  if(i!=0) o << '.';
333  o << p[i];
334  }
335  return o;
336 }
337 }
338 
339 #endif // __NODAMUSHI_SVD_PATH_HPP__
path< STR > & operator=(path< STR > &&)=default
path< STR > & operator=(const path< STR2 > &p)
Definition: path.hpp:168
ostream & operator<<(std::ostream &os, const ::nodamushi::svd::Access &value)
Definition: Access.hpp:144
auto cbegin() const
Definition: path.hpp:229
auto begin() const
Definition: path.hpp:227
auto cend() const
Definition: path.hpp:230
size_t size() const noexcept
Definition: path.hpp:218
bool empty() const noexcept
Definition: path.hpp:220
int compare(const path< S > &s) const noexcept
Definition: path.hpp:291
static constexpr bool set(const std::string &src, path< STR > &dst)
Definition: path.hpp:315
bool operator<(const path< S > &s) const noexcept
Definition: path.hpp:303
bool operator!=(string_ref s) const
Definition: path.hpp:263
path< STR > & add(path< STR > &&p)
Definition: path.hpp:197
Definition: Access.hpp:143
path< STR > & add_name(string_ref p)
Definition: path.hpp:206
const std::string & string_ref
Definition: string_type.hpp:44
C++17/14 string type.
path< STR > subpath(size_t from, size_t end=0) const
Definition: path.hpp:222
path< STR > add(path< STR > &&a) const
Definition: path.hpp:215
bool single() const noexcept
Definition: path.hpp:219
path< STR > append(const path< STR > &a) const
Definition: path.hpp:212
path(const path< STR2 > &p)
Definition: path.hpp:156
bool equals(const path< S > &s) const
Definition: path.hpp:235
bool operator==(const path< S > &s) const
Definition: path.hpp:253
path< STR > add(const path< STR > &a) const
Definition: path.hpp:214
bool operator>=(const path< S > &s) const noexcept
Definition: path.hpp:306
constexpr int compare(char a, char b)
Definition: path.hpp:19
This class reperesents SVD(xml) element / attribute.
Definition: value.hpp:53
constexpr int num(char c)
Definition: path.hpp:29
path< STR > append(path< STR > &&a) const
Definition: path.hpp:213
path< STR > & operator=(const std::string &s)
Definition: path.hpp:177
string_ref operator[](size_t i) const
Definition: path.hpp:217
path(const path< STR > &a, const path< STR > &b)
Definition: path.hpp:141
path(string_ref s)
Definition: path.hpp:117
bool operator<=(const path< S > &s) const noexcept
Definition: path.hpp:305
path(const path< STR > &a, path< STR > &&b)
Definition: path.hpp:147
bool operator>(const path< S > &s) const noexcept
Definition: path.hpp:304
dot '.' separeted path.
Definition: path.hpp:16
bool operator==(string_ref s) const
Definition: path.hpp:258
void emplace_back_string(std::vector< std::string > &v, ITR itr, ITR_END end)
Definition: string_type.hpp:56
path< STR > & add(const path< STR > &p)
Definition: path.hpp:188
path(const path< STR > &p, size_t from, size_t size)
Definition: path.hpp:139
auto end() const
Definition: path.hpp:228
bool operator!=(const path< S > &s) const
Definition: path.hpp:248