| 1 | // boost::compressed_pair test program |
|---|
| 2 | |
|---|
| 3 | // (C) Copyright John Maddock 2000. |
|---|
| 4 | // Use, modification and distribution are subject to the Boost Software License, |
|---|
| 5 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
|---|
| 6 | // http://www.boost.org/LICENSE_1_0.txt). |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | // standalone test program for <boost/call_traits.hpp> |
|---|
| 10 | // 18 Mar 2002: |
|---|
| 11 | // Changed some names to prevent conflicts with some new type_traits additions. |
|---|
| 12 | // 03 Oct 2000: |
|---|
| 13 | // Enabled extra tests for VC6. |
|---|
| 14 | |
|---|
| 15 | #include <iostream> |
|---|
| 16 | #include <iomanip> |
|---|
| 17 | #include <algorithm> |
|---|
| 18 | #include <typeinfo> |
|---|
| 19 | #include <boost/call_traits.hpp> |
|---|
| 20 | |
|---|
| 21 | #include <libs/type_traits/test/test.hpp> |
|---|
| 22 | #include <libs/type_traits/test/check_type.hpp> |
|---|
| 23 | |
|---|
| 24 | // a way prevent warnings for unused variables |
|---|
| 25 | template<class T> inline void unused_variable(const T&) {} |
|---|
| 26 | |
|---|
| 27 | // |
|---|
| 28 | // struct contained models a type that contains a type (for example std::pair) |
|---|
| 29 | // arrays are contained by value, and have to be treated as a special case: |
|---|
| 30 | // |
|---|
| 31 | template <class T> |
|---|
| 32 | struct contained |
|---|
| 33 | { |
|---|
| 34 | // define our typedefs first, arrays are stored by value |
|---|
| 35 | // so value_type is not the same as result_type: |
|---|
| 36 | typedef typename boost::call_traits<T>::param_type param_type; |
|---|
| 37 | typedef typename boost::call_traits<T>::reference reference; |
|---|
| 38 | typedef typename boost::call_traits<T>::const_reference const_reference; |
|---|
| 39 | typedef T value_type; |
|---|
| 40 | typedef typename boost::call_traits<T>::value_type result_type; |
|---|
| 41 | |
|---|
| 42 | // stored value: |
|---|
| 43 | value_type v_; |
|---|
| 44 | |
|---|
| 45 | // constructors: |
|---|
| 46 | contained() {} |
|---|
| 47 | contained(param_type p) : v_(p){} |
|---|
| 48 | // return byval: |
|---|
| 49 | result_type value()const { return v_; } |
|---|
| 50 | // return by_ref: |
|---|
| 51 | reference get() { return v_; } |
|---|
| 52 | const_reference const_get()const { return v_; } |
|---|
| 53 | // pass value: |
|---|
| 54 | void call(param_type){} |
|---|
| 55 | |
|---|
| 56 | }; |
|---|
| 57 | |
|---|
| 58 | #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
|---|
| 59 | template <class T, std::size_t N> |
|---|
| 60 | struct contained<T[N]> |
|---|
| 61 | { |
|---|
| 62 | typedef typename boost::call_traits<T[N]>::param_type param_type; |
|---|
| 63 | typedef typename boost::call_traits<T[N]>::reference reference; |
|---|
| 64 | typedef typename boost::call_traits<T[N]>::const_reference const_reference; |
|---|
| 65 | typedef T value_type[N]; |
|---|
| 66 | typedef typename boost::call_traits<T[N]>::value_type result_type; |
|---|
| 67 | |
|---|
| 68 | value_type v_; |
|---|
| 69 | |
|---|
| 70 | contained(param_type p) |
|---|
| 71 | { |
|---|
| 72 | std::copy(p, p+N, v_); |
|---|
| 73 | } |
|---|
| 74 | // return byval: |
|---|
| 75 | result_type value()const { return v_; } |
|---|
| 76 | // return by_ref: |
|---|
| 77 | reference get() { return v_; } |
|---|
| 78 | const_reference const_get()const { return v_; } |
|---|
| 79 | void call(param_type){} |
|---|
| 80 | }; |
|---|
| 81 | #endif |
|---|
| 82 | |
|---|
| 83 | template <class T> |
|---|
| 84 | contained<typename boost::call_traits<T>::value_type> test_wrap_type(const T& t) |
|---|
| 85 | { |
|---|
| 86 | typedef typename boost::call_traits<T>::value_type ct; |
|---|
| 87 | return contained<ct>(t); |
|---|
| 88 | } |
|---|
| 89 | |
|---|
| 90 | namespace test{ |
|---|
| 91 | |
|---|
| 92 | template <class T1, class T2> |
|---|
| 93 | std::pair< |
|---|
| 94 | typename boost::call_traits<T1>::value_type, |
|---|
| 95 | typename boost::call_traits<T2>::value_type> |
|---|
| 96 | make_pair(const T1& t1, const T2& t2) |
|---|
| 97 | { |
|---|
| 98 | return std::pair< |
|---|
| 99 | typename boost::call_traits<T1>::value_type, |
|---|
| 100 | typename boost::call_traits<T2>::value_type>(t1, t2); |
|---|
| 101 | } |
|---|
| 102 | |
|---|
| 103 | } // namespace test |
|---|
| 104 | |
|---|
| 105 | using namespace std; |
|---|
| 106 | |
|---|
| 107 | // |
|---|
| 108 | // struct call_traits_checker: |
|---|
| 109 | // verifies behaviour of contained example: |
|---|
| 110 | // |
|---|
| 111 | template <class T> |
|---|
| 112 | struct call_traits_checker |
|---|
| 113 | { |
|---|
| 114 | typedef typename boost::call_traits<T>::param_type param_type; |
|---|
| 115 | void operator()(param_type); |
|---|
| 116 | }; |
|---|
| 117 | |
|---|
| 118 | template <class T> |
|---|
| 119 | void call_traits_checker<T>::operator()(param_type p) |
|---|
| 120 | { |
|---|
| 121 | T t(p); |
|---|
| 122 | contained<T> c(t); |
|---|
| 123 | cout << "checking contained<" << typeid(T).name() << ">..." << endl; |
|---|
| 124 | BOOST_CHECK(t == c.value()); |
|---|
| 125 | BOOST_CHECK(t == c.get()); |
|---|
| 126 | BOOST_CHECK(t == c.const_get()); |
|---|
| 127 | #ifndef __ICL |
|---|
| 128 | //cout << "typeof contained<" << typeid(T).name() << ">::v_ is: " << typeid(&contained<T>::v_).name() << endl; |
|---|
| 129 | cout << "typeof contained<" << typeid(T).name() << ">::value() is: " << typeid(&contained<T>::value).name() << endl; |
|---|
| 130 | cout << "typeof contained<" << typeid(T).name() << ">::get() is: " << typeid(&contained<T>::get).name() << endl; |
|---|
| 131 | cout << "typeof contained<" << typeid(T).name() << ">::const_get() is: " << typeid(&contained<T>::const_get).name() << endl; |
|---|
| 132 | cout << "typeof contained<" << typeid(T).name() << ">::call() is: " << typeid(&contained<T>::call).name() << endl; |
|---|
| 133 | cout << endl; |
|---|
| 134 | #endif |
|---|
| 135 | } |
|---|
| 136 | |
|---|
| 137 | #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
|---|
| 138 | template <class T, std::size_t N> |
|---|
| 139 | struct call_traits_checker<T[N]> |
|---|
| 140 | { |
|---|
| 141 | typedef typename boost::call_traits<T[N]>::param_type param_type; |
|---|
| 142 | void operator()(param_type t) |
|---|
| 143 | { |
|---|
| 144 | contained<T[N]> c(t); |
|---|
| 145 | cout << "checking contained<" << typeid(T[N]).name() << ">..." << endl; |
|---|
| 146 | unsigned int i = 0; |
|---|
| 147 | for(i = 0; i < N; ++i) |
|---|
| 148 | BOOST_CHECK(t[i] == c.value()[i]); |
|---|
| 149 | for(i = 0; i < N; ++i) |
|---|
| 150 | BOOST_CHECK(t[i] == c.get()[i]); |
|---|
| 151 | for(i = 0; i < N; ++i) |
|---|
| 152 | BOOST_CHECK(t[i] == c.const_get()[i]); |
|---|
| 153 | |
|---|
| 154 | cout << "typeof contained<" << typeid(T[N]).name() << ">::v_ is: " << typeid(&contained<T[N]>::v_).name() << endl; |
|---|
| 155 | cout << "typeof contained<" << typeid(T[N]).name() << ">::value is: " << typeid(&contained<T[N]>::value).name() << endl; |
|---|
| 156 | cout << "typeof contained<" << typeid(T[N]).name() << ">::get is: " << typeid(&contained<T[N]>::get).name() << endl; |
|---|
| 157 | cout << "typeof contained<" << typeid(T[N]).name() << ">::const_get is: " << typeid(&contained<T[N]>::const_get).name() << endl; |
|---|
| 158 | cout << "typeof contained<" << typeid(T[N]).name() << ">::call is: " << typeid(&contained<T[N]>::call).name() << endl; |
|---|
| 159 | cout << endl; |
|---|
| 160 | } |
|---|
| 161 | }; |
|---|
| 162 | #endif |
|---|
| 163 | |
|---|
| 164 | // |
|---|
| 165 | // check_wrap: |
|---|
| 166 | template <class W, class U> |
|---|
| 167 | void check_wrap(const W& w, const U& u) |
|---|
| 168 | { |
|---|
| 169 | cout << "checking " << typeid(W).name() << "..." << endl; |
|---|
| 170 | BOOST_CHECK(w.value() == u); |
|---|
| 171 | } |
|---|
| 172 | |
|---|
| 173 | // |
|---|
| 174 | // check_make_pair: |
|---|
| 175 | // verifies behaviour of "make_pair": |
|---|
| 176 | // |
|---|
| 177 | template <class T, class U, class V> |
|---|
| 178 | void check_make_pair(T c, U u, V v) |
|---|
| 179 | { |
|---|
| 180 | cout << "checking std::pair<" << typeid(c.first).name() << ", " << typeid(c.second).name() << ">..." << endl; |
|---|
| 181 | BOOST_CHECK(c.first == u); |
|---|
| 182 | BOOST_CHECK(c.second == v); |
|---|
| 183 | cout << endl; |
|---|
| 184 | } |
|---|
| 185 | |
|---|
| 186 | |
|---|
| 187 | struct comparible_UDT |
|---|
| 188 | { |
|---|
| 189 | int i_; |
|---|
| 190 | comparible_UDT() : i_(2){} |
|---|
| 191 | comparible_UDT(const comparible_UDT& other) : i_(other.i_){} |
|---|
| 192 | comparible_UDT& operator=(const comparible_UDT& other) |
|---|
| 193 | { |
|---|
| 194 | i_ = other.i_; |
|---|
| 195 | return *this; |
|---|
| 196 | } |
|---|
| 197 | bool operator == (const comparible_UDT& v){ return v.i_ == i_; } |
|---|
| 198 | }; |
|---|
| 199 | |
|---|
| 200 | int main(int argc, char *argv[ ]) |
|---|
| 201 | { |
|---|
| 202 | call_traits_checker<comparible_UDT> c1; |
|---|
| 203 | comparible_UDT u; |
|---|
| 204 | c1(u); |
|---|
| 205 | call_traits_checker<int> c2; |
|---|
| 206 | int i = 2; |
|---|
| 207 | c2(i); |
|---|
| 208 | int* pi = &i; |
|---|
| 209 | int a[2] = {1,2}; |
|---|
| 210 | #if defined(BOOST_MSVC6_MEMBER_TEMPLATES) && !defined(__ICL) |
|---|
| 211 | call_traits_checker<int*> c3; |
|---|
| 212 | c3(pi); |
|---|
| 213 | call_traits_checker<int&> c4; |
|---|
| 214 | c4(i); |
|---|
| 215 | call_traits_checker<const int&> c5; |
|---|
| 216 | c5(i); |
|---|
| 217 | #if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__MWERKS__) && !defined(__SUNPRO_CC) |
|---|
| 218 | call_traits_checker<int[2]> c6; |
|---|
| 219 | c6(a); |
|---|
| 220 | #endif |
|---|
| 221 | #endif |
|---|
| 222 | |
|---|
| 223 | check_wrap(test_wrap_type(2), 2); |
|---|
| 224 | #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC) |
|---|
| 225 | check_wrap(test_wrap_type(a), a); |
|---|
| 226 | check_make_pair(test::make_pair(a, a), a, a); |
|---|
| 227 | #endif |
|---|
| 228 | |
|---|
| 229 | // cv-qualifiers applied to reference types should have no effect |
|---|
| 230 | // declare these here for later use with is_reference and remove_reference: |
|---|
| 231 | typedef int& r_type; |
|---|
| 232 | typedef const r_type cr_type; |
|---|
| 233 | |
|---|
| 234 | BOOST_CHECK_TYPE(comparible_UDT, boost::call_traits<comparible_UDT>::value_type); |
|---|
| 235 | BOOST_CHECK_TYPE(comparible_UDT&, boost::call_traits<comparible_UDT>::reference); |
|---|
| 236 | BOOST_CHECK_TYPE(const comparible_UDT&, boost::call_traits<comparible_UDT>::const_reference); |
|---|
| 237 | BOOST_CHECK_TYPE(const comparible_UDT&, boost::call_traits<comparible_UDT>::param_type); |
|---|
| 238 | BOOST_CHECK_TYPE(int, boost::call_traits<int>::value_type); |
|---|
| 239 | BOOST_CHECK_TYPE(int&, boost::call_traits<int>::reference); |
|---|
| 240 | BOOST_CHECK_TYPE(const int&, boost::call_traits<int>::const_reference); |
|---|
| 241 | BOOST_CHECK_TYPE(const int, boost::call_traits<int>::param_type); |
|---|
| 242 | BOOST_CHECK_TYPE(int*, boost::call_traits<int*>::value_type); |
|---|
| 243 | BOOST_CHECK_TYPE(int*&, boost::call_traits<int*>::reference); |
|---|
| 244 | BOOST_CHECK_TYPE(int*const&, boost::call_traits<int*>::const_reference); |
|---|
| 245 | BOOST_CHECK_TYPE(int*const, boost::call_traits<int*>::param_type); |
|---|
| 246 | #if defined(BOOST_MSVC6_MEMBER_TEMPLATES) |
|---|
| 247 | BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::value_type); |
|---|
| 248 | BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::reference); |
|---|
| 249 | BOOST_CHECK_TYPE(const int&, boost::call_traits<int&>::const_reference); |
|---|
| 250 | BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::param_type); |
|---|
| 251 | #if !(defined(__GNUC__) && ((__GNUC__ < 3) || (__GNUC__ == 3) && (__GNUC_MINOR__ < 1))) |
|---|
| 252 | BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::value_type); |
|---|
| 253 | BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::reference); |
|---|
| 254 | BOOST_CHECK_TYPE(const int&, boost::call_traits<cr_type>::const_reference); |
|---|
| 255 | BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::param_type); |
|---|
| 256 | #else |
|---|
| 257 | std::cout << "Your compiler cannot instantiate call_traits<int&const>, skipping four tests (4 errors)" << std::endl; |
|---|
| 258 | #endif |
|---|
| 259 | BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::value_type); |
|---|
| 260 | BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::reference); |
|---|
| 261 | BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::const_reference); |
|---|
| 262 | BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::param_type); |
|---|
| 263 | #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
|---|
| 264 | BOOST_CHECK_TYPE(const int*, boost::call_traits<int[3]>::value_type); |
|---|
| 265 | BOOST_CHECK_TYPE(int(&)[3], boost::call_traits<int[3]>::reference); |
|---|
| 266 | BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<int[3]>::const_reference); |
|---|
| 267 | BOOST_CHECK_TYPE(const int*const, boost::call_traits<int[3]>::param_type); |
|---|
| 268 | BOOST_CHECK_TYPE(const int*, boost::call_traits<const int[3]>::value_type); |
|---|
| 269 | BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<const int[3]>::reference); |
|---|
| 270 | BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<const int[3]>::const_reference); |
|---|
| 271 | BOOST_CHECK_TYPE(const int*const, boost::call_traits<const int[3]>::param_type); |
|---|
| 272 | // test with abstract base class: |
|---|
| 273 | BOOST_CHECK_TYPE(test_abc1, boost::call_traits<test_abc1>::value_type); |
|---|
| 274 | BOOST_CHECK_TYPE(test_abc1&, boost::call_traits<test_abc1>::reference); |
|---|
| 275 | BOOST_CHECK_TYPE(const test_abc1&, boost::call_traits<test_abc1>::const_reference); |
|---|
| 276 | BOOST_CHECK_TYPE(const test_abc1&, boost::call_traits<test_abc1>::param_type); |
|---|
| 277 | #else |
|---|
| 278 | std::cout << "You're compiler does not support partial template specialiation, skipping 8 tests (8 errors)" << std::endl; |
|---|
| 279 | #endif |
|---|
| 280 | #else |
|---|
| 281 | std::cout << "You're compiler does not support partial template specialiation, skipping 20 tests (20 errors)" << std::endl; |
|---|
| 282 | #endif |
|---|
| 283 | // test with an incomplete type: |
|---|
| 284 | BOOST_CHECK_TYPE(incomplete_type, boost::call_traits<incomplete_type>::value_type); |
|---|
| 285 | BOOST_CHECK_TYPE(incomplete_type&, boost::call_traits<incomplete_type>::reference); |
|---|
| 286 | BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::const_reference); |
|---|
| 287 | BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::param_type); |
|---|
| 288 | |
|---|
| 289 | return 0; |
|---|
| 290 | } |
|---|
| 291 | |
|---|
| 292 | // |
|---|
| 293 | // define call_traits tests to check that the assertions in the docs do actually work |
|---|
| 294 | // this is an compile-time only set of tests: |
|---|
| 295 | // |
|---|
| 296 | template <typename T, bool isarray = false> |
|---|
| 297 | struct call_traits_test |
|---|
| 298 | { |
|---|
| 299 | typedef ::boost::call_traits<T> ct; |
|---|
| 300 | typedef typename ct::param_type param_type; |
|---|
| 301 | typedef typename ct::reference reference; |
|---|
| 302 | typedef typename ct::const_reference const_reference; |
|---|
| 303 | typedef typename ct::value_type value_type; |
|---|
| 304 | static void assert_construct(param_type val); |
|---|
| 305 | }; |
|---|
| 306 | |
|---|
| 307 | template <typename T, bool isarray> |
|---|
| 308 | void call_traits_test<T, isarray>::assert_construct(typename call_traits_test<T, isarray>::param_type val) |
|---|
| 309 | { |
|---|
| 310 | // |
|---|
| 311 | // this is to check that the call_traits assertions are valid: |
|---|
| 312 | T t(val); |
|---|
| 313 | value_type v(t); |
|---|
| 314 | reference r(t); |
|---|
| 315 | const_reference cr(t); |
|---|
| 316 | param_type p(t); |
|---|
| 317 | value_type v2(v); |
|---|
| 318 | value_type v3(r); |
|---|
| 319 | value_type v4(p); |
|---|
| 320 | reference r2(v); |
|---|
| 321 | reference r3(r); |
|---|
| 322 | const_reference cr2(v); |
|---|
| 323 | const_reference cr3(r); |
|---|
| 324 | const_reference cr4(cr); |
|---|
| 325 | const_reference cr5(p); |
|---|
| 326 | param_type p2(v); |
|---|
| 327 | param_type p3(r); |
|---|
| 328 | param_type p4(p); |
|---|
| 329 | |
|---|
| 330 | unused_variable(v2); |
|---|
| 331 | unused_variable(v3); |
|---|
| 332 | unused_variable(v4); |
|---|
| 333 | unused_variable(r2); |
|---|
| 334 | unused_variable(r3); |
|---|
| 335 | unused_variable(cr2); |
|---|
| 336 | unused_variable(cr3); |
|---|
| 337 | unused_variable(cr4); |
|---|
| 338 | unused_variable(cr5); |
|---|
| 339 | unused_variable(p2); |
|---|
| 340 | unused_variable(p3); |
|---|
| 341 | unused_variable(p4); |
|---|
| 342 | } |
|---|
| 343 | #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
|---|
| 344 | template <typename T> |
|---|
| 345 | struct call_traits_test<T, true> |
|---|
| 346 | { |
|---|
| 347 | typedef ::boost::call_traits<T> ct; |
|---|
| 348 | typedef typename ct::param_type param_type; |
|---|
| 349 | typedef typename ct::reference reference; |
|---|
| 350 | typedef typename ct::const_reference const_reference; |
|---|
| 351 | typedef typename ct::value_type value_type; |
|---|
| 352 | static void assert_construct(param_type val); |
|---|
| 353 | }; |
|---|
| 354 | |
|---|
| 355 | template <typename T> |
|---|
| 356 | void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>::param_type val) |
|---|
| 357 | { |
|---|
| 358 | // |
|---|
| 359 | // this is to check that the call_traits assertions are valid: |
|---|
| 360 | T t; |
|---|
| 361 | value_type v(t); |
|---|
| 362 | value_type v5(val); |
|---|
| 363 | reference r = t; |
|---|
| 364 | const_reference cr = t; |
|---|
| 365 | reference r2 = r; |
|---|
| 366 | #ifndef __BORLANDC__ |
|---|
| 367 | // C++ Builder buglet: |
|---|
| 368 | const_reference cr2 = r; |
|---|
| 369 | #endif |
|---|
| 370 | param_type p(t); |
|---|
| 371 | value_type v2(v); |
|---|
| 372 | const_reference cr3 = cr; |
|---|
| 373 | value_type v3(r); |
|---|
| 374 | value_type v4(p); |
|---|
| 375 | param_type p2(v); |
|---|
| 376 | param_type p3(r); |
|---|
| 377 | param_type p4(p); |
|---|
| 378 | |
|---|
| 379 | unused_variable(v2); |
|---|
| 380 | unused_variable(v3); |
|---|
| 381 | unused_variable(v4); |
|---|
| 382 | unused_variable(v5); |
|---|
| 383 | #ifndef __BORLANDC__ |
|---|
| 384 | unused_variable(r2); |
|---|
| 385 | unused_variable(cr2); |
|---|
| 386 | #endif |
|---|
| 387 | unused_variable(cr3); |
|---|
| 388 | unused_variable(p2); |
|---|
| 389 | unused_variable(p3); |
|---|
| 390 | unused_variable(p4); |
|---|
| 391 | } |
|---|
| 392 | #endif //BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION |
|---|
| 393 | // |
|---|
| 394 | // now check call_traits assertions by instantiating call_traits_test: |
|---|
| 395 | template struct call_traits_test<int>; |
|---|
| 396 | template struct call_traits_test<const int>; |
|---|
| 397 | template struct call_traits_test<int*>; |
|---|
| 398 | #if defined(BOOST_MSVC6_MEMBER_TEMPLATES) |
|---|
| 399 | template struct call_traits_test<int&>; |
|---|
| 400 | template struct call_traits_test<const int&>; |
|---|
| 401 | #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC) |
|---|
| 402 | template struct call_traits_test<int[2], true>; |
|---|
| 403 | #endif |
|---|
| 404 | #endif |
|---|
| 405 | |
|---|