1//
2// immer: immutable data structures for C++
3// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente
4//
5// This software is distributed under the Boost Software License, Version 1.0.
6// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt
7//
8
9#include <immer/detail/type_traits.hpp>
10#include <forward_list>
11#include <list>
12#include <vector>
13#include <catch.hpp>
14
15struct string_sentinel {};
16bool operator==(const char* i, string_sentinel);
17bool operator!=(const char* i, string_sentinel);
18
19TEST_CASE("compatible_sentinel_v")
20{
21 SECTION("iterator pairs")
22 {
23 using Iter = std::vector<int>::iterator;
24 static_assert(immer::detail::compatible_sentinel_v<Iter, Iter>, "");
25 }
26
27 SECTION("pointer pairs")
28 {
29 using Iter = char*;
30 static_assert(immer::detail::compatible_sentinel_v<Iter, Iter>, "");
31 }
32
33 SECTION("iterator/sentinel pair")
34 {
35 using Iter = char*;
36 using Sent = string_sentinel;
37 static_assert(immer::detail::compatible_sentinel_v<Iter, Sent>, "");
38 }
39
40 SECTION("incompatible pair")
41 {
42 using Iter1 = std::vector<int>::iterator;
43 using Iter2 = std::list<double>::iterator;
44 static_assert(not immer::detail::compatible_sentinel_v<Iter1, Iter2>, "");
45 }
46}
47
48TEST_CASE("equality comparable")
49{
50 SECTION("iterator pairs")
51 {
52 using Iter = std::vector<int>::iterator;
53 static_assert(immer::detail::is_equality_comparable_v<Iter, Iter>, "");
54 }
55
56 SECTION("pointer pairs")
57 {
58 using Iter = char*;
59 static_assert(immer::detail::is_equality_comparable_v<Iter, Iter>, "");
60 }
61
62 SECTION("iterator/sentinel pair")
63 {
64 using Iter = char*;
65 using Sent = string_sentinel;
66 static_assert(immer::detail::is_equality_comparable_v<Iter, Sent>, "");
67 }
68
69 SECTION("not equality comparable")
70 {
71 static_assert(not immer::detail::is_equality_comparable_v<std::string, double>, "");
72 }
73}
74
75TEST_CASE("inequality comparable")
76{
77 SECTION("iterator pairs")
78 {
79 using Iter = std::vector<int>::iterator;
80 static_assert(immer::detail::is_inequality_comparable_v<Iter, Iter>, "");
81 }
82
83 SECTION("pointer pairs")
84 {
85 using Iter = char*;
86 static_assert(immer::detail::is_inequality_comparable_v<Iter, Iter>, "");
87 }
88
89 SECTION("iterator/sentinel pair")
90 {
91 using Iter = char*;
92 using Sent = string_sentinel;
93 static_assert(immer::detail::is_inequality_comparable_v<Iter, Sent>, "");
94 }
95
96 SECTION("not inequality comparable")
97 {
98 static_assert(not immer::detail::is_inequality_comparable_v<std::string, double>, "");
99 }
100}
101
102TEST_CASE("is dereferenceable")
103{
104 SECTION("iterator")
105 {
106 using Iter = std::vector<int>::iterator;
107 static_assert(immer::detail::is_dereferenceable_v<Iter>, "");
108 }
109
110 SECTION("pointer")
111 {
112 using Iter = char*;
113 static_assert(immer::detail::is_dereferenceable_v<Iter>, "");
114 }
115
116 SECTION("not dereferenceable")
117 {
118 static_assert(not immer::detail::is_dereferenceable_v<int>, "");
119 }
120}
121
122TEST_CASE("is forward iterator")
123{
124 SECTION("random access iterator")
125 {
126 using Iter = std::vector<int>::iterator;
127 static_assert(immer::detail::is_forward_iterator_v<Iter>, "");
128 }
129
130 SECTION("bidirectional iterator")
131 {
132 using Iter = std::list<int>::iterator;
133 static_assert(immer::detail::is_forward_iterator_v<Iter>, "");
134 }
135
136 SECTION("forward iterator")
137 {
138 using Iter = std::forward_list<int>::iterator;
139 static_assert(immer::detail::is_forward_iterator_v<Iter>, "");
140 }
141
142 SECTION("input iterator")
143 {
144 using Iter = std::istream_iterator<double>;
145 static_assert(not immer::detail::is_forward_iterator_v<Iter>, "");
146 }
147
148 SECTION("output iterator")
149 {
150 using Iter = std::ostream_iterator<double>;
151 static_assert(not immer::detail::is_forward_iterator_v<Iter>, "");
152 }
153
154 SECTION("pointer")
155 {
156 using Iter = char*;
157 static_assert(immer::detail::is_forward_iterator_v<Iter>, "");
158 }
159}
160
161TEST_CASE("is iterator")
162{
163 SECTION("iterator")
164 {
165 using Iter = std::vector<int>::iterator;
166 static_assert(immer::detail::is_iterator_v<Iter>, "");
167 }
168
169 SECTION("pointer")
170 {
171 using Iter = char*;
172 static_assert(immer::detail::is_iterator_v<Iter>, "");
173 }
174
175 SECTION("not iterator")
176 {
177 static_assert(not immer::detail::is_iterator_v<int>, "");
178 }
179}
180
181TEST_CASE("provides preincrement")
182{
183 SECTION("iterator")
184 {
185 using Iter = std::vector<int>::iterator;
186 static_assert(immer::detail::is_preincrementable_v<Iter>, "");
187 }
188
189 SECTION("pointer")
190 {
191 using Iter = char*;
192 static_assert(immer::detail::is_preincrementable_v<Iter>, "");
193 }
194
195 SECTION("does not provide preincrement")
196 {
197 struct type{};
198 static_assert(not immer::detail::is_preincrementable_v<type>, "");
199 }
200}
201
202TEST_CASE("void_t")
203{
204 static_assert(std::is_same<void, immer::detail::void_t<int>>::value, "");
205}
206