• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2019 T. Zachary Laine
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 #include <boost/stl_interfaces/sequence_container_interface.hpp>
7 
8 #include "ill_formed.hpp"
9 
10 #include <boost/core/lightweight_test.hpp>
11 
12 #include <array>
13 #include <deque>
14 #include <vector>
15 
16 
17 // Just like std::array, except for the 0-size specialization, and the fact
18 // that the base class makes brace-initialization wonky.
19 template<typename T, std::size_t N>
20 struct array : boost::stl_interfaces::sequence_container_interface<
21                    array<T, N>,
22                    boost::stl_interfaces::v1::element_layout::contiguous>
23 {
24     using value_type = T;
25     using pointer = T *;
26     using const_pointer = T const *;
27     using reference = value_type &;
28     using const_reference = value_type const &;
29     using size_type = std::size_t;
30     using difference_type = std::ptrdiff_t;
31     using iterator = T *;
32     using const_iterator = T const *;
33     using reverse_iterator = boost::stl_interfaces::reverse_iterator<iterator>;
34     using const_reverse_iterator =
35         boost::stl_interfaces::reverse_iterator<const_iterator>;
36 
fillarray37     void fill(T const & x) { std::fill(begin(), end(), x); }
38 
beginarray39     iterator begin() noexcept { return elements_; }
endarray40     iterator end() noexcept { return elements_ + N; }
41 
max_sizearray42     size_type max_size() const noexcept { return N; }
43 
swaparray44     void swap(array & other)
45     {
46         using std::swap;
47         T * element = elements_;
48         for (auto & x : other) {
49             swap(*element++, x);
50         }
51     }
52 
53     using base_type = boost::stl_interfaces::sequence_container_interface<
54         array<T, N>,
55         boost::stl_interfaces::v1::element_layout::contiguous>;
56     using base_type::begin;
57     using base_type::end;
58 
59     T elements_[N];
60 };
61 
62 using arr_type = array<int, 5>;
63 
64 
test_comparisons()65 void test_comparisons()
66 {
67     arr_type sm;
68     sm[0] = 1;
69     sm[1] = 2;
70     sm[2] = 3;
71     sm[3] = 0;
72     sm[4] = 0;
73     arr_type md;
74     md[0] = 1;
75     md[1] = 2;
76     md[2] = 3;
77     md[3] = 4;
78     md[4] = 0;
79     arr_type lg;
80     lg[0] = 1;
81     lg[1] = 2;
82     lg[2] = 3;
83     lg[3] = 4;
84     lg[4] = 5;
85 
86     BOOST_TEST(sm == sm);
87     BOOST_TEST(!(sm == md));
88     BOOST_TEST(!(sm == lg));
89 
90     BOOST_TEST(!(sm != sm));
91     BOOST_TEST(sm != md);
92     BOOST_TEST(sm != lg);
93 
94     BOOST_TEST(!(sm < sm));
95     BOOST_TEST(sm < md);
96     BOOST_TEST(sm < lg);
97 
98     BOOST_TEST(sm <= sm);
99     BOOST_TEST(sm <= md);
100     BOOST_TEST(sm <= lg);
101 
102     BOOST_TEST(!(sm > sm));
103     BOOST_TEST(!(sm > md));
104     BOOST_TEST(!(sm > lg));
105 
106     BOOST_TEST(sm >= sm);
107     BOOST_TEST(!(sm >= md));
108     BOOST_TEST(!(sm >= lg));
109 
110 
111     BOOST_TEST(!(md == sm));
112     BOOST_TEST(md == md);
113     BOOST_TEST(!(md == lg));
114 
115     BOOST_TEST(!(md < sm));
116     BOOST_TEST(!(md < md));
117     BOOST_TEST(md < lg);
118 
119     BOOST_TEST(!(md <= sm));
120     BOOST_TEST(md <= md);
121     BOOST_TEST(md <= lg);
122 
123     BOOST_TEST(md > sm);
124     BOOST_TEST(!(md > md));
125     BOOST_TEST(!(md > lg));
126 
127     BOOST_TEST(md >= sm);
128     BOOST_TEST(md >= md);
129     BOOST_TEST(!(md >= lg));
130 
131 
132     BOOST_TEST(!(lg == sm));
133     BOOST_TEST(!(lg == md));
134     BOOST_TEST(lg == lg);
135 
136     BOOST_TEST(!(lg < sm));
137     BOOST_TEST(!(lg < md));
138     BOOST_TEST(!(lg < lg));
139 
140     BOOST_TEST(!(lg <= sm));
141     BOOST_TEST(!(lg <= md));
142     BOOST_TEST(lg <= lg);
143 
144     BOOST_TEST(lg > sm);
145     BOOST_TEST(lg > md);
146     BOOST_TEST(!(lg > lg));
147 
148     BOOST_TEST(lg >= sm);
149     BOOST_TEST(lg >= md);
150     BOOST_TEST(lg >= lg);
151 }
152 
153 
test_swap()154 void test_swap()
155 {
156     {
157         arr_type v1;
158         v1[0] = 3;
159         v1[1] = 4;
160         v1[2] = 0;
161         v1[3] = 0;
162         v1[4] = 0;
163         arr_type v2;
164         v2[0] = 4;
165         v2[1] = 3;
166         v2[2] = 0;
167         v2[3] = 0;
168         v2[4] = 0;
169 
170         arr_type const v1_copy = v1;
171         arr_type const v2_copy = v2;
172 
173         static_assert(std::is_same<decltype(v1.swap(v2)), void>::value, "");
174         static_assert(std::is_same<decltype(swap(v1, v2)), void>::value, "");
175 
176         v1.swap(v2);
177 
178         BOOST_TEST(v1 == v2_copy);
179         BOOST_TEST(v2 == v1_copy);
180     }
181 
182     {
183         arr_type v1;
184         v1[0] = 3;
185         v1[1] = 4;
186         v1[2] = 0;
187         v1[3] = 0;
188         v1[4] = 0;
189         arr_type v2;
190         v2[0] = 4;
191         v2[1] = 3;
192         v2[2] = 0;
193         v2[3] = 0;
194         v2[4] = 0;
195 
196         arr_type const v1_copy = v1;
197         arr_type const v2_copy = v2;
198 
199         swap(v1, v2);
200 
201         BOOST_TEST(v1 == v2_copy);
202         BOOST_TEST(v2 == v1_copy);
203     }
204 }
205 
206 template<typename Iter>
207 using writable_iter_t = decltype(
208     *std::declval<Iter>() =
209         std::declval<typename std::iterator_traits<Iter>::value_type>());
210 
211 static_assert(
212     !ill_formed<writable_iter_t, decltype(std::declval<arr_type &>().begin())>::
213         value,
214     "");
215 static_assert(
216     !ill_formed<writable_iter_t, decltype(std::declval<arr_type &>().end())>::
217         value,
218     "");
219 
220 static_assert(
221     ill_formed<
222         writable_iter_t,
223         decltype(std::declval<arr_type const &>().begin())>::value,
224     "");
225 static_assert(
226     ill_formed<
227         writable_iter_t,
228         decltype(std::declval<arr_type const &>().end())>::value,
229     "");
230 static_assert(
231     ill_formed<writable_iter_t, decltype(std::declval<arr_type &>().cbegin())>::
232         value,
233     "");
234 static_assert(
235     ill_formed<writable_iter_t, decltype(std::declval<arr_type &>().cend())>::
236         value,
237     "");
238 
239 static_assert(
240     ill_formed<
241         writable_iter_t,
242         decltype(std::declval<arr_type const &>().rbegin())>::value,
243     "");
244 static_assert(
245     ill_formed<
246         writable_iter_t,
247         decltype(std::declval<arr_type const &>().rend())>::value,
248     "");
249 static_assert(
250     ill_formed<
251         writable_iter_t,
252         decltype(std::declval<arr_type &>().crbegin())>::value,
253     "");
254 static_assert(
255     ill_formed<writable_iter_t, decltype(std::declval<arr_type &>().crend())>::
256         value,
257     "");
258 
test_iterators()259 void test_iterators()
260 {
261     arr_type v0;
262     v0[0] = 3;
263     v0[1] = 2;
264     v0[2] = 1;
265     v0[3] = 0;
266     v0[4] = 0;
267 
268     {
269         arr_type v = v0;
270 
271         static_assert(
272             std::is_same<decltype(v.begin()), arr_type::iterator>::value, "");
273         static_assert(
274             std::is_same<decltype(v.end()), arr_type::iterator>::value, "");
275         static_assert(
276             std::is_same<decltype(v.cbegin()), arr_type::const_iterator>::value,
277             "");
278         static_assert(
279             std::is_same<decltype(v.cend()), arr_type::const_iterator>::value,
280             "");
281         static_assert(
282             std::is_same<decltype(v.rbegin()), arr_type::reverse_iterator>::
283                 value,
284             "");
285         static_assert(
286             std::is_same<decltype(v.rbegin()), arr_type::reverse_iterator>::
287                 value,
288             "");
289         static_assert(
290             std::is_same<
291                 decltype(v.crbegin()),
292                 arr_type::const_reverse_iterator>::value,
293             "");
294         static_assert(
295             std::is_same<
296                 decltype(v.crbegin()),
297                 arr_type::const_reverse_iterator>::value,
298             "");
299 
300         std::array<int, 5> const a = {{3, 2, 1, 0, 0}};
301         std::array<int, 5> const ra = {{0, 0, 1, 2, 3}};
302 
303         BOOST_TEST(std::equal(v.begin(), v.end(), a.begin(), a.end()));
304         BOOST_TEST(std::equal(v.cbegin(), v.cend(), a.begin(), a.end()));
305 
306         BOOST_TEST(std::equal(v.rbegin(), v.rend(), ra.begin(), ra.end()));
307         BOOST_TEST(std::equal(v.crbegin(), v.crend(), ra.begin(), ra.end()));
308 
309         arr_type v2;
310         v2[0] = 8;
311         v2[1] = 2;
312         v2[2] = 1;
313         v2[3] = 0;
314         v2[4] = 9;
315 
316         *v.begin() = 8;
317         *v.rbegin() = 9;
318         BOOST_TEST(v == v2);
319     }
320 
321     {
322         arr_type const v = v0;
323 
324         static_assert(
325             std::is_same<decltype(v.begin()), arr_type::const_iterator>::value,
326             "");
327         static_assert(
328             std::is_same<decltype(v.end()), arr_type::const_iterator>::value,
329             "");
330         static_assert(
331             std::is_same<decltype(v.cbegin()), arr_type::const_iterator>::value,
332             "");
333         static_assert(
334             std::is_same<decltype(v.cend()), arr_type::const_iterator>::value,
335             "");
336         static_assert(
337             std::is_same<
338                 decltype(v.rbegin()),
339                 arr_type::const_reverse_iterator>::value,
340             "");
341         static_assert(
342             std::is_same<
343                 decltype(v.rbegin()),
344                 arr_type::const_reverse_iterator>::value,
345             "");
346         static_assert(
347             std::is_same<
348                 decltype(v.crbegin()),
349                 arr_type::const_reverse_iterator>::value,
350             "");
351         static_assert(
352             std::is_same<
353                 decltype(v.crbegin()),
354                 arr_type::const_reverse_iterator>::value,
355             "");
356 
357         std::array<int, 5> const a = {{3, 2, 1, 0, 0}};
358         std::array<int, 5> const ra = {{0, 0, 1, 2, 3}};
359 
360         BOOST_TEST(std::equal(v.begin(), v.end(), a.begin(), a.end()));
361         BOOST_TEST(std::equal(v.cbegin(), v.cend(), a.begin(), a.end()));
362 
363         BOOST_TEST(std::equal(v.rbegin(), v.rend(), ra.begin(), ra.end()));
364         BOOST_TEST(std::equal(v.crbegin(), v.crend(), ra.begin(), ra.end()));
365     }
366 }
367 
368 
369 template<
370     typename Container,
371     typename ValueType = typename Container::value_type>
372 using lvalue_push_front_t = decltype(
373     std::declval<Container &>().push_front(std::declval<ValueType const &>()));
374 template<
375     typename Container,
376     typename ValueType = typename Container::value_type>
377 using rvalue_push_front_t = decltype(std::declval<Container &>().push_front(0));
378 template<typename Container>
379 using pop_front_t = decltype(std::declval<Container &>().pop_front());
380 
381 static_assert(ill_formed<lvalue_push_front_t, arr_type>::value, "");
382 static_assert(ill_formed<rvalue_push_front_t, arr_type>::value, "");
383 static_assert(ill_formed<pop_front_t, arr_type>::value, "");
384 
385 using std_deq_int = std::deque<int>;
386 
387 static_assert(!ill_formed<lvalue_push_front_t, std_deq_int>::value, "");
388 static_assert(!ill_formed<rvalue_push_front_t, std_deq_int>::value, "");
389 static_assert(!ill_formed<pop_front_t, std_deq_int>::value, "");
390 
391 
392 template<
393     typename Container,
394     typename ValueType = typename Container::value_type>
395 using lvalue_push_back_t = decltype(
396     std::declval<Container &>().push_back(std::declval<ValueType const &>()));
397 template<
398     typename Container,
399     typename ValueType = typename Container::value_type>
400 using rvalue_push_back_t = decltype(std::declval<Container &>().push_back(0));
401 template<typename Container>
402 using pop_back_t = decltype(std::declval<Container &>().pop_back());
403 
404 static_assert(ill_formed<lvalue_push_back_t, arr_type>::value, "");
405 static_assert(ill_formed<rvalue_push_back_t, arr_type>::value, "");
406 static_assert(ill_formed<pop_back_t, arr_type>::value, "");
407 
408 using std_vec_int = std::vector<int>;
409 
410 static_assert(!ill_formed<lvalue_push_back_t, std_vec_int>::value, "");
411 static_assert(!ill_formed<rvalue_push_back_t, std_vec_int>::value, "");
412 static_assert(!ill_formed<pop_back_t, std_vec_int>::value, "");
413 
414 
test_front_back()415 void test_front_back()
416 {
417     {
418         arr_type v;
419         v[0] = 0;
420         v[1] = 0;
421         v[2] = 0;
422         v[3] = 0;
423         v[4] = 0;
424 
425         static_assert(std::is_same<decltype(v.front()), int &>::value, "");
426         static_assert(std::is_same<decltype(v.back()), int &>::value, "");
427 
428         v.front() = 9;
429         v.back() = 8;
430         BOOST_TEST(v[0] == v.front());
431         BOOST_TEST(v[4] == v.back());
432     }
433 
434     {
435         arr_type v0;
436         v0[0] = 3;
437         v0[1] = 0;
438         v0[2] = 2;
439         v0[3] = 0;
440         v0[4] = 1;
441 
442         arr_type const v = v0;
443         BOOST_TEST(v.front() == 3);
444         BOOST_TEST(v.back() == 1);
445 
446         static_assert(
447             std::is_same<decltype(v.front()), int const &>::value, "");
448         static_assert(std::is_same<decltype(v.back()), int const &>::value, "");
449     }
450 }
451 
452 
test_cindex_at()453 void test_cindex_at()
454 {
455     arr_type v0;
456     v0[0] = 3;
457     v0[1] = 2;
458     v0[2] = 1;
459     v0[3] = 0;
460     v0[4] = 0;
461 
462     {
463         arr_type v = v0;
464         BOOST_TEST(v[0] == 3);
465         BOOST_TEST(v[1] == 2);
466         BOOST_TEST(v[2] == 1);
467         BOOST_TEST_NO_THROW(v.at(0));
468         BOOST_TEST_NO_THROW(v.at(1));
469         BOOST_TEST_NO_THROW(v.at(2));
470         BOOST_TEST_THROWS(v.at(5), std::out_of_range);
471 
472         static_assert(std::is_same<decltype(v[0]), int &>::value, "");
473         static_assert(std::is_same<decltype(v.at(0)), int &>::value, "");
474 
475         v[0] = 8;
476         v.at(1) = 9;
477         BOOST_TEST(v[0] == 8);
478         BOOST_TEST(v[1] == 9);
479     }
480 
481     {
482         arr_type const v = v0;
483         BOOST_TEST(v[0] == 3);
484         BOOST_TEST(v[1] == 2);
485         BOOST_TEST(v[2] == 1);
486         BOOST_TEST_NO_THROW(v.at(0));
487         BOOST_TEST_NO_THROW(v.at(1));
488         BOOST_TEST_NO_THROW(v.at(2));
489         BOOST_TEST_THROWS(v.at(5), std::out_of_range);
490 
491         static_assert(std::is_same<decltype(v[0]), int const &>::value, "");
492         static_assert(std::is_same<decltype(v.at(0)), int const &>::value, "");
493     }
494 }
495 
496 
497 template<typename Container>
498 using resize_t = decltype(std::declval<Container &>().resize(0));
499 
500 static_assert(ill_formed<resize_t, arr_type>::value, "");
501 
502 static_assert(!ill_formed<resize_t, std_vec_int>::value, "");
503 
504 template<
505     typename Container,
506     typename ValueType = typename Container::value_type>
507 using lvalue_insert_t = decltype(std::declval<Container &>().insert(
508     std::declval<Container &>().begin(), std::declval<ValueType const &>()));
509 template<
510     typename Container,
511     typename ValueType = typename Container::value_type>
512 using rvalue_insert_t = decltype(std::declval<Container &>().insert(
513     std::declval<Container &>().begin(), std::declval<ValueType &&>()));
514 template<
515     typename Container,
516     typename ValueType = typename Container::value_type>
517 using insert_n_t = decltype(std::declval<Container &>().insert(
518     std::declval<Container &>().begin(), 2, std::declval<ValueType const &>()));
519 template<
520     typename Container,
521     typename ValueType = typename Container::value_type>
522 using insert_il_t = decltype(std::declval<Container &>().insert(
523     std::declval<Container &>().begin(), std::initializer_list<int>{}));
524 
525 static_assert(ill_formed<lvalue_insert_t, arr_type>::value, "");
526 static_assert(ill_formed<rvalue_insert_t, arr_type>::value, "");
527 
528 // TODO: Broken in v1.  Adding the proper constraint ICE's GCC 8, or
529 // infinitely recurses within the compiler for GCC and Clang, depending on the
530 // constraint technique used.
531 #if 0
532 static_assert(ill_formed<insert_n_t, arr_type>::value, "");
533 #endif
534 
535 static_assert(ill_formed<insert_il_t, arr_type>::value, "");
536 
537 static_assert(!ill_formed<lvalue_insert_t, std_vec_int>::value, "");
538 static_assert(!ill_formed<rvalue_insert_t, std_vec_int>::value, "");
539 static_assert(!ill_formed<insert_n_t, std_vec_int>::value, "");
540 static_assert(!ill_formed<insert_il_t, std_vec_int>::value, "");
541 
542 
543 template<typename Container>
544 using erase_t = decltype(
545     std::declval<Container &>().erase(std::declval<Container &>().begin()));
546 
547 static_assert(ill_formed<erase_t, arr_type>::value, "");
548 
549 static_assert(!ill_formed<erase_t, std_vec_int>::value, "");
550 
551 
552 template<typename Container>
553 using assign_t = decltype(std::declval<Container &>().assign(
554     std::declval<int *>(), std::declval<int *>()));
555 template<typename Container>
556 using assign_n_t = decltype(std::declval<Container &>().assign(5, 5));
557 template<typename Container>
558 using assign_il_t =
559     decltype(std::declval<Container &>().assign(std::initializer_list<int>{}));
560 template<typename Container>
561 using assignment_operator_il_t =
562     decltype(std::declval<Container &>() = std::initializer_list<int>{});
563 
564 static_assert(ill_formed<assign_t, arr_type>::value, "");
565 static_assert(ill_formed<assign_n_t, arr_type>::value, "");
566 static_assert(ill_formed<assign_il_t, arr_type>::value, "");
567 static_assert(ill_formed<assignment_operator_il_t, arr_type>::value, "");
568 
569 static_assert(!ill_formed<assign_t, std_vec_int>::value, "");
570 static_assert(!ill_formed<assign_n_t, std_vec_int>::value, "");
571 static_assert(!ill_formed<assign_il_t, std_vec_int>::value, "");
572 static_assert(!ill_formed<assignment_operator_il_t, std_vec_int>::value, "");
573 
574 template<typename Container>
575 using clear_t = decltype(std::declval<Container &>().clear());
576 
577 static_assert(ill_formed<clear_t, arr_type>::value, "");
578 
579 static_assert(!ill_formed<clear_t, std_vec_int>::value, "");
580 
main()581 int main()
582 {
583     test_comparisons();
584     test_swap();
585     test_iterators();
586     test_front_back();
587     test_cindex_at();
588     return boost::report_errors();
589 }
590