YSTest  PreAlpha_b500_20140530
The YSLib Test Project
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
path.hpp
浏览该文件的文档.
1 /*
2  © 2013-2014 FrankHB.
3 
4  This file is part of the YSLib project, and may only be used,
5  modified, and distributed under the terms of the YSLib project
6  license, LICENSE.TXT. By continuing to use, modify, or distribute
7  this file you indicate that you have read the license and
8  understand and accept it fully.
9 */
10 
28 #ifndef YB_INC_ystdex_path_hpp_
29 #define YB_INC_ystdex_path_hpp_ 1
30 
31 #include "string.hpp" // for ystdex::sequence_container_adaptor,
32 // ystdex::erase_all_if, ystdex::string_traits, ystdex::to_array;
33 #include "memory.hpp" // for std::unique_ptr, ystdex::make_unique;
34 #include <string> // for std::string;
35 #include <algorithm> // for std::adjencent_find;
36 #include <typeinfo> // for typeid;
37 
38 namespace ystdex
39 {
40 
46 template<typename _type>
48 class path_norm : public cloneable
49 {
50 public:
51  using value_type = _type;
52 
54  virtual
55  ~path_norm() = default;
56 
57  virtual bool
59  {
60  return true;
61  }
62 
63  virtual bool
64  is_delimiter(const value_type&) = 0;
65 
66  virtual bool
67  is_parent(const value_type&) ynothrow = 0;
68 
69  virtual bool
70  is_root(const value_type&) ynothrow = 0;
71 
72  virtual bool
73  is_self(const value_type&) ynothrow = 0;
74 
75 // virtual bool
76 // is_wildcard(const value_type&) ynothrow = 0;
77 
79  virtual path_norm*
80  clone() const override = 0;
81 };
82 
83 
85 template<typename _type>
87 
92 template<typename _tChar, class _tAlloc>
93 class file_path_norm<std::basic_string<_tChar, _tAlloc>>
94  : public path_norm<std::string>
95 {
96 public:
97  using value_type = std::basic_string<_tChar, _tAlloc>;
98 
99  bool
100  is_delimiter(const value_type& str) override
101  {
102  return str.length() == 1 && str[0] == '/';
103  }
104 
105  bool
106  is_parent(const value_type& str) ynothrow override
107  {
108  return str.length() == 2 && str[0] == '.' && str[1] == '.';
109  }
110 
111  bool
112  is_root(const value_type& str) ynothrow override
113  {
114  return str.empty();
115  }
116 
117  bool
118  is_self(const value_type& str) ynothrow override
119  {
120  return str.length() == 1 && str[0] == '.';
121  }
122 
124  file_path_norm*
125  clone() const override
126  {
127  return new file_path_norm(*this);
128  }
129 };
131 
132 
134 
135 
147 template<class _tSeqCon,
149 class path : private sequence_container_adaptor<_tSeqCon>
150 {
151 private:
153 
154 public:
155  using value_type = typename _tSeqCon::value_type;
156  using norm = _tNorm;
158  using default_norm = ystdex::conditional_t<std::is_default_constructible<
160  using reference = typename _tSeqCon::reference;
161  using const_reference = typename _tSeqCon::const_reference;
162  using size_type = typename base::size_type;
163  using difference_type = typename base::difference_type;
164  using iterator = typename base::iterator;
165  using const_iterator = typename base::const_iterator;
166  using reverse_iterator = typename base::container_type::reverse_iterator;
168  = typename base::container_type::const_reverse_iterator;
169 
170  std::unique_ptr<norm> p_norm;
171 
172 public:
173  path(std::unique_ptr<norm> p = std::unique_ptr<norm>())
174  : path(base(), std::move(p))
175  {}
177  explicit
178  path(base&& b, std::unique_ptr<norm> p = std::unique_ptr<norm>())
179  : base(std::move(b)), p_norm(unique_norm(p))
180  {}
181  explicit
182  path(size_type n, std::unique_ptr<norm> p = std::unique_ptr<norm>())
183  : path(base(n), std::move(p))
184  {}
186  std::unique_ptr<norm> p = std::unique_ptr<norm>())
187  : path(n != 0 ? n : 1, std::move(p))
188  {
189  this->begin() = std::move(root);
190  }
191  template<typename _tIn>
192  path(_tIn first, _tIn last,
193  std::unique_ptr<norm> p = std::unique_ptr<norm>())
194  : path(base(first, last), std::move(p))
195  {}
197  template<typename... _tParams>
198  path(std::unique_ptr<norm> p, _tParams&&... args)
199  : path(base(yforward(args)...), std::move(p))
200  {}
201  path(const path& pth)
202  : base(pth), p_norm(pth.get_norm().clone())
203  {}
205  : path()
206  {
207  pth.swap(*this);
208  }
209  path(std::initializer_list<value_type> il,
210  std::unique_ptr<norm> p = std::unique_ptr<norm>())
211  : path(base(il), std::move(p))
212  {}
213 
214  path&
215  operator=(const path& pth)
216  {
217  return *this = path(pth);
218  }
219  path&
221  {
222  pth.swap(*this);
223  return *this;
224  }
225  path&
226  operator=(std::initializer_list<value_type> il)
227  {
228  return *this = path(il);
229  }
230 
231  using base::begin;
232 
233  using base::end;
234 
235  using base::cbegin;
236 
237  using base::cend;
238 
239  using base::container_type::rbegin;
240 
241  using base::container_type::rend;
242 
243  using base::container_type::crbegin;
244 
245  using base::container_type::crend;
246 
247  using base::size;
248 
249  using base::max_size;
250 
251  using base::empty;
252 
253  using base::back;
254 
255 // using base::emplace;
256 
257 // using base::emplace_back;
258 
259  using base::front;
260 
261  using base::pop_back;
262 
263  using base::push_back;
264 
265  using base::insert;
266 
267  using base::erase;
268 
269  using base::clear;
270 
271  using base::assign;
272 
273  bool
274  before(const path& pth) const
275  {
276  return typeid(get_norm()).before(typeid(pth.get_norm()))
277  && static_cast<const base&>(*this) < static_cast<const base&>(pth);
278  }
279 
280  bool
281  equals(const path& pth) const
282  {
283  return typeid(get_norm()) == typeid(pth.get_norm())
284  && static_cast<const base&>(*this) == static_cast<const base&>(pth);
285  }
286 
287  void
289  {
290  auto& nm(get_norm());
291 
292  ystdex::erase_all_if(*this, [&](const value_type& s){
293  return nm.is_self(s);
294  });
295  }
296 
297  norm&
299  {
300  yconstraint(p_norm);
301  return *p_norm;
302  }
303 
304  value_type
305  get_root() const
306  {
307  return is_absolute() ? front() : value_type();
308  }
309 
310  bool
312  {
313  return !empty() && get_norm().is_root(front());
314  }
315 
316  bool
318  {
319  return !is_absolute();
320  }
321 
322  void
324  {
325  auto& nm(get_norm());
326 
327  for(auto i(this->begin()); i != this->end();)
328  {
329  auto j(std::adjacent_find(i, this->end(),
330  [&](const value_type& x, const value_type& y){
331  return !nm.is_self(x) && !nm.is_parent(x)
332  && nm.is_parent(y);
333  }));
334 
335  if(j == this->end())
336  break;
337  i = j++;
338  yassume(j != this->end());
339  i = erase(i, ++j);
340  }
341  }
342 
343  void
345  {
346  base::swap(static_cast<base&>(pth)),
347  p_norm.swap(pth.p_norm);
348  }
349 
350 private:
351  static std::unique_ptr<norm>
352  unique_norm(std::unique_ptr<norm>& p)
353  {
354  return p ? std::move(p) : make_unique<default_norm>();
355  }
356 };
357 
363 template<class _tSeqCon, class _tNorm>
364 inline bool
366 {
367  return x.equals(y);
368 }
369 
370 template<class _tSeqCon, class _tNorm>
371 bool
373 {
374  return !(x == y);
375 }
376 
377 template<class _tSeqCon, class _tNorm>
378 bool
379 operator<(const path<_tSeqCon, _tNorm>& x, const path<_tSeqCon, _tNorm>& y)
380 {
381  return x.before(y);
382 }
383 
384 template<class _tSeqCon, class _tNorm>
385 bool
386 operator<=(const path<_tSeqCon, _tNorm>& x, const path<_tSeqCon, _tNorm>& y)
387 {
388  return !(y < x);
389 }
390 
391 template<class _tSeqCon, class _tNorm>
392 bool
394 {
395  return y < x;
396 }
397 
398 template<class _tSeqCon, class _tNorm>
399 bool
401 {
402  return !(x < y);
403 }
405 
410 template<class _tSeqCon, class _tNorm>
411 inline void
413 {
414  pth.filter_self(), pth.merge_parents();
415 }
416 
421 template<class _tSeqCon, class _tNorm>
422 inline void
424 {
425  x.swap(y);
426 }
427 
432 template<class _tSeqCon, class _tNorm>
433 typename _tSeqCon::value_type
435  const typename _tSeqCon::value_type& seperator = &to_array<
437 {
438  static_assert(is_object<typename _tSeqCon::value_type>::value,
439  "Invalid type found.");
440 
441  if(pth.empty())
442  return {};
443 
444  auto i(pth.begin());
445  typename _tSeqCon::value_type res(*i);
446 
447  while(++i != pth.end())
448  {
449  res += seperator;
450  res += *i;
451  }
452  return res;
453 }
454 
459 template<class _tSeqCon, class _tNorm>
460 typename _tSeqCon::value_type
461 to_string_d(const path<_tSeqCon, _tNorm>& pth, typename string_traits<typename
462  _tSeqCon::value_type>::value_type delimiter = '/')
463 {
464  static_assert(is_object<typename _tSeqCon::value_type>::value,
465  "Invalid type found.");
466  typename _tSeqCon::value_type res;
467 
468  for(const auto& s : pth)
469  {
470  res += s;
471  res += delimiter;
472  }
473  return res;
474 }
476 
477 } // namespace ystdex;
478 
479 #endif
480 
void assign(_tCon &c, _tParams &&...args)
插入参数指定的元素到容器。
Definition: container.hpp:289
virtual bool is_compatible_with(const path_norm &) const
Definition: path.hpp:58
ISO C++ 标准字符串扩展。
path(const path &pth)
Definition: path.hpp:201
bool operator>=(const path< _tSeqCon, _tNorm > &x, const path< _tSeqCon, _tNorm > &y)
Definition: path.hpp:400
typename container_type::const_reference const_reference
Definition: container.hpp:62
path(path &&pth)
Definition: path.hpp:204
static auto first(const _tIterator &i) -> decltype((i->first))
Definition: iterator.hpp:759
bool operator!=(nullptr_t lhs, const _type &rhs)
Definition: ydef.h:638
path(_tIn first, _tIn last, std::unique_ptr< norm > p=std::unique_ptr< norm >())
Definition: path.hpp:192
path(base &&b, std::unique_ptr< norm > p=std::unique_ptr< norm >())
Definition: path.hpp:178
yconstfn const string _tParams && args
Definition: Loader.h:111
typename conditional< _bCond, _type, _type2 >::type conditional_t
Definition: type_op.hpp:277
path(std::initializer_list< value_type > il, std::unique_ptr< norm > p=std::unique_ptr< norm >())
Definition: path.hpp:209
_tSeqCon::value_type to_string_d(const path< _tSeqCon, _tNorm > &pth, typename string_traits< typename _tSeqCon::value_type >::value_type delimiter= '/')
取分隔符结尾的字符串表示。
Definition: path.hpp:461
一般路径模板。
Definition: path.hpp:149
std::array< _type, _vN > to_array(const _tSrc &src)
取指定参数转换为 std::array 对象。
Definition: container.hpp:514
path & operator=(std::initializer_list< value_type > il)
Definition: path.hpp:226
bool is_root(const value_type &str) override
Definition: path.hpp:112
std::basic_string< _tChar, _tAlloc > value_type
Definition: path.hpp:97
字符串特征。
Definition: string.hpp:47
virtual ~path_norm()=default
可动态复制的抽象基类。
Definition: utility.hpp:142
bool equals(const path &pth) const
Definition: path.hpp:281
path(std::unique_ptr< norm > p=std::unique_ptr< norm >())
Definition: path.hpp:173
typename base::container_type::const_reverse_iterator const_reverse_iterator
Definition: path.hpp:168
typename container_type::size_type size_type
Definition: container.hpp:66
typename container_type::const_iterator const_iterator
Definition: container.hpp:64
std::unique_ptr< norm > p_norm
Definition: path.hpp:170
typename container_type::difference_type difference_type
Definition: container.hpp:65
#define yforward(_expr)
根据参数类型使用 std::forward 传递对应参数。
Definition: ydef.h:722
path & operator=(const path &pth)
Definition: path.hpp:215
bool is_parent(const value_type &str) override
Definition: path.hpp:106
bool operator>(const path< _tSeqCon, _tNorm > &x, const path< _tSeqCon, _tNorm > &y)
Definition: path.hpp:393
typename container_type::value_type value_type
满足容器要求。
Definition: container.hpp:60
void normalize(path< _tSeqCon, _tNorm > &pth)
正规化。
Definition: path.hpp:412
path & operator=(path &&pth)
Definition: path.hpp:220
void swap(any &x, any &y)
交换对象。
Definition: any.h:729
bool before(const path &pth) const
Definition: path.hpp:274
remove_rcv_t< decltype(std::declval< string_type >()[0])> value_type
Definition: string.hpp:50
存储和智能指针特性。
void merge_parents()
Definition: path.hpp:323
#define yassume
假定:环境语义。
Definition: cassert.h:58
static std::unique_ptr< norm > unique_norm(std::unique_ptr< norm > &p)
Definition: path.hpp:352
#define ynothrow
YSLib 无异常抛出保证:若支持 noexcept 关键字, 指定特定的 noexcept 异常规范。
Definition: ydef.h:514
path(std::unique_ptr< norm > p, _tParams &&...args)
Definition: path.hpp:198
typename container_type::iterator iterator
Definition: container.hpp:63
#define yconstraint
约束:接口语义。
Definition: cassert.h:47
void swap(path< _tSeqCon, _tNorm > &x, path< _tSeqCon, _tNorm > &y)
交换。
Definition: path.hpp:423
value_type get_root() const
Definition: path.hpp:305
序列容器适配器。
Definition: container.hpp:181
typename base::container_type::reverse_iterator reverse_iterator
Definition: path.hpp:166
typename container_type::reference reference
Definition: container.hpp:61
virtual bool is_self(const value_type &)=0
bool is_absolute() const
Definition: path.hpp:311
_tSeqCon::value_type to_string(const path< _tSeqCon, _tNorm > &pth, const typename _tSeqCon::value_type &seperator=&to_array< typename string_traits< typename _tSeqCon::value_type >::value_type >("/")[0])
取字符串表示。
Definition: path.hpp:434
virtual bool is_delimiter(const value_type &)=0
virtual bool is_root(const value_type &)=0
void swap(path &pth)
Definition: path.hpp:344
bool is_delimiter(const value_type &str) override
Definition: path.hpp:100
virtual bool is_parent(const value_type &)=0
_tNorm norm
Definition: path.hpp:156
bool is_self(const value_type &str) override
Definition: path.hpp:118
ystdex::conditional_t< std::is_default_constructible< norm >::value, norm, file_path_norm< value_type >> default_norm
Definition: path.hpp:159
路径范式。
Definition: path.hpp:48
norm & get_norm() const
Definition: path.hpp:298
void erase_all_if(_tRange &c, _fPred pred)
删除指定序列范围中满足条件的元素。
Definition: container.hpp:416
bool is_relative() const
Definition: path.hpp:317
void filter_self()
Definition: path.hpp:288
path(size_type n, std::unique_ptr< norm > p=std::unique_ptr< norm >())
Definition: path.hpp:182
virtual path_norm * clone() const override=0
path(size_type n, value_type root, std::unique_ptr< norm > p=std::unique_ptr< norm >())
Definition: path.hpp:185
bool operator==(nullptr_t lhs, const _type &rhs)
Definition: ydef.h:625
文件路径范式。
Definition: path.hpp:86