]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | |
2 | // (C) Copyright John Maddock 2000. | |
3 | // Use, modification and distribution are subject to the | |
4 | // Boost 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 | #include "test.hpp" | |
8 | #include "check_integral_constant.hpp" | |
9 | #ifdef TEST_STD | |
10 | # include <type_traits> | |
11 | #else | |
12 | # include <boost/type_traits/is_convertible.hpp> | |
13 | #endif | |
14 | #include <boost/utility/enable_if.hpp> | |
15 | ||
16 | ||
17 | template <class T> | |
18 | struct convertible_from | |
19 | { | |
20 | convertible_from(T); | |
21 | }; | |
22 | ||
23 | struct base2 { }; | |
24 | struct middle2 : public virtual base2 { }; | |
25 | struct derived2 : public middle2 { }; | |
26 | ||
27 | #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | |
28 | ||
29 | template<typename T> | |
30 | struct test_bug_4530 | |
31 | { | |
b32b8144 FG |
32 | template<typename A> |
33 | test_bug_4530(A&&, typename boost::enable_if< ::tt::is_convertible<A&&, T> >::type* =0); | |
7c673cae FG |
34 | }; |
35 | ||
36 | struct A4530 | |
37 | { | |
38 | template <class T> | |
39 | A4530(T); | |
40 | }; | |
41 | ||
42 | #endif | |
43 | ||
44 | #ifdef BOOST_MSVC | |
45 | ||
46 | struct bug_5271a | |
47 | { | |
48 | __declspec(align(16)) int value; | |
49 | }; | |
50 | ||
51 | struct bug_5271b | |
52 | { | |
53 | __declspec(align(16)) int value; | |
54 | bug_5271b(int v) : value(v) {} | |
55 | }; | |
56 | ||
57 | #endif | |
58 | ||
59 | #if (defined(BOOST_TT_CXX11_IS_CONVERTIBLE) || defined(BOOST_IS_CONVERTIBLE)) && !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) | |
60 | struct bug9910 | |
61 | { | |
62 | bug9910() = default; | |
63 | bug9910(const bug9910&) = delete; // or private: A(const A&) = default; | |
64 | }; | |
65 | struct Ref_bug9910 | |
66 | { | |
67 | // proxy reference to bug9910 | |
68 | operator bug9910& () { return *_ptr; } | |
69 | bug9910* _ptr; | |
70 | }; | |
71 | #endif | |
72 | ||
73 | TT_TEST_BEGIN(is_convertible) | |
74 | ||
75 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<Derived,Base>::value), true); | |
76 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<Derived,Derived>::value), true); | |
77 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<Base,Base>::value), true); | |
78 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<Base,Derived>::value), false); | |
79 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<Derived,Derived>::value), true); | |
80 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<NonDerived,Base>::value), false); | |
81 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<float,int>::value), true); | |
82 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<virtual_inherit2,virtual_inherit1>::value), true); | |
83 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<VD,VB>::value), true); | |
84 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<polymorphic_derived1,polymorphic_base>::value), true); | |
85 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<polymorphic_derived2,polymorphic_base>::value), true); | |
86 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<polymorphic_base,polymorphic_derived1>::value), false); | |
87 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<polymorphic_base,polymorphic_derived2>::value), false); | |
88 | #ifndef TEST_STD | |
89 | // Ill-formed behaviour, supported by Boost as an extension: | |
90 | #ifndef BOOST_NO_IS_ABSTRACT | |
91 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<test_abc1,test_abc1>::value), false); | |
92 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<Base,test_abc1>::value), false); | |
93 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<polymorphic_derived2,test_abc1>::value), false); | |
94 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int,test_abc1>::value), false); | |
95 | #endif | |
96 | #endif | |
97 | ||
98 | // The following four do not compile without member template support: | |
99 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<float,void>::value), false); | |
100 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<void,void>::value), true); | |
101 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<void,float>::value), false); | |
102 | ||
103 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<enum1, int>::value), true); | |
104 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<Derived*, Base*>::value), true); | |
105 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<Base*, Derived*>::value), false); | |
106 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<Derived&, Base&>::value), true); | |
107 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<Base&, Derived&>::value), false); | |
108 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<const Derived*, const Base*>::value), true); | |
109 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<const Base*, const Derived*>::value), false); | |
110 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<const Derived&, const Base&>::value), true); | |
111 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<const Base&, const Derived&>::value), false); | |
112 | ||
113 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<const int *, int*>::value), false); | |
114 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<const int&, int&>::value), false); | |
115 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<const int*, int[3]>::value), false); | |
116 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<const int&, int>::value), true); | |
117 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES | |
118 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<const int&&, int>::value), true); | |
119 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int&&, const int&>::value), true); | |
120 | #if !defined(__GNUC__) || ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 6))) | |
121 | // Machinary required to support this, not available prior to gcc-4.7.0: | |
122 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int, int&>::value), false); | |
123 | #endif | |
124 | #endif | |
125 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int(&)[4], const int*>::value), true); | |
126 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int(&)(int), int(*)(int)>::value), true); | |
127 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int *, const int*>::value), true); | |
128 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int&, const int&>::value), true); | |
129 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int[2], int*>::value), true); | |
130 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int[2], const int*>::value), true); | |
131 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<const int[2], int*>::value), false); | |
132 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int*, int[3]>::value), false); | |
133 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<test_abc3, const test_abc1&>::value), true); | |
134 | ||
135 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<non_pointer, void*>::value), true); | |
136 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<non_pointer, int*>::value), false); | |
137 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<non_int_pointer, int*>::value), true); | |
138 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<non_int_pointer, void*>::value), true); | |
139 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<test_abc1&, test_abc2&>::value), false); | |
140 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<test_abc1&, int_constructible>::value), false); | |
141 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int_constructible, test_abc1&>::value), false); | |
142 | #if !defined(BOOST_NO_IS_ABSTRACT) && !(defined(__hppa) && defined(__HP_aCC)) | |
143 | // | |
144 | // This doesn't work with aCC on PA RISC even though the is_abstract tests do | |
145 | // all pass, this may indicate a deeper problem... | |
146 | // | |
147 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<test_abc1&, test_abc2>::value), false); | |
148 | #endif | |
149 | ||
150 | // | |
151 | // the following tests all involve user defined conversions which do | |
152 | // not compile with Borland C++ Builder 5: | |
153 | // | |
154 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int, int_constructible>::value), true); | |
155 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<float,convertible_from<float> >::value), true); | |
156 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<float,convertible_from<float const&> >::value), true); | |
157 | // | |
158 | // These two tests give different results with different compilers, we used to require *true* results | |
159 | // from these, but C++0x behaviour requires *false*: | |
160 | // | |
161 | //BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<float,convertible_from<float&> >::value), false); | |
162 | //BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<char,convertible_from<char&> >::value), false); | |
163 | ||
164 | #if !(defined(__GNUC__) && (__GNUC__ < 4)) | |
165 | // GCC 3.x emits warnings here, which causes the tests to fail when we compile with warnings-as-errors: | |
166 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<float,convertible_from<char> >::value), true); | |
167 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<float,convertible_from<char const&> >::value), true); | |
168 | #endif | |
169 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<float,convertible_from<char&> >::value), false); | |
170 | ||
171 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<char,convertible_from<char> >::value), true); | |
172 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<char,convertible_from<char const&> >::value), true); | |
173 | ||
174 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<float&,convertible_from<float> >::value), true); | |
175 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<float const&,convertible_from<float> >::value), true); | |
176 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<float&,convertible_from<float&> >::value), true); | |
177 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<float const&,convertible_from<float const&> >::value), true); | |
178 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<float&,convertible_from<float const&> >::value), true); | |
179 | ||
180 | // | |
181 | // the following all generate warnings unless we can find a way to | |
182 | // suppress them: | |
183 | // | |
184 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<float,int>::value), true); | |
185 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<double,int>::value), true); | |
186 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<double,float>::value), true); | |
187 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<long,int>::value), true); | |
188 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int,char>::value), true); | |
189 | #ifdef BOOST_HAS_LONG_LONG | |
190 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<boost::long_long_type,int>::value), true); | |
191 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<boost::long_long_type,char>::value), true); | |
192 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<boost::long_long_type,float>::value), true); | |
193 | #elif defined(BOOST_HAS_MS_INT64) | |
194 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<__int64,int>::value), true); | |
195 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<__int64,char>::value), true); | |
196 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<__int64,float>::value), true); | |
197 | #endif | |
198 | ||
199 | #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES | |
200 | // Test bug case 4530: | |
201 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<test_bug_4530<A4530>,A4530>::value), true); | |
202 | #endif | |
203 | ||
204 | #if defined(BOOST_MSVC) && (BOOST_MSVC > 1310) | |
205 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int, bug_5271a>::value), false); | |
206 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int, bug_5271b>::value), true); | |
207 | #endif | |
208 | ||
209 | #if (defined(BOOST_TT_CXX11_IS_CONVERTIBLE) || defined(BOOST_IS_CONVERTIBLE)) && !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) | |
210 | #ifndef _MSC_VER | |
211 | // MSVC gives the wrong answer here, see https://connect.microsoft.com/VisualStudio/feedback/details/858956/std-is-convertible-returns-incorrect-value | |
212 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<Ref_bug9910, bug9910>::value), false); | |
213 | #endif | |
214 | // From https://svn.boost.org/trac/boost/ticket/9910#comment:2: | |
215 | BOOST_CHECK_INTEGRAL_CONSTANT((::tt::is_convertible<int, incomplete_type[]>::value), false); | |
216 | #endif | |
217 | ||
218 | TT_TEST_END | |
219 |