1 // Copyright (C) 2019 T. Zachary Laine
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>
8 #include "ill_formed.hpp"
10 #include <boost/core/lightweight_test.hpp>
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
<
22 boost::stl_interfaces::v1::element_layout::contiguous
>
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;
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
>;
37 void fill(T
const & x
) { std::fill(begin(), end(), x
); }
39 iterator
begin() noexcept
{ return elements_
; }
40 iterator
end() noexcept
{ return elements_
+ N
; }
42 size_type
max_size() const noexcept
{ return N
; }
44 void swap(array
& other
)
47 T
* element
= elements_
;
48 for (auto & x
: other
) {
53 using base_type
= boost::stl_interfaces::sequence_container_interface
<
55 boost::stl_interfaces::v1::element_layout::contiguous
>;
56 using base_type::begin
;
62 using arr_type
= array
<int, 5>;
65 void test_comparisons()
87 BOOST_TEST(!(sm
== md
));
88 BOOST_TEST(!(sm
== lg
));
90 BOOST_TEST(!(sm
!= sm
));
94 BOOST_TEST(!(sm
< sm
));
100 BOOST_TEST(sm
<= lg
);
102 BOOST_TEST(!(sm
> sm
));
103 BOOST_TEST(!(sm
> md
));
104 BOOST_TEST(!(sm
> lg
));
106 BOOST_TEST(sm
>= sm
);
107 BOOST_TEST(!(sm
>= md
));
108 BOOST_TEST(!(sm
>= lg
));
111 BOOST_TEST(!(md
== sm
));
112 BOOST_TEST(md
== md
);
113 BOOST_TEST(!(md
== lg
));
115 BOOST_TEST(!(md
< sm
));
116 BOOST_TEST(!(md
< md
));
119 BOOST_TEST(!(md
<= sm
));
120 BOOST_TEST(md
<= md
);
121 BOOST_TEST(md
<= lg
);
124 BOOST_TEST(!(md
> md
));
125 BOOST_TEST(!(md
> lg
));
127 BOOST_TEST(md
>= sm
);
128 BOOST_TEST(md
>= md
);
129 BOOST_TEST(!(md
>= lg
));
132 BOOST_TEST(!(lg
== sm
));
133 BOOST_TEST(!(lg
== md
));
134 BOOST_TEST(lg
== lg
);
136 BOOST_TEST(!(lg
< sm
));
137 BOOST_TEST(!(lg
< md
));
138 BOOST_TEST(!(lg
< lg
));
140 BOOST_TEST(!(lg
<= sm
));
141 BOOST_TEST(!(lg
<= md
));
142 BOOST_TEST(lg
<= lg
);
146 BOOST_TEST(!(lg
> lg
));
148 BOOST_TEST(lg
>= sm
);
149 BOOST_TEST(lg
>= md
);
150 BOOST_TEST(lg
>= lg
);
170 arr_type
const v1_copy
= v1
;
171 arr_type
const v2_copy
= v2
;
173 static_assert(std::is_same
<decltype(v1
.swap(v2
)), void>::value
, "");
174 static_assert(std::is_same
<decltype(swap(v1
, v2
)), void>::value
, "");
178 BOOST_TEST(v1
== v2_copy
);
179 BOOST_TEST(v2
== v1_copy
);
196 arr_type
const v1_copy
= v1
;
197 arr_type
const v2_copy
= v2
;
201 BOOST_TEST(v1
== v2_copy
);
202 BOOST_TEST(v2
== v1_copy
);
206 template<typename Iter
>
207 using writable_iter_t
= decltype(
208 *std::declval
<Iter
>() =
209 std::declval
<typename
std::iterator_traits
<Iter
>::value_type
>());
212 !ill_formed
<writable_iter_t
, decltype(std::declval
<arr_type
&>().begin())>::
216 !ill_formed
<writable_iter_t
, decltype(std::declval
<arr_type
&>().end())>::
223 decltype(std::declval
<arr_type
const &>().begin())>::value
,
228 decltype(std::declval
<arr_type
const &>().end())>::value
,
231 ill_formed
<writable_iter_t
, decltype(std::declval
<arr_type
&>().cbegin())>::
235 ill_formed
<writable_iter_t
, decltype(std::declval
<arr_type
&>().cend())>::
242 decltype(std::declval
<arr_type
const &>().rbegin())>::value
,
247 decltype(std::declval
<arr_type
const &>().rend())>::value
,
252 decltype(std::declval
<arr_type
&>().crbegin())>::value
,
255 ill_formed
<writable_iter_t
, decltype(std::declval
<arr_type
&>().crend())>::
259 void test_iterators()
272 std::is_same
<decltype(v
.begin()), arr_type::iterator
>::value
, "");
274 std::is_same
<decltype(v
.end()), arr_type::iterator
>::value
, "");
276 std::is_same
<decltype(v
.cbegin()), arr_type::const_iterator
>::value
,
279 std::is_same
<decltype(v
.cend()), arr_type::const_iterator
>::value
,
282 std::is_same
<decltype(v
.rbegin()), arr_type::reverse_iterator
>::
286 std::is_same
<decltype(v
.rbegin()), arr_type::reverse_iterator
>::
291 decltype(v
.crbegin()),
292 arr_type::const_reverse_iterator
>::value
,
296 decltype(v
.crbegin()),
297 arr_type::const_reverse_iterator
>::value
,
300 std::array
<int, 5> const a
= {{3, 2, 1, 0, 0}};
301 std::array
<int, 5> const ra
= {{0, 0, 1, 2, 3}};
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()));
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()));
322 arr_type
const v
= v0
;
325 std::is_same
<decltype(v
.begin()), arr_type::const_iterator
>::value
,
328 std::is_same
<decltype(v
.end()), arr_type::const_iterator
>::value
,
331 std::is_same
<decltype(v
.cbegin()), arr_type::const_iterator
>::value
,
334 std::is_same
<decltype(v
.cend()), arr_type::const_iterator
>::value
,
338 decltype(v
.rbegin()),
339 arr_type::const_reverse_iterator
>::value
,
343 decltype(v
.rbegin()),
344 arr_type::const_reverse_iterator
>::value
,
348 decltype(v
.crbegin()),
349 arr_type::const_reverse_iterator
>::value
,
353 decltype(v
.crbegin()),
354 arr_type::const_reverse_iterator
>::value
,
357 std::array
<int, 5> const a
= {{3, 2, 1, 0, 0}};
358 std::array
<int, 5> const ra
= {{0, 0, 1, 2, 3}};
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()));
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()));
371 typename ValueType
= typename
Container::value_type
>
372 using lvalue_push_front_t
= decltype(
373 std::declval
<Container
&>().push_front(std::declval
<ValueType
const &>()));
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());
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
, "");
385 using std_deq_int
= std::deque
<int>;
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
, "");
394 typename ValueType
= typename
Container::value_type
>
395 using lvalue_push_back_t
= decltype(
396 std::declval
<Container
&>().push_back(std::declval
<ValueType
const &>()));
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());
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
, "");
408 using std_vec_int
= std::vector
<int>;
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
, "");
415 void test_front_back()
425 static_assert(std::is_same
<decltype(v
.front()), int &>::value
, "");
426 static_assert(std::is_same
<decltype(v
.back()), int &>::value
, "");
430 BOOST_TEST(v
[0] == v
.front());
431 BOOST_TEST(v
[4] == v
.back());
442 arr_type
const v
= v0
;
443 BOOST_TEST(v
.front() == 3);
444 BOOST_TEST(v
.back() == 1);
447 std::is_same
<decltype(v
.front()), int const &>::value
, "");
448 static_assert(std::is_same
<decltype(v
.back()), int const &>::value
, "");
453 void test_cindex_at()
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
);
472 static_assert(std::is_same
<decltype(v
[0]), int &>::value
, "");
473 static_assert(std::is_same
<decltype(v
.at(0)), int &>::value
, "");
477 BOOST_TEST(v
[0] == 8);
478 BOOST_TEST(v
[1] == 9);
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
);
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
, "");
497 template<typename Container
>
498 using resize_t
= decltype(std::declval
<Container
&>().resize(0));
500 static_assert(ill_formed
<resize_t
, arr_type
>::value
, "");
502 static_assert(!ill_formed
<resize_t
, std_vec_int
>::value
, "");
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 &>()));
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
&&>()));
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 &>()));
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>{}));
525 static_assert(ill_formed
<lvalue_insert_t
, arr_type
>::value
, "");
526 static_assert(ill_formed
<rvalue_insert_t
, arr_type
>::value
, "");
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.
532 static_assert(ill_formed
<insert_n_t
, arr_type
>::value
, "");
535 static_assert(ill_formed
<insert_il_t
, arr_type
>::value
, "");
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
, "");
543 template<typename Container
>
544 using erase_t
= decltype(
545 std::declval
<Container
&>().erase(std::declval
<Container
&>().begin()));
547 static_assert(ill_formed
<erase_t
, arr_type
>::value
, "");
549 static_assert(!ill_formed
<erase_t
, std_vec_int
>::value
, "");
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
>
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>{});
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
, "");
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
, "");
574 template<typename Container
>
575 using clear_t
= decltype(std::declval
<Container
&>().clear());
577 static_assert(ill_formed
<clear_t
, arr_type
>::value
, "");
579 static_assert(!ill_formed
<clear_t
, std_vec_int
>::value
, "");
588 return boost::report_errors();