YSTest: YBase.cpp 源文件

YSTest PreAlpha_b700_20160611 The YSLib Test Project

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

- 文件列表
- 文件成员

YBase.cpp
浏览该文件的文档.
1 /*
2 © 2014-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 #include <ytest/test.h>
29 #include <ystdex/functional.hpp>
30 #include <vector>
31 #include <list>
32 #include <deque>
33 #include <cmath>
34 #include <iostream>
35 #include <sstream>
36 #include <iomanip>
37 #include <ystdex/algorithm.hpp>
38 #include <ystdex/container.hpp>
39 #include <ystdex/tstring_view.hpp>
40 #include <ystdex/mixin.hpp>
41 #include <ystdex/bitseg.hpp>
42
43 namespace
44 {
45
46 void
47 show_result(std::ostream& out, const std::string& name, size_t pass_n,
48 size_t fail_n)
49 {
50 out << name << ": " << pass_n << '/' << pass_n + fail_n << '.'
51 << std::endl;
52 }
53
54 using namespace std;
55 using namespace placeholders;
56 using namespace ystdex;
57 using namespace ytest;
58
60 struct cwam
61 {
62 // NOTE: Class with array member, used to test member prvalue before CWG616
63 // is resoved, or member xvalue after CWG616 is resolved.
64 char foo[42];
65
66 cwam()
67 : foo()
68 {
69 yunseq(foo[0] = 'B', foo[sizeof(foo) - 1] = 'E');
70 }
71 };
72
74 namespace vbase_test
75 {
76
77 template<class _type>
78 yconstfn bool
79 v() ynothrow
80 {
81 return has_nonempty_virtual_base<_type>();
82 }
83
84 template<class _type1, class _type2>
85 yconstfn bool
86 cv() ynothrow
87 {
88 return have_common_nonempty_virtual_base<_type1, _type2>();
89 }
90
91 struct eb
92 {};
93
94 struct neb
95 {
96 int i;
97 };
98
99 struct ed : eb
100 {};
101
102 struct ned : neb
103 {};
104
105 struct ved : virtual eb
106 {};
107
108 struct vned : virtual neb
109 {};
110
111 struct vned2 : virtual neb
112 {};
113
114 } // namespace vbase_test;
115
117 namespace vseq_test
118 {
119
120 using namespace vseq;
121 static_assert(at_t<integer_sequence<int, 3>, 0>() == 3,
122 "Integer sequence check failed.");
123 static_assert(at_t<make_peano_sequence_t<int, -3, 4>, 2>() == -1,
124 "Peano sequence check failed.");
125
126 using test_t = tuple<int, int, void, void, int>;
127 static_assert(is_same<front_t<test_t>, int>(), "");
128 static_assert(is_same<back_t<test_t>, int>(), "");
129 static_assert(is_same<pop_back_t<test_t>, tuple<int, int, void, void>>(), "");
130 static_assert(is_same<pop_front_t<test_t>, tuple<int, void, void, int>>(), "");
131 static_assert(is_same<deduplicate_t<test_t>, tuple<void, int>>(), "");
132 static_assert(is_same<unique_t<test_t>, tuple<int, void, int>>(), "");
133
134 static_assert(is_same<concat_t<index_sequence<1, 2>,
135 index_sequence<2, 3>>, index_sequence<1, 2, 2, 3>>(), "");
136 static_assert(is_same<unique_t<index_sequence<>>, index_sequence<>>(), "");
137 static_assert(is_same<unique_t<index_sequence<1>>, index_sequence<1>>(),
138 "");
139 static_assert(at_t<index_sequence<1, 2, 3>, 0>() == 1, "");
140 static_assert(at_t<index_sequence<1, 2, 3>, 1>() == 2, "");
141 static_assert(at_t<index_sequence<1, 2, 3>, 2>() == 3, "");
142 static_assert(at_t<index_sequence<1, 2>, 0>() == 1, "");
143 static_assert(at_t<index_sequence<1, 2>, 1>() == 2, "");
144 static_assert(at_t<index_sequence<1>, 0>() == 1, "");
145 static_assert(is_same<unique_t<index_sequence<1, 1>>, index_sequence<1>>(),
146 "");
147 static_assert(is_same<unique_t<index_sequence<1, 2, 2, 3>>,
148 index_sequence<1, 2, 3>>(), "");
149
150 static_assert(is_same<vseq::vec_subtract_t<integer_sequence<long, 1, 2, 3>,
151 integer_sequence<long, -1, 4, 7>>,
152 integer_sequence<long, 2, -2, -4>>(), "");
153
154 template<typename... S1, typename... S2, size_t... SD, size_t... SS>
155 void
156 copy_tail_impl(tuple<S1...>& d, const tuple<S2...>& s,
157 index_sequence<SD...>, index_sequence<SS...>)
158 {
159 yunseq((get<SD>(d) = get<SS>(s))...);
160 }
161
162 template<typename... S1, typename... S2>
163 void
164 copy_tail(const tuple<S2...>& s, tuple<S1...>& d)
165 {
166 copy_tail_impl(d, s, index_sequence_for<S1...>(),
167 make_peano_sequence_t<size_t, sizeof...(S2) - sizeof...(S1),
168 sizeof...(S1)>());
169 }
170
171 using A = tuple<int, double, float>;
172 using C = tuple<float>;
173
174 float
175 f()
176 {
177 A a{1, 2, 3};
178 C c;
179
180 copy_tail(a, c);
181 return get<0>(c);
182 }
183
184 } // namespace vseq_test;
185
187 namespace memory_test
188 {
189
190 struct t1
191 {
192 const t1*
193 operator&() const ynothrow
194 {
195 return {};
196 }
197 };
198
199 struct t2
200 {};
201
202 const t2*
203 operator&(const t2&) ynothrow
204 {
205 return {};
206 }
207
208 static_assert(!ystdex::has_overloaded_addressof<void>(), "Type check failed.");
209 // NOTE: Use '&x' to suppress Clang++ warning:
210 // [-Wunneeded-internal-declaration].
212 const void* volatile unused = &t2();
213
214 template<class _type>
215 bool
216 t_constfn() ynothrow
217 {
218 static_assert(ystdex::has_overloaded_addressof<_type>(),
219 "Type check failed.");
220 _type x;
221
222 return constfn_addressof(x) == std::addressof(x);
223 }
224
225 } // namespace memory_test;
226
228 namespace bitseg_test
229 {
230
231 template<size_t _vN, bool _bEndian = false>
232 static bool
233 expect(const string& str, vector<byte>&& seq)
234 {
235 using bit = bitseg_iterator<_vN, _bEndian>;
236
237 if(seq.empty())
238 return str.empty();
239
240 const bit e(&seq[0] + seq.size());
241 ostringstream oss;
242
243 oss << hex;
244 for(bit b(&seq[0]); b != e; ++b)
245 oss << int(*b);
246 return str == oss.str();
247 }
248
249 } // namespace bitseg_test;
250
251 } // unnamed namespace;
252
253
254 int
255 main()
256 {
257 const auto make_guard([](const string& subject){
258 return group_guard(subject, [](group_guard& printer){
259 cout << "CASES: " << printer.subject << ':' << endl;
260 }, [](group_guard& printer){
261 show_result(cout, printer.subject, printer.pass_n, printer.fail_n);
262 });
263 });
264 size_t pass_n(0), fail_n(0), case_n(0);
265 const auto pass([&]{
266 yunseq(++pass_n, cout << '#' << ++case_n << ": PASS." << endl);
267 });
268 const auto fail([&]{
269 yunseq(++fail_n, cout << '#' << ++case_n << ": FAIL." << endl);
270 });
271
272 // TODO: Check stream error.
273 // 30 cases covering: ystdex::begin, ystdex::end, ystdex::cbegin,
274 // ystdex::cend, ystdex::rbegin, ystdex::rend, ystdex::crbegin,
275 // ystdex::crend, ystdex::size, ystdex::data.
276 seq_apply(make_guard("YStandard.Range").get(pass, fail),
277 // 3 cases covering: ystdex::begin.
278 'a' == *begin({'a', 'b', 'c', char(), 'd', 'e'}),
279 u'a' == *begin(u"abc\0de"),
280 'B' == *begin(cwam().foo),
281 // 3 cases covering: ystdex::end.
282 'e' == *(end({'a', 'b', 'c', char(), 'd', 'e'}) - 1),
283 u'e' == *(end(u"abc\0de") - 2),
284 'B' == *(end(cwam().foo) - sizeof(cwam::foo)),
285 // 3 cases covering: ystdex::cbegin.
286 'a' == *cbegin({'a', 'b', 'c', char(), 'd', 'e'}),
287 u'a' == *cbegin(u"abc\0de"),
288 'B' == *cbegin(cwam().foo),
289 // 3 cases covering: ystdex::cend.
290 'e' == *(cend({'a', 'b', 'c', char(), 'd', 'e'}) - 1),
291 u'e' == *(cend(u"abc\0de") - 2),
292 'B' == *(cend(cwam().foo) - sizeof(cwam::foo)),
293 // 3 cases covering: ystdex::rbegin.
294 'e' == *rbegin({'a', 'b', 'c', char(), 'd', 'e'}),
295 u'\0' == *rbegin(u"abc\0de"),
296 'E' == *rbegin(cwam().foo),
297 // 3 cases covering: ystdex::rend.
298 'a' == *(rend({'a', 'b', 'c', char(), 'd', 'e'}) - 1),
299 u'a' == *(rend(u"abc\0de") - 1),
300 'E' == *(rend(cwam().foo) - sizeof(cwam::foo)),
301 // 3 cases covering: ystdex::crbegin.
302 'e' == *crbegin({'a', 'b', 'c', char(), 'd', 'e'}),
303 u'e' == *(crbegin(u"abc\0de") + 1),
304 'E' == *crbegin(cwam().foo),
305 // 3 cases covering: ystdex::crend.
306 'a' == *(crend({'a', 'b', 'c', char(), 'd', 'e'}) - 1),
307 u'a' == *(crend(u"abc\0de") - 1),
308 'E' == *(crend(cwam().foo) - sizeof(cwam::foo)),
309 // 3 cases covering: ystdex::size.
310 6 == size({'a', 'b', 'c', char(), 'd', 'e'}),
311 7 == size(u"abc\0de"),
312 sizeof(cwam::foo) == size(cwam().foo),
313 // 3 cases covering: ystdex::data.
314 'a' == *data({'a', 'b', 'c', char(), 'd', 'e'}),
315 u'a' == *data(u"abc\0de"),
316 'B' == *data(cwam().foo)
317 );
318 // 11 cases covering: ystdex::has_nonempty_virtual_base,
319 // ystdex::have_common_nonempty_virtual_base.
320 seq_apply(make_guard("YStandard.TypeOperation").get(pass, fail),
321 // 6 cases covering: ystdex::has_nonempty_virtual_base.
322 !vbase_test::v<vbase_test::eb>(),
323 !vbase_test::v<vbase_test::neb>(),
324 !vbase_test::v<vbase_test::ed>(),
325 !vbase_test::v<vbase_test::ned>(),
326 !vbase_test::v<vbase_test::ved>(),
327 vbase_test::v<vbase_test::vned>(),
328 // 5 cases covering: ystdex::have_common_nonempty_virtual_base.
329 !vbase_test::cv<vbase_test::neb, vbase_test::neb>(),
330 !vbase_test::cv<vbase_test::ed, vbase_test::ved>(),
331 !vbase_test::cv<vbase_test::ved, vbase_test::ved>(),
332 !vbase_test::cv<vbase_test::ved, vbase_test::vned>(),
333 vbase_test::cv<vbase_test::vned, vbase_test::vned2>()
334 );
335 // 1 case covering: ystdex::index_sequence, ystdex::make_peano_sequence.
336 seq_apply(make_guard("YStandard.IntegerSequence").get(pass, fail),
337 std::fabs(vseq_test::f() - 3.F) < numeric_limits<float>::epsilon()
338 );
339 // 2 cases covering: ystdex::constfn_addressof.
340 seq_apply(make_guard("YStandard.Memory").get(pass, fail),
341 memory_test::t_constfn<memory_test::t1>(),
342 memory_test::t_constfn<memory_test::t2>()
343 );
344 // 4 cases covering: ystdex::apply, ystdex::compose, ystdex::make_expanded.
345 seq_apply(make_guard("YStandard.Functional").get(pass, fail),
346 // 1 case covering: ystdex::apply.
347 abs(7.0 - apply([](int i, float f, double d){
348 return i + f + d;
349 }, make_tuple(1, 2.0F, 4.0))) < numeric_limits<double>::epsilon(),
350 // 2 cases covering: ystdex::compose.
351 abs(0.5 - compose(static_cast<double(&)(double)>(sin),
352 static_cast<double(&)(double)>(asin))(0.5))
353 < numeric_limits<double>::epsilon(),
354 expect(145, []{
355 return compose([](int x, int y){
356 return x + y + 1;
357 }, [](int x){
358 return x * 2;
359 }, [](int x){
360 return x - 1;
361 })(42, 32);
362 }),
363 expect(make_pair(8, 2), []{
364 using ftype = int(random_access_iterator_tag, double);
365 const int i(-1);
366
367 return make_pair((make_expanded<ftype>(
368 [](input_iterator_tag, short x){
369 return x * 2;
370 }))(random_access_iterator_tag(), 4), make_expanded<ftype>(
371 [=](forward_iterator_tag){
372 return i + 3;
373 })(random_access_iterator_tag(), 0));
374 })
375 );
376 // 2 cases covering: ystdex::transposed_iterator, ystdex::make_transposed.
377 seq_apply(make_guard("YStandard.Iterator").get(pass, fail),
378 expect(vector<int>{0, 4, 1, 5, 2, 6, 3, 7}, []{
379 vector<int> v{0, 1, 2, 3, 4, 5, 6, 7}, r;
380
381 copy(make_transposed(v.begin(), 4U, 2U, 0U),
382 make_transposed(v.begin(), 4U, 2U, 8U), back_inserter(r));
383 return r;
384 }),
385 expect(deque<int>{0, 1, 2, 3, 4, 5, 6, 7}, []{
386 deque<int> d{0, 4, 1, 5, 2, 6, 3, 7}, r;
387
388 copy(make_transposed(d.begin(), 2U, 4U) - ptrdiff_t(d.size()),
389 make_transposed(d.begin(), 2U, 4U), back_inserter(r));
390 return r;
391 })
392 );
393 // 6 cases covering: ystdex::transform_n, ystdex::min, ystdex::max.
394 seq_apply(make_guard("YStandard.Algorithm").get(pass, fail),
395 expect(vector<int>{-2, 5, 16, 16}, []{
396 vector<int> a{1, 2, 3, 4}, b{5, 4, 6, 5}, c{7, 3, 2, 4}, r(4);
397
398 transform_n([](int x, int y, int z)->int{
399 return x * y - z;
400 }, r.begin(), 4, a.cbegin(), b.cbegin(), c.cbegin());
401 return r;
402 }),
403 expect(list<int>{21, 18, 27, 24, 41}, []{
404 list<int> a{1, 2, 3, 4, 5}, b{5, 4, 6, 5, 9}, r(5);
405
406 transform_n([](int x, int y)->int{
407 return x + y * 4;
408 }, r.begin(), 5, a.cbegin(), b.cbegin());
409 return r;
410 }),
411 #if YB_HAS_CONSTEXPR
412 1 == sizeof(char[ystdex::min(1, 2)]),
413 #else
414 1 == ystdex::min(1, 2),
415 #endif
416 abs(2.F - ystdex::max(1.F, 2.F)) < numeric_limits<float>::epsilon(),
417 4U == integral_constant<unsigned, ystdex::min({5U, 6U, 7U, 8U, 4U})>(),
418 4 == ystdex::max({4, -5, -6, -7})
419 );
420 // 32 cases covering: ystdex::string_begin, ystdex::string_end,
421 // ystdex::string_length, ystdex::begins_with, ystdex::ends_with,
422 // ystdex::erase_left, ystdex::erase_right, ystdex::ltrim, ystdex::rtrim,
423 // ystdex::trim.
424 seq_apply(make_guard("YStandard.String").get(pass, fail),
425 'a' == *string_begin({'a', 'b', 'c', char(), 'd', 'e'}),
426 u'a' == *string_begin(u"abc\0de"),
427 'e' == *(string_end({'a', 'b', 'c', char(), 'd', 'e'}) - 1),
428 u'c' == *(string_end(u"abc\0de") - 1),
429 0 == string_length(u8""),
430 5 == string_length("abcde"),
431 3 == string_length(u"abc\0de"),
432 6 == string_length({'a', 'b', 'c', char(), 'd', 'e'}),
433 3 == string_length(wstring(L"abc\0de")),
434 6 == string_length(u16string{'a', 'b', 'c', 0, 'd', 'e'}),
435 true == begins_with("test_string", "test"),
436 true == begins_with("test string", string("test")),
437 false == begins_with("test_string", "tests"),
438 false == begins_with("test_string", "test_string_too_long"),
439 true == ends_with("test_string", "string"),
440 false == ends_with("test_string", "strnig"),
441 "de" == erase_left(3, string("abcde")),
442 "cde" == erase_left(string("abcde"), "c"),
443 "abcd" == erase_right(3, string("abcde")),
444 "ab" == erase_right(string("abcde"), 'b'),
445 string("de") == string(erase_left(3, string_view("abcde"))),
446 string("cde") == erase_left(string_view("abcde"), "c").to_string(),
447 string("abcd") == string(erase_right(3, string_view("abcde"))),
448 string("ab") == erase_right(string_view("abcde"), 'b').to_string(),
449 ltrim(string("aabcbaa"), 'a') == "bcbaa",
450 ltrim(string_view("aabcbaa"), 'a').to_string() == "bcbaa",
451 rtrim(string("aabcbaa"), 'a') == "aabcb",
452 rtrim(string_view("aabcbaa"), 'a').to_string() == "aabcb",
453 trim(string("aabcbaa"), 'a') == "bcb",
454 trim(string("\v\nabcde\t\n")) == "abcde",
455 trim(string_view("aabcbaa"), 'a').to_string() == "bcb",
456 trim(string_view("\v\nabcde\t\n")) == "abcde"
457 );
458 // 4 cases covering: ystdex::range_size.
459 seq_apply(make_guard("YStandard.Container").get(pass, fail),
460 3 == range_size({1, 2, 3}),
461 4 == range_size(vector<int>(4)),
462 expect(size_t(5), []{
463 int a[5];
464
465 return range_size(a);
466 }),
467 expect(size_t(6), []{
468 struct no_size_function : initializer_list<int>
469 {
470 no_size_function(initializer_list<int> il)
471 : initializer_list<int>(il)
472 {}
473
474 using initializer_list::begin;
475 using initializer_list::end;
476 };
477
478 // XXX: How to detect %std::distance used?
479 return range_size(no_size_function({3, 4, 5, 6, 7, 8}));
480 })
481 );
482 // 4 cases covering: ystdex::string_view.
483 seq_apply(make_guard("YStandard.StringView").get(pass, fail),
484 string_view("????") == std::string(4, '?'),
485 string_view("///a/b/c").find_first_not_of('/') == 3,
486 string_view("///a/b/c/").find_last_not_of('/') == 7,
487 expect(true, []{
488 static_assert(is_same<string_traits<string_view>::string_type,
489 string_view>(), "");
490 static_assert(is_same<string_traits<string_view>::value_type,
491 char>(), "");
492 const string str("Hello!");
493 const string_view sv(str);
494
495 return sv.find("el") == 1 && sv.find("loo") == string_view::npos
496 && sv.rfind('l') == 3 && sv.find_first_of("abcde") == 1
497 && sv.find_first_not_of("Hel!") == 4;
498 })
499 );
500 // 4 cases covering: ystdex::tstring_view.
501 seq_apply(make_guard("YStandard.TStringView").get(pass, fail),
502 tstring_view("????") == std::string(4, '?'),
503 tstring_view("///a/b/c").find_first_not_of('/') == 3,
504 tstring_view("///a/b/c/").find_last_not_of('/') == 7,
505 expect(true, []{
506 static_assert(is_same<string_traits<tstring_view>::string_type,
507 tstring_view>(), "");
508 static_assert(is_same<string_traits<tstring_view>::value_type,
509 char>(), "");
510 const string str("Hello!");
511 const tstring_view sv(str);
512
513 return sv.find("el") == 1 && sv.find("loo") == string_view::npos
514 && sv.rfind('l') == 3 && sv.find_first_of("abcde") == 1
515 && sv.find_first_not_of("Hel!") == 4;
516 })
517 );
518 // 1 case covering: mixin interface.
519 seq_apply(make_guard("YStandard.Mixin").get(pass, fail),
520 expect(make_pair(string("e"), boxed_value<int>(3)), []{
521 using int_exception = wrap_mixin_t<runtime_error, int>;
522 using exception_tuple = typename int_exception::tuple_type;
523 using type_0 = tuple_element_t<0, exception_tuple>;
524 using type_1 = tuple_element_t<1, exception_tuple>;
525 static_assert(is_same<type_0, runtime_error>(), "");
526 static_assert(is_same<type_1, ystdex::boxed_value<int>>(), "");
527 static_assert(is_constructible<type_0, const char*>(), "");
528 static_assert(is_constructible<type_1, double>(), "");
529
530 const auto et(int_exception(forward_as_tuple(runtime_error("e"), 3))
531 .to_tuple());
532 return make_pair(string(get<0>(et).what()), get<1>(et));
533 })
534 );
535 // 3 cases covering: ystdex::bitseg_iterator.
536 seq_apply(make_guard("YStandard.BitSegment").get(pass, fail),
537 bitseg_test::expect<1>("1000000001000000110000001010000011101000"
538 "000000110000111111111111", {1, 2, 3, 5, 0x17, 0xC0, 0xF0, 0xFF}),
539 bitseg_test::expect<1, true>("0000000100000010000000110000010100010111"
540 "110000001111000011111111", {1, 2, 3, 5, 0x17, 0xC0, 0xF0, 0xFF}),
541 bitseg_test::expect<2>("10002000300011003110000300333333",
542 {1, 2, 3, 5, 0x17, 0xC0, 0xF0, 0xFF}),
543 bitseg_test::expect<2, true>("00010002000300110113300033003333",
544 {1, 2, 3, 5, 0x17, 0xC0, 0xF0, 0xFF}),
545 bitseg_test::expect<4>("10203050710c0fff",
546 {1, 2, 3, 5, 0x17, 0xC0, 0xF0, 0xFF}),
547 bitseg_test::expect<4, true>("0102030517c0f0ff",
548 {1, 2, 3, 5, 0x17, 0xC0, 0xF0, 0xFF})
549 );
550 show_result(cout, "ALL", pass_n, fail_n);
551 }
552
ytest::group_guard
测试组 RAII 辅助对象。
Definition: test.h:65
YSLib::Drawing::x
The boundary is out of the const Rect SDst SPos x
Definition: YDraw.h:127
ystdex::bitseg_iterator
位段迭代器。
Definition: bitseg.hpp:51
ytest::group_guard::fail_n
size_t fail_n
Definition: test.h:70
ystdex::string_view
basic_string_view< char > string_view
Definition: string_view.hpp:415
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:740
platform::containers::string
basic_string< char > string
Definition: Container.h:101
ystdex::tstring_view
basic_tstring_view< char > tstring_view
Definition: tstring_view.hpp:291
placeholders
ystdex::have_common_nonempty_virtual_base
判断指定的两个类类型是否不同且有公共非空虚基类。
Definition: type_op.hpp:221
ystdex::has_nonempty_virtual_base
判断指定类型是否有非空虚基类。
Definition: type_op.hpp:209
memory_test
Definition: YBase.cpp:187
bitseg_test
Definition: YBase.cpp:228
v
byte v
Definition: CharRenderer.cpp:75
ystdex::cpp2014::cend
auto cend(const _tRange &c) -> decltype(std::end(c))
Definition: range.hpp:87
ystdex::vseq::vec_subtract_t
_t< vec_subtract< _tSeq1, _tSeq2, _tEnabler >> vec_subtract_t
Definition: variadic.hpp:821
platform::KeyCodes::DS::L
Definition: Keys.h:227
ystdex::basic_string_view::rfind
size_type rfind(basic_string_view s, size_type pos=npos) const
Definition: string_view.hpp:338
platform::containers::u16string
basic_string< char16_t > u16string
Definition: Container.h:103
ystdex::trim
_tString && trim(_tString &&str, typename string_traits< _tString >::value_type c)
删除字符串中指定的连续前缀与后缀字符。
Definition: string.hpp:649
ystdex::basic_string_view::find_first_of
size_type find_first_of(basic_string_view s, size_type pos=0) const
Definition: string_view.hpp:340
NPL::A1::name
ctx const string & name
Definition: NPLA1.h:248
ystdex::transform_n
void transform_n(_fOp op, _tOut result, size_t n, _tIns...iters)
指定数量的序列变换。
Definition: algorithm.hpp:335
ystdex::boxed_value
包装类类型的值的对象。
Definition: utility.hpp:139
ystdex::begins_with
bool begins_with(const _tRange1 &input, const _tRange2 &test, _fPred comp)
判断第一个参数指定的串是否以第二个参数起始。
Definition: string.hpp:343
ytest::group_guard::pass_n
size_t pass_n
Definition: test.h:69
ystdex::erase_right
enable_if_t< is_class< decay_t< _tString > >::value, _tString && > erase_right(typename string_traits< _tString >::size_type pos, _tString &&str)
删除字符串中指定的连续字符右侧的字符串。
Definition: string.hpp:545
ystdex::string_traits::value_type
remove_rcv_t< decltype(std::declval< string_type >()[0])> value_type
Definition: string.hpp:58
CHRLib::e
const char const char * e
Definition: CharacterProcessing.h:109
ystdex::string_end
auto string_end(_tRange &c) -> decltype(c.end())
Definition: string.hpp:264
ystdex::vseq::unique_t
_t< unique< _tSeq, _tEnabler >> unique_t
Definition: variadic.hpp:717
CHRLib::d
_tDst * d
Definition: CharacterProcessing.h:139
ystdex::data
auto data(_tRange &c) -> decltype(c.data())
Definition: range.hpp:280
ystdex::make_peano_sequence_t
_t< make_peano_sequence< _tInt, _vBase, _vN >> make_peano_sequence_t
Definition: integer_sequence.hpp:177
CHRLib::c
c
Definition: CharacterProcessing.h:81
ystdex::basic_string_view::find_first_not_of
size_type find_first_not_of(basic_string_view s, size_type pos=0) const
Definition: string_view.hpp:344
platform_ex::Windows::unsigned
YF_API unsigned
Definition: MinGW32.h:630
ystdex::constfn_addressof
enable_if_t<!has_overloaded_addressof< _type >::value, _type * > constfn_addressof(_type &r)
尝试对非重载 operator& 提供 constexpr 的 std::addressof 替代。
Definition: addressof.hpp:78
container.hpp
通用容器操作。
ytest::expect
bool expect(const _type &result, _func &&f, _tParams &&...args)
判断可调用对象的应用求值结果是否符合预期值。
Definition: test.h:55
ystdex::rtrim
_tString && rtrim(_tString &&str, typename string_traits< _tString >::value_type c)
删除字符串中指定的连续后缀字符。
Definition: string.hpp:618
functional.hpp
函数和可调用对象。
std
Definition: memory.hpp:1100
ystdex::size
auto size(const _tRange &c) -> decltype(c.size())
类容器访问。
Definition: range.hpp:233
ystdex::basic_string_view
Definition: string_view.hpp:49
ystdex::details::range_size
auto range_size(const _tRange &c, true_type) -> decltype(size(c))
Definition: container.hpp:352
platform::containers::wstring
basic_string< wchar_t > wstring
Definition: Container.h:108
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:996
vseq
ystdex::vseq::at_t
_t< at< _tSeq, _vIdx, _tEnabler >> at_t
Definition: variadic.hpp:467
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::max
const _type & max(const _type &a, const _type &b, _fComp comp=less< _type >())
取较大的元素。
Definition: algorithm.hpp:543
ystdex::ltrim
_tString && ltrim(_tString &&str, typename string_traits< _tString >::value_type c)
删除字符串中指定的连续前缀字符。
Definition: string.hpp:587
ytest
YFramework 基础测试库命名空间。
Definition: test.h:44
ystdex::string_begin
auto string_begin(_tRange &c) -> decltype(c.begin())
Definition: string.hpp:233
YSLib::Drawing::r
The boundary is out of the const Graphics const Rect const Point const Point Color c const Rect const Rect & r
Definition: YDraw.h:174
ystdex::has_overloaded_addressof
判断是否存在合式重载 & 操作符接受指定类型的表达式。
Definition: addressof.hpp:63
ystdex::basic_string_view::find
size_type find(basic_string_view s, size_type pos=0) const
Definition: string_view.hpp:336
YSLib::IO::int
YF_API int
Definition: File.h:49
YSLib::UI::y
SPos SPos y
Definition: YWidget.cpp:44
YSLib::i
return i
Definition: YCoreUtilities.h:176
platform::KeyCodes::DS::A
Definition: Keys.h:215
vseq_test
Definition: YBase.cpp:117
mixin.hpp
基于类继承的混入接口。
ystdex::vseq::apply
typename _func::template apply< _tParams... > apply
元函数应用。
Definition: variadic.hpp:69
test.h
基础测试工具。
ystdex::string_traits::string_type
remove_rcv_t< _tString > string_type
Definition: string.hpp:57
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:654
YSLib::a
YB_PURE const _type * a
Definition: YCoreUtilities.h:167
main
int main()
Definition: YBase.cpp:255
ytest::group_guard::subject
std::string subject
Definition: test.h:68
vbase_test
Definition: YBase.cpp:74
ystdex::cpp2014::rend
auto rend(_tRange &c) -> decltype(c.rend())
Definition: range.hpp:119
ystdex::vseq::concat_t
_t< concat< _tSeq1, _tSeq2, _tEnabler >> concat_t
Definition: variadic.hpp:300
ystdex::mixin
混入对象。
Definition: mixin.hpp:45
ystdex::min
const _type & min(const _type &a, const _type &b, _fComp comp=less< _type >())
取较小的元素。
Definition: algorithm.hpp:521
ystdex::compose
auto compose(_func1 f, _func2 g, _funcs...args) -> decltype(ystdex::compose(ystdex::compose(f, g), args...))
Definition: functional.hpp:646
bitseg.hpp
位段数据结构和访问。
ystdex::ends_with
bool ends_with(const _tRange1 &input, const _tRange2 &test, _fPred comp)
判断第一个参数指定的串是否以第二个参数结束。
Definition: string.hpp:362
tstring_view.hpp
指定结束字符的只读字符串视图。
YSLib::char
char
Definition: ValueNode.h:851
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
YSLib::IO::f
const string &path const String &path _func f
Definition: YSLib/Service/FileSystem.h:430
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::erase_left
enable_if_t< is_class< decay_t< _tString > >::value, _tString && > erase_left(typename string_traits< _tString >::size_type pos, _tString &&str)
删除字符串中指定的连续字符左侧的字符串。
Definition: string.hpp:510
ystdex::seq_apply
void seq_apply(_func &&)
顺序递归调用。
Definition: functional.hpp:225
ystdex::make_guard
guard< _type > make_guard(_type f)
Definition: scope_guard.hpp:83
algorithm.hpp
泛型算法。
ystdex::basic_tstring_view
指定结束字符的只读字符串视图。
Definition: tstring_view.hpp:47
ystdex::string_length
size_t string_length(const _type *str)
计算字符串长度。
Definition: string.hpp:309
ystdex::cpp2011::end
_type * end(_type(&&array)[_vN])
Definition: range.hpp:54
CHRLib::s
_tDst const _tSrc * s
Definition: CharacterProcessing.h:140