YSTest: path.hpp 源文件

YSTest PreAlpha_b700_20160611 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
260 void
261 filter_self()
262 {
263 ystdex::erase_all_if(*this, [&](const value_type& s) ynothrow{
264 return traits_type::is_self(s);
265 });
266 }
267
268 value_type
269 get_root() const
270 {
271 return is_absolute() ? front() : value_type();
272 }
273
274 bool
275 is_absolute() const ynothrow
276 {
277 return !empty() && traits_type::is_root(front());
278 }
279
280 bool
281 is_relative() const ynothrow
282 {
283 return !is_absolute();
284 }
285
286 void
287 merge_parents()
288 {
289 for(auto i(this->begin()); i != this->end(); )
290 {
291 auto j(std::adjacent_find(i, this->end(),
292 [&](const value_type& x, const value_type& y){
293 return !traits_type::is_self(x) && !traits_type::is_parent(x)
294 && traits_type::is_parent(y);
295 }));
296
297 if(j == this->end())
298 break;
299 i = j++;
300 yassume(j != this->end());
301 i = erase(i, ++j);
302 }
303 }
304
305 void
306 swap(path& pth) ynothrow
307 {
308 base::swap(static_cast<base&>(pth));
309 }
311 };
313
319 template<class _tSeqCon, class _tTraits>
321 inline void
322 normalize(path<_tSeqCon, _tTraits>& pth)
323 {
324 pth.filter_self(), pth.merge_parents();
325 }
326
328 template<class _tSeqCon, class _tTraits>
329 inline void
330 swap(path<_tSeqCon, _tTraits>& x, path<_tSeqCon, _tTraits>& y)
331 {
332 x.swap(y);
333 }
334
336 template<class _tSeqCon, class _tTraits>
337 typename _tSeqCon::value_type
338 to_string(const path<_tSeqCon, _tTraits>& pth,
339 const typename _tSeqCon::value_type& seperator = &to_array<
340 typename string_traits<typename _tSeqCon::value_type>::value_type>("/")[0])
341 {
342 static_assert(is_object<typename _tSeqCon::value_type>(),
343 "Invalid type found.");
344
345 if(pth.empty())
346 return {};
347
348 auto i(pth.begin());
349 typename _tSeqCon::value_type res(*i);
350
351 while(++i != pth.end())
352 {
353 res += seperator;
354 res += *i;
355 }
356 return res;
357 }
358
360 template<class _tSeqCon, class _tTraits>
361 typename _tSeqCon::value_type
362 to_string_d(const path<_tSeqCon, _tTraits>& pth, typename string_traits<typename
363 _tSeqCon::value_type>::value_type delimiter = '/')
364 {
365 static_assert(is_object<typename _tSeqCon::value_type>(),
366 "Invalid type found.");
367 typename _tSeqCon::value_type res;
368
369 for(const auto& s : pth)
370 {
371 res += s;
372 res += delimiter;
373 }
374 return res;
375 }
377
378 } // namespace ystdex;
379
380 #endif
381
ystdex::erase_all_if
void erase_all_if(_tCon &con, _tIter first, _tIter last, _fPred pred)
删除指定容器中指定区间中的或全部满足谓词的元素。
Definition: container.hpp:723
yassume
#define yassume(_expr)
假定：环境语义。
Definition: cassert.h:99
YSLib::Drawing::x
The boundary is out of the const Rect SDst SPos x
Definition: YDraw.h:127
ystdex::path::operator/=
path & operator/=(const path &pth)
Definition: path.hpp:192
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:740
ystdex::sequence_container_adaptor::base
container_adaptor< _tSeqCon > base
Definition: container.hpp:200
ystdex::path::reverse_iterator
typename base::container_type::reverse_iterator reverse_iterator
Definition: path.hpp:143
ystdex::path::merge_parents
void merge_parents()
Definition: path.hpp:287
ystdex::cpp2014::cend
auto cend(const _tRange &c) -> decltype(std::end(c))
Definition: range.hpp:87
ystdex::path::filter_self
void filter_self()
Definition: path.hpp:261
NPL::A1::name
ctx const string & name
Definition: NPLA1.h:248
ystdex::path_traits
路径特征。
Definition: path.hpp:44
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:362
ystdex::string_traits::value_type
remove_rcv_t< decltype(std::declval< string_type >()[0])> value_type
Definition: string.hpp:58
ystdex::path_category::parent
ystdex::sequence_container_adaptor
序列容器适配器。
Definition: container.hpp:197
ystdex::path_traits< std::basic_string< _tChar, _tAlloc > >::value_type
std::basic_string< _tChar, _tAlloc > value_type
Definition: path.hpp:55
ystdex::path::operator=
path & operator=(path &&pth)
Definition: path.hpp:160
ystdex::path::get_root
value_type get_root() const
Definition: path.hpp:269
ystdex::path_category
path_category
路径类别。
Definition: path.hpp:83
ystdex::path::value_type
typename _tSeqCon::value_type value_type
Definition: path.hpp:134
ystdex::path::operator=
path & operator=(std::initializer_list< value_type > il)
Definition: path.hpp:166
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::path::swap
void swap(path &pth)
Definition: path.hpp:306
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::is_relative
bool is_relative() const
Definition: path.hpp:281
yimpl
#define yimpl(...)
实现标签。
Definition: ydef.h:256
ystdex::assign
void assign(_tCon &con, _tParams &&...args)
插入参数指定的元素到容器。
Definition: container.hpp:412
ystdex::path_traits< std::basic_string< _tChar, _tAlloc > >::is_parent
static bool is_parent(view_type sv)
Definition: path.hpp:59
ystdex::path::path
path()=default
ystdex::container_adaptor::difference_type
typename container_type::difference_type difference_type
Definition: container.hpp:67
ystdex::path_category::node
YB_UNLIKELY
#define YB_UNLIKELY(_expr)
分支预测提示。
Definition: ydef.h:438
std
Definition: memory.hpp:1100
ystdex::path::const_reverse_iterator
typename base::container_type::const_reverse_iterator const_reverse_iterator
Definition: path.hpp:145
ystdex::sequence_container_adaptor::size_type
typename container_type::size_type size_type
Definition: container.hpp:205
ystdex::container_adaptor::const_reference
typename container_type::const_reference const_reference
Definition: container.hpp:64
ystdex::container_adaptor::const_iterator
typename container_type::const_iterator const_iterator
Definition: container.hpp:66
ystdex::size
auto size(const _tRange &c) -> decltype(c.size())
类容器访问。
Definition: range.hpp:233
ystdex::path_traits< std::basic_string< _tChar, _tAlloc > >::char_type
_tChar char_type
Definition: path.hpp:54
ystdex::basic_string_view
Definition: string_view.hpp:49
ystdex::container_adaptor::base
container_type base
Definition: container.hpp:57
ystdex::path::operator=
path & operator=(const path &pth)
Definition: path.hpp:155
ystdex::container_adaptor::swap
void swap(container_adaptor &con)
Definition: container.hpp:151
ystdex::path
一般路径模板。
Definition: path.hpp:123
ystdex::cpp2014::crend
auto crend(const _tRange &c) -> decltype(ystdex::rend(c))
Definition: range.hpp:150
ystdex
特性测试宏。
Definition: ydef.h:796
YSLib::Text::str
const char const char * str
Definition: TextFile.h:77
ystdex::path::operator==
friend bool operator==(const path &x, const path &y)
Definition: path.hpp:203
ystdex::path_traits::value_type
_type value_type
Definition: path.hpp:46
string_view.hpp
只读字符串视图。
YSLib::UI::y
SPos SPos y
Definition: YWidget.cpp:44
YSLib::i
return i
Definition: YCoreUtilities.h:176
ystdex::container_adaptor::get_container
container_type & get_container()
Definition: container.hpp:138
ystdex::path_category::empty
ystdex::path::operator<
friend bool operator<(const path &x, const path &y)
Definition: path.hpp:209
ystdex::string_traits
字符串特征。
Definition: string.hpp:55
ystdex::path_category::self
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
ystdex::container_adaptor::iterator
typename container_type::iterator iterator
Definition: container.hpp:65
ystdex::path_traits< std::basic_string< _tChar, _tAlloc > >::is_root
static bool is_root(view_type sv)
Definition: path.hpp:65
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:654
ystdex::cpp2014::rend
auto rend(_tRange &c) -> decltype(c.rend())
Definition: range.hpp:119
ystdex::path::normalize
void normalize(path< _tSeqCon, _tTraits > &pth)
正规化。
Definition: path.hpp:322
ystdex::path::traits_type
_tTraits traits_type
Definition: path.hpp:136
ystdex::container_adaptor::value_type
typename container_type::value_type value_type
满足容器要求。
Definition: container.hpp:62
ystdex::path::is_absolute
bool is_absolute() const
Definition: path.hpp:275
ystdex::cpp2014::crbegin
auto crbegin(const _tRange &c) -> decltype(ystdex::rbegin(c))
Definition: range.hpp:143
ystdex::cpp2011::begin
_type * begin(_type(&&array)[_vN])
Definition: range.hpp:46
ystdex::dep_ops::totally_ordered
details::flat_ops< _type, _type2, _tOpt, less_than_comparable, equality_comparable > totally_ordered
Definition: operators.hpp:367
ystdex::cpp2014::rbegin
auto rbegin(_tRange &c) -> decltype(c.rbegin())
Definition: range.hpp:94
ystdex::cpp2014::cbegin
auto cbegin(const _tRange &c) -> decltype(std::begin(c))
Definition: range.hpp:79
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:338
ystdex::path_traits< std::basic_string< _tChar, _tAlloc > >::is_self
static bool is_self(const value_type &str)
Definition: path.hpp:71
ystdex::to_array
std::array< _type, _vN > to_array(const _tSrc &src)
转换指定参数为 std::array 对象。
Definition: array.hpp:87
ystdex::cpp2011::end
_type * end(_type(&&array)[_vN])
Definition: range.hpp:54
CHRLib::s
_tDst const _tSrc * s
Definition: CharacterProcessing.h:140
ystdex::path::swap
void swap(path< _tSeqCon, _tTraits > &x, path< _tSeqCon, _tTraits > &y)
交换。
Definition: path.hpp:330
ystdex::path::operator/=
path & operator/=(const value_type &s)
Definition: path.hpp:173