diff --git a/algo_opt_examples.cpp b/algo_opt_examples.cpp index 6b795e7..759a0ed 100644 --- a/algo_opt_examples.cpp +++ b/algo_opt_examples.cpp @@ -24,6 +24,13 @@ * */ +/* Release notes: + 23rd July 2000: + Added explicit failure for broken compilers that don't support these examples. + Fixed broken gcc support (broken using directive). + Reordered tests slightly. +*/ + #include #include #include @@ -39,6 +46,10 @@ using std::cout; using std::endl; using std::cin; +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +#error "Sorry, without template partial specialisation support there isn't anything to test here..." +#endif + namespace opt{ // @@ -221,6 +232,10 @@ struct swapper } }; +#ifdef __GNUC__ +using std::swap; +#endif + template <> struct swapper { @@ -295,6 +310,44 @@ int main() result = t.elapsed(); cout << "destroy_array(unoptimised#2): " << result << endl << endl; + cout << "testing fill(char)...\n" + "[Some standard library versions may already perform this optimisation.]" << endl; + /*cache load*/ opt::fill(c_array, c_array + array_size, (char)3); + t.restart(); + for(i = 0; i < iter_count; ++i) + { + opt::fill(c_array, c_array + array_size, (char)3); + } + result = t.elapsed(); + cout << "opt::fill: " << result << endl; + /*cache load*/ std::fill(c_array, c_array + array_size, (char)3); + t.restart(); + for(i = 0; i < iter_count; ++i) + { + std::fill(c_array, c_array + array_size, (char)3); + } + result = t.elapsed(); + cout << "std::fill: " << result << endl << endl; + + cout << "testing fill(int)...\n" + "[Tests the effect of call_traits pass-by-value optimisation -\nthe value of this optimisation may depend upon hardware characteristics.]" << endl; + /*cache load*/ opt::fill(i_array, i_array + array_size, 3); + t.restart(); + for(i = 0; i < iter_count; ++i) + { + opt::fill(i_array, i_array + array_size, 3); + } + result = t.elapsed(); + cout << "opt::fill: " << result << endl; + /*cache load*/ std::fill(i_array, i_array + array_size, 3); + t.restart(); + for(i = 0; i < iter_count; ++i) + { + std::fill(i_array, i_array + array_size, 3); + } + result = t.elapsed(); + cout << "std::fill: " << result << endl << endl; + cout << "testing copy...\n" "[Some standard library versions may already perform this optimisation.]" << endl; /*cache load*/ opt::copy(ci_array, ci_array + array_size, i_array); @@ -347,43 +400,6 @@ int main() result = t.elapsed(); cout << "standard \"unoptimised\" copy: " << result << endl << endl; - cout << "testing fill(char)...\n" - "[Some standard library versions may already perform this optimisation.]" << endl; - /*cache load*/ opt::fill(c_array, c_array + array_size, (char)3); - t.restart(); - for(i = 0; i < iter_count; ++i) - { - opt::fill(c_array, c_array + array_size, (char)3); - } - result = t.elapsed(); - cout << "opt::fill: " << result << endl; - /*cache load*/ std::fill(c_array, c_array + array_size, (char)3); - t.restart(); - for(i = 0; i < iter_count; ++i) - { - std::fill(c_array, c_array + array_size, (char)3); - } - result = t.elapsed(); - cout << "std::fill: " << result << endl << endl; - - cout << "testing fill(int)...\n" - "[Tests the effect of call_traits pass-by-value optimisation -\nthe value of this optimisation may depend upon hardware characteristics.]" << endl; - /*cache load*/ opt::fill(i_array, i_array + array_size, 3); - t.restart(); - for(i = 0; i < iter_count; ++i) - { - opt::fill(i_array, i_array + array_size, 3); - } - result = t.elapsed(); - cout << "opt::fill: " << result << endl; - /*cache load*/ std::fill(i_array, i_array + array_size, 3); - t.restart(); - for(i = 0; i < iter_count; ++i) - { - std::fill(i_array, i_array + array_size, 3); - } - result = t.elapsed(); - cout << "std::fill: " << result << endl << endl; // // testing iter_swap @@ -404,3 +420,4 @@ int main() + diff --git a/call_traits_test.cpp b/call_traits_test.cpp index c615013..c89169f 100644 --- a/call_traits_test.cpp +++ b/call_traits_test.cpp @@ -6,6 +6,12 @@ #include #include +#ifdef __BORLANDC__ +// turn off some warnings, the way we do the tests will generate a *lot* of these +// this is a result of the tests not call_traits itself.... +#pragma option -w-8004 -w-ccc -w-rch -w-eff -w-aus +#endif + // // struct contained models a type that contains a type (for example std::pair) // arrays are contained by value, and have to be treated as a special case: @@ -28,7 +34,7 @@ struct contained contained() {} contained(param_type p) : v_(p){} // return byval: - result_type value() { return v_; } + result_type value()const { return v_; } // return by_ref: reference get() { return v_; } const_reference const_get()const { return v_; } @@ -37,6 +43,7 @@ struct contained }; +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template struct contained { @@ -53,30 +60,36 @@ struct contained std::copy(p, p+N, v_); } // return byval: - result_type value() { return v_; } + result_type value()const { return v_; } // return by_ref: reference get() { return v_; } const_reference const_get()const { return v_; } void call(param_type p){} }; +#endif template contained::value_type> wrap(const T& t) { - return contained::value_type>(t); + typedef typename boost::call_traits::value_type ct; + return contained(t); } +namespace test{ + template std::pair< - typename boost::call_traits::value_type, - typename boost::call_traits::value_type> + typename boost::call_traits::value_type, + typename boost::call_traits::value_type> make_pair(const T1& t1, const T2& t2) { return std::pair< - typename boost::call_traits::value_type, + typename boost::call_traits::value_type, typename boost::call_traits::value_type>(t1, t2); } +} // namespace test + using namespace std; // @@ -108,51 +121,40 @@ void checker::operator()(param_type p) cout << endl; } +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION template struct checker { typedef typename boost::call_traits::param_type param_type; - void operator()(param_type); + void operator()(param_type t) + { + contained c(t); + cout << "checking contained<" << typeid(T[N]).name() << ">..." << endl; + unsigned int i = 0; + for(i = 0; i < N; ++i) + assert(t[i] == c.value()[i]); + for(i = 0; i < N; ++i) + assert(t[i] == c.get()[i]); + for(i = 0; i < N; ++i) + assert(t[i] == c.const_get()[i]); + + cout << "typeof contained<" << typeid(T[N]).name() << ">::v_ is: " << typeid(&contained::v_).name() << endl; + cout << "typeof contained<" << typeid(T[N]).name() << ">::value is: " << typeid(&contained::value).name() << endl; + cout << "typeof contained<" << typeid(T[N]).name() << ">::get is: " << typeid(&contained::get).name() << endl; + cout << "typeof contained<" << typeid(T[N]).name() << ">::const_get is: " << typeid(&contained::const_get).name() << endl; + cout << "typeof contained<" << typeid(T[N]).name() << ">::call is: " << typeid(&contained::call).name() << endl; + cout << endl; + } }; - -template -void checker::operator()(param_type t) -{ - contained c(t); - cout << "checking contained<" << typeid(T[N]).name() << ">..." << endl; - unsigned int i = 0; - for(i = 0; i < N; ++i) - assert(t[i] == c.value()[i]); - for(i = 0; i < N; ++i) - assert(t[i] == c.get()[i]); - for(i = 0; i < N; ++i) - assert(t[i] == c.const_get()[i]); - - cout << "typeof contained<" << typeid(T[N]).name() << ">::v_ is: " << typeid(&contained::v_).name() << endl; - cout << "typeof contained<" << typeid(T[N]).name() << ">::value is: " << typeid(&contained::value).name() << endl; - cout << "typeof contained<" << typeid(T[N]).name() << ">::get is: " << typeid(&contained::get).name() << endl; - cout << "typeof contained<" << typeid(T[N]).name() << ">::const_get is: " << typeid(&contained::const_get).name() << endl; - cout << "typeof contained<" << typeid(T[N]).name() << ">::call is: " << typeid(&contained::call).name() << endl; - cout << endl; -} +#endif // // check_wrap: -// verifies behaviour of "wrap": -// -template -void check_wrap(T c, U u, const V& v) +template +void check_wrap(const contained& w, const U& u) { - cout << "checking contained<" << typeid(T::value_type).name() << ">..." << endl; - assert(c.get() == u); - cout << "typeof deduced argument was: " << typeid(V).name() << endl; - cout << "typeof deduced parameter after adjustment was: " << typeid(v).name() << endl; - cout << "typeof contained<" << typeid(T::value_type).name() << ">::v_ is: " << typeid(&T::v_).name() << endl; - cout << "typeof contained<" << typeid(T::value_type).name() << ">::value is: " << typeid(&T::value).name() << endl; - cout << "typeof contained<" << typeid(T::value_type).name() << ">::get is: " << typeid(&T::get).name() << endl; - cout << "typeof contained<" << typeid(T::value_type).name() << ">::const_get is: " << typeid(&T::const_get).name() << endl; - cout << "typeof contained<" << typeid(T::value_type).name() << ">::call is: " << typeid(&T::call).name() << endl; - cout << endl; + cout << "checking contained<" << typeid(T).name() << ">..." << endl; + assert(w.value() == u); } // @@ -176,6 +178,29 @@ struct UDT bool operator == (const UDT& v){ return v.i_ == i_; } }; +// +// define tests here +unsigned failures = 0; +unsigned test_count = 0; + +#define value_test(v, x) ++test_count;\ + if(v != x){++failures; std::cout << "checking value of " << #x << "...failed" << std::endl;} + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +#define type_test(v, x) ++test_count;\ + if(boost::is_same::value == false){\ + ++failures; \ + std::cout << "checking type of " << #x << "...failed" << std::endl; \ + std::cout << " expected type was " << #v << std::endl; \ + std::cout << " " << typeid(boost::is_same).name() << "::value is false" << std::endl; } +#else +#define type_test(v, x) ++test_count;\ + if(typeid(v) != typeid(x)){\ + ++failures; \ + std::cout << "checking type of " << #x << "...failed" << std::endl; \ + std::cout << " expected type was " << #v << std::endl; \ + std::cout << " " << "typeid(" #v ") != typeid(" #x ")" << std::endl; } +#endif int main() { @@ -188,6 +213,7 @@ int main() int* pi = &i; checker c3; c3(pi); +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION checker c4; c4(i); checker c5; @@ -196,13 +222,147 @@ int main() int a[2] = {1,2}; checker c6; c6(a); +#endif - check_wrap(wrap(2), 2, 2); + check_wrap(wrap(2), 2); const char ca[4] = "abc"; // compiler can't deduce this for some reason: - //check_wrap(wrap(ca), ca, ca); - check_wrap(wrap(a), a, a); - check_make_pair(::make_pair(a, a), a, a); + //check_wrap(wrap(ca), ca); +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + check_wrap(wrap(a), a); + check_make_pair(test::make_pair(a, a), a, a); +#endif - return 0; + // cv-qualifiers applied to reference types should have no effect + // declare these here for later use with is_reference and remove_reference: + typedef int& r_type; + typedef const r_type cr_type; + + type_test(UDT, boost::call_traits::value_type) + type_test(UDT&, boost::call_traits::reference) + type_test(const UDT&, boost::call_traits::const_reference) + type_test(const UDT&, boost::call_traits::param_type) + type_test(int, boost::call_traits::value_type) + type_test(int&, boost::call_traits::reference) + type_test(const int&, boost::call_traits::const_reference) + type_test(const int, boost::call_traits::param_type) + type_test(int*, boost::call_traits::value_type) + type_test(int*&, boost::call_traits::reference) + type_test(int*const&, boost::call_traits::const_reference) + type_test(int*const, boost::call_traits::param_type) +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + type_test(int&, boost::call_traits::value_type) + type_test(int&, boost::call_traits::reference) + type_test(const int&, boost::call_traits::const_reference) + type_test(int&, boost::call_traits::param_type) +#if !(defined(__GNUC__) && (__GNUC__ < 3)) + type_test(int&, boost::call_traits::value_type) + type_test(int&, boost::call_traits::reference) + type_test(const int&, boost::call_traits::const_reference) + type_test(int&, boost::call_traits::param_type) +#else + std::cout << "GNU C++ cannot instantiate call_traits, skipping four tests (4 errors)" << std::endl; + failures += 4; + test_count += 4; +#endif + type_test(const int&, boost::call_traits::value_type) + type_test(const int&, boost::call_traits::reference) + type_test(const int&, boost::call_traits::const_reference) + type_test(const int&, boost::call_traits::param_type) + type_test(const int*, boost::call_traits::value_type) + type_test(int(&)[3], boost::call_traits::reference) + type_test(const int(&)[3], boost::call_traits::const_reference) + type_test(const int*const, boost::call_traits::param_type) + type_test(const int*, boost::call_traits::value_type) + type_test(const int(&)[3], boost::call_traits::reference) + type_test(const int(&)[3], boost::call_traits::const_reference) + type_test(const int*const, boost::call_traits::param_type) +#else + std::cout << "You're compiler does not support partial template instantiation, skipping 20 tests (20 errors)" << std::endl; + failures += 20; + test_count += 20; +#endif + + std::cout << std::endl << test_count << " tests completed (" << failures << " failures)... press any key to exit"; + std::cin.get(); + return failures; } + +// +// define call_traits tests to check that the assertions in the docs do actually work +// this is an instantiate only set of tests: +// +template +struct call_traits_test +{ + static void assert_construct(boost::call_traits::param_type val); +}; + +template +void call_traits_test::assert_construct(boost::call_traits::param_type val) +{ + // + // this is to check that the call_traits assertions are valid: + T t(val); + boost::call_traits::value_type v(t); + boost::call_traits::reference r(t); + boost::call_traits::const_reference cr(t); + boost::call_traits::param_type p(t); + boost::call_traits::value_type v2(v); + boost::call_traits::value_type v3(r); + boost::call_traits::value_type v4(p); + boost::call_traits::reference r2(v); + boost::call_traits::reference r3(r); + boost::call_traits::const_reference cr2(v); + boost::call_traits::const_reference cr3(r); + boost::call_traits::const_reference cr4(cr); + boost::call_traits::const_reference cr5(p); + boost::call_traits::param_type p2(v); + boost::call_traits::param_type p3(r); + boost::call_traits::param_type p4(p); +} +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template +struct call_traits_test +{ + static void assert_construct(boost::call_traits::param_type val); +}; + +template +void call_traits_test::assert_construct(boost::call_traits::param_type val) +{ + // + // this is to check that the call_traits assertions are valid: + T t; + boost::call_traits::value_type v(t); + boost::call_traits::value_type v5(val); + boost::call_traits::reference r = t; + boost::call_traits::const_reference cr = t; + boost::call_traits::reference r2 = r; + #ifndef __BORLANDC__ + // C++ Builder buglet: + boost::call_traits::const_reference cr2 = r; + #endif + boost::call_traits::param_type p(t); + boost::call_traits::value_type v2(v); + boost::call_traits::const_reference cr3 = cr; + boost::call_traits::value_type v3(r); + boost::call_traits::value_type v4(p); + boost::call_traits::param_type p2(v); + boost::call_traits::param_type p3(r); + boost::call_traits::param_type p4(p); +} +#endif //BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +// +// now check call_traits assertions by instantiating call_traits_test: +template struct call_traits_test; +template struct call_traits_test; +template struct call_traits_test; +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template struct call_traits_test; +template struct call_traits_test; +template struct call_traits_test; +#endif + + diff --git a/include/boost/detail/call_traits.hpp b/include/boost/detail/call_traits.hpp index 07ed4ec..93dc7b1 100644 --- a/include/boost/detail/call_traits.hpp +++ b/include/boost/detail/call_traits.hpp @@ -6,6 +6,13 @@ // See http://www.boost.org for most recent version including documentation. +/* Release notes: + 23rd July 2000: + Fixed array specialization. (JM) + Added Borland specific fixes for reference types + (issue raised by Steve Cleary). +*/ + #ifndef BOOST_DETAIL_CALL_TRAITS_HPP #define BOOST_DETAIL_CALL_TRAITS_HPP @@ -66,6 +73,37 @@ struct call_traits typedef T& param_type; // hh removed const }; +#if defined(__BORLANDC__) && (__BORLANDC__ <= 0x550) +// these are illegal specialisations; cv-qualifies applied to +// references have no effect according to [8.3.2p1], +// C++ Builder requires them though as it treats cv-qualified +// references as distinct types... +template +struct call_traits +{ + typedef T& value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T& param_type; // hh removed const +}; +template +struct call_traits +{ + typedef T& value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T& param_type; // hh removed const +}; +template +struct call_traits +{ + typedef T& value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T& param_type; // hh removed const +}; +#endif + template struct call_traits { @@ -76,7 +114,7 @@ public: typedef const T* value_type; typedef array_type& reference; typedef const array_type& const_reference; - typedef const T* param_type; + typedef const T* const param_type; }; template @@ -89,7 +127,7 @@ public: typedef const T* value_type; typedef array_type& reference; typedef const array_type& const_reference; - typedef const T* param_type; + typedef const T* const param_type; }; } diff --git a/include/boost/detail/ob_compressed_pair.hpp b/include/boost/detail/ob_compressed_pair.hpp index f5f5664..ce7e064 100644 --- a/include/boost/detail/ob_compressed_pair.hpp +++ b/include/boost/detail/ob_compressed_pair.hpp @@ -6,7 +6,14 @@ // See http://www.boost.org for most recent version including documentation. // -// this version crippled for use with crippled compilers - John Maddock Jan 2000. +/* Release notes: + 23rd July 2000: + Additional comments added. (JM) + Jan 2000: + Original version: this version crippled for use with crippled compilers + - John Maddock Jan 2000. +*/ + #ifndef BOOST_OB_COMPRESSED_PAIR_HPP #define BOOST_OB_COMPRESSED_PAIR_HPP @@ -41,7 +48,8 @@ public: compressed_pair() : _first(), _second() {} compressed_pair(first_param_type x, second_param_type y) : _first(x), _second(y) {} explicit compressed_pair(first_param_type x) : _first(x), _second() {} - //explicit compressed_pair(second_param_type y) : _first(), _second(y) {} + // can't define this in case T1 == T2: + // explicit compressed_pair(second_param_type y) : _first(), _second(y) {} first_reference first() { return _first; } first_const_reference first() const { return _first; } diff --git a/type_traits_test.cpp b/type_traits_test.cpp index ffea91d..b50892a 100644 --- a/type_traits_test.cpp +++ b/type_traits_test.cpp @@ -4,12 +4,18 @@ // in all copies. This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. +/* Release notes: + 23rd July 2000: + Removed all call_traits tests to call_traits_test.cpp + Removed all compressed_pair tests to compressed_pair_tests.cpp + Improved tests macros + Tidied up specialistions of type_types classes for test cases. +*/ + #include #include #include -#include -#include using namespace boost; @@ -20,73 +26,25 @@ using namespace boost; // // define tests here unsigned failures = 0; +unsigned test_count = 0; -#define value_test(v, x) if(v == x) /*std::cout << "checking value of " << #x << "...OK" << std::endl*/;\ - else{++failures; std::cout << "checking value of " << #x << "...failed" << std::endl;} - -#define type_test(v, x) if(is_same::value) /*std::cout << "checking type of " << #x << "...OK" << std::endl*/;\ - else{++failures; std::cout << "checking type of " << #x << "...failed (type was: " << typeid(is_same).name() << ")" << std::endl;} - -template -struct call_traits_test -{ - static void assert_construct(call_traits::param_type val); -}; - -template -void call_traits_test::assert_construct(call_traits::param_type val) -{ - // - // this is to check that the call_traits assertions are valid: - T t(val); - call_traits::value_type v(t); - call_traits::reference r(t); - call_traits::const_reference cr(t); - call_traits::param_type p(t); - call_traits::value_type v2(v); - call_traits::value_type v3(r); - call_traits::value_type v4(p); - call_traits::reference r2(v); - call_traits::reference r3(r); - call_traits::const_reference cr2(v); - call_traits::const_reference cr3(r); - call_traits::const_reference cr4(cr); - call_traits::const_reference cr5(p); - call_traits::param_type p2(v); - call_traits::param_type p3(r); - call_traits::param_type p4(p); -} +#define value_test(v, x) ++test_count;\ + if(v != x){++failures; std::cout << "checking value of " << #x << "...failed" << std::endl;} #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct call_traits_test -{ - static void assert_construct(call_traits::param_type val); -}; - -template -void call_traits_test::assert_construct(call_traits::param_type val) -{ - // - // this is to check that the call_traits assertions are valid: - T t; - call_traits::value_type v(t); - call_traits::reference r(t); - call_traits::const_reference cr(t); - call_traits::param_type p(t); - call_traits::value_type v2(v); - call_traits::value_type v3(r); - call_traits::value_type v4(p); - call_traits::reference r2(v); - call_traits::reference r3(r); - call_traits::const_reference cr2(v); - call_traits::const_reference cr3(r); - call_traits::const_reference cr4(cr); - call_traits::const_reference cr5(p); - call_traits::param_type p2(v); - call_traits::param_type p3(r); - call_traits::param_type p4(p); -} -#endif //BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +#define type_test(v, x) ++test_count;\ + if(is_same::value == false){\ + ++failures; \ + std::cout << "checking type of " << #x << "...failed" << std::endl; \ + std::cout << " expected type was " << #v << std::endl; \ + std::cout << " " << typeid(is_same).name() << "::value is false" << std::endl; } +#else +#define type_test(v, x) ++test_count;\ + if(typeid(v) != typeid(x)){\ + ++failures; \ + std::cout << "checking type of " << #x << "...failed" << std::endl; \ + std::cout << " expected type was " << #v << std::endl; \ + std::cout << " " << "typeid(" #v ") != typeid(" #x ")" << std::endl; } +#endif // Since there is no compiler support, we should specialize: // is_enum for all enumerations (is_enum implies is_POD) @@ -96,12 +54,6 @@ void call_traits_test::assert_construct(call_traits::param_type val) // has_* for any UDT that has that trait and is not POD enum enum_UDT{ one, two, three }; -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -namespace boost { -template <> struct is_enum -{ static const bool value = true; }; -} -#endif struct UDT { UDT(); @@ -116,74 +68,47 @@ struct UDT int f4(int, float); }; -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION struct POD_UDT { int x; }; -namespace boost { -template <> struct is_POD -{ static const bool value = true; }; -} -#endif -struct empty_UDT -{ - ~empty_UDT(){}; -}; -namespace boost { -//template <> struct is_empty -//{ static const bool value = true; }; -// this type is not POD, so we have to specialize the has_* individually -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template <> struct has_trivial_constructor -{ static const bool value = true; }; -template <> struct has_trivial_copy -{ static const bool value = true; }; -template <> struct has_trivial_assign -{ static const bool value = true; }; -} -#endif - +struct empty_UDT{ ~empty_UDT(){}; }; struct empty_POD_UDT{}; -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -namespace boost { -template <> struct is_empty -{ static const bool value = true; }; -template <> struct is_POD -{ static const bool value = true; }; -} -#endif union union_UDT { int x; double y; ~union_UDT(); }; -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -namespace boost { -template <> struct is_union -{ static const bool value = true; }; -} -#endif union POD_union_UDT { int x; double y; }; -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -namespace boost { -template <> struct is_union -{ static const bool value = true; }; -template <> struct is_POD -{ static const bool value = true; }; -} -#endif union empty_union_UDT { ~empty_union_UDT(); }; -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +union empty_POD_union_UDT{}; +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION namespace boost { -template <> struct is_union +template <> struct is_enum { static const bool value = true; }; -template <> struct is_empty +template <> struct is_POD +{ static const bool value = true; }; +// this type is not POD, so we have to specialize the has_* individually +template <> struct has_trivial_constructor +{ static const bool value = true; }; +template <> struct has_trivial_copy +{ static const bool value = true; }; +template <> struct has_trivial_assign +{ static const bool value = true; }; +template <> struct is_POD +{ static const bool value = true; }; +template <> struct is_union +{ static const bool value = true; }; +template <> struct is_union +{ static const bool value = true; }; +template <> struct is_POD +{ static const bool value = true; }; +template <> struct is_union { static const bool value = true; }; // this type is not POD, so we have to specialize the has_* individually template <> struct has_trivial_constructor @@ -192,19 +117,48 @@ template <> struct has_trivial_copy { static const bool value = true; }; template <> struct has_trivial_assign { static const bool value = true; }; -} -#endif -union empty_POD_union_UDT{}; -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -namespace boost { template <> struct is_union { static const bool value = true; }; -template <> struct is_empty -{ static const bool value = true; }; template <> struct is_POD { static const bool value = true; }; -#endif } +#else +namespace boost { +template <> struct is_enum +{ enum{ value = true }; }; +template <> struct is_POD +{ enum{ value = true }; }; +// this type is not POD, so we have to specialize the has_* individually +template <> struct has_trivial_constructor +{ enum{ value = true }; }; +template <> struct has_trivial_copy +{ enum{ value = true }; }; +template <> struct has_trivial_assign +{ enum{ value = true }; }; +template <> struct is_POD +{ enum{ value = true }; }; +template <> struct is_union +{ enum{ value = true }; }; +template <> struct is_union +{ enum{ value = true }; }; +template <> struct is_POD +{ enum{ value = true }; }; +template <> struct is_union +{ enum{ value = true }; }; +// this type is not POD, so we have to specialize the has_* individually +template <> struct has_trivial_constructor +{ enum{ value = true }; }; +template <> struct has_trivial_copy +{ enum{ value = true }; }; +template <> struct has_trivial_assign +{ enum{ value = true }; }; +template <> struct is_union +{ enum{ value = true }; }; +template <> struct is_POD +{ enum{ value = true }; }; +} +#endif + // Steve: All comments that I (Steve Cleary) have added below are prefixed with // "Steve:" The failures that BCB4 has on the tests are due to Borland's // not considering cv-qual's as a part of the type -- they are considered @@ -214,11 +168,18 @@ int main() { std::cout << "Checking type operations..." << std::endl << std::endl; + // cv-qualifiers applied to reference types should have no effect + // declare these here for later use with is_reference and remove_reference: + typedef int& r_type; + typedef const r_type cr_type; + type_test(int, remove_reference::type) type_test(const int, remove_reference::type) type_test(int, remove_reference::type) type_test(const int, remove_reference::type) type_test(volatile int, remove_reference::type) + type_test(int, remove_reference::type) + type_test(int, remove_const::type) // Steve: fails on BCB4 type_test(volatile int, remove_const::type) @@ -246,14 +207,15 @@ int main() type_test(int, remove_bounds::type) type_test(int[3], remove_bounds::type) - type_test(const int, call_traits::param_type) - type_test(const char, call_traits::param_type) -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - type_test(char&, call_traits::param_type) - type_test(const char&, call_traits::param_type) -#endif std::cout << std::endl << "Checking type properties..." << std::endl << std::endl; + value_test(true, (is_same::value)) + value_test(false, (is_same::value)) + value_test(false, (is_same::value)) + value_test(false, (is_same::value)) + value_test(false, (is_same::value)) + value_test(false, (is_same::value)) + value_test(false, is_const::value) value_test(true, is_const::value) value_test(false, is_const::value) @@ -266,7 +228,8 @@ int main() value_test(true, is_void::value) // Steve: fails on BCB4 - value_test(false, is_void::value) + // JM: but looks as though it should according to [3.9.3p1]? + //value_test(false, is_void::value) value_test(false, is_void::value) value_test(false, is_standard_unsigned_integral::value) @@ -432,6 +395,8 @@ int main() value_test(true, is_reference::value) value_test(true, is_reference::value) value_test(true, is_reference::value) + value_test(true, is_reference::value) + value_test(true, is_reference::value) value_test(false, is_class::value) value_test(false, is_class::value) @@ -477,8 +442,9 @@ int main() value_test(false, is_empty::value) value_test(false, is_empty::value) value_test(false, is_empty::value) - value_test(false, is_empty::value) value_test(true, is_empty::value) + value_test(true, is_empty::value) + value_test(true, is_empty::value) value_test(false, is_empty::value) value_test(true, has_trivial_constructor::value) @@ -558,66 +524,11 @@ int main() value_test(false, is_POD::value) value_test(true, is_POD::value) - compressed_pair cp1; - compressed_pair cp1b; - swap(cp1, cp1b); - compressed_pair cp2; - compressed_pair cp3; - compressed_pair cp4; - compressed_pair cp5; -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - int i; - compressed_pair cp6(i,i); - compressed_pair cp7; - cp7.first(); - double* pd = cp7.second(); -#endif - value_test(true, (sizeof(compressed_pair) < sizeof(std::pair))) - value_test(true, (sizeof(compressed_pair) < sizeof(std::pair))) - value_test(true, (sizeof(compressed_pair) < sizeof(std::pair))) - value_test(true, (sizeof(compressed_pair) < sizeof(std::pair))) - - std::cout << std::endl << "Tests completed (" << failures << " failures)... press any key to exit"; + std::cout << std::endl << test_count << " tests completed (" << failures << " failures)... press any key to exit"; std::cin.get(); - return 0; + return failures; } -// -// instanciate some compressed pairs: -template class boost::compressed_pair; -template class boost::compressed_pair; -template class boost::compressed_pair; -template class boost::compressed_pair; -template class boost::compressed_pair; -template class boost::compressed_pair; - -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -// -// now some for which only a few specific members can be instantiated, -// first references: -template double& compressed_pair::first(); -template int& compressed_pair::second(); -template compressed_pair::compressed_pair(int&); -template compressed_pair::compressed_pair(call_traits::param_type,int&); -// -// and then arrays: -#ifndef __BORLANDC__ -template call_traits::reference compressed_pair::second(); -#endif -template call_traits::reference compressed_pair::first(); -template compressed_pair::compressed_pair(const double&); -template compressed_pair::compressed_pair(); -#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -// -// now check call_traits assertions by instantiating call_traits_test: -template struct call_traits_test; -template struct call_traits_test; -template struct call_traits_test; -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template struct call_traits_test; -template struct call_traits_test; -// this doesn't work (yet) (JM): -template struct call_traits_test; -#endif +