YSTest: path.hpp 源文件

YSTest PreAlpha_b800_20170810 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

path.hpp
浏览该文件的文档.
1 /*
2 © 2013-2016 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_view.hpp" // for std::basic_string, string_view,
32 // sequence_container_adaptor, dividable, totally_ordered,
33 // ystdex::erase_all_if, to_array, string_traits;
34
35 namespace ystdex
36 {
37
39
40
42 template<typename _type>
44 class path_traits
45 {
46 using value_type = _type;
47 };
48
50 template<typename _tChar, class _tAlloc>
51 class path_traits<std::basic_string<_tChar, _tAlloc>>
52 {
53 public:
54 using char_type = _tChar;
55 using value_type = std::basic_string<_tChar, _tAlloc>;
56 using view_type = basic_string_view<char_type>;
57
58 static yconstfn bool
59 is_parent(view_type sv) ynothrow
60 {
61 return sv.length() == 2 && sv[0] == '.' && sv[1] == '.';
62 }
63
64 static yconstfn bool
65 is_root(view_type sv) ynothrow
66 {
67 return sv.empty();
68 }
69
70 static yconstfn bool
71 is_self(const value_type& str) ynothrow
72 {
73 return str.length() == 1 && str[0] == '.';
74 }
75 };
77
78
83 enum class path_category : yimpl(size_t)
84 {
85 empty,
86 self,
87 parent,
88 node
89 };
90
95 template<class _tString, class _tTraits = path_traits<_tString>>
96 path_category
97 classify_path(const _tString& name) ynothrow
98 {
99 if(YB_UNLIKELY(name.empty()))
100 return path_category::empty;
101 if(_tTraits::is_self(name))
102 return path_category::self;
103 if(_tTraits::is_parent(name))
104 return path_category::parent;
105 return path_category::node;
106 }
107
108
121 template<class _tSeqCon,
122 class _tTraits = path_traits<typename _tSeqCon::value_type>>
123 class path : private sequence_container_adaptor<_tSeqCon>,
124 private dividable<path<_tSeqCon, _tTraits>, typename _tSeqCon::value_type>,
125 private totally_ordered<path<_tSeqCon, _tTraits>>,
126 private dividable<path<_tSeqCon, _tTraits>>
127 {
128 private:
130
131 using base = sequence_container_adaptor<_tSeqCon>;
132
133 public:
134 using value_type = typename _tSeqCon::value_type;
136 using traits_type = _tTraits;
137 using reference = typename _tSeqCon::reference;
138 using const_reference = typename _tSeqCon::const_reference;
139 using size_type = typename base::size_type;
140 using difference_type = typename base::difference_type;
141 using iterator = typename base::iterator;
142 using const_iterator = typename base::const_iterator;
143 using reverse_iterator = typename base::container_type::reverse_iterator;
144 using const_reverse_iterator
145 = typename base::container_type::const_reverse_iterator;
146
148 path() = default;
150 using base::base;
151 path(const path&) = default;
152 path(path&&) = default;
153
154 path&
155 operator=(const path& pth)
156 {
157 return *this = path(pth);
158 }
159 path&
160 operator=(path&& pth) ynothrow
161 {
162 pth.swap(*this);
163 return *this;
164 }
165 path&
166 operator=(std::initializer_list<value_type> il)
167 {
168 return *this = path(il);
169 }
170
172 path&
173 operator/=(const value_type& s)
174 {
175 if(!empty() && traits_type::is_parent(s))
176 {
177 if(!traits_type::is_root(front()) || 1U < size())
178 {
179 if(!(traits_type::is_parent(back())
180 || traits_type::is_self(back())))
181 pop_back();
182 else
183 push_back(s);
184 }
185 }
186 else if(!traits_type::is_self(s))
187 push_back(s);
188 return *this;
189 }
191 path&
192 operator/=(const path& pth)
193 {
194 if(pth.is_relative())
195 for(const auto& s : pth)
196 *this /= s;
197 return *this;
198 }
199
201
202 friend bool
203 operator==(const path& x, const path& y)
204 {
205 return static_cast<const base&>(x) == static_cast<const base&>(y);
206 }
207
208 friend bool
209 operator<(const path& x, const path& y)
210 {
211 return static_cast<const base&>(x) < static_cast<const base&>(y);
212 }
214
215 using base::begin;
216
217 using base::end;
218
219 using base::cbegin;
220
221 using base::cend;
222
223 using base::container_type::rbegin;
224
225 using base::container_type::rend;
226
227 using base::container_type::crbegin;
228
229 using base::container_type::crend;
230
231 using base::size;
232
233 using base::max_size;
234
235 using base::empty;
236
237 using base::back;
238
239 // using base::emplace;
240
241 // using base::emplace_back;
242
243 using base::front;
244
245 using base::pop_back;
246
247 using base::push_back;
248
249 using base::insert;
250
251 using base::erase;
252
253 using base::clear;
254
255 using base::assign;
256
258 using base::get_container;
259
261 void
262 filter_self() ynothrow
263 {
264 // NOTE: Lambda is needed to support possibly overloaded function.
265 ystdex::erase_all_if(*this, [](const value_type& s) ynothrow{
266 return traits_type::is_self(s);
267 });
268 }
269
270 value_type
271 get_root() const
272 {
273 return is_absolute() ? front() : value_type();
274 }
275
276 bool
277 is_absolute() const ynothrow
278 {
279 return !empty() && traits_type::is_root(front());
280 }
281
282 bool
283 is_relative() const ynothrow
284 {
285 return !is_absolute();
286 }
287
288 void
289 merge_parents()
290 {
291 for(auto i(this->begin()); i != this->end(); )
292 {
293 auto j(std::adjacent_find(i, this->end(),
294 [&](const value_type& x, const value_type& y){
295 return !traits_type::is_self(x) && !traits_type::is_parent(
296 x) && traits_type::is_parent(y);
297 }));
298
299 if(j == this->end())
300 break;
301 i = j++;
302 yassume(j != this->end());
303 i = erase(i, ++j);
304 }
305 }
306
307 void
308 swap(path& pth) ynothrow
309 {
310 base::swap(static_cast<base&>(pth));
311 }
313 };
315
321 template<class _tSeqCon, class _tTraits>
323 inline void
324 normalize(path<_tSeqCon, _tTraits>& pth)
325 {
326 pth.filter_self(), pth.merge_parents();
327 }
328
330 template<class _tSeqCon, class _tTraits>
331 inline void
332 swap(path<_tSeqCon, _tTraits>& x, path<_tSeqCon, _tTraits>& y)
333 {
334 x.swap(y);
335 }
336
338 template<class _tSeqCon, class _tTraits>
339 typename _tSeqCon::value_type
340 to_string(const path<_tSeqCon, _tTraits>& pth,
341 const typename _tSeqCon::value_type& seperator = &to_array<
342 typename string_traits<typename _tSeqCon::value_type>::value_type>("/")[0])
343 {
344 static_assert(is_object<typename _tSeqCon::value_type>(),
345 "Invalid type found.");
346
347 if(pth.empty())
348 return {};
349
350 auto i(pth.begin());
351 typename _tSeqCon::value_type res(*i);
352
353 while(++i != pth.end())
354 {
355 res += seperator;
356 res += *i;
357 }
358 return res;
359 }
360
362 template<class _tSeqCon, class _tTraits>
363 typename _tSeqCon::value_type
364 to_string_d(const path<_tSeqCon, _tTraits>& pth, typename string_traits<typename
365 _tSeqCon::value_type>::value_type delimiter = '/')
366 {
367 static_assert(is_object<typename _tSeqCon::value_type>(),
368 "Invalid type found.");
369 typename _tSeqCon::value_type res;
370
371 for(const auto& s : pth)
372 {
373 res += s;
374 res += delimiter;
375 }
376 return res;
377 }
379
380 } // namespace ystdex;
381
382 #endif
383
ystdex::path::filter_self
void filter_self()
Definition: path.hpp:262
ystdex::container_adaptor::size_type
typename container_type::size_type size_type
Definition: container.hpp:68
ystdex::container_adaptor::reference
typename container_type::reference reference
Definition: container.hpp:63
ystdex::container_adaptor::get_container
container_type & get_container()
Definition: container.hpp:138
ystdex::basic_string_view
Definition: string_view.hpp:49
ystdex::path::const_reverse_iterator
typename base::container_type::const_reverse_iterator const_reverse_iterator
Definition: path.hpp:145
ystdex::container_adaptor::difference_type
typename container_type::difference_type difference_type
Definition: container.hpp:67
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:680
ystdex::dep_ops::totally_ordered
details::flat_ops< _type, _type2, _tOpt, less_than_comparable, equality_comparable > totally_ordered
Definition: operators.hpp:367
ystdex::path::operator=
path & operator=(const path &pth)
Definition: path.hpp:155
YSLib::UI::y
SPos SPos y
Definition: YWidget.cpp:44
NPL::x
const TermNode &term ynothrow const TermNode &term ynothrow const TermNode &term ynothrow TermNode &term const TermNode &term ValueNode &node const ValueNode &node const _type & x
Definition: SContext.h:94
ystdex::path::operator/=
path & operator/=(const path &pth)
Definition: path.hpp:192
ystdex::path_traits
路径特征。
Definition: path.hpp:44
ystdex::cpp2014::rbegin
auto rbegin(_tRange &c) -> decltype(c.rbegin())
Definition: range.hpp:94
ystdex::container_adaptor::value_type
typename container_type::value_type value_type
满足容器要求。
Definition: container.hpp:62
ystdex::path::normalize
void normalize(path< _tSeqCon, _tTraits > &pth)
正规化。
Definition: path.hpp:324
yimpl
#define yimpl(...)
实现标签。
Definition: ydef.h:262
ystdex::cpp2014::crend
auto crend(const _tRange &c) -> decltype(ystdex::rend(c))
Definition: range.hpp:150
YB_UNLIKELY
#define YB_UNLIKELY(_expr)
分支预测提示。
Definition: ydef.h:464
ystdex::cpp2014::cend
auto cend(const _tRange &c) -> decltype(std::end(c))
Definition: range.hpp:87
ystdex::path_traits< std::basic_string< _tChar, _tAlloc > >::is_root
static bool is_root(view_type sv)
Definition: path.hpp:65
ystdex::path_category::node
ystdex::cpp2011::end
_type * end(_type(&&array)[_vN])
Definition: range.hpp:54
ystdex::string_traits
字符串特征。
Definition: string.hpp:55
ystdex::sequence_container_adaptor
序列容器适配器。
Definition: container.hpp:197
ystdex::path_category::self
ystdex::cpp2014::rend
auto rend(_tRange &c) -> decltype(c.rend())
Definition: range.hpp:119
ystdex::container_adaptor::base
container_type base
Definition: container.hpp:57
ystdex::path_traits< std::basic_string< _tChar, _tAlloc > >::char_type
_tChar char_type
Definition: path.hpp:54
ystdex::path::traits_type
_tTraits traits_type
Definition: path.hpp:136
ystdex::path_category::empty
ystdex::path::value_type
typename _tSeqCon::value_type value_type
Definition: path.hpp:134
ystdex::path::is_absolute
bool is_absolute() const
Definition: path.hpp:277
ystdex::path::to_string
_tSeqCon::value_type to_string(const path< _tSeqCon, _tTraits > &pth, const typename _tSeqCon::value_type &seperator=&to_array< typename string_traits< typename _tSeqCon::value_type >::value_type >("/")[0])
取字符串表示。
Definition: path.hpp:340
ystdex::path_traits::value_type
_type value_type
Definition: path.hpp:46
ystdex::erase_all_if
void erase_all_if(_tCon &con, _tIter first, _tIter last, _fPred pred)
删除指定容器中指定区间中的或全部满足谓词的元素。
Definition: container.hpp:727
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:766
ystdex::path_traits< std::basic_string< _tChar, _tAlloc > >::is_self
static bool is_self(const value_type &str)
Definition: path.hpp:71
ystdex::sequence_container_adaptor::base
container_adaptor< _tSeqCon > base
Definition: container.hpp:200
CHRLib::s
_tDst const _tSrc * s
Definition: CharacterProcessing.h:140
ystdex::cpp2014::cbegin
auto cbegin(const _tRange &c) -> decltype(std::begin(c))
Definition: range.hpp:79
ystdex
特性测试宏。
Definition: ydef.h:822
YSLib::i
return i
Definition: YCoreUtilities.h:176
ystdex::sequence_container_adaptor::size_type
typename container_type::size_type size_type
Definition: container.hpp:205
ystdex::path::merge_parents
void merge_parents()
Definition: path.hpp:289
ystdex::path_traits< std::basic_string< _tChar, _tAlloc > >::is_parent
static bool is_parent(view_type sv)
Definition: path.hpp:59
string_view.hpp
只读字符串视图。
ystdex::path::operator<
friend bool operator<(const path &x, const path &y)
Definition: path.hpp:209
ystdex::path::operator/=
path & operator/=(const value_type &s)
Definition: path.hpp:173
ystdex::path
一般路径模板。
Definition: path.hpp:123
ystdex::path::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:364
ystdex::fseq::front
identity< _type > front(empty_base< _type, _types... >)
Definition: variadic.hpp:74
ystdex::assign
void assign(_tCon &con, _tParams &&...args)
插入参数指定的元素到容器。
Definition: container.hpp:413
ystdex::cpp2014::crbegin
auto crbegin(const _tRange &c) -> decltype(ystdex::rbegin(c))
Definition: range.hpp:143
ystdex::path::operator=
path & operator=(path &&pth)
Definition: path.hpp:160
ystdex::to_array
std::array< _type, _vN > to_array(const _tSrc &src)
转换指定参数为 std::array 对象。
Definition: array.hpp:87
ystdex::path::get_root
value_type get_root() const
Definition: path.hpp:271
ystdex::container_adaptor::iterator
typename container_type::iterator iterator
Definition: container.hpp:65
std
Definition: memory.hpp:1183
ystdex::path::reverse_iterator
typename base::container_type::reverse_iterator reverse_iterator
Definition: path.hpp:143
ystdex::container_adaptor::swap
void swap(container_adaptor &con)
Definition: container.hpp:151
ystdex::path::operator==
friend bool operator==(const path &x, const path &y)
Definition: path.hpp:203
YSLib::UI::name
yconstfn const string & name
Definition: Loader.h:130
platform::containers::basic_string
std::basic_string< _tChar, _tTraits, _tAlloc > basic_string
满足 ISO C++03 std::basic_string 但不保证满足 ISO C++11 的实现。
Definition: Container.h:98
YSLib::Text::str
const char const char * str
Definition: TextFile.h:81
ystdex::path::is_relative
bool is_relative() const
Definition: path.hpp:283
ystdex::container_adaptor::const_reference
typename container_type::const_reference const_reference
Definition: container.hpp:64
yassume
#define yassume(_expr)
假定：环境语义。
Definition: cassert.h:105
ystdex::container_adaptor::const_iterator
typename container_type::const_iterator const_iterator
Definition: container.hpp:66
ystdex::path::swap
void swap(path< _tSeqCon, _tTraits > &x, path< _tSeqCon, _tTraits > &y)
交换。
Definition: path.hpp:332
ystdex::path_traits< std::basic_string< _tChar, _tAlloc > >::value_type
std::basic_string< _tChar, _tAlloc > value_type
Definition: path.hpp:55
ystdex::cpp2011::begin
_type * begin(_type(&&array)[_vN])
Definition: range.hpp:46
ystdex::path::path
path()=default
ystdex::string_traits::value_type
remove_rcv_t< decltype(std::declval< string_type >()[0])> value_type
Definition: string.hpp:58
ystdex::size
auto size(const _tRange &c) -> decltype(c.size())
类容器访问。
Definition: range.hpp:233
ystdex::path::operator=
path & operator=(std::initializer_list< value_type > il)
Definition: path.hpp:166
ystdex::dep_ops::dividable
_t< details::ops_seq< _type, _type2, _tOpt, details::ops_bin_id_seq< 3, 0, 1 >>> dividable
Definition: operators.hpp:280
ystdex::path::swap
void swap(path &pth)
Definition: path.hpp:308
ystdex::path_category::parent
ystdex::path_category
path_category
路径类别。
Definition: path.hpp:83