YSTest: path.hpp 源文件

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
58 is_compatible_with(const path_norm&) const ynothrow
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>
86 class file_path_norm;
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,
148 class _tNorm = ystdex::path_norm<typename _tSeqCon::value_type>>
149 class path : private sequence_container_adaptor<_tSeqCon>
150 {
151 private:
152 using base = sequence_container_adaptor<_tSeqCon>;
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<
159 norm>::value, norm, file_path_norm<value_type>>;
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;
167 using const_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 {}
185 path(size_type n, value_type root,
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 {}
204 path(path&& pth) ynothrow
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&
220 operator=(path&& pth) ynothrow
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
288 filter_self()
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&
298 get_norm() const ynothrow
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
311 is_absolute() const ynothrow
312 {
313 return !empty() && get_norm().is_root(front());
314 }
315
316 bool
317 is_relative() const ynothrow
318 {
319 return !is_absolute();
320 }
321
322 void
323 merge_parents()
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
344 swap(path& pth) ynothrow
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
365 operator==(const path<_tSeqCon, _tNorm>& x, const path<_tSeqCon, _tNorm>& y)
366 {
367 return x.equals(y);
368 }
369
370 template<class _tSeqCon, class _tNorm>
371 bool
372 operator!=(const path<_tSeqCon, _tNorm>& x, const path<_tSeqCon, _tNorm>& y)
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
393 operator>(const path<_tSeqCon, _tNorm>& x, const path<_tSeqCon, _tNorm>& y)
394 {
395 return y < x;
396 }
397
398 template<class _tSeqCon, class _tNorm>
399 bool
400 operator>=(const path<_tSeqCon, _tNorm>& x, const path<_tSeqCon, _tNorm>& y)
401 {
402 return !(x < y);
403 }
405
410 template<class _tSeqCon, class _tNorm>
411 inline void
412 normalize(path<_tSeqCon, _tNorm>& pth)
413 {
414 pth.filter_self(), pth.merge_parents();
415 }
416
421 template<class _tSeqCon, class _tNorm>
422 inline void
423 swap(path<_tSeqCon, _tNorm>& x, path<_tSeqCon, _tNorm>& y)
424 {
425 x.swap(y);
426 }
427
432 template<class _tSeqCon, class _tNorm>
433 typename _tSeqCon::value_type
434 to_string(const path<_tSeqCon, _tNorm>& pth,
435 const typename _tSeqCon::value_type& seperator = &to_array<
436 typename string_traits<typename _tSeqCon::value_type>::value_type>("/")[0])
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
ystdex::assign
void assign(_tCon &c, _tParams &&...args)
插入参数指定的元素到容器。
Definition: container.hpp:289
ystdex::path_norm::is_compatible_with
virtual bool is_compatible_with(const path_norm &) const
Definition: path.hpp:58
string.hpp
ISO C++ 标准字符串扩展。
ystdex::path::path
path(const path &pth)
Definition: path.hpp:201
ystdex::operator>=
bool operator>=(const path< _tSeqCon, _tNorm > &x, const path< _tSeqCon, _tNorm > &y)
Definition: path.hpp:400
ystdex::container_adaptor::const_reference
typename container_type::const_reference const_reference
Definition: container.hpp:62
ystdex::path::path
path(path &&pth)
Definition: path.hpp:204
ystdex::iterator_transformation::first
static auto first(const _tIterator &i) -> decltype((i->first))
Definition: iterator.hpp:759
ystdex::operator!=
bool operator!=(nullptr_t lhs, const _type &rhs)
Definition: ydef.h:638
ystdex::path::path
path(_tIn first, _tIn last, std::unique_ptr< norm > p=std::unique_ptr< norm >())
Definition: path.hpp:192
ystdex::path::path
path(base &&b, std::unique_ptr< norm > p=std::unique_ptr< norm >())
Definition: path.hpp:178
YSLib::UI::args
yconstfn const string _tParams && args
Definition: Loader.h:111
ystdex::conditional_t
typename conditional< _bCond, _type, _type2 >::type conditional_t
Definition: type_op.hpp:277
ystdex::path::path
path(std::initializer_list< value_type > il, std::unique_ptr< norm > p=std::unique_ptr< norm >())
Definition: path.hpp:209
ystdex::path::to_string_d
_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
ystdex::path
一般路径模板。
Definition: path.hpp:149
ystdex::to_array
std::array< _type, _vN > to_array(const _tSrc &src)
取指定参数转换为 std::array 对象。
Definition: container.hpp:514
ystdex::path::operator=
path & operator=(std::initializer_list< value_type > il)
Definition: path.hpp:226
ystdex::file_path_norm< std::basic_string< _tChar, _tAlloc > >::is_root
bool is_root(const value_type &str) override
Definition: path.hpp:112
ystdex::file_path_norm< std::basic_string< _tChar, _tAlloc > >::value_type
std::basic_string< _tChar, _tAlloc > value_type
Definition: path.hpp:97
ystdex::container_adaptor::base
container_type base
Definition: container.hpp:55
ystdex::string_traits
字符串特征。
Definition: string.hpp:47
ystdex::path_norm::~path_norm
virtual ~path_norm()=default
ystdex::cloneable
可动态复制的抽象基类。
Definition: utility.hpp:142
ystdex::path::equals
bool equals(const path &pth) const
Definition: path.hpp:281
ystdex::path::path
path(std::unique_ptr< norm > p=std::unique_ptr< norm >())
Definition: path.hpp:173
ystdex::path::const_reverse_iterator
typename base::container_type::const_reverse_iterator const_reverse_iterator
Definition: path.hpp:168
ystdex::container_adaptor::size_type
typename container_type::size_type size_type
Definition: container.hpp:66
ystdex::container_adaptor::const_iterator
typename container_type::const_iterator const_iterator
Definition: container.hpp:64
ystdex::path::p_norm
std::unique_ptr< norm > p_norm
Definition: path.hpp:170
ystdex::container_adaptor::difference_type
typename container_type::difference_type difference_type
Definition: container.hpp:65
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 传递对应参数。
Definition: ydef.h:722
ystdex::path::operator=
path & operator=(const path &pth)
Definition: path.hpp:215
ystdex::file_path_norm< std::basic_string< _tChar, _tAlloc > >::is_parent
bool is_parent(const value_type &str) override
Definition: path.hpp:106
ystdex::operator>
bool operator>(const path< _tSeqCon, _tNorm > &x, const path< _tSeqCon, _tNorm > &y)
Definition: path.hpp:393
ystdex::container_adaptor::value_type
typename container_type::value_type value_type
满足容器要求。
Definition: container.hpp:60
ystdex::path::normalize
void normalize(path< _tSeqCon, _tNorm > &pth)
正规化。
Definition: path.hpp:412
ystdex::path::operator=
path & operator=(path &&pth)
Definition: path.hpp:220
ystdex::swap
void swap(any &x, any &y)
交换对象。
Definition: any.h:729
ystdex::path::before
bool before(const path &pth) const
Definition: path.hpp:274
ystdex::string_traits::value_type
remove_rcv_t< decltype(std::declval< string_type >()[0])> value_type
Definition: string.hpp:50
ystdex::file_path_norm< std::basic_string< _tChar, _tAlloc > >::clone
file_path_norm * clone() const override
Definition: path.hpp:125
memory.hpp
存储和智能指针特性。
ystdex::path::merge_parents
void merge_parents()
Definition: path.hpp:323
yassume
#define yassume
假定：环境语义。
Definition: cassert.h:58
ystdex::path::unique_norm
static std::unique_ptr< norm > unique_norm(std::unique_ptr< norm > &p)
Definition: path.hpp:352
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:514
ystdex::path::path
path(std::unique_ptr< norm > p, _tParams &&...args)
Definition: path.hpp:198
ystdex::container_adaptor::iterator
typename container_type::iterator iterator
Definition: container.hpp:63
yconstraint
#define yconstraint
约束：接口语义。
Definition: cassert.h:47
ystdex::path_norm< std::string >::value_type
std::string value_type
Definition: path.hpp:51
ystdex::path::swap
void swap(path< _tSeqCon, _tNorm > &x, path< _tSeqCon, _tNorm > &y)
交换。
Definition: path.hpp:423
ystdex::path::get_root
value_type get_root() const
Definition: path.hpp:305
ystdex::sequence_container_adaptor
序列容器适配器。
Definition: container.hpp:181
ystdex::path::reverse_iterator
typename base::container_type::reverse_iterator reverse_iterator
Definition: path.hpp:166
ystdex::container_adaptor::reference
typename container_type::reference reference
Definition: container.hpp:61
ystdex::path_norm::is_self
virtual bool is_self(const value_type &)=0
ystdex::path::is_absolute
bool is_absolute() const
Definition: path.hpp:311
ystdex::path::to_string
_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
ystdex::path_norm::is_delimiter
virtual bool is_delimiter(const value_type &)=0
ystdex::path_norm::is_root
virtual bool is_root(const value_type &)=0
platform_ex::Windows::s
return s
Definition: MinGW32.cpp:49
ystdex::path::swap
void swap(path &pth)
Definition: path.hpp:344
ystdex::file_path_norm< std::basic_string< _tChar, _tAlloc > >::is_delimiter
bool is_delimiter(const value_type &str) override
Definition: path.hpp:100
ystdex::path_norm::is_parent
virtual bool is_parent(const value_type &)=0
ystdex::path::norm
_tNorm norm
Definition: path.hpp:156
ystdex::file_path_norm< std::basic_string< _tChar, _tAlloc > >::is_self
bool is_self(const value_type &str) override
Definition: path.hpp:118
ystdex::path::default_norm
ystdex::conditional_t< std::is_default_constructible< norm >::value, norm, file_path_norm< value_type >> default_norm
Definition: path.hpp:159
ystdex::path_norm
路径范式。
Definition: path.hpp:48
ystdex::path::get_norm
norm & get_norm() const
Definition: path.hpp:298
ystdex::erase_all_if
void erase_all_if(_tRange &c, _fPred pred)
删除指定序列范围中满足条件的元素。
Definition: container.hpp:416
ystdex::path::is_relative
bool is_relative() const
Definition: path.hpp:317
ystdex::path::filter_self
void filter_self()
Definition: path.hpp:288
ystdex::path::path
path(size_type n, std::unique_ptr< norm > p=std::unique_ptr< norm >())
Definition: path.hpp:182
ystdex::path_norm::clone
virtual path_norm * clone() const override=0
ystdex::path::path
path(size_type n, value_type root, std::unique_ptr< norm > p=std::unique_ptr< norm >())
Definition: path.hpp:185
ystdex::operator==
bool operator==(nullptr_t lhs, const _type &rhs)
Definition: ydef.h:625
ystdex::file_path_norm
文件路径范式。
Definition: path.hpp:86