1 /* Copyright 2017-2018 Fizyr B.V. - https://fizyr.com
2  *
3  * Redistribution and use in source and binary forms, with or without modification,
4  * are permitted provided that the following conditions are met:
5  *
6  * 1. Redistributions of source code must retain the above copyright notice,
7  *    this list of conditions and the following disclaimer.
8  *
9  * 2. Redistributions in binary form must reproduce the above copyright notice,
10  *    this list of conditions and the following disclaimer in the documentation
11  *    and/or other materials provided with the distribution.
12  *
13  * 3. Neither the name of the copyright holder nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software without
15  *    specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "traits/iterator.hpp"
30 
31 #include <iterator>
32 #include <list>
33 #include <string>
34 #include <vector>
35 
36 namespace estd {
37 
38 // minimal_iterator_tag
39 static_assert(std::is_same_v<std::input_iterator_tag,         minimal_iterator_tag<std::input_iterator_tag>>);
40 static_assert(std::is_same_v<std::output_iterator_tag,        minimal_iterator_tag<std::output_iterator_tag>>);
41 static_assert(std::is_same_v<std::forward_iterator_tag,       minimal_iterator_tag<std::forward_iterator_tag>>);
42 static_assert(std::is_same_v<std::bidirectional_iterator_tag, minimal_iterator_tag<std::bidirectional_iterator_tag>>);
43 static_assert(std::is_same_v<std::random_access_iterator_tag, minimal_iterator_tag<std::random_access_iterator_tag>>);
44 
45 static_assert(std::is_same_v<std::input_iterator_tag, minimal_iterator_tag<
46 	std::random_access_iterator_tag,
47 	std::bidirectional_iterator_tag,
48 	std::input_iterator_tag
49 >>);
50 
51 static_assert(std::is_same_v<std::input_iterator_tag, minimal_iterator_tag<
52 	std::input_iterator_tag,
53 	std::forward_iterator_tag
54 >>);
55 
56 static_assert(std::is_same_v<std::output_iterator_tag, minimal_iterator_tag<
57 	std::output_iterator_tag,
58 	std::forward_iterator_tag
59 >>);
60 
61 static_assert(std::is_same_v<std::forward_iterator_tag, minimal_iterator_tag<
62 	std::forward_iterator_tag,
63 	std::bidirectional_iterator_tag
64 >>);
65 
66 static_assert(std::is_same_v<std::bidirectional_iterator_tag, minimal_iterator_tag<
67 	std::bidirectional_iterator_tag,
68 	std::random_access_iterator_tag
69 >>);
70 
71 static_assert(std::is_same_v<std::output_iterator_tag, minimal_iterator_tag<
72 	std::random_access_iterator_tag,
73 	std::forward_iterator_tag,
74 	std::output_iterator_tag
75 >>);
76 
77 static_assert(std::is_same_v<std::forward_iterator_tag, minimal_iterator_tag<
78 	std::bidirectional_iterator_tag,
79 	std::forward_iterator_tag,
80 	std::random_access_iterator_tag
81 >>);
82 
83 static_assert(std::is_same_v<std::random_access_iterator_tag, minimal_iterator_category<std::vector<int>::iterator>>);
84 static_assert(std::is_same_v<std::bidirectional_iterator_tag, minimal_iterator_category<std::list<int>::iterator>>);
85 static_assert(std::is_same_v<std::bidirectional_iterator_tag, minimal_iterator_category<std::vector<int>::iterator, std::list<int>::iterator>>);
86 static_assert(std::is_same_v<std::output_iterator_tag,        minimal_iterator_category<std::back_insert_iterator<std::vector<int>>>>);
87 static_assert(std::is_same_v<std::input_iterator_tag,         minimal_iterator_category<std::istreambuf_iterator<char>>>);
88 
89 /// minimun_iterator_tag for tuples of iterators
90 static_assert(std::is_same_v<std::input_iterator_tag,         minimal_iterator_tag<std::tuple<std::input_iterator_tag>>>);
91 static_assert(std::is_same_v<std::output_iterator_tag,        minimal_iterator_tag<std::tuple<std::output_iterator_tag>>>);
92 static_assert(std::is_same_v<std::forward_iterator_tag,       minimal_iterator_tag<std::tuple<std::forward_iterator_tag>>>);
93 static_assert(std::is_same_v<std::bidirectional_iterator_tag, minimal_iterator_tag<std::tuple<std::bidirectional_iterator_tag>>>);
94 static_assert(std::is_same_v<std::random_access_iterator_tag, minimal_iterator_tag<std::tuple<std::random_access_iterator_tag>>>);
95 
96 static_assert(std::is_same_v<std::forward_iterator_tag, minimal_iterator_tag<std::tuple<
97 	std::bidirectional_iterator_tag,
98 	std::forward_iterator_tag,
99 	std::random_access_iterator_tag
100 >>>);
101 
102 static_assert(std::is_same_v<std::random_access_iterator_tag, minimal_iterator_category<std::tuple<std::vector<int>::iterator>>>);
103 static_assert(std::is_same_v<std::bidirectional_iterator_tag, minimal_iterator_category<std::tuple<std::list<int>::iterator>>>);
104 static_assert(std::is_same_v<std::bidirectional_iterator_tag, minimal_iterator_category<std::tuple<std::vector<int>::iterator, std::list<int>::iterator>>>);
105 static_assert(std::is_same_v<std::output_iterator_tag,        minimal_iterator_category<std::tuple<std::back_insert_iterator<std::vector<int>>>>>);
106 static_assert(std::is_same_v<std::input_iterator_tag,         minimal_iterator_category<std::tuple<std::istreambuf_iterator<char>>>>);
107 
108 // is_iterator_tag_atleast
109 static_assert(is_iterator_tag_atleast<std::input_iterator_tag,         std::input_iterator_tag>);
110 static_assert(is_iterator_tag_atleast<std::output_iterator_tag,        std::input_iterator_tag>);
111 static_assert(is_iterator_tag_atleast<std::forward_iterator_tag,       std::input_iterator_tag>);
112 static_assert(is_iterator_tag_atleast<std::bidirectional_iterator_tag, std::input_iterator_tag>);
113 static_assert(is_iterator_tag_atleast<std::random_access_iterator_tag, std::input_iterator_tag>);
114 
115 static_assert(is_iterator_tag_atleast<std::input_iterator_tag,         std::output_iterator_tag>);
116 static_assert(is_iterator_tag_atleast<std::output_iterator_tag,        std::output_iterator_tag>);
117 static_assert(is_iterator_tag_atleast<std::forward_iterator_tag,       std::output_iterator_tag>);
118 static_assert(is_iterator_tag_atleast<std::bidirectional_iterator_tag, std::output_iterator_tag>);
119 static_assert(is_iterator_tag_atleast<std::random_access_iterator_tag, std::output_iterator_tag>);
120 
121 static_assert(is_iterator_tag_atleast<std::input_iterator_tag,         std::forward_iterator_tag> == false);
122 static_assert(is_iterator_tag_atleast<std::output_iterator_tag,        std::forward_iterator_tag> == false);
123 static_assert(is_iterator_tag_atleast<std::forward_iterator_tag,       std::forward_iterator_tag>);
124 static_assert(is_iterator_tag_atleast<std::bidirectional_iterator_tag, std::forward_iterator_tag>);
125 static_assert(is_iterator_tag_atleast<std::random_access_iterator_tag, std::forward_iterator_tag>);
126 
127 static_assert(is_iterator_tag_atleast<std::input_iterator_tag,         std::bidirectional_iterator_tag> == false);
128 static_assert(is_iterator_tag_atleast<std::output_iterator_tag,        std::bidirectional_iterator_tag> == false);
129 static_assert(is_iterator_tag_atleast<std::forward_iterator_tag,       std::bidirectional_iterator_tag> == false);
130 static_assert(is_iterator_tag_atleast<std::bidirectional_iterator_tag, std::bidirectional_iterator_tag>);
131 static_assert(is_iterator_tag_atleast<std::random_access_iterator_tag, std::bidirectional_iterator_tag>);
132 
133 static_assert(is_iterator_tag_atleast<std::input_iterator_tag,         std::random_access_iterator_tag> == false);
134 static_assert(is_iterator_tag_atleast<std::output_iterator_tag,        std::random_access_iterator_tag> == false);
135 static_assert(is_iterator_tag_atleast<std::forward_iterator_tag,       std::random_access_iterator_tag> == false);
136 static_assert(is_iterator_tag_atleast<std::bidirectional_iterator_tag, std::random_access_iterator_tag> == false);
137 static_assert(is_iterator_tag_atleast<std::random_access_iterator_tag, std::random_access_iterator_tag>);
138 
139 // is_iterator_atleast
140 static_assert(is_iterator_atleast<std::vector<int>::iterator, std::input_iterator_tag>);
141 static_assert(is_iterator_atleast<std::vector<int>::iterator, std::output_iterator_tag>);
142 static_assert(is_iterator_atleast<std::vector<int>::iterator, std::forward_iterator_tag>);
143 static_assert(is_iterator_atleast<std::vector<int>::iterator, std::bidirectional_iterator_tag>);
144 static_assert(is_iterator_atleast<std::vector<int>::iterator, std::random_access_iterator_tag>);
145 
146 static_assert(is_iterator_atleast<std::list<int>::iterator, std::input_iterator_tag>);
147 static_assert(is_iterator_atleast<std::list<int>::iterator, std::output_iterator_tag>);
148 static_assert(is_iterator_atleast<std::list<int>::iterator, std::forward_iterator_tag>);
149 static_assert(is_iterator_atleast<std::list<int>::iterator, std::bidirectional_iterator_tag>);
150 static_assert(is_iterator_atleast<std::list<int>::iterator, std::random_access_iterator_tag> == false);
151 
152 static_assert(is_iterator_atleast<std::back_insert_iterator<std::vector<int>>, std::input_iterator_tag>);
153 static_assert(is_iterator_atleast<std::back_insert_iterator<std::vector<int>>, std::output_iterator_tag>);
154 static_assert(is_iterator_atleast<std::back_insert_iterator<std::vector<int>>, std::forward_iterator_tag>       == false);
155 static_assert(is_iterator_atleast<std::back_insert_iterator<std::vector<int>>, std::bidirectional_iterator_tag> == false);
156 static_assert(is_iterator_atleast<std::back_insert_iterator<std::vector<int>>, std::random_access_iterator_tag> == false);
157 
158 static_assert(is_iterator_atleast<std::istreambuf_iterator<char>, std::input_iterator_tag>);
159 static_assert(is_iterator_atleast<std::istreambuf_iterator<char>, std::output_iterator_tag>);
160 static_assert(is_iterator_atleast<std::istreambuf_iterator<char>, std::forward_iterator_tag>       == false);
161 static_assert(is_iterator_atleast<std::istreambuf_iterator<char>, std::bidirectional_iterator_tag> == false);
162 static_assert(is_iterator_atleast<std::istreambuf_iterator<char>, std::random_access_iterator_tag> == false);
163 
164 }
165