Author: elemings Date: Wed Jul 16 15:49:27 2008 New Revision: 677458 URL: http://svn.apache.org/viewvc?rev=677458&view=rev Log: 2008-07-16 Eric Lemings <[EMAIL PROTECTED]>
STDCXX-958 * include/rw/_tuple.h: Fix move semantics in heterogenous move constructor. (Move assignment operator fixed previously in revision 675044.) * include/tuple: Removed unnecessary `explicit' keywords. Fix move semantics in value move constructor for pair specialization. * tests/utilities/20.tuple.h: Add UserDefined class -- similar to UserClass with additional move semantics and implicit conversions for tuple testing (and without unused stuff from UserClass). Add general utilities for tuple names, formatting directives. * tests/utilities/20.tuple.cnstr.cpp: Generalize test facility. Abstract differences between tuple and element types with template function overloads. Update all tests to utilize new UserDefined class and test facility. * tests/utilities/20.tuple.creation.cpp: Update tests for new UserDefined class. * tests/utilities/20.tuple.elem.cpp: Same. * tests/utilities/20.tuple.helpers.cpp: Same. * tests/utilities/20.tuple.rel.cpp: Same. Modified: stdcxx/branches/4.3.x/include/rw/_tuple.h stdcxx/branches/4.3.x/include/tuple stdcxx/branches/4.3.x/tests/utilities/20.tuple.cnstr.cpp stdcxx/branches/4.3.x/tests/utilities/20.tuple.creation.cpp stdcxx/branches/4.3.x/tests/utilities/20.tuple.elem.cpp stdcxx/branches/4.3.x/tests/utilities/20.tuple.h stdcxx/branches/4.3.x/tests/utilities/20.tuple.helpers.cpp stdcxx/branches/4.3.x/tests/utilities/20.tuple.rel.cpp Modified: stdcxx/branches/4.3.x/include/rw/_tuple.h URL: http://svn.apache.org/viewvc/stdcxx/branches/4.3.x/include/rw/_tuple.h?rev=677458&r1=677457&r2=677458&view=diff ============================================================================== --- stdcxx/branches/4.3.x/include/rw/_tuple.h (original) +++ stdcxx/branches/4.3.x/include/rw/_tuple.h Wed Jul 16 15:49:27 2008 @@ -122,7 +122,7 @@ template <class _HeadU, class... _TailU> __rw_tuple (__rw_tuple<_HeadU, _TailU...>&& __tuple) - : _Base (_RWSTD_FORWARD (_Base, __tuple._C_tail ())) + : _Base (_RWSTD_MOVE (__tuple._C_tail ())) , _C_data (_RWSTD_MOVE (__tuple._C_head ())) { /* empty */ } template <class _HeadU, class... _TailU> Modified: stdcxx/branches/4.3.x/include/tuple URL: http://svn.apache.org/viewvc/stdcxx/branches/4.3.x/include/tuple?rev=677458&r1=677457&r2=677458&view=diff ============================================================================== --- stdcxx/branches/4.3.x/include/tuple (original) +++ stdcxx/branches/4.3.x/include/tuple Wed Jul 16 15:49:27 2008 @@ -184,7 +184,6 @@ return *this; } - explicit tuple (const _TypeT1& __x, const _TypeT2& __y) : _Base (__x, __y) { /* empty */ } @@ -211,9 +210,8 @@ # if !defined _RWSTD_NO_RVALUE_REFERENCES template <class _TypeU1, class _TypeU2> - explicit tuple (_TypeU1&& __x, _TypeU2&& __y) - : _Base (_RWSTD_FORWARD (_TypeU1, __x), - _RWSTD_FORWARD (_TypeU2, __y)) { /* empty */ } + tuple (_TypeU1&& __x, _TypeU2&& __y) + : _Base (_RWSTD_MOVE (__x), _RWSTD_MOVE (__y)) { /* empty */ } tuple (tuple&& __tuple) : _Base (_RWSTD_FORWARD (_Base, __tuple)) { /* empty */ } Modified: stdcxx/branches/4.3.x/tests/utilities/20.tuple.cnstr.cpp URL: http://svn.apache.org/viewvc/stdcxx/branches/4.3.x/tests/utilities/20.tuple.cnstr.cpp?rev=677458&r1=677457&r2=677458&view=diff ============================================================================== --- stdcxx/branches/4.3.x/tests/utilities/20.tuple.cnstr.cpp (original) +++ stdcxx/branches/4.3.x/tests/utilities/20.tuple.cnstr.cpp Wed Jul 16 15:49:27 2008 @@ -32,8 +32,11 @@ #if !defined (_RWSTD_NO_EXT_CXX_0X) \ && !defined(_RWSTD_NO_RVALUE_REFERENCES) +#include <climits> // for CHAR_MAX +#include <cstdlib> // for rand #include <cstring> // for strcmp #include <tuple> +#include <type_traits> // for decay #include <rw_valcmp.h> // for rw_fltcmp @@ -41,112 +44,124 @@ /**************************************************************************/ -static void -test_default_ctor () -{ - rw_info (0, __FILE__, __LINE__, "default constructor"); +// general test function and underlying abstractions - EmptyTuple et; _RWSTD_UNUSED (et); - IntTuple it; _RWSTD_UNUSED (it); - ConstIntTuple ct; _RWSTD_UNUSED (ct); - // ill-formed for tuples with element types containing references - PairTuple pt; _RWSTD_UNUSED (pt); - NestedTuple nt; _RWSTD_UNUSED (nt); - BigTuple bt; _RWSTD_UNUSED (bt); +template <class T, class U = T> +bool equal (const T& x, const U& y) +{ + return x == y; +} - UserClass::reset_totals (); - UserTuple ut; _RWSTD_UNUSED (ut); +template <> +bool equal (const float& x, const float& y) +{ + return 0 == rw_fltcmp (x, y); +} - rw_assert (1 == UserClass::n_total_def_ctor_, __FILE__, __LINE__, - "tuple<UserClass>::tuple() called %d default ctors, " - "expected 1", UserClass::n_total_def_ctor_); +template <> +bool equal (const char* const& x, const char* const& y) +{ + return 0 == std::strcmp (x, y); } -/**************************************************************************/ -#define INT_VALUE int ('a') +template <class T, class U> +void assert (int line, unsigned index, const char* tuple_name, + const T& t, const U& u) +{ + const char* fmtT = FMT_SPEC (T); + const char* fmtU = FMT_SPEC (U); + rw_assert (equal (t, u), __FILE__, line, + "get<%d, %s> (); got [EMAIL PROTECTED], expected [EMAIL PROTECTED]", + index, tuple_name, fmtT, t, fmtU, u); +} -// assume that std::get() has been fully tested and works correctly -#define VERIFY_TUPLE(it) \ - rw_assert (std::get<0> (it) == INT_VALUE, __FILE__, __LINE__, \ - "std::get<0> (" #it "), got %d, expected %d", \ - std::get<0> (it), INT_VALUE); +void assert (int line, unsigned index, const char* tuple_name, + const UserDefined& t, const UserDefined& u) +{ + rw_assert (equal (t, u), __FILE__, line, + "get<%d, %s> (); got %p [%d], expected %p [%d]", + index, tuple_name, &t, t.value (), &u, u.value ()); + UserDefined::size_type a, e; -#define LONG_VALUE INT_VALUE -#define STRING_VALUE "string" +#undef CHECK +#define CHECK(N) \ + a = UserDefined::actual.N; e = UserDefined::expect.N; \ + rw_assert (a == e, __FILE__, line, \ + "UserDefined::" #N "; got %u, expected %u", a, e) -static void -verify_tuple (const PairTuple& pt) -{ - rw_assert (std::get<0> (pt) == LONG_VALUE, __FILE__, __LINE__, - "std::get<0> (pt), got %d, expected %d", - std::get<0> (pt), LONG_VALUE); - rw_assert (0 == std::strcmp (std::get<1> (pt), STRING_VALUE), - __FILE__, __LINE__, - "std::get<1> (pt), got %s, expected %s", - std::get<1> (pt), STRING_VALUE); + CHECK (dflt_ctor); + CHECK (copy_ctor); + CHECK (tmpl_ctor); + CHECK (move_ctor); + CHECK (copy_asgn); + CHECK (tmpl_asgn); + CHECK (move_asgn); } +template <class T, class U> +void assert (int line, unsigned index, const char* tuple_name, + const std::tuple<T>& t, const std::tuple<U>& u) +{ + const char* fmtT = FMT_SPEC (T); + const char* fmtU = FMT_SPEC (U); + rw_assert (equal (t, u), __FILE__, line, + "get<%d, %s> (); got [EMAIL PROTECTED], expected [EMAIL PROTECTED]", + index, tuple_name, + fmtT, std::get<0> (t), fmtU, std::get<0> (u)); +} -#define USER_VALUE user_val -static UserClass user_val; +template <unsigned Index, class Tuple, class... Elements> +/*static*/ void +test_impl (int line, const Tuple& tuple, const Elements&... values); -typedef unsigned int uint_t; +// terminating specialization +template <unsigned Index, class Tuple> +/*static*/ void +test_impl (int, const Tuple&) {} -static void -verify_tuple (const UserTuple& ut, int line, - uint_t dflt = 0, uint_t copy = 0, uint_t asgn = 0) +// generic definition +template <unsigned Index, class Tuple, class Element, class... Elements> +/*static*/ void +test_impl (int line, const Tuple& tuple, + const Element& value, const Elements&... values) { - rw_assert (std::get<0> (ut) == USER_VALUE, __FILE__, line, - "std::get<0> (ut), got %d, expected %d", - (std::get<0> (ut)).data_.val_, - USER_VALUE.data_.val_); + // assume std::get() has been fully tested and works correctly + assert (line, Index, TYPE_NAME (Tuple), + std::get<Index> (tuple), value); - rw_assert (dflt == UserClass::n_total_def_ctor_, __FILE__, line, - "tuple<UserClass>::tuple() called %d default ctors, " - "expected %d", UserClass::n_total_def_ctor_, dflt); - rw_assert (copy == UserClass::n_total_copy_ctor_, __FILE__, line, - "tuple<UserClass>::tuple() called %d copy ctors, " - "expected %d", UserClass::n_total_copy_ctor_, copy); - rw_assert (asgn == UserClass::n_total_op_assign_, __FILE__, line, - "tuple<UserClass>::tuple() called %d assign ops, " - "expected %d", UserClass::n_total_op_assign_, asgn); + test_impl<Index+1> (line, tuple, values...); } +template <class Tuple, class... Elements> +/*static*/ void +test (int line, const Tuple& tuple, const Elements&... values) +{ + test_impl<0> (line, tuple, values...); +} -#define BOOL_VALUE true -#define CHAR_VALUE 'a' -#define DBL_VALUE 3.14159 -#define PTR_VALUE ptr_val - -static void* ptr_val = 0; +/**************************************************************************/ static void -verify_tuple (const BigTuple& bt) +test_default_ctor () { - rw_assert (std::get<0> (bt) == BOOL_VALUE, __FILE__, __LINE__, - "std::get<0> (bt), got %b, expected %b", - std::get<0> (bt), BOOL_VALUE); - rw_assert (std::get<1> (bt) == CHAR_VALUE, __FILE__, __LINE__, - "std::get<1> (bt), got %c, expected %c", - std::get<1> (bt), CHAR_VALUE); - rw_assert (std::get<2> (bt) == INT_VALUE, __FILE__, __LINE__, - "std::get<2> (bt), got %d, expected %d", - std::get<2> (bt), INT_VALUE); - // compare as floats because floats promoted to doubles will not - // be equal even if the values are logically equal - int result = rw_fltcmp (std::get<3> (bt), DBL_VALUE); - rw_assert (0 == result, __FILE__, __LINE__, - "std::get<3> (bt), got %f, expected %f", - std::get<3> (bt), DBL_VALUE); - rw_assert (std::get<4> (bt) == PTR_VALUE, __FILE__, __LINE__, - "std::get<4> (bt), got %p, expected %p", - std::get<4> (bt), PTR_VALUE); - rw_assert ((std::get<5> (bt)) == USER_VALUE, __FILE__, __LINE__, - "std::get<5> (bt), got %d, expected %d", - (std::get<5> (bt)).data_.val_, INT_VALUE); + rw_info (0, __FILE__, __LINE__, "default constructor"); + + EmptyTuple et; _RWSTD_UNUSED (et); + IntTuple it; _RWSTD_UNUSED (it); + ConstIntTuple ct; _RWSTD_UNUSED (ct); + // ill-formed for tuples with element types containing references + PairTuple pt; _RWSTD_UNUSED (pt); + NestedTuple nt; _RWSTD_UNUSED (nt); + BigTuple bt; _RWSTD_UNUSED (bt); + + UserDefined::reset (); + UserTuple ut; _RWSTD_UNUSED (ut); + rw_assert (1 == UserDefined::actual.dflt_ctor, __FILE__, __LINE__, + "UserTuple::UserTuple (); called %d default ctors, " + "expected 1", UserDefined::actual.dflt_ctor); } /**************************************************************************/ @@ -156,37 +171,39 @@ { rw_info (0, __FILE__, __LINE__, "value copy constructor"); - const int i = INT_VALUE; + const int i = std::rand (); IntTuple it1 (i); - VERIFY_TUPLE (it1); + test (__LINE__, it1, i); const IntTuple it2 (i); - VERIFY_TUPLE (it2); + test (__LINE__, it2, i); ConstIntTuple ct (i); - VERIFY_TUPLE (ct); + test (__LINE__, ct, i); - int j = INT_VALUE; + int j = std::rand (); const IntRefTuple rt (j); - VERIFY_TUPLE (rt); + test (__LINE__, rt, j); NestedTuple nt (it2); - VERIFY_TUPLE (std::get<0> (nt)); + //std::get<0> (it2) = std::rand (); // diliberately cause assertion + test (__LINE__, nt, it2); - const long l = LONG_VALUE; - const char* s = STRING_VALUE; - PairTuple pt (l, s); - verify_tuple (pt); - - UserClass::reset_totals (); - const UserClass& uc = USER_VALUE; - UserTuple ut (uc); - verify_tuple (ut, __LINE__, 0, 1); - - const bool b = BOOL_VALUE; const char c = CHAR_VALUE; - const double d = DBL_VALUE; void* const p = PTR_VALUE; - BigTuple bt (b, c, i, d, p, uc); - verify_tuple (bt); + const long l = std::rand (); + PairTuple pt (l, "string"); + test (__LINE__, pt, l, (const char*) "string"); + + const UserDefined ud (i); + UserDefined::reset (); + UserTuple ut (ud); + UserDefined::expect.copy_ctor = 1; + test (__LINE__, ut, ud); + + const bool b = true; const char c = 'a'; + const double d = 3.14159; void* const p = (void*) &i; + BigTuple bt (b, c, i, d, p, ud); + ++UserDefined::expect.copy_ctor; + test (__LINE__, bt, b, c, i, d, p, ud); } /**************************************************************************/ @@ -196,40 +213,47 @@ { rw_info (0, __FILE__, __LINE__, "value move constructor"); - IntTuple it1 (INT_VALUE); // literal constant - VERIFY_TUPLE (it1); - int i = INT_VALUE; - IntTuple it2 (i); // temporary value - VERIFY_TUPLE (it2); +#define INTEGER_CONSTANT 256 - const IntTuple it3 (INT_VALUE); - VERIFY_TUPLE (it3); + IntTuple it1 (INTEGER_CONSTANT); + test (__LINE__, it1, INTEGER_CONSTANT); + const int c = std::rand (); + int i = c; // move semantics can alter source value + IntTuple it2 (i); // temporary source value + test (__LINE__, it2, c); + + const IntTuple it3 (INTEGER_CONSTANT); + test (__LINE__, it3, INTEGER_CONSTANT); + i = c; const IntTuple it4 (i); - VERIFY_TUPLE (it4); + test (__LINE__, it4, c); - ConstIntTuple ct1 (INT_VALUE); - VERIFY_TUPLE (ct1); + ConstIntTuple ct1 (INTEGER_CONSTANT); + test (__LINE__, ct1, INTEGER_CONSTANT); + i = c; ConstIntTuple ct2 (i); - VERIFY_TUPLE (ct2); + test (__LINE__, ct2, c); // ill-formed for tuples with element types containing references - NestedTuple nt (ct1); - VERIFY_TUPLE (std::get<0> (nt)); + NestedTuple nt (it1); + test (__LINE__, nt, it1); - PairTuple pt (LONG_VALUE, STRING_VALUE); - verify_tuple (pt); + PairTuple pt (123456789L, "string"); + test (__LINE__, pt, 123456789L, (const char*) "string"); - UserClass uc (USER_VALUE); - UserClass::reset_totals (); - UserTuple ut (uc); // may alter temporary/source value - // no move semantics in UserClass currently - verify_tuple (ut, __LINE__, 0, 1); - - void* p = PTR_VALUE; - uc = USER_VALUE; - BigTuple bt (BOOL_VALUE, CHAR_VALUE, INT_VALUE, DBL_VALUE, p, uc); - verify_tuple (bt); + const UserDefined src (c); + UserDefined tmp (src); + UserDefined::reset (); + UserTuple ut (tmp); + UserDefined::expect.move_ctor = 1; + test (__LINE__, ut, src); + + tmp = src; ++UserDefined::expect.copy_asgn; + BigTuple bt (true, 'a', INTEGER_CONSTANT, 3.14159, (void*) 0, tmp); + ++UserDefined::expect.move_ctor; + test (__LINE__, bt, + true, 'a', INTEGER_CONSTANT, 3.14159, (void*) 0, src); } /**************************************************************************/ @@ -243,36 +267,40 @@ EmptyTuple et1, et2 (et1); _RWSTD_UNUSED (et2); - const IntTuple it1 (INT_VALUE); + const int ci = std::rand (); + const IntTuple it1 (ci); IntTuple it2 (it1); - VERIFY_TUPLE (it2); + test (__LINE__, it2, ci); - const ConstIntTuple& ct1 = it1; + const ConstIntTuple& ct1 = it1; // same as copy ctor ConstIntTuple ct2 (ct1); - VERIFY_TUPLE (it2); + test (__LINE__, ct2, ci); - int i = INT_VALUE; + int i = ci; const IntRefTuple rt1 (i); IntRefTuple rt2 (rt1); - VERIFY_TUPLE (rt2); + test (__LINE__, rt2, ci); const NestedTuple nt1 (it1); NestedTuple nt2 (nt1); - VERIFY_TUPLE (std::get<0> (nt2)); + test (__LINE__, nt2, it1); - const PairTuple pt1 (LONG_VALUE, STRING_VALUE); + const PairTuple pt1 (1234567890L, "string"); PairTuple pt2 (pt1); - verify_tuple (pt2); + test (__LINE__, pt2, 1234567890L, (const char*) "string"); - const UserTuple ut1 (USER_VALUE); - UserClass::reset_totals (); + UserDefined ud (ci); + const UserTuple ut1 (ud); + UserDefined::reset (); UserTuple ut2 (ut1); - verify_tuple (ut2, __LINE__, 0, 1); + ++UserDefined::expect.copy_ctor; + test (__LINE__, ut2, ud); - const BigTuple bt1 (BOOL_VALUE, CHAR_VALUE, INT_VALUE, DBL_VALUE, - PTR_VALUE, USER_VALUE); + const BigTuple bt1 (true, 'a', ci, 3.14159, (void* const) &i, ud); + ++UserDefined::expect.move_ctor; // moved ud to bt1 BigTuple bt2 (bt1); - verify_tuple (bt2); + ++UserDefined::expect.copy_ctor; // copied to bt2 + test (__LINE__, bt2, true, 'a', ci, 3.14159, (void* const) &i, ud); } /**************************************************************************/ @@ -285,33 +313,36 @@ EmptyTuple et (EmptyTuple ()); _RWSTD_UNUSED (et); - IntTuple it1 (INT_VALUE); + const int ci = std::rand (); + + IntTuple it1 (ci); IntTuple it2 (std::move (it1)); - VERIFY_TUPLE (it2); + test (__LINE__, it2, ci); - ConstIntTuple ct1 (INT_VALUE); + ConstIntTuple ct1 (ci); ConstIntTuple ct2 = std::move (ct1); - VERIFY_TUPLE (ct2); + test (__LINE__, ct2, ci); NestedTuple nt1 (it1); NestedTuple nt2 = std::move (nt1); - VERIFY_TUPLE (std::get<0> (nt2)); + test (__LINE__, nt2, it1); - PairTuple pt1 (LONG_VALUE, STRING_VALUE); + PairTuple pt1 (1234567890L, "string"); PairTuple pt2 (std::move (pt1)); - verify_tuple (pt2); + test (__LINE__, pt2, 1234567890L, (const char*) "string"); - BigTuple bt1 (BOOL_VALUE, CHAR_VALUE, INT_VALUE, DBL_VALUE, - PTR_VALUE, USER_VALUE); - BigTuple bt2 (std::move (bt1)); - verify_tuple (bt2); - - const UserClass& uc = USER_VALUE; - UserTuple ut1 (uc); - UserClass::reset_totals (); - // no move semantics in UserClass currently so it uses copy ctor + const UserDefined ud (ci); + UserTuple ut1 (ud); + UserDefined::reset (); UserTuple ut2 (std::move (ut1)); - verify_tuple (ut2, __LINE__, 0, 1); + ++UserDefined::expect.move_ctor; + test (__LINE__, ut2, ud); + + BigTuple bt1 (true, 'a', ci, 3.14159, (void*) &ci, ud); + ++UserDefined::expect.copy_ctor; + BigTuple bt2 (std::move (bt1)); + ++UserDefined::expect.move_ctor; + test (__LINE__, bt2, true, 'a', ci, 3.14159, (void*) &ci, ud); } /**************************************************************************/ @@ -327,41 +358,42 @@ et2 = et1; _RWSTD_UNUSED (et2); - const IntTuple it1 (INT_VALUE); + int i = std::rand (); + const IntTuple it1 (i); IntTuple it2; it2 = it1; - VERIFY_TUPLE (it2); + test (__LINE__, it2, i); // copy assignment ill-formed for constant element types - int i = INT_VALUE; const IntRefTuple rt1 (i); - int j = 0; + int j = -1; // outside range of rand() IntRefTuple rt2 (j); // note, different reference rt2 = rt1; - VERIFY_TUPLE (rt2); + test (__LINE__, rt2, i); NestedTuple nt1 (it1); NestedTuple nt2; nt2 = nt1; - VERIFY_TUPLE (std::get<0> (nt2)); + test (__LINE__, nt2, it1); - const PairTuple pt1 (LONG_VALUE, STRING_VALUE); + const PairTuple pt1 (long (i), "string"); PairTuple pt2; pt2 = pt1; - verify_tuple (pt2); - - const BigTuple bt1 (BOOL_VALUE, CHAR_VALUE, INT_VALUE, DBL_VALUE, - PTR_VALUE, USER_VALUE); - BigTuple bt2; - bt2 = bt1; - verify_tuple (bt2); + test (__LINE__, pt2, long (i), (const char*) "string"); - const UserTuple ut1 (USER_VALUE); + const UserDefined ud (i); + const UserTuple ut1 (ud); UserTuple ut2; - UserClass::reset_totals (); - ut2 = ut1; - verify_tuple (ut2, __LINE__, 0, 0, 1); + UserDefined::reset (); + ut2 = ut1; ++UserDefined::expect.copy_asgn; + test (__LINE__, ut2, ud); + + const BigTuple bt1 (true, 'a', i, 3.14159, (void* const) &i, ud); + ++UserDefined::expect.copy_ctor; + BigTuple bt2; ++UserDefined::expect.dflt_ctor; + bt2 = bt1; ++UserDefined::expect.copy_asgn; + test (__LINE__, bt2, true, 'a', i, 3.14159, (void* const) &i, ud); } /**************************************************************************/ @@ -376,44 +408,43 @@ et2 = std::move (et1); _RWSTD_UNUSED (et2); - IntTuple it1 (INT_VALUE); + int i = std::rand (); + + IntTuple it1 (i); IntTuple it2; it2 = std::move (it1); - VERIFY_TUPLE (it2); + test (__LINE__, it2, i); // move assignment ill-formed for constant element types NestedTuple nt1 (it2); NestedTuple nt2; nt2 = std::move (nt1); - VERIFY_TUPLE (std::get<0> (nt2)); + test (__LINE__, nt2, it2); - PairTuple pt1 (LONG_VALUE, STRING_VALUE); + PairTuple pt1 (1234567890L, "string"); PairTuple pt2; pt2 = std::move (pt1); - verify_tuple (pt2); - - BigTuple bt1 (BOOL_VALUE, CHAR_VALUE, INT_VALUE, DBL_VALUE, - PTR_VALUE, USER_VALUE); - BigTuple bt2; - bt2 = std::move (bt1); - verify_tuple (bt2); + test (__LINE__, pt2, 1234567890L, (const char*) "string"); - const UserClass& uc = USER_VALUE; - UserTuple ut1 (uc); + const UserDefined ud (i); + UserTuple ut1 (ud); UserTuple ut2; - UserClass::reset_totals (); - ut2 = std::move (ut1); - verify_tuple (ut2, __LINE__, 0, 0, 1); + UserDefined::reset (); + ut2 = std::move (ut1); ++UserDefined::expect.move_asgn; + test (__LINE__, ut2, ud); + + BigTuple bt1 (true, 'a', i, 3.14159, (void* const) &i, ud); + BigTuple bt2; + UserDefined::reset (); + bt2 = std::move (bt1); ++UserDefined::expect.move_asgn; + test (__LINE__, bt2, true, 'a', i, 3.14159, (void* const) &i, ud); } /**************************************************************************/ // heterogenous tests do not apply to empty tuples so no tests required -// UserClass does not currently contain any constructors or assignment -// operators for heterogenous types so no user tuple tests performed - #include <string> // need a string class with implicit conversion to type `const char*' @@ -426,8 +457,8 @@ typedef std::tuple<char> CompatIntTuple; typedef std::tuple<unsigned, String> CompatPairTuple; -typedef std::tuple<int, int, short, float, char*, - UserClass> CompatBigTuple; +typedef std::tuple<int, int, short, float, + char*, UserDefined> CompatBigTuple; static void test_hetero_copy_ctor () @@ -435,18 +466,24 @@ rw_info (0, __FILE__, __LINE__, "copy constructor (heterogenous tuples)"); - const CompatIntTuple ct1 (INT_VALUE); - IntTuple it (ct1); - VERIFY_TUPLE (it); - - CompatPairTuple ct2 (LONG_VALUE, STRING_VALUE); - PairTuple pt (ct2); - verify_tuple (pt); - - const CompatBigTuple ct3 (BOOL_VALUE, CHAR_VALUE, INT_VALUE, - DBL_VALUE, (char*) PTR_VALUE, USER_VALUE); - BigTuple bt (ct3); - verify_tuple (bt); + int i = 0; + do i = std::rand (); + while (i > CHAR_MAX); + + const CompatIntTuple cit (static_cast<char> (i)); + IntTuple it (cit); + test (__LINE__, it, i); + + CompatPairTuple cpt (12345U, "string"); + PairTuple pt (cpt); + test (__LINE__, pt, 12345U, (const char*) "string"); + + char s [] = "string"; const UserDefined ud (i); + const CompatBigTuple cbt (int (true), int ('a'), short (i), + 3.14159f, s, ud); + UserDefined::reset (); + BigTuple bt (cbt); ++UserDefined::expect.copy_ctor; + test (__LINE__, bt, true, 'a', i, 3.14159f, s, ud); } /**************************************************************************/ @@ -457,18 +494,24 @@ rw_info (0, __FILE__, __LINE__, "move constructor (heterogenous tuples)"); - CompatIntTuple ct1 (INT_VALUE); - IntTuple it (std::move (ct1)); - VERIFY_TUPLE (it); - - CompatPairTuple ct2 (LONG_VALUE, STRING_VALUE); - PairTuple pt (std::move (ct2)); - verify_tuple (pt); - - CompatBigTuple ct3 (BOOL_VALUE, CHAR_VALUE, INT_VALUE, - DBL_VALUE, (char*) PTR_VALUE, USER_VALUE); - BigTuple bt (std::move (ct3)); - verify_tuple (bt); + int i = 0; + do i = std::rand (); + while (i > CHAR_MAX); + + CompatIntTuple cit (static_cast<char> (i)); + IntTuple it (std::move (cit)); + test (__LINE__, it, i); + + CompatPairTuple cpt (12345U, "string"); + PairTuple pt (std::move (cpt)); + test (__LINE__, pt, 12345U, (const char*) "string"); + + char s [] = "string"; const UserDefined ud (i); + CompatBigTuple cbt (int (true), int ('a'), short (i), + 3.14159f, s, ud); + UserDefined::reset (); + BigTuple bt (std::move (cbt)); ++UserDefined::expect.move_ctor; + test (__LINE__, bt, true, 'a', i, 3.14159f, s, ud); } /**************************************************************************/ @@ -478,21 +521,28 @@ { rw_info (0, __FILE__, __LINE__, "copy assignment operator (heterogenous tuples)"); - CompatIntTuple ct1 (INT_VALUE); + + int i = 0; + do i = std::rand (); + while (i > CHAR_MAX); + + CompatIntTuple cit (static_cast<char> (i)); IntTuple it; - it = ct1; - VERIFY_TUPLE (it); + it = cit; + test (__LINE__, it, i); - CompatPairTuple ct2 (LONG_VALUE, STRING_VALUE); + CompatPairTuple cpt (12345U, "string"); PairTuple pt; - pt = ct2; - verify_tuple (pt); + pt = cpt; + test (__LINE__, pt, 12345U, (const char*) "string"); - CompatBigTuple ct3 (BOOL_VALUE, CHAR_VALUE, INT_VALUE, - DBL_VALUE, (char*) PTR_VALUE, USER_VALUE); + char s [] = "string"; const UserDefined ud (i); + CompatBigTuple cbt (int (true), int ('a'), short (i), + 3.14159f, s, ud); BigTuple bt; - bt = ct3; - verify_tuple (bt); + UserDefined::reset (); + bt = cbt; ++UserDefined::expect.copy_asgn; + test (__LINE__, bt, true, 'a', i, 3.14159f, s, ud); } /**************************************************************************/ @@ -503,21 +553,27 @@ rw_info (0, __FILE__, __LINE__, "move assignment operator (heterogenous tuples)"); - CompatIntTuple ct1 (INT_VALUE); + int i = 0; + do i = std::rand (); + while (i > CHAR_MAX); + + CompatIntTuple cit (i); IntTuple it; - it = std::move (ct1); - VERIFY_TUPLE (it); + it = std::move (cit); + test (__LINE__, it, i); - CompatPairTuple ct2 (LONG_VALUE, STRING_VALUE); + CompatPairTuple cpt (12345U, "string"); PairTuple pt; - pt = std::move (ct2); - verify_tuple (pt); + pt = std::move (cpt); + test (__LINE__, pt, 12345U, (const char*) "string"); - CompatBigTuple ct3 (BOOL_VALUE, CHAR_VALUE, INT_VALUE, - DBL_VALUE, (char*) PTR_VALUE, USER_VALUE); - BigTuple bt; - bt = std::move (ct3); - verify_tuple (bt); + char s [] = "string"; const UserDefined ud (i); + CompatBigTuple cbt (int (true), int ('a'), short (i), + 3.14159f, s, ud); + BigTuple bt; ++UserDefined::expect.move_ctor; + UserDefined::reset (); + bt = std::move (cbt); ++UserDefined::expect.move_asgn; + test (__LINE__, bt, true, 'a', i, 3.14159f, s, ud); } /**************************************************************************/ @@ -535,13 +591,10 @@ /**************************************************************************/ static int -run_test (int /*argc*/, char* argv []) +run_test (int /*argc*/, char* /*argv*/ []) { test_default_ctor (); - ptr_val = argv [0]; - user_val.data_.val_ = INT_VALUE; - test_value_copy_ctor (); test_value_move_ctor (); Modified: stdcxx/branches/4.3.x/tests/utilities/20.tuple.creation.cpp URL: http://svn.apache.org/viewvc/stdcxx/branches/4.3.x/tests/utilities/20.tuple.creation.cpp?rev=677458&r1=677457&r2=677458&view=diff ============================================================================== --- stdcxx/branches/4.3.x/tests/utilities/20.tuple.creation.cpp (original) +++ stdcxx/branches/4.3.x/tests/utilities/20.tuple.creation.cpp Wed Jul 16 15:49:27 2008 @@ -84,22 +84,19 @@ /**************************************************************************/ -#define Big1stPart bool, char, int, double -#define Big2ndPart void*, UserClass - static void test_tuple_cat () { rw_info (0, __FILE__, __LINE__, "tuple_cat"); #define Big1stPart bool, char, int, double -#define Big2ndPart void*, UserClass +#define Big2ndPart void*, UserDefined typedef std::tuple<Big1stPart> Big1stTuple; Big1stTuple bt1 (true, 'a', 256, 3.14159); typedef std::tuple<Big2ndPart> Big2ndTuple; - Big2ndTuple bt2 (&bt1, UserClass ()); + Big2ndTuple bt2 (&bt1, UserDefined ()); //BigTuple bt (tuple_cat (bt1, bt2)); } Modified: stdcxx/branches/4.3.x/tests/utilities/20.tuple.elem.cpp URL: http://svn.apache.org/viewvc/stdcxx/branches/4.3.x/tests/utilities/20.tuple.elem.cpp?rev=677458&r1=677457&r2=677458&view=diff ============================================================================== --- stdcxx/branches/4.3.x/tests/utilities/20.tuple.elem.cpp (original) +++ stdcxx/branches/4.3.x/tests/utilities/20.tuple.elem.cpp Wed Jul 16 15:49:27 2008 @@ -48,7 +48,7 @@ #define USER_VAL user_val static void* ptr_val; -static UserClass user_val; +static UserDefined user_val; static void test_const_get (const BigTuple& bt) @@ -75,10 +75,10 @@ rw_assert (p == PTR_VAL, __FILE__, __LINE__, "get<4>(bt), got %p, expected %p", p, PTR_VAL); - const UserClass& uc = std::get<5> (bt); + const UserDefined& uc = std::get<5> (bt); rw_assert (uc == USER_VAL, __FILE__, __LINE__, "get<5>(bt), got %d, expected %d", - uc.data_.val_, USER_VAL.data_.val_); + uc.value (), USER_VAL.value ()); } /**************************************************************************/ @@ -127,14 +127,14 @@ rw_assert (std::get<4> (bt) == &d, __FILE__, __LINE__, "get<4>(bt), got %p, expected %p", std::get<4> (bt), &d); - UserClass& uc = std::get<5> (bt); + UserDefined& uc = std::get<5> (bt); rw_assert (uc == USER_VAL, __FILE__, __LINE__, "get<5>(bt), got %d, expected %d", - uc.data_.val_, USER_VAL.data_.val_); - uc.data_.val_ = INT_VAL; - rw_assert ((std::get<5> (bt)).data_.val_ == INT_VAL, __FILE__, __LINE__, + uc.value (), USER_VAL.value ()); + uc = UserDefined (INT_VAL); + rw_assert ((std::get<5> (bt)).value () == INT_VAL, __FILE__, __LINE__, "get<5>(bt), got %d, expected %d", - (std::get<5> (bt)).data_.val_, INT_VAL); + (std::get<5> (bt)).value (), INT_VAL); } /**************************************************************************/ Modified: stdcxx/branches/4.3.x/tests/utilities/20.tuple.h URL: http://svn.apache.org/viewvc/stdcxx/branches/4.3.x/tests/utilities/20.tuple.h?rev=677458&r1=677457&r2=677458&view=diff ============================================================================== --- stdcxx/branches/4.3.x/tests/utilities/20.tuple.h (original) +++ stdcxx/branches/4.3.x/tests/utilities/20.tuple.h Wed Jul 16 15:49:27 2008 @@ -29,10 +29,141 @@ #ifndef RW_20_TUPLE_H_INCLUDED #define RW_20_TUPLE_H_INCLUDED +#include <ostream> // for std::ostream #include <tuple> +#include <type_traits> // for std::decay +#include <utility> // for std::move -#include <rw_value.h> // for UserClass +// user-defined class for tuple testing (similar to UserClass) + +class UserDefined +{ + + int value_; // some arbitrary value + +public: + + // types + + typedef int value_type; + typedef unsigned size_type; + + struct count_type // number of constructors/operators called + { + size_type dflt_ctor; + size_type copy_ctor; + size_type tmpl_ctor; + size_type move_ctor; + size_type copy_asgn; + size_type tmpl_asgn; + size_type move_asgn; + }; + + static count_type actual; // since last reset() + static count_type expect; // modified by expect() + + + // constructors + + UserDefined () + : value_ () { ++actual.dflt_ctor; } + + UserDefined (const UserDefined& src) + : value_ (src.value_) { ++actual.copy_ctor; } + +#if !defined _RWSTD_NO_RVALUE_REFERENCES + + UserDefined (UserDefined&& src) + : value_ (std::move (src.value_)) + { ++actual.move_ctor; } + + // Requires: U is convertible to `value_type'. + template <class U > + explicit UserDefined (U&& u) + : value_ (std::move (u)) { ++actual.tmpl_ctor; } + +#endif // !defined _RWSTD_NO_RVALUE_REFERENCES + + + // assignment + + UserDefined& operator= (const UserDefined& src) + { + value_ = src.value_; + ++actual.copy_asgn; + return *this; + } + + template <class U> + UserDefined& operator= (const U& src) + { + value_ = src; + ++actual.tmpl_asgn; + return *this; + } + +#if !defined _RWSTD_NO_RVALUE_REFERENCES + + UserDefined& operator= (const UserDefined&& src) + { + value_ = std::move (src.value_); + ++actual.move_asgn; + return *this; + } + +#endif // !defined _RWSTD_NO_RVALUE_REFERENCES + + + // accessors + + value_type value () const { return value_; } + + //void value (const value_type& value) { value_ = value; } + + // testing + + static void reset () + { + actual.dflt_ctor = actual.copy_ctor = actual.tmpl_ctor = + actual.move_ctor = actual.copy_asgn = actual.move_asgn = + actual.tmpl_asgn = 0; + + expect.dflt_ctor = expect.copy_ctor = expect.tmpl_ctor = + expect.move_ctor = expect.copy_asgn = expect.move_asgn = + expect.tmpl_asgn = 0; + } + + + // implicit value_type conversion? +}; + +UserDefined::count_type +UserDefined::actual = { 0, 0, 0, 0, 0, 0, 0 }; + +UserDefined::count_type +UserDefined::expect = { 0, 0, 0, 0, 0, 0, 0 }; + +inline bool +operator== (const UserDefined& lhs, const UserDefined& rhs) +{ + return lhs.value () == rhs.value (); +} + +inline bool +operator< (const UserDefined& lhs, const UserDefined& rhs) +{ + return lhs.value () < rhs.value (); +} + +inline std::ostream& +operator< (std::ostream& os, const UserDefined& src) +{ + os << "UserDefined@" << &src << " [value_ = " << src.value () << "]"; + return os; +} + +/**************************************************************************/ // various tuple types for test purposes @@ -46,12 +177,76 @@ typedef std::tuple <long, const char*> PairTuple; -typedef std::tuple <UserClass> UserTuple; +typedef std::tuple <UserDefined> UserTuple; -#define BIG_TYPES bool, char, int, double, void*, UserClass +#define BIG_TYPES bool, char, int, double, void*, UserDefined #define BIG_SIZE 6 typedef std::tuple <BIG_TYPES> BigTuple; +// tuple names + +template <class T> +struct type_name_ { static const char* value; }; + +#define TYPE_NAME(T) \ +template <> const char* type_name_<T>::value = #T; + +TYPE_NAME (std::tuple<>) +TYPE_NAME (std::tuple<int>) +TYPE_NAME (std::tuple<const int>) +TYPE_NAME (std::tuple<int&>) +TYPE_NAME (std::tuple<std::tuple<int> >) +TYPE_NAME (std::tuple<UserDefined>) + +#undef TYPE_NAME +#define TYPE_NAME(T, S) \ +template <> const char* type_name_<T>::value = S; + +#undef TUPLE +#define TUPLE std::tuple<long, const char*> +TYPE_NAME (TUPLE, "std::tuple<long, const char*>") + +#undef TUPLE +#define TUPLE std::tuple<BIG_TYPES> +// should use BIG_TYPES in string if possible +TYPE_NAME (TUPLE, "std::tuple<bool, char, int, double, void*, " \ + "UserDefined>") + +#undef TUPLE + +#undef TYPE_NAME +#define TYPE_NAME(T) type_name_<T>::value + +/**************************************************************************/ + +// formatting specifiers + +template <class T> +struct fmt_spec { static const char* value; }; + +#define FMT_SPEC(T, S) \ +template <> const char* fmt_spec<T>::value = #S; + +FMT_SPEC (bool, %b) +FMT_SPEC (char, %c) +FMT_SPEC (int, %d) +FMT_SPEC (unsigned, %u) +FMT_SPEC (long, %ld) +FMT_SPEC (float, %f) +FMT_SPEC (double, %f) +FMT_SPEC (char*, %s) +FMT_SPEC (char const*, %s) +FMT_SPEC (void*, %p) +FMT_SPEC (void const*, %p) + +#undef DECAY +#define DECAY(T) typename std::decay<T>::type + +// ignore cv-qualifiers and references +#undef FMT_SPEC +#define FMT_SPEC(T) fmt_spec<DECAY (T)>::value + + #endif // define RW_20_TUPLE_H_INCLUDED Modified: stdcxx/branches/4.3.x/tests/utilities/20.tuple.helpers.cpp URL: http://svn.apache.org/viewvc/stdcxx/branches/4.3.x/tests/utilities/20.tuple.helpers.cpp?rev=677458&r1=677457&r2=677458&view=diff ============================================================================== --- stdcxx/branches/4.3.x/tests/utilities/20.tuple.helpers.cpp (original) +++ stdcxx/branches/4.3.x/tests/utilities/20.tuple.helpers.cpp Wed Jul 16 15:49:27 2008 @@ -73,7 +73,7 @@ enum { inherited, const_int, - user_class, + user_defined, int_tuple } type_id; @@ -86,8 +86,8 @@ any_t (const int) : rw_any_t (char ()), type_id (const_int) { } - any_t (UserClass) - : rw_any_t (char ()), type_id (user_class) { } + any_t (UserDefined) + : rw_any_t (char ()), type_id (user_defined) { } any_t (std::tuple< int >) : rw_any_t (char ()), type_id (int_tuple) { } @@ -95,7 +95,7 @@ const char* type_name () const { return type_id == const_int? "const int": - type_id == user_class? "UserClass": + type_id == user_defined? "UserDefined": type_id == int_tuple? "std::tuple<int>": rw_any_t::type_name (); } @@ -121,7 +121,7 @@ TEST (0, IntTuple, int); TEST (0, ConstIntTuple, const int); TEST (0, NestedTuple, std::tuple<int>); - TEST (0, UserTuple, UserClass); + TEST (0, UserTuple, UserDefined); TEST (0, PairTuple, long); TEST (1, PairTuple, const char*); @@ -131,7 +131,7 @@ TEST (2, BigTuple, int); TEST (3, BigTuple, double); TEST (4, BigTuple, void*); - TEST (5, BigTuple, UserClass); + TEST (5, BigTuple, UserDefined); } /**************************************************************************/ Modified: stdcxx/branches/4.3.x/tests/utilities/20.tuple.rel.cpp URL: http://svn.apache.org/viewvc/stdcxx/branches/4.3.x/tests/utilities/20.tuple.rel.cpp?rev=677458&r1=677457&r2=677458&view=diff ============================================================================== --- stdcxx/branches/4.3.x/tests/utilities/20.tuple.rel.cpp (original) +++ stdcxx/branches/4.3.x/tests/utilities/20.tuple.rel.cpp Wed Jul 16 15:49:27 2008 @@ -55,15 +55,15 @@ rw_assert (it1 == it2, __FILE__, __LINE__, "it1 == it2, got false, expected true"); - UserClass uc; - UserTuple ut1 (uc), ut2 (uc); + UserDefined ud; + UserTuple ut1 (ud), ut2 (ud); rw_assert (ut1 == ut1, __FILE__, __LINE__, "ut1 == ut1, got false, expected true"); rw_assert (ut1 == ut2, __FILE__, __LINE__, "ut1 == ut2, got false, expected true"); - BigTuple bt1 (true, 'a', 256, 3.14159, &nt1, uc); - BigTuple bt2 (true, 'a', 256, 3.14159, &nt1, uc); + BigTuple bt1 (true, 'a', 256, 3.14159, &nt1, ud); + BigTuple bt2 (true, 'a', 256, 3.14159, &nt1, ud); rw_assert (bt1 == bt1, __FILE__, __LINE__, "bt1 == bt1, got false, expected true"); rw_assert (bt1 == bt2, __FILE__, __LINE__, @@ -87,15 +87,13 @@ rw_assert (it1 < it2, __FILE__, __LINE__, "it1 < it2, got false, expected true"); - UserClass uc1, uc2; - uc1.data_.val_ = 1, uc2.data_.val_ = 2; - - UserTuple ut1 (uc1), ut2 (uc2); + UserDefined ud1 (1), ud2 (2); + UserTuple ut1 (ud1), ut2 (ud2); rw_assert (ut1 < ut2, __FILE__, __LINE__, "ut1 < ut2, got false, expected true"); - BigTuple bt1 (true, 'a', 255, 3.14159, &nt1, uc1); - BigTuple bt2 (true, 'a', 256, 3.14159, &nt1, uc1); + BigTuple bt1 (true, 'a', 255, 3.14159, &nt1, ud1); + BigTuple bt2 (true, 'a', 256, 3.14159, &nt1, ud1); rw_assert (bt1 < bt2, __FILE__, __LINE__, "bt1 < bt2, got false, expected true"); }