1 | ////////////////////////////////////////////////////////////////////////////// |
2 | // |
3 | // (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost |
4 | // Software License, Version 1.0. (See accompanying file |
5 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6 | // |
7 | // See http://www.boost.org/libs/container for documentation. |
8 | // |
9 | ////////////////////////////////////////////////////////////////////////////// |
10 | |
11 | #include <boost/container/vector.hpp> |
12 | #include <boost/container/deque.hpp> |
13 | #include <boost/container/stable_vector.hpp> |
14 | #include <boost/container/static_vector.hpp> |
15 | #include <boost/container/string.hpp> |
16 | #include <boost/container/list.hpp> |
17 | #include <boost/container/slist.hpp> |
18 | #include <boost/container/map.hpp> |
19 | #include <boost/container/set.hpp> |
20 | #include <boost/container/flat_set.hpp> |
21 | #include <boost/container/flat_map.hpp> |
22 | #include <boost/intrusive/detail/mpl.hpp> |
23 | |
24 | #include <boost/core/lightweight_test.hpp> |
25 | #include <cstring> |
26 | #include <iterator> |
27 | #include <new> |
28 | |
29 | using namespace boost::container; |
30 | |
31 | typedef boost::container::dtl::aligned_storage<sizeof(void*)*4>::type buffer_t; |
32 | |
33 | static buffer_t buffer_0x00; |
34 | static buffer_t buffer_0xFF; |
35 | |
36 | template<class Iterator> |
37 | const Iterator &on_0x00_buffer() |
38 | { |
39 | BOOST_CONTAINER_STATIC_ASSERT(sizeof(buffer_t) >= sizeof(Iterator)); |
40 | return * ::new(std::memset(s: &buffer_0x00, c: 0x00, n: sizeof(buffer_0x00))) Iterator(); |
41 | } |
42 | |
43 | template<class Iterator> |
44 | const Iterator &on_0xFF_buffer() |
45 | { |
46 | BOOST_CONTAINER_STATIC_ASSERT(sizeof(buffer_t) >= sizeof(Iterator)); |
47 | return * ::new(std::memset(s: &buffer_0xFF, c: 0xFF, n: sizeof(buffer_0xFF))) Iterator(); |
48 | } |
49 | |
50 | namespace boost { |
51 | namespace container { |
52 | namespace test { |
53 | |
54 | BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reverse_iterator) |
55 | BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reverse_iterator) |
56 | |
57 | }}} //namespace boost::container::test { |
58 | |
59 | template<class RandomAccessIterator> |
60 | void check_plus_zero_impl(RandomAccessIterator it) |
61 | { |
62 | RandomAccessIterator cpy(it + 0); |
63 | BOOST_TEST(cpy == it); |
64 | } |
65 | |
66 | template<class Container, class Category> |
67 | void check_plus_zero(const Category&) |
68 | {} |
69 | |
70 | template<class Container> |
71 | void check_plus_zero(const std::random_access_iterator_tag&) |
72 | { |
73 | check_plus_zero_impl(typename Container::iterator()); |
74 | check_plus_zero_impl(typename Container::const_iterator()); |
75 | check_plus_zero_impl(typename Container::reverse_iterator()); |
76 | check_plus_zero_impl(typename Container::const_reverse_iterator()); |
77 | Container c; |
78 | check_plus_zero_impl(c.begin()); |
79 | check_plus_zero_impl(c.cbegin()); |
80 | check_plus_zero_impl(c.rbegin()); |
81 | check_plus_zero_impl(c.crbegin()); |
82 | } |
83 | |
84 | template<class Container> |
85 | void check_plus_zero() |
86 | { |
87 | typedef typename Container::iterator iterator; |
88 | typedef typename std::iterator_traits<iterator>::iterator_category category; |
89 | category tag; |
90 | check_plus_zero<Container>(tag); |
91 | } |
92 | |
93 | template<class Container> |
94 | void check_null_iterators() |
95 | { |
96 | typedef typename Container::iterator iterator; |
97 | typedef typename Container::const_iterator const_iterator; |
98 | typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT |
99 | (boost::container::test::, Container |
100 | ,reverse_iterator, iterator) reverse_iterator; |
101 | typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT |
102 | (boost::container::test::, Container |
103 | ,const_reverse_iterator, const_iterator) const_reverse_iterator; |
104 | |
105 | BOOST_TEST(on_0xFF_buffer<iterator>() == on_0x00_buffer<iterator>()); |
106 | BOOST_TEST(on_0xFF_buffer<const_iterator>() == on_0x00_buffer<const_iterator>()); |
107 | BOOST_TEST(on_0xFF_buffer<reverse_iterator>() == on_0x00_buffer<reverse_iterator>()); |
108 | BOOST_TEST(on_0xFF_buffer<const_reverse_iterator>() == on_0x00_buffer<const_reverse_iterator>()); |
109 | } |
110 | |
111 | int main() |
112 | { |
113 | check_null_iterators< vector<int> >(); |
114 | check_plus_zero< vector<int> >(); |
115 | check_null_iterators< deque<int> >(); |
116 | check_plus_zero< deque<int> >(); |
117 | check_null_iterators< stable_vector<int> >(); |
118 | check_plus_zero< stable_vector<int> >(); |
119 | check_null_iterators< static_vector<int, 1> >(); |
120 | check_plus_zero< static_vector<int, 1> >(); |
121 | check_null_iterators< string >(); |
122 | check_plus_zero< string >(); |
123 | check_null_iterators< list<int> >(); |
124 | check_plus_zero< list<int> >(); |
125 | check_null_iterators< slist<int> >(); |
126 | check_plus_zero< slist<int> >(); |
127 | check_null_iterators< map<int, int> >(); |
128 | check_plus_zero< map<int, int> >(); |
129 | check_null_iterators< multimap<int, int> >(); |
130 | check_plus_zero< multimap<int, int> >(); |
131 | check_null_iterators< set<int> >(); |
132 | check_plus_zero< set<int> >(); |
133 | check_null_iterators< multiset<int> >(); |
134 | check_plus_zero< multiset<int> >(); |
135 | check_null_iterators< flat_set<int> >(); |
136 | check_plus_zero< flat_set<int> >(); |
137 | check_null_iterators< flat_multiset<int> >(); |
138 | check_plus_zero< flat_multiset<int> >(); |
139 | check_null_iterators< flat_map<int, int> >(); |
140 | check_plus_zero< flat_map<int, int> >(); |
141 | check_null_iterators< flat_multimap<int, int> >(); |
142 | check_plus_zero< flat_multimap<int, int> >(); |
143 | |
144 | return boost::report_errors(); |
145 | } |
146 | |