YSTest: path.hpp 源文件

YSTest PreAlpha_b900_20201012 The YSLib Test Project

path.hpp
浏览该文件的文档.
1 /*
2 © 2013-2016, 2018-2020 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
52 #ifndef YB_INC_ystdex_path_hpp_
53 #define YB_INC_ystdex_path_hpp_ 1
54
55 #include "string.hpp" // for basic_string, string_view, nested_allocator_base,
56 // enable_if_t, ystdex::erase_all_if, to_array, string_traits;
57 #include "operators.hpp" // for dividable, totally_ordered;
58 #include "type_op.hpp" // for cond_or_t;
59
60 namespace ystdex
61 {
62
64
65
82 template<typename _type>
83 struct path_traits;
84
86 template<>
87 struct path_traits<void>
88 {
89 template<typename _tString>
90 YB_PURE static yconstfn bool
91 is_parent(const _tString& str) ynothrow
92 {
93 using char_value_t = decltype(str[0]);
94
95 return ystdex::string_length(str) == 2 && str[0] == char_value_t('.')
96 && str[1] == char_value_t('.');
97 }
98
99 template<typename _tString>
100 static yconstfn bool
101 is_absolute(const _tString& x) ynothrow
102 {
103 return ystdex::string_empty(x);
104 }
105
106 template<typename _tString>
107 YB_PURE static yconstfn bool
108 is_self(const _tString& str) ynothrow
109 {
110 return
111 ystdex::string_length(str) == 1 && str[0] == decltype(str[0])('.');
112 }
113
114 template<typename _tString>
115 YB_PURE static yconstfn bool
116 has_root_name(const _tString& x) ynothrow
117 {
118 return ystdex::string_empty(x);
119 }
120
121 template<typename _tString>
122 YB_PURE static yconstfn bool
123 has_root_path(const _tString& x) ynothrow
124 {
125 return ystdex::string_empty(x);
126 }
127
128 template<typename _tString1, typename _tString2>
129 YB_PURE static yconstfn bool
130 have_same_root_names(const _tString1& x, const _tString2& y) ynothrow
131 {
132 return x == y;
133 }
134 };
135
140 template<typename _tChar, class _tTraits, class _tAlloc>
141 struct path_traits<basic_string<_tChar, _tTraits, _tAlloc>>
142 {
143 using char_type = _tChar;
144 using value_type = basic_string<_tChar, _tTraits, _tAlloc>;
145 using view_type = basic_string_view<char_type>;
146
147 static yconstfn bool
148 is_parent(view_type sv) ynothrow
149 {
150 return sv.length() == 2 && sv[0] == '.' && sv[1] == '.';
151 }
152
154
155 static yconstfn bool
156 is_absolute(view_type sv) ynothrow
157 {
158 return sv.empty();
159 }
160
161 static yconstfn bool
162 is_self(view_type sv) ynothrow
163 {
164 return sv.length() == 1 && sv.front() == '.';
165 }
166
167 static yconstfn bool
168 has_root_name(view_type sv) ynothrow
169 {
170 return sv.empty();
171 }
172
173 static yconstfn bool
174 has_root_path(view_type sv) ynothrow
175 {
176 return sv.empty();
177 }
178
179 static yconstfn bool
180 have_same_root_names(view_type x, view_type y) ynothrow
181 {
182 return x == y;
183 }
185 };
187
188
193 enum class path_category : yimpl(size_t)
194 {
195 empty,
196 self,
197 parent,
198 node
199 };
200
205 template<class _tString, class _tTraits = path_traits<_tString>>
206 YB_PURE path_category
207 classify_path(const _tString& name) ynothrow
208 {
209 if(YB_UNLIKELY(name.empty()))
210 return path_category::empty;
211 if(_tTraits::is_self(name))
212 return path_category::self;
213 if(_tTraits::is_parent(name))
214 return path_category::parent;
215 return path_category::node;
216 }
217
218
262 template<class _tSeqCon,
263 class _tTraits = path_traits<typename _tSeqCon::value_type>>
264 class path : private _tSeqCon, yimpl(public) nested_allocator_base<_tSeqCon>,
265 private dividable<path<_tSeqCon, _tTraits>, typename _tSeqCon::value_type>,
266 private totally_ordered<path<_tSeqCon, _tTraits>>,
267 private dividable<path<_tSeqCon, _tTraits>>
268 {
269 private:
271
272 using base = _tSeqCon;
273
274 public:
276 using container_type = _tSeqCon;
277 using value_type = typename _tSeqCon::value_type;
279 using traits_type = _tTraits;
280 using reference = typename _tSeqCon::reference;
281 using const_reference = typename _tSeqCon::const_reference;
282 using size_type = typename base::size_type;
283 using difference_type = typename base::difference_type;
284 using iterator = typename base::iterator;
285 using const_iterator = typename base::const_iterator;
286 using reverse_iterator = typename base::reverse_iterator;
287 using const_reverse_iterator = typename base::const_reverse_iterator;
288
290 path() = default;
292
293 template<typename _tParam, yimpl(typename
294 = enable_if_t<is_constructible<base, const base&, _tParam>::value>)>
295 path(const path& pth, _tParam&& arg)
296 : base(pth, yforward(arg))
297 {}
298 template<typename _tParam, yimpl(typename
299 = enable_if_t<is_constructible<base, base, _tParam>::value>)>
300 path(path&& pth, _tParam&& arg)
301 : base(std::move(pth), yforward(arg))
302 {}
303 path(std::initializer_list<value_type> il)
304 : base(il)
305 {}
306 template<typename... _tParams, yimpl(typename
307 = enable_if_t<sizeof...(_tParams) != 0 && is_constructible<base,
308 std::initializer_list<value_type>, _tParams&&...>::value>)>
309 path(std::initializer_list<value_type> il, _tParams&&... args)
310 : base(il, yforward(args)...)
311 {}
312 template<typename... _tParams, yimpl(typename
313 = enable_if_t<is_constructible<base, _tParams...>::value>)>
314 path(_tParams&&... args)
315 : base(yforward(args)...)
316 {}
317 template<class _tAlloc, typename... _tParams, yimpl(typename = enable_if_t<
318 is_constructible<base, _tParams..., const _tAlloc&>::value>)>
319 path(std::allocator_arg_t, const _tAlloc& a, _tParams&&... args)
320 : base(yforward(args)..., a)
321 {}
323 path(const path&) = default;
324 path(path&&) = default;
325
326 path&
327 operator=(const path& pth)
328 {
329 return *this = path(pth);
330 }
331 path&
332 operator=(path&& pth) ynothrow
333 {
334 pth.swap(*this);
335 return *this;
336 }
337 path&
338 operator=(std::initializer_list<value_type> il)
339 {
340 return *this = path(il);
341 }
342
357 path&
358 operator/=(const value_type& s)
359 {
360 if(!empty() && traits_type::is_parent(s))
361 {
362 if(has_leaf_nonempty())
363 {
364 if(!(traits_type::is_parent(back())
365 || traits_type::is_self(back())))
366 pop_back();
367 else if(!s.empty())
368 push_back(s);
369 }
370 }
371 else if(!traits_type::is_self(s))
372 push_back(s);
373 return *this;
374 }
375 path&
376 operator/=(value_type&& s) ynothrow
377 {
378 if(!empty() && traits_type::is_parent(s))
379 {
380 if(!traits_type::is_absolute(front()) || 1U < size())
381 {
382 if(!(traits_type::is_parent(back())
383 || traits_type::is_self(back())))
384 pop_back();
385 else if(!s.empty())
386 push_back(std::move(s));
387 }
388 }
389 else if(!traits_type::is_self(s))
390 push_back(std::move(s));
391 return *this;
392 }
394
407 path&
408 operator/=(const path& pth)
409 {
410 if(!root_diverged(pth))
411 for(const auto& s : pth)
412 *this /= s;
413 else
414 *this = pth;
415 return *this;
416 }
417 path&
418 operator/=(path&& pth) ynothrow
419 {
420 if(!root_diverged(pth))
421 for(auto& s : pth)
422 *this /= std::move(s);
423 else
424 *this = std::move(pth);
425 return *this;
426 }
428
430
431 YB_PURE friend bool
432 operator==(const path& x, const path& y)
433 {
434 return static_cast<const base&>(x) == static_cast<const base&>(y);
435 }
436
437 YB_PURE friend bool
438 operator<(const path& x, const path& y)
439 {
440 return static_cast<const base&>(x) < static_cast<const base&>(y);
441 }
443
444 using base::begin;
445
446 using base::end;
447
448 using base::cbegin;
449
450 using base::cend;
451
453
454 using base::rbegin;
455
456 using base::rend;
457
458 using base::crbegin;
459
460 using base::crend;
462
463 using base::size;
464
465 using base::max_size;
466
467 using base::empty;
468
469 using base::back;
470
471 // using base::emplace;
472
473 // using base::emplace_back;
474
475 using base::front;
476
477 using base::pop_back;
478
479 using base::push_back;
480
481 using base::insert;
482
483 using base::erase;
484
485 using base::clear;
486
487 using base::assign;
488
490 container_type&
491 get_container() ynothrow
492 {
493 return *this;
494 }
496 const container_type&
497 get_container() const ynothrow
498 {
499 return *this;
500 }
501
503 void
504 filter_self() ynothrow
505 {
506 // NOTE: Lambda is needed to support possibly overloaded function.
507 ystdex::erase_all_if(*this, [](const value_type& s) ynothrow{
508 return traits_type::is_self(s);
509 });
510 }
511
512 value_type
513 get_root() const
514 {
515 return is_absolute() ? front() : value_type();
516 }
517
518 bool
519 is_absolute() const ynothrow
520 {
521 return !empty() && traits_type::is_absolute(front());
522 }
523
524 bool
525 is_relative() const ynothrow
526 {
527 return !is_absolute();
528 }
529
530 void
531 merge_parents()
532 {
533 for(auto i(this->begin()); i != this->end(); )
534 {
535 auto j(std::adjacent_find(i, this->end(),
536 [&](const value_type& x, const value_type& y){
537 return !traits_type::is_self(x) && !traits_type::is_parent(
538 x) && traits_type::is_parent(y);
539 }));
540
541 if(j == this->end())
542 break;
543 i = j++;
544 yassume(j != this->end());
545 i = erase(i, ++j);
546 }
547 }
548
550
551
553 YB_ATTR_nodiscard bool
554 has_leaf() const ynothrow
555 {
556 return !empty() && has_leaf_nonempty();
557 }
558
560 YB_ATTR_nodiscard bool
561 has_leaf_nonempty() const ynothrowv
562 {
563 yconstraint(!empty());
564 return 1U < size() || !traits_type::has_root_path(front());
565 }
567
574 path&
575 redirect(const path& pth)
576 {
577 if(!root_diverged(pth))
578 {
579 remove_leaf();
580 for(const auto& s : pth)
581 *this /= s;
582 }
583 else
584 *this = pth;
585 return *this;
586 }
587 path&
588 redirect(path&& pth) ynothrow
589 {
590 if(!root_diverged(pth))
591 {
592 remove_leaf();
593 for(auto& s : pth)
594 *this /= std::move(s);
595 }
596 else
597 *this = std::move(pth);
598 return *this;
599 }
601
603 bool
604 remove_leaf() ynothrow
605 {
606 if(has_leaf())
607 {
608 pop_back();
609 return true;
610 }
611 return {};
612 }
614
629 bool
630 root_diverged(const path& pth) const
631 {
632 return !pth.empty() && (traits_type::is_absolute(pth.front())
633 || (traits_type::has_root_name(pth.front())
634 && !traits_type::have_same_root_names(front(), pth.front())));
635 }
636
637 void
638 swap(path& pth) ynothrow
639 {
640 base::swap(static_cast< base&>(pth));
641 }
643
647 friend inline void
648 swap(path& x, path& y) ynothrow
649 {
650 x.swap(y);
651 }
652 };
654
660 template<class _tSeqCon, class _tTraits>
662 inline void
663 normalize(path<_tSeqCon, _tTraits>& pth)
664 {
665 pth.filter_self(), pth.merge_parents();
666 }
667
669 template<class _tSeqCon, class _tTraits>
670 typename _tSeqCon::value_type
671 to_string(const path<_tSeqCon, _tTraits>& pth,
672 const typename _tSeqCon::value_type& seperator = &to_array<
673 typename string_traits<typename _tSeqCon::value_type>::value_type>("/")[0])
674 {
675 static_assert(is_object<typename _tSeqCon::value_type>(),
676 "Invalid type found.");
677
678 if(pth.empty())
679 return {};
680
681 auto i(pth.begin());
682 typename _tSeqCon::value_type res(*i);
683
684 if(_tTraits::has_root_path(res))
685 {
686 auto j(i);
687
688 if(++j != pth.end())
689 {
690 res += *j;
691 i = j;
692 }
693 }
694 while(++i != pth.end())
695 {
696 res += seperator;
697 res += *i;
698 }
699 return res;
700 }
701
703 template<class _tSeqCon, class _tTraits>
704 typename _tSeqCon::value_type
705 to_string_d(const path<_tSeqCon, _tTraits>& pth, typename string_traits<typename
706 _tSeqCon::value_type>::value_type delimiter = '/')
707 {
708 static_assert(is_object<typename _tSeqCon::value_type>(),
709 "Invalid type found.");
710 auto i(pth.begin());
711 typename _tSeqCon::value_type res(*i);
712
713 if(!_tTraits::has_root_path(res))
714 res += delimiter;
715 while(++i != pth.end())
716 {
717 res += *i;
718 res += delimiter;
719 }
720 return res;
721 }
723
724 } // namespace ystdex;
725
727 namespace std
728 {
729
731 template<class _tSeqCon, class _tTraits, class _tAlloc>
732 struct uses_allocator<ystdex::path<_tSeqCon, _tTraits>, _tAlloc>
733 : uses_allocator<_tSeqCon, _tAlloc>
734 {};
735
736 } // namespace std;
737
738 #endif
739
ystdex::path_traits< basic_string< _tChar, _tTraits, _tAlloc > >::has_root_name
static bool has_root_name(view_type sv)
Definition: path.hpp:168
ystdex::path::container_type
_tSeqCon container_type
Definition: path.hpp:276
YB_ATTR_nodiscard
#define YB_ATTR_nodiscard
标记返回值不被忽略的属性。
Definition: ydef.h:715
ystdex::fseq::front
identity< _type > front(empty_base< _type, _types... >)
Definition: variadic.hpp:74
x
const EncapsulationBase & x
Definition: NPLA1Forms.cpp:1536
string.hpp
ISO C++ 标准字符串扩展。
size
size_t size
Definition: memory_resource.cpp:295
ystdex::cpp2017::swap
void swap(optional< _type > &x, optional< _type > &y)
Definition: optional.h:888
ystdex::path_traits< void >::is_parent
static bool is_parent(const _tString &str)
Definition: path.hpp:91
ystdex::path::normalize
void normalize(path< _tSeqCon, _tTraits > &pth)
正规化。
Definition: path.hpp:663
ystdex::path::path
path(path &&pth, _tParam &&arg)
Definition: path.hpp:300
YB_PURE
#define YB_PURE
指示函数或函数模板实例为纯函数。
Definition: ydef.h:919
ystdex::cpp2017::basic_string
Definition: string.hpp:77
ystdex::path::get_container
const container_type & get_container() const
Definition: path.hpp:497
ystdex::cpp2017::basic_string_view
Definition: string_view.hpp:95
ystdex::path::operator/=
path & operator/=(const path &pth)
追加路径。
Definition: path.hpp:408
ystdex::path::path
path(const path &)=default
ystdex::path_traits< basic_string< _tChar, _tTraits, _tAlloc > >::char_type
_tChar char_type
Definition: path.hpp:143
YSLib::IO::_tTraits
const string &path const String &path class class _tTraits
Definition: YSLib/Service/FileSystem.h:582
ystdex::cpp2014::enable_if_t
typename enable_if< _bCond, _type >::type enable_if_t
Definition: meta.hpp:199
ystdex::path::path
path(std::initializer_list< value_type > il, _tParams &&... args)
Definition: path.hpp:309
ystdex::path::path
path(std::allocator_arg_t, const _tAlloc &a, _tParams &&... args)
Definition: path.hpp:319
ystdex::path::redirect
path & redirect(const path &pth)
重定向路径
Definition: path.hpp:575
ystdex::path_traits< basic_string< _tChar, _tTraits, _tAlloc > >::has_root_path
static bool has_root_path(view_type sv)
Definition: path.hpp:174
ystdex::path::has_leaf
bool has_leaf() const
判断移除最后元素是否保持根路径不变。
Definition: path.hpp:554
ystdex::path::iterator
typename base::iterator iterator
Definition: path.hpp:284
ystdex::path::path
path(std::initializer_list< value_type > il)
Definition: path.hpp:303
ystdex::path::root_diverged
bool root_diverged(const path &pth) const
判断参数指定的路径是否和 *this 不同而无法直接作为相对路径追加。
Definition: path.hpp:630
ystdex::path
一般路径模板。
Definition: path.hpp:268
ystdex::path::operator/=
path & operator/=(value_type &&s)
Definition: path.hpp:376
ystdex::path_category::empty
@ empty
ystdex::path_traits< void >::have_same_root_names
static bool have_same_root_names(const _tString1 &x, const _tString2 &y)
Definition: path.hpp:130
ystdex::rend
reverse_iterator< _type * > rend(_type(&&array)[_vN])
Definition: range.hpp:397
ystdex::path::path
path(const path &pth, _tParam &&arg)
Definition: path.hpp:295
ystdex::path::const_reference
typename _tSeqCon::const_reference const_reference
Definition: path.hpp:281
ystdex::path::operator=
path & operator=(const path &pth)
Definition: path.hpp:327
ystdex::path::const_reverse_iterator
typename base::const_reverse_iterator const_reverse_iterator
Definition: path.hpp:287
ystdex::path_category
path_category
路径类别。
Definition: path.hpp:194
ystdex::path_traits
路径特征。
Definition: path.hpp:83
ystdex::cpp2014::cbegin
auto cbegin(const _tRange &c) -> decltype(ystdex::begin(c))
Definition: range.hpp:418
ystdex::erase_all_if
void erase_all_if(_tCon &con, _tIter first, _tIter last, _fPred pred)
删除指定容器中指定区间中的或全部满足谓词的元素。
Definition: container.hpp:525
ystdex::path_traits< void >::is_self
static bool is_self(const _tString &str)
Definition: path.hpp:108
CHRLib::args
YB_ATTR_nodiscard _tParams && args
Definition: CharacterProcessing.h:649
ystdex::path::redirect
path & redirect(path &&pth)
Definition: path.hpp:588
ystdex::cpp2014::cend
auto cend(const _tRange &c) -> decltype(ystdex::end(c))
Definition: range.hpp:427
yassume
#define yassume(_expr)
假定：环境语义。
Definition: cassert.h:96
ystdex::path_category::self
@ self
ystdex::path::size_type
typename base::size_type size_type
Definition: path.hpp:282
ystdex::path::has_leaf_nonempty
bool has_leaf_nonempty() const
Definition: path.hpp:561
ystdex::path::is_relative
bool is_relative() const
Definition: path.hpp:525
YSLib::IO::_tString
const string &path const String &path class class class _tString
Definition: YSLib/Service/FileSystem.h:612
ystdex::path::get_root
value_type get_root() const
Definition: path.hpp:513
ystdex::dep_ops::dividable
_t< details::ops_seq< _type, _type2, _tOpt, details::ops_bin_id_seq< 3, 0, 1 > >> dividable
Definition: operators.hpp:302
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 转发对应参数。
Definition: ydef.h:1508
ystdex::path_traits< basic_string< _tChar, _tTraits, _tAlloc > >::is_parent
static bool is_parent(view_type sv)
Definition: path.hpp:148
ystdex::path_traits< basic_string< _tChar, _tTraits, _tAlloc > >::is_absolute
static bool is_absolute(view_type sv)
Definition: path.hpp:156
ystdex::path_traits< void >::has_root_path
static bool has_root_path(const _tString &x)
Definition: path.hpp:123
ystdex::cpp2017::size
auto size(const _tRange &c) -> decltype(c.size())
Definition: range.hpp:540
ystdex::path::operator<
friend bool operator<(const path &x, const path &y)
Definition: path.hpp:438
ystdex::cpp2017::end
auto end(_tRange &c) -> decltype(c.end())
Definition: range.hpp:345
std
Definition: optional.h:982
ystdex::path::filter_self
void filter_self()
Definition: path.hpp:504
ystdex::path::difference_type
typename base::difference_type difference_type
Definition: path.hpp:283
ystdex::to_array
std::array< _type, _vN > to_array(const _tSrc &src)
转换指定参数为 std::array 对象。
Definition: array.hpp:92
operators.hpp
重载操作符。
YSLib::i
return i
Definition: YCoreUtilities.h:177
type_op.hpp
C++ 类型操作。
ystdex::dep_ops::totally_ordered
details::flat_ops< _type, _type2, _tOpt, less_than_comparable, equality_comparable > totally_ordered
Definition: operators.hpp:389
ystdex::path::traits_type
_tTraits traits_type
Definition: path.hpp:279
yconstraint
#define yconstraint(_expr)
约束：接口语义。
Definition: cassert.h:125
YSLib::UI::y
SPos SPos y
Definition: YWidget.cpp:44
ystdex::path::reference
typename _tSeqCon::reference reference
Definition: path.hpp:280
ystdex::to_string
std::string to_string(const std::thread::id &)
转换 thread::id 为字符串表示。
ystdex::path::reverse_iterator
typename base::reverse_iterator reverse_iterator
Definition: path.hpp:286
YSLib::path
YB_ATTR_nodiscard YF_API const char * path
Definition: Initialization.h:116
ystdex::path::path
path(path &&)=default
ystdex::cpp2017::empty
auto empty(const _tRange &c) -> decltype(c.empty())
Definition: range.hpp:562
CHRLib::s
_tDst const _tSrc * s
Definition: CharacterProcessing.h:143
ystdex::path::operator/=
path & operator/=(path &&pth)
Definition: path.hpp:418
ystdex::path::merge_parents
void merge_parents()
Definition: path.hpp:531
ystdex::cpp2017::crbegin
auto crbegin(const _tRange &c) -> decltype(ystdex::rbegin(c))
Definition: range.hpp:506
ystdex::path::operator/=
path & operator/=(const value_type &s)
追加路径元素。
Definition: path.hpp:358
ystdex::string_length
size_t string_length(const _tChar *str)
计算字符串长度。
Definition: string.hpp:1142
ystdex::path::swap
friend void swap(path &x, path &y)
交换。
Definition: path.hpp:648
ystdex::path_traits< void >::has_root_name
static bool has_root_name(const _tString &x)
Definition: path.hpp:116
NPL::A1::name
const char * name
Definition: NPLA1.h:1876
ystdex::path_traits< void >::is_absolute
static bool is_absolute(const _tString &x)
Definition: path.hpp:101
ystdex::path::swap
void swap(path &pth)
Definition: path.hpp:638
ynothrowv
#define ynothrowv
YSLib 无异常抛出保证验证：有条件地使用无异常抛出规范。
Definition: ydef.h:1219
ystdex
<memory> 特性测试宏。
Definition: ydef.h:1262
ystdex::cpp2017::crend
auto crend(const _tRange &c) -> decltype(ystdex::rend(c))
Definition: range.hpp:513
ystdex::path::const_iterator
typename base::const_iterator const_iterator
Definition: path.hpp:285
ystdex::assign
void assign(_tCon &con, _tParams &&... args)
插入参数指定的元素到容器。
Definition: container.hpp:150
ystdex::string_traits::value_type
remove_cvref_t< decltype(std::declval< string_type >()[0])> value_type
Definition: string.hpp:790
YSLib::_tParams
YB_ATTR_nodiscard YB_PURE typename _tParams
Definition: ValueNode.h:1294
ystdex::path::operator=
path & operator=(std::initializer_list< value_type > il)
Definition: path.hpp:338
ystdex::path::path
path()=default
ystdex::path::remove_leaf
bool remove_leaf()
若移除最后元素不会改变根路径，则移除最后的元素。
Definition: path.hpp:604
ystdex::path::operator=
path & operator=(path &&pth)
Definition: path.hpp:332
ystdex::to_string_d
_tSeqCon::value_type to_string_d(const path< _tSeqCon, _tTraits > &pth, typename string_traits< typename _tSeqCon::value_type >::value_type delimiter='/')
取以分隔符结束的字符串表示。
Definition: path.hpp:705
ystdex::path::is_absolute
bool is_absolute() const
Definition: path.hpp:519
ystdex::path::value_type
typename _tSeqCon::value_type value_type
Definition: path.hpp:277
ystdex::path::get_container
container_type & get_container()
Definition: path.hpp:491
YB_UNLIKELY
#define YB_UNLIKELY(_expr)
分支预测提示。
Definition: ydef.h:828
ystdex::path_traits< basic_string< _tChar, _tTraits, _tAlloc > >::is_self
static bool is_self(view_type sv)
Definition: path.hpp:162
YSLib::Text::str
YB_ATTR_nodiscard YB_PURE const char const char * str
Definition: TextFile.h:83
ystdex::path::path
path(_tParams &&... args)
Definition: path.hpp:314
const
const Decapsulate const Decapsulate &y ynothrow ContextNode &ctx const
Definition: NPLA1Forms.cpp:1629
yimpl
#define yimpl(...)
实现标签。
Definition: ydef.h:413
ystdex::path::operator==
friend bool operator==(const path &x, const path &y)
Definition: path.hpp:432
ystdex::rbegin
reverse_iterator< _type * > rbegin(_type(&&array)[_vN])
Definition: range.hpp:390
ystdex::path_category::node
@ node
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:1199
ystdex::string_traits
字符串特征。
Definition: string.hpp:788
ystdex::path_traits< basic_string< _tChar, _tTraits, _tAlloc > >::have_same_root_names
static bool have_same_root_names(view_type x, view_type y)
Definition: path.hpp:180
ystdex::path_category::parent
@ parent
ystdex::nested_allocator_base
启用 allocator_type 的基类。
Definition: allocator.hpp:652
ystdex::path::base
_tSeqCon base
Definition: path.hpp:272
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:1073
ystdex::cpp2017::begin
auto begin(_tRange &c) -> decltype(c.begin())
Definition: range.hpp:323
ystdex::string_empty
bool string_empty(const _tChar *str)
判断字符串是否为空。
Definition: string.hpp:1110
YSLib::a
YB_PURE const _type * a
Definition: YCoreUtilities.h:168
NPL::_tParam
_tParam
Definition: NPLA.h:2367