You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stdcxx.apache.org by el...@apache.org on 2008/07/09 01:13:36 UTC

svn commit: r675044 - in /stdcxx/branches/4.3.x: include/rw/_tuple.h include/tuple tests/utilities/20.tuple.cnstr.cpp tests/utilities/20.tuple.creation.cpp tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp

Author: elemings
Date: Tue Jul  8 16:13:36 2008
New Revision: 675044

URL: http://svn.apache.org/viewvc?rev=675044&view=rev
Log:
2008-07-08  Eric Lemings <er...@roguewave.com>

	STDCXX-958
	* include/tuple: Second parameter in value move ctor of pair
	specialization missing rvalue reference.
	(make_tuple, get, relational operators): Explicitly declare
	as inline functions.
	(tie): Implemented.
	* include/rw/_tuple.h: Fix move semantics in heterogenous move
	assignment operator.
	(__rw_ignore): Add assignment operator to ignore all values.
	* tests/utilities/20.tuple.cnstr.cpp: Added V&V for tuple
	state and invariants.  Manually inspected proper construction
	of all test tuples.  Updated/corrected/added tests as necessary.
	* tests/utilities/20.tuple.creation.cpp: Added simple tie()
	test.
	* tests/utilities/20.tuple.h: Minor stylistic changes.
	* tests/utilities/20.tuple.helpers.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.h
    stdcxx/branches/4.3.x/tests/utilities/20.tuple.helpers.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=675044&r1=675043&r2=675044&view=diff
==============================================================================
--- stdcxx/branches/4.3.x/include/rw/_tuple.h (original)
+++ stdcxx/branches/4.3.x/include/rw/_tuple.h Tue Jul  8 16:13:36 2008
@@ -127,7 +127,7 @@
 
     template <class _HeadU, class... _TailU>
     __rw_tuple& operator= (__rw_tuple<_HeadU, _TailU...>&& __tuple) {
-        _Base::operator= (_RWSTD_FORWARD (_Base, __tuple._C_tail ()));
+        _Base::operator= (_RWSTD_MOVE (__tuple._C_tail ()));
         _C_data = _RWSTD_MOVE (__tuple._C_head ());
         return *this;
     }
@@ -174,7 +174,14 @@
 };
 
 
-struct __rw_ignore { /* empty */ };
+struct __rw_ignore
+{
+    template <class _TypeT>
+    inline __rw_ignore const&
+    operator= (const _TypeT& /*unused*/) const {
+        return *this;
+    }
+};
 
 
 template <class _TypeT>

Modified: stdcxx/branches/4.3.x/include/tuple
URL: http://svn.apache.org/viewvc/stdcxx/branches/4.3.x/include/tuple?rev=675044&r1=675043&r2=675044&view=diff
==============================================================================
--- stdcxx/branches/4.3.x/include/tuple (original)
+++ stdcxx/branches/4.3.x/include/tuple Tue Jul  8 16:13:36 2008
@@ -211,7 +211,7 @@
 #    if !defined _RWSTD_NO_RVALUE_REFERENCES
 
     template <class _TypeU1, class _TypeU2>
-    _EXPLICIT tuple (_TypeU1&& __x, _TypeU2 __y)
+    _EXPLICIT tuple (_TypeU1&& __x, _TypeU2&& __y)
         : _Base (_RWSTD_FORWARD (_TypeU1, __x),
                  _RWSTD_FORWARD (_TypeU2, __y)) { /* empty */ }
 
@@ -294,7 +294,7 @@
 #    if !defined _RWSTD_NO_RVALUE_REFERENCES
 
 template <class... _TypesT>
-tuple<_TYPENAME _RW::__rw_make_tuple<_TypesT>::_C_type...>
+inline tuple<_TYPENAME _RW::__rw_make_tuple<_TypesT>::_C_type...>
 make_tuple (_TypesT&&... __values)
 {
     typedef tuple<_TYPENAME _RW::__rw_make_tuple<_TypesT>::_C_type...> _Tuple;
@@ -326,7 +326,11 @@
 
 
 template <class... _TypesT>
-tuple<_TypesT&...> tie (_TypesT&...);
+inline tuple<_TypesT&...>
+tie (_TypesT&... __values)
+{
+    return tuple<_TypesT&...> (__values...);
+}
 
 
 // 20.3.1.4, tuple helper classes:
@@ -377,7 +381,7 @@
 // 20.3.1.5, element access:
 
 template <_RWSTD_SIZE_T _Index, class _Head, class... _Tail>
-_TYPENAME tuple_element<_Index, tuple<_Head, _Tail...> >::_Ref
+inline _TYPENAME tuple_element<_Index, tuple<_Head, _Tail...> >::_Ref
 get (tuple<_Head, _Tail...>& __tuple)
 {
     typedef tuple_element<_Index, tuple<_Head, _Tail...> > _Tuple;
@@ -385,7 +389,7 @@
 }
 
 template <_RWSTD_SIZE_T _Index, class _Head, class... _Tail>
-_TYPENAME tuple_element<_Index, tuple<_Head, _Tail...> >::_ConstRef
+inline _TYPENAME tuple_element<_Index, tuple<_Head, _Tail...> >::_ConstRef
 get (const tuple<_Head, _Tail...>& __tuple)
 {
     typedef tuple_element<_Index, tuple<_Head, _Tail...> > _Tuple;
@@ -396,59 +400,67 @@
 // 20.3.1.6, relational operators:
 
 template <class... _TypesT, class... _TypesU>
-bool operator== (const tuple<_TypesT...>& __x,
-                 const tuple<_TypesU...>& __y)
+inline bool
+operator== (const tuple<_TypesT...>& __x,
+            const tuple<_TypesU...>& __y)
 {
     return _RWSTD_STATIC_CAST (const _RW::__rw_tuple<_TypesT...>&, __x)
            == _RWSTD_STATIC_CAST (const _RW::__rw_tuple<_TypesU...>&, __y);
 }
 
 _RWSTD_SPECIALIZED_FUNCTION
-bool operator== (const tuple<>& /*__x*/,
-                 const tuple<>& /*__y*/)
+inline bool
+operator== (const tuple<>& /*__x*/,
+            const tuple<>& /*__y*/)
 {
     return true;
 }
 
 template <class... _TypesT, class... _TypesU>
-bool operator< (const tuple<_TypesT...>& __x,
-                const tuple<_TypesU...>& __y)
+inline bool
+operator< (const tuple<_TypesT...>& __x,
+           const tuple<_TypesU...>& __y)
 {
     return _RWSTD_STATIC_CAST (const _RW::__rw_tuple<_TypesT...>&, __x)
            < _RWSTD_STATIC_CAST (const _RW::__rw_tuple<_TypesU...>&, __y);
 }
 
 _RWSTD_SPECIALIZED_FUNCTION
-bool operator< (const tuple<>& /*__x*/,
-                const tuple<>& /*__y*/)
+inline bool
+operator< (const tuple<>& /*__x*/,
+           const tuple<>& /*__y*/)
 {
     return false;
 }
 
 template <class... _TypesT, class... _TypesU>
-bool operator!= (const tuple<_TypesT...>& __x,
-                 const tuple<_TypesU...>& __y)
+inline bool
+operator!= (const tuple<_TypesT...>& __x,
+            const tuple<_TypesU...>& __y)
 {
     return !(__x == __y);
 }
 
 template <class... _TypesT, class... _TypesU>
-bool operator> (const tuple<_TypesT...>& __x,
-                const tuple<_TypesU...>& __y)
+inline bool
+operator> (const tuple<_TypesT...>& __x,
+           const tuple<_TypesU...>& __y)
 {
     return __y < __x;
 }
 
 template <class... _TypesT, class... _TypesU>
-bool operator<= (const tuple<_TypesT...>& __x,
-                 const tuple<_TypesU...>& __y)
+inline bool
+operator<= (const tuple<_TypesT...>& __x,
+            const tuple<_TypesU...>& __y)
 {
     return !(__y < __x);
 }
 
 template <class... _TypesT, class... _TypesU>
-bool operator>= (const tuple<_TypesT...>& __x,
-                 const tuple<_TypesU...>& __y)
+inline bool
+operator>= (const tuple<_TypesT...>& __x,
+            const tuple<_TypesU...>& __y)
 {
     return !(__x < __y);
 }

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=675044&r1=675043&r2=675044&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 Tue Jul  8 16:13:36 2008
@@ -32,8 +32,11 @@
 #if    !defined (_RWSTD_NO_EXT_CXX_0X) \
     && !defined(_RWSTD_NO_RVALUE_REFERENCES)
 
+#include <cstring>              // for strcmp
 #include <tuple>
 
+#include <rw_valcmp.h>          // for rw_dblcmp
+
 #include "20.tuple.h"
 
 /**************************************************************************/
@@ -46,7 +49,7 @@
     EmptyTuple et; _RWSTD_UNUSED (et);
     IntTuple it; _RWSTD_UNUSED (it);
     ConstIntTuple ct; _RWSTD_UNUSED (ct);
-    //IntRefTuple rt; _RWSTD_UNUSED (rt); // ill-formed for references
+    // ill-formed for tuples with element types containing references
     PairTuple pt; _RWSTD_UNUSED (pt);
     NestedTuple nt; _RWSTD_UNUSED (nt);
     BigTuple bt; _RWSTD_UNUSED (bt);
@@ -57,80 +60,174 @@
     rw_assert (1 == UserClass::n_total_def_ctor_, __FILE__, __LINE__,
                "tuple<UserClass>::tuple() called %d default ctors, "
                "expected 1", UserClass::n_total_def_ctor_);
-    rw_assert (0 == UserClass::n_total_copy_ctor_, __FILE__, __LINE__,
-               "tuple<UserClass>::tuple() called %d copy ctors, "
-               "expected 0", UserClass::n_total_copy_ctor_);
 }
 
 /**************************************************************************/
 
+#define INT_VALUE       int ('a')
+
+// 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);
+
+
+#define LONG_VALUE      INT_VALUE
+#define STRING_VALUE    "string"
+
 static void
-test_value_copy_ctor ()
+verify_tuple (const PairTuple& pt)
 {
-    rw_info (0, __FILE__, __LINE__, "value copy constructor");
+    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);
+}
 
-    int i = 1;
-    IntTuple it1 (i); _RWSTD_UNUSED (it1);
-    const IntTuple it2 (i); _RWSTD_UNUSED (it2);
-    ConstIntTuple ct (i); _RWSTD_UNUSED (ct);
-    IntRefTuple rt (i); _RWSTD_UNUSED (rt);
 
-    NestedTuple nt (it2); _RWSTD_UNUSED (nt);
+#define USER_VALUE      user_val
 
-    const long l = 1;
-    const char* s = "string";
-    PairTuple pt (l, s);
+static UserClass user_val;
 
-    UserClass::reset_totals ();
-    const UserClass uc;
-    UserTuple ut (uc); _RWSTD_UNUSED (ut);
+typedef unsigned int uint_t;
 
-    rw_assert (1 == UserClass::n_total_def_ctor_, __FILE__, __LINE__,
+static void
+verify_tuple (const UserTuple& ut, int line,
+              uint_t dflt = 0, uint_t copy = 0, uint_t asgn = 0)
+{
+    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_);
+
+    rw_assert (dflt == UserClass::n_total_def_ctor_, __FILE__, line,
                "tuple<UserClass>::tuple() called %d default ctors, "
-               "expected 1", UserClass::n_total_def_ctor_);
-    rw_assert (1 == UserClass::n_total_copy_ctor_, __FILE__, __LINE__,
+               "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 1", UserClass::n_total_copy_ctor_);
+               "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);
+}
+
 
-    const bool b = true; const char c = 'a';
-    const double d = 1.2; void* const p = 0;
-    BigTuple bt (b, c, i, d, p, uc); _RWSTD_UNUSED (bt);
+#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)
+{
+    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);
+    int result = rw_dblcmp (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);
 }
 
 /**************************************************************************/
 
 static void
-test_value_move_ctor ()
+test_value_copy_ctor ()
 {
-    rw_info (0, __FILE__, __LINE__, "value move constructor");
-
-    IntTuple it1 (1); _RWSTD_UNUSED (it1);
-    IntTuple it2 (int ()); _RWSTD_UNUSED (it2);
+    rw_info (0, __FILE__, __LINE__, "value copy constructor");
 
-    const IntTuple it3 (1); _RWSTD_UNUSED (it3);
-    const IntTuple it4 (const IntTuple ()); _RWSTD_UNUSED (it4);
+    const int i = INT_VALUE;
+    IntTuple it1 (i);
+    VERIFY_TUPLE (it1);
 
-    ConstIntTuple ct1 (1); _RWSTD_UNUSED (ct1);
-    ConstIntTuple ct2 (ConstIntTuple ()); _RWSTD_UNUSED (ct2);
+    const IntTuple it2 (i);
+    VERIFY_TUPLE (it2);
 
-    IntRefTuple rt2 (int ()); _RWSTD_UNUSED (rt2);
+    ConstIntTuple ct (i);
+    VERIFY_TUPLE (ct);
 
-    NestedTuple nt (ct1); _RWSTD_UNUSED (nt);
+    int j = INT_VALUE;
+    const IntRefTuple rt (j);
+    VERIFY_TUPLE (rt);
 
-    PairTuple pt (1L, "string"); _RWSTD_UNUSED (pt);
+    NestedTuple nt (it2);
+    VERIFY_TUPLE (std::get<0> (nt));
 
-    BigTuple bt (true, 'a', 1, 1.0, (void*)0, UserClass ());
-    _RWSTD_UNUSED (bt);
+    const long l = LONG_VALUE;
+    const char* s = STRING_VALUE;
+    PairTuple pt (l, s);
+    verify_tuple (pt);
 
     UserClass::reset_totals ();
-    UserTuple ut (UserClass ()); _RWSTD_UNUSED (ut);
+    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);
+}
 
-    rw_assert (0 == UserClass::n_total_def_ctor_, __FILE__, __LINE__,
-               "tuple<UserClass>::tuple() called %d default ctors, "
-               "expected 0", UserClass::n_total_def_ctor_);
-    rw_assert (0 == UserClass::n_total_copy_ctor_, __FILE__, __LINE__,
-               "tuple<UserClass>::tuple() called %d copy ctors, "
-               "expected 0", UserClass::n_total_copy_ctor_);
+/**************************************************************************/
+
+static void
+test_value_move_ctor ()
+{
+    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);
+
+    const IntTuple it3 (INT_VALUE);
+    VERIFY_TUPLE (it3);
+    const IntTuple it4 (i);
+    VERIFY_TUPLE (it4);
+
+    ConstIntTuple ct1 (INT_VALUE);
+    VERIFY_TUPLE (ct1);
+    ConstIntTuple ct2 (i);
+    VERIFY_TUPLE (ct2);
+
+    // ill-formed for tuples with element types containing references
+
+    NestedTuple nt (ct1);
+    VERIFY_TUPLE (std::get<0> (nt));
+
+    PairTuple pt (LONG_VALUE, STRING_VALUE);
+    verify_tuple (pt);
+
+    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);
 }
 
 /**************************************************************************/
@@ -144,34 +241,36 @@
     EmptyTuple et1, et2 (et1);
     _RWSTD_UNUSED (et2);
 
-    const IntTuple it1;
-    IntTuple it2 (it1); _RWSTD_UNUSED (it2);
-
-    const ConstIntTuple ct1;
-    ConstIntTuple ct2 (ct1); _RWSTD_UNUSED (ct2);
-
-    int i; const IntRefTuple rt1 (i);
-    IntRefTuple rt2 (rt1); _RWSTD_UNUSED (rt2);
-
-    const PairTuple pt1;
-    PairTuple pt2 (pt1); _RWSTD_UNUSED (pt2);
-
-    const NestedTuple nt1;
-    NestedTuple nt2 (nt1); _RWSTD_UNUSED (nt2);
+    const IntTuple it1 (INT_VALUE);
+    IntTuple it2 (it1);
+    VERIFY_TUPLE (it2);
+
+    const ConstIntTuple& ct1 = it1;
+    ConstIntTuple ct2 (ct1);
+    VERIFY_TUPLE (it2);
+
+    int i = INT_VALUE;
+    const IntRefTuple rt1 (i);
+    IntRefTuple rt2 (rt1);
+    VERIFY_TUPLE (rt2);
+
+    const NestedTuple nt1 (it1);
+    NestedTuple nt2 (nt1);
+    VERIFY_TUPLE (std::get<0> (nt2));
+
+    const PairTuple pt1 (LONG_VALUE, STRING_VALUE);
+    PairTuple pt2 (pt1);
+    verify_tuple (pt2);
 
+    const UserTuple ut1 (USER_VALUE);
     UserClass::reset_totals ();
-    const UserTuple ut1; UserTuple ut2 (ut1);
-    _RWSTD_UNUSED (ut1);
+    UserTuple ut2 (ut1);
+    verify_tuple (ut2, __LINE__, 0, 1);
 
-    rw_assert (1 == UserClass::n_total_def_ctor_, __FILE__, __LINE__,
-               "tuple<UserClass>::tuple() called %d default ctors, "
-               "expected 1", UserClass::n_total_def_ctor_);
-    rw_assert (1 == UserClass::n_total_copy_ctor_, __FILE__, __LINE__,
-               "tuple<UserClass>::tuple() called %d copy ctors, "
-               "expected 1", UserClass::n_total_copy_ctor_);
-
-    const BigTuple bt1; BigTuple bt2 (bt1);
-    _RWSTD_UNUSED (bt1); _RWSTD_UNUSED (bt2);
+    const BigTuple bt1 (BOOL_VALUE, CHAR_VALUE, INT_VALUE, DBL_VALUE,
+                        PTR_VALUE, USER_VALUE);
+    BigTuple bt2 (bt1);
+    verify_tuple (bt2);
 }
 
 /**************************************************************************/
@@ -183,20 +282,34 @@
              "move constructor (homogenous tuples)");
 
     EmptyTuple et (EmptyTuple ()); _RWSTD_UNUSED (et);
-    IntTuple it (IntTuple ()); _RWSTD_UNUSED (it);
-    ConstIntTuple ct (ConstIntTuple ()); _RWSTD_UNUSED (ct);
-    PairTuple pt (PairTuple ()); _RWSTD_UNUSED (pt);
-    NestedTuple nt (NestedTuple ()); _RWSTD_UNUSED (nt);
-    BigTuple bt (BigTuple ());
 
+    IntTuple it1 (INT_VALUE);
+    IntTuple it2 (std::move (it1));
+    VERIFY_TUPLE (it2);
+
+    ConstIntTuple ct1 (INT_VALUE);
+    ConstIntTuple ct2 = std::move (ct1);
+    VERIFY_TUPLE (ct2);
+
+    NestedTuple nt1 (it1);
+    NestedTuple nt2 = std::move (nt1);
+    VERIFY_TUPLE (std::get<0> (nt2));
+
+    PairTuple pt1 (LONG_VALUE, STRING_VALUE);
+    PairTuple pt2 (std::move (pt1));
+    verify_tuple (pt2);
+
+    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 ();
-    UserTuple ut (UserTuple ());
-    rw_assert (0 == UserClass::n_total_def_ctor_, __FILE__, __LINE__,
-               "tuple<UserClass>::tuple() called %d default ctors, "
-               "expected 0", UserClass::n_total_def_ctor_);
-    rw_assert (0 == UserClass::n_total_copy_ctor_, __FILE__, __LINE__,
-               "tuple<UserClass>::tuple() called %d copy ctors, "
-               "expected 0", UserClass::n_total_copy_ctor_);
+    // no move semantics in UserClass currently so it uses copy ctor
+    UserTuple ut2 (std::move (ut1));
+    verify_tuple (ut2, __LINE__, 0, 1);
 }
 
 /**************************************************************************/
@@ -207,24 +320,46 @@
     rw_info (0, __FILE__, __LINE__,
              "copy assignment operator (homogenous tuples)");
 
-    EmptyTuple et1, et2; et2 = et1;
-    IntTuple it1, it2; it2 = it1;
-    //ConstIntTuple ct1, ct2; ct2 = ct1;  // Can't assign to const element.
-    PairTuple pt1, pt2; pt2 = pt1;
-    NestedTuple nt1, nt2; nt2 = nt1;
-    BigTuple bt1, bt2; bt2 = bt1;
+    const EmptyTuple et1 = EmptyTuple ();
+    EmptyTuple et2;
+    et2 = et1;
+    _RWSTD_UNUSED (et2);
 
+    const IntTuple it1 (INT_VALUE);
+    IntTuple it2;
+    it2 = it1;
+    VERIFY_TUPLE (it2);
+
+    // copy assignment ill-formed for constant element types
+
+    int i = INT_VALUE;
+    const IntRefTuple rt1 (i);
+    int j = 0;
+    IntRefTuple rt2 (j); // note, different reference
+    rt2 = rt1;
+    VERIFY_TUPLE (rt2);
+
+    NestedTuple nt1 (it1);
+    NestedTuple nt2;
+    nt2 = nt1;
+    VERIFY_TUPLE (std::get<0> (nt2));
+
+    const PairTuple pt1 (LONG_VALUE, STRING_VALUE);
+    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);
+
+    const UserTuple ut1 (USER_VALUE);
+    UserTuple ut2;
     UserClass::reset_totals ();
-    UserTuple ut1, ut2; ut1 = ut2;
-    rw_assert (2 == UserClass::n_total_def_ctor_, __FILE__, __LINE__,
-               "tuple<UserClass>::tuple() called %d default ctors, "
-               "expected 2", UserClass::n_total_def_ctor_);
-    rw_assert (0 == UserClass::n_total_copy_ctor_, __FILE__, __LINE__,
-               "tuple<UserClass>::tuple() called %d copy ctors, "
-               "expected 0", UserClass::n_total_copy_ctor_);
-    rw_assert (1 == UserClass::n_total_op_assign_, __FILE__, __LINE__,
-               "tuple<UserClass>::tuple() called %d assign ops, "
-               "expected 1", UserClass::n_total_op_assign_);
+    ut2 = ut1;
+    verify_tuple (ut2, __LINE__, 0, 0, 1);
 }
 
 /**************************************************************************/
@@ -235,45 +370,81 @@
     rw_info (0, __FILE__, __LINE__,
              "move assignment operator (homogenous tuples)");
 
-    EmptyTuple et1, et2; et2 = et1;
-    IntTuple it1, it2; it2 = it1;
-    //ConstIntTuple ct1, ct2; ct2 = ct1;  // Can't assign to const element.
-    PairTuple pt1, pt2; pt2 = pt1;
-    NestedTuple nt1, nt2; nt2 = nt1;
-    BigTuple bt1, bt2; bt2 = bt1;
+    EmptyTuple et1, et2;
+    et2 = std::move (et1);
+    _RWSTD_UNUSED (et2);
 
+    IntTuple it1 (INT_VALUE);
+    IntTuple it2;
+    it2 = std::move (it1);
+    VERIFY_TUPLE (it2);
+
+    // move assignment ill-formed for constant element types
+
+    NestedTuple nt1 (it2);
+    NestedTuple nt2;
+    nt2 = std::move (nt1);
+    VERIFY_TUPLE (std::get<0> (nt2));
+
+    PairTuple pt1 (LONG_VALUE, STRING_VALUE);
+    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);
+
+    const UserClass& uc = USER_VALUE;
+    UserTuple ut1 (uc);
+    UserTuple ut2;
     UserClass::reset_totals ();
-    UserTuple ut1, ut2; ut1 = ut2;
-    rw_assert (2 == UserClass::n_total_def_ctor_, __FILE__, __LINE__,
-               "tuple<UserClass>::tuple() called %d default ctors, "
-               "expected 2", UserClass::n_total_def_ctor_);
-    rw_assert (0 == UserClass::n_total_copy_ctor_, __FILE__, __LINE__,
-               "tuple<UserClass>::tuple() called %d copy ctors, "
-               "expected 0", UserClass::n_total_copy_ctor_);
-    rw_assert (1 == UserClass::n_total_op_assign_, __FILE__, __LINE__,
-               "tuple<UserClass>::tuple() called %d assign ops, "
-               "expected 1", UserClass::n_total_op_assign_);
+    ut2 = std::move (ut1);
+    verify_tuple (ut2, __LINE__, 0, 0, 1);
 }
 
 /**************************************************************************/
 
+// 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*'
+struct String: public std::string
+{
+    String (): std::string () {}
+    String (const char* s): std::string (s) {}
+    operator const char* () const { return this->data (); }
+};
+
+typedef std::tuple<char>                CompatIntTuple;
+typedef std::tuple<unsigned, String>    CompatPairTuple;
+typedef std::tuple<int, int, short, float, char*,
+                   UserClass>           CompatBigTuple;
+
 static void
 test_hetero_copy_ctor ()
 {
     rw_info (0, __FILE__, __LINE__,
              "copy constructor (heterogenous tuples)");
 
-    const int i1 = 0; const char c = 'a'; const double d = 1.2;
-    void* const p = 0; const UserClass uc;
-    BigTuple bt1 (i1, c, i1, d, p, uc); _RWSTD_UNUSED (bt1);
-
-    const bool b = true; const int i2 = 'a';
-    BigTuple bt2 (b, i2, i1, d, p, uc); _RWSTD_UNUSED (bt2);
-
-    const float f = 1.2;
-    BigTuple bt3 (b, c, i1, f, p, uc); _RWSTD_UNUSED (bt3);
-
-    //UserTuple
+    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);
 }
 
 /**************************************************************************/
@@ -284,14 +455,18 @@
     rw_info (0, __FILE__, __LINE__,
              "move constructor (heterogenous tuples)");
 
-    //EmptyTuple
-    //IntTuple
-    //ConstIntTuple;
-    //PairTuple
-    //NestedTuple
-
-    //UserTuple
-    // BigTuple
+    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);
 }
 
 /**************************************************************************/
@@ -301,15 +476,21 @@
 {
     rw_info (0, __FILE__, __LINE__,
              "copy assignment operator (heterogenous tuples)");
-
-    //EmptyTuple
-    //IntTuple
-    //ConstIntTuple;
-    //PairTuple
-    //NestedTuple
-
-    //UserTuple
-    // BigTuple
+    CompatIntTuple ct1 (INT_VALUE);
+    IntTuple it;
+    it = ct1;
+    VERIFY_TUPLE (it);
+
+    CompatPairTuple ct2 (LONG_VALUE, STRING_VALUE);
+    PairTuple pt;
+    pt = ct2;
+    verify_tuple (pt);
+
+    CompatBigTuple ct3 (BOOL_VALUE, CHAR_VALUE, INT_VALUE,
+        DBL_VALUE, (char*) PTR_VALUE, USER_VALUE);
+    BigTuple bt;
+    bt = ct3;
+    verify_tuple (bt);
 }
 
 /**************************************************************************/
@@ -320,14 +501,21 @@
     rw_info (0, __FILE__, __LINE__,
              "move assignment operator (heterogenous tuples)");
 
-    //EmptyTuple
-    //IntTuple
-    //ConstIntTuple;
-    //PairTuple
-    //NestedTuple
-
-    //UserTuple
-    // BigTuple
+    CompatIntTuple ct1 (INT_VALUE);
+    IntTuple it;
+    it = std::move (ct1);
+    VERIFY_TUPLE (it);
+
+    CompatPairTuple ct2 (LONG_VALUE, STRING_VALUE);
+    PairTuple pt;
+    pt = std::move (ct2);
+    verify_tuple (pt);
+
+    CompatBigTuple ct3 (BOOL_VALUE, CHAR_VALUE, INT_VALUE,
+        DBL_VALUE, (char*) PTR_VALUE, USER_VALUE);
+    BigTuple bt;
+    bt = std::move (ct3);
+    verify_tuple (bt);
 }
 
 /**************************************************************************/
@@ -345,10 +533,13 @@
 /**************************************************************************/
 
 static int
-run_test (int /*unused*/, char* /*unused*/ [])
+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 ();
 
@@ -375,13 +566,13 @@
 #if defined (_RWSTD_NO_EXT_CXX_OX)
 
     rw_warn (0, 0, __LINE__,
-			 "test disabled because _RWSTD_NO_EXT_CXX_0X is defined");
+             "test disabled because _RWSTD_NO_EXT_CXX_0X is defined");
 
 #elif defined (_RWSTD_NO_RVALUE_REFERENCES)
 
     rw_warn (0, 0, __LINE__,
-			 "test disabled because _RWSTD_NO_RVALUE_REFERENCES is "
-			 "defined");
+             "test disabled because _RWSTD_NO_RVALUE_REFERENCES is "
+             "defined");
 
 #endif
 

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=675044&r1=675043&r2=675044&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 Tue Jul  8 16:13:36 2008
@@ -63,11 +63,23 @@
 
 /**************************************************************************/
 
+#include <cstring>
+
 static void
 test_tie ()
 {
     rw_info (0, __FILE__, __LINE__, "tie");
 
+    int i = 0; double d = 0.0; const char* s = 0;
+    std::tie (i, std::ignore, s)
+        = std::make_tuple (256, 3.14159, "string");
+
+    rw_assert (i == 256, __FILE__, __LINE__,
+               "i == 256, got false, expected true");
+    rw_assert (d == 0.0, __FILE__, __LINE__,
+               "d == 0.0, got false, expected true");
+    rw_assert (0 == std::strcmp (s, "string"), __FILE__, __LINE__,
+               "s == \"string\", got false, expected true");
 }
 
 /**************************************************************************/

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=675044&r1=675043&r2=675044&view=diff
==============================================================================
--- stdcxx/branches/4.3.x/tests/utilities/20.tuple.h (original)
+++ stdcxx/branches/4.3.x/tests/utilities/20.tuple.h Tue Jul  8 16:13:36 2008
@@ -36,22 +36,22 @@
 
 // various tuple types for test purposes
 
-typedef std::tuple < >                      EmptyTuple;
+typedef std::tuple <>                       EmptyTuple;
 
-typedef std::tuple < int >                  IntTuple;
-typedef std::tuple < const int >            ConstIntTuple;
-typedef std::tuple < int& >                 IntRefTuple;
+typedef std::tuple <int>                    IntTuple;
+typedef std::tuple <const int>              ConstIntTuple;
+typedef std::tuple <int&>                   IntRefTuple;
 
-typedef std::tuple < std::tuple < int > >   NestedTuple;
+typedef std::tuple <IntTuple>               NestedTuple;
 
-typedef std::tuple < long, const char* >    PairTuple;
+typedef std::tuple <long, const char*>      PairTuple;
 
-typedef std::tuple < UserClass >            UserTuple;
+typedef std::tuple <UserClass>              UserTuple;
 
-#define BigList      bool, char, int, double, void*, UserClass
-#define BigListSize  6
+#define BIG_TYPES   bool, char, int, double, void*, UserClass
+#define BIG_SIZE    6
 
-typedef std::tuple < BigList >              BigTuple;
+typedef std::tuple <BIG_TYPES>              BigTuple;
 
 
 #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=675044&r1=675043&r2=675044&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 Tue Jul  8 16:13:36 2008
@@ -58,7 +58,7 @@
 
     TEST (PairTuple, 2);
 
-    TEST (BigTuple, BigListSize);
+    TEST (BigTuple, BIG_SIZE);
 }
 
 /**************************************************************************/



RE: svn commit: r675044 - in /stdcxx/branches/4.3.x: include/rw/_tuple.h include/tuple tests/utilities/20.tuple.cnstr.cpp tests/utilities/20.tuple.creation.cpp tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp

Posted by Eric Lemings <Er...@roguewave.com>.
 

> -----Original Message-----
> From: Eric Lemings 
> Sent: Wednesday, July 09, 2008 3:14 PM
> To: 'dev@stdcxx.apache.org'
> Subject: RE: svn commit: r675044 - in /stdcxx/branches/4.3.x: 
> include/rw/_tuple.h include/tuple 
> tests/utilities/20.tuple.cnstr.cpp 
> tests/utilities/20.tuple.creation.cpp 
> tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp
> 
>  
> 
> > -----Original Message-----
> > From: Martin Sebor [mailto:sebor@roguewave.com] 
> > Sent: Wednesday, July 09, 2008 11:10 AM
> > To: dev@stdcxx.apache.org
> > Subject: Re: svn commit: r675044 - in /stdcxx/branches/4.3.x: 
> > include/rw/_tuple.h include/tuple 
> > tests/utilities/20.tuple.cnstr.cpp 
> > tests/utilities/20.tuple.creation.cpp 
> > tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp
> > 
> ...
> > > This can probably be changed to use a void return type, which will
> > > simplify the code further. You only really need the return 
> > type to chain
> > > assignments or to call a function on the result, none of 
> > which we should
> > > be doing.
> > 
> > Good idea! Also, the inline specifier is redundant and should
> > be removed.
> 
> A void return type causes an compile error:

Duh.  Disregard.

RE: svn commit: r675044 - in /stdcxx/branches/4.3.x: include/rw/_tuple.h include/tuple tests/utilities/20.tuple.cnstr.cpp tests/utilities/20.tuple.creation.cpp tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp

Posted by Eric Lemings <Er...@roguewave.com>.
 

> -----Original Message-----
> From: Martin Sebor [mailto:sebor@roguewave.com] 
> Sent: Wednesday, July 09, 2008 11:10 AM
> To: dev@stdcxx.apache.org
> Subject: Re: svn commit: r675044 - in /stdcxx/branches/4.3.x: 
> include/rw/_tuple.h include/tuple 
> tests/utilities/20.tuple.cnstr.cpp 
> tests/utilities/20.tuple.creation.cpp 
> tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp
> 
...
> > This can probably be changed to use a void return type, which will
> > simplify the code further. You only really need the return 
> type to chain
> > assignments or to call a function on the result, none of 
> which we should
> > be doing.
> 
> Good idea! Also, the inline specifier is redundant and should
> be removed.

A void return type causes an compile error:

gcc -c -I/work/stdcxx/branches/4.3.x/include/ansi -D_RWSTDDEBUG
-pthread -I/work/stdcxx/branches/4.3.x/include
-I/build/stdcxx-4.3.x-15D/include
-I/work/stdcxx/branches/4.3.x/tests/include  -pedantic -nostdinc++
-std=gnu++0x -D_RWSTD_EXT_CXX_0X -g   -W -Wall -Wcast-qual -Winline
-Wshadow -Wwrite-strings -Wno-long-long -Wcast-align
/work/stdcxx/branches/4.3.x/tests/utilities/20.tuple.creation.cpp
/work/stdcxx/branches/4.3.x/include/rw/_tuple.h: In member function
'void __rw::__rw_ignore::operator=(const _TypeT&) const [with _TypeT =
double]':
/work/stdcxx/branches/4.3.x/include/rw/_tuple.h:131:   instantiated from
'__rw::__rw_tuple<_HeadT, _TailT ...>& __rw::__rw_tuple<_HeadT, _TailT
...>::operator=(__rw::__rw_tuple<_HeadU, _TailU ...>&&) [with _HeadU =
double, _TailU = const char*, _HeadT = const __rw::__rw_ignore&, _TailT
= const char*&]'
/work/stdcxx/branches/4.3.x/include/rw/_tuple.h:130:   instantiated from
'__rw::__rw_tuple<_HeadT, _TailT ...>& __rw::__rw_tuple<_HeadT, _TailT
...>::operator=(__rw::__rw_tuple<_HeadU, _TailU ...>&&) [with _HeadU =
int, _TailU = double, const char*, _HeadT = int&, _TailT = const
__rw::__rw_ignore&, const char*&]'
/work/stdcxx/branches/4.3.x/include/tuple:123:   instantiated from
'std::tuple<_TypesT>& std::tuple<_TypesT>::operator=(std::tuple<_TypesU
...>&&) [with _TypesU = int, double, const char*, _TypesT = int&, const
__rw::__rw_ignore&, const char*&]'
/work/stdcxx/branches/4.3.x/tests/utilities/20.tuple.creation.cpp:75:
instantiated from here
/work/stdcxx/branches/4.3.x/include/rw/_tuple.h:181: error:
return-statement with a value, in function returning 'void'
make: *** [20.tuple.creation.o] Error 1

Brad.

RE: svn commit: r675044 - in /stdcxx/branches/4.3.x: include/rw/_tuple.h include/tuple tests/utilities/20.tuple.cnstr.cpp tests/utilities/20.tuple.creation.cpp tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp

Posted by Eric Lemings <Er...@roguewave.com>.
 

> -----Original Message-----
> From: Martin Sebor [mailto:sebor@roguewave.com] 
> Sent: Wednesday, July 09, 2008 2:49 PM
> To: dev@stdcxx.apache.org
> Subject: Re: svn commit: r675044 - in /stdcxx/branches/4.3.x: 
> include/rw/_tuple.h include/tuple 
> tests/utilities/20.tuple.cnstr.cpp 
> tests/utilities/20.tuple.creation.cpp 
> tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp
> 
> Eric Lemings wrote:
> >  
> > 
> >> -----Original Message-----
> >> From: Martin Sebor [mailto:sebor@roguewave.com] 
> >> Sent: Wednesday, July 09, 2008 11:10 AM
> >> To: dev@stdcxx.apache.org
> >> Subject: Re: svn commit: r675044 - in /stdcxx/branches/4.3.x: 
> >> include/rw/_tuple.h include/tuple 
> >> tests/utilities/20.tuple.cnstr.cpp 
> >> tests/utilities/20.tuple.creation.cpp 
> >> tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp
> >>
> > ...
> >>> I think the commented out parameter name should be removed. 
> >> I don't see
> >>> this in existing code, and I personally find it a bit distracting.
> >> I agree. Without a name, it's obvious that the parameter
> >> is unused.
> > 
> > Examples in existing code:
> 
> As I said before, you can find examples of pretty much any
> style, including two space indents. Are you purposely seeking
> out these rare, obscure cases and adopting them in your code
> just to make things interesting?

Actually no, if you believe that.  Was just providing examples since
Travis could find no such usage in existing code.

Brad.

Re: svn commit: r675044 - in /stdcxx/branches/4.3.x: include/rw/_tuple.h include/tuple tests/utilities/20.tuple.cnstr.cpp tests/utilities/20.tuple.creation.cpp tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp

Posted by Martin Sebor <se...@roguewave.com>.
Eric Lemings wrote:
>  
> 
>> -----Original Message-----
>> From: Martin Sebor [mailto:sebor@roguewave.com] 
>> Sent: Wednesday, July 09, 2008 11:10 AM
>> To: dev@stdcxx.apache.org
>> Subject: Re: svn commit: r675044 - in /stdcxx/branches/4.3.x: 
>> include/rw/_tuple.h include/tuple 
>> tests/utilities/20.tuple.cnstr.cpp 
>> tests/utilities/20.tuple.creation.cpp 
>> tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp
>>
> ...
>>> I think the commented out parameter name should be removed. 
>> I don't see
>>> this in existing code, and I personally find it a bit distracting.
>> I agree. Without a name, it's obvious that the parameter
>> is unused.
> 
> Examples in existing code:

As I said before, you can find examples of pretty much any
style, including two space indents. Are you purposely seeking
out these rare, obscure cases and adopting them in your code
just to make things interesting?

> 
> The run_test() function in tests/containers/23.vector.cons.cpp.

Not sure why the names are commented out. Maybe because
the author was intending to use them and didn't and they
got commented out to silence warnings.

> Lines 56-64 in tests/containers/23.deque.modifiers.cpp.

They are there because normally, names local to each test
are declared static. In this test (and many others) they
can't be declared static because they are referenced from
template code and no all compilers find time (Sun C++ 5.3
has a bug that prevents it from finding static symbols
referenced from template code). So the /* extern */
comment is a reminder to prevent people from making them
static.

> The __rw_smanip member functions in include/iomanip.

This is the { /* empty */ } comment that some style guides
suggest for non-trivial ctors with deliberately empty bodies
to indicate that the body wasn't left empty by accident when
the ctor was stubbed out early in the development of the
class. I don't feel strongly about using this style.

> 
> Who did all that?  Not me.  :)  I'm sure there are plenty more examples.

I'm sure there are.

> 
> Anyone care to search for all such cases and make it all consistent?

No. Please just adjust your code as suggested.

Thanks
Martin


RE: svn commit: r675044 - in /stdcxx/branches/4.3.x: include/rw/_tuple.h include/tuple tests/utilities/20.tuple.cnstr.cpp tests/utilities/20.tuple.creation.cpp tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp

Posted by Eric Lemings <Er...@roguewave.com>.
 

> -----Original Message-----
> From: Martin Sebor [mailto:sebor@roguewave.com] 
> Sent: Wednesday, July 09, 2008 11:10 AM
> To: dev@stdcxx.apache.org
> Subject: Re: svn commit: r675044 - in /stdcxx/branches/4.3.x: 
> include/rw/_tuple.h include/tuple 
> tests/utilities/20.tuple.cnstr.cpp 
> tests/utilities/20.tuple.creation.cpp 
> tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp
> 
...
> > 
> > I think the commented out parameter name should be removed. 
> I don't see
> > this in existing code, and I personally find it a bit distracting.
> 
> I agree. Without a name, it's obvious that the parameter
> is unused.

Examples in existing code:

The run_test() function in tests/containers/23.vector.cons.cpp.
Lines 56-64 in tests/containers/23.deque.modifiers.cpp.
The __rw_smanip member functions in include/iomanip.

Who did all that?  Not me.  :)  I'm sure there are plenty more examples.

Anyone care to search for all such cases and make it all consistent?

Brad.

Re: svn commit: r675044 - in /stdcxx/branches/4.3.x: include/rw/_tuple.h include/tuple tests/utilities/20.tuple.cnstr.cpp tests/utilities/20.tuple.creation.cpp tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp

Posted by Martin Sebor <se...@roguewave.com>.
Travis Vitek wrote:
>  
> 
>> Author: elemings
>> Date: Tue Jul  8 16:13:36 2008
>> New Revision: 675044
>>
>> URL: http://svn.apache.org/viewvc?rev=675044&view=rev
>> Log:
>> 2008-07-08  Eric Lemings <er...@roguewave.com>
>>
>> 	STDCXX-958
>> 	* include/tuple: Second parameter in value move ctor of pair
>> 	specialization missing rvalue reference.
>> 	(make_tuple, get, relational operators): Explicitly declare
>> 	as inline functions.
>> 	(tie): Implemented.
>> 	* include/rw/_tuple.h: Fix move semantics in heterogenous move
>> 	assignment operator.
>> 	(__rw_ignore): Add assignment operator to ignore all values.
>> 	* tests/utilities/20.tuple.cnstr.cpp: Added V&V for tuple
>> 	state and invariants.  Manually inspected proper construction
>> 	of all test tuples.  Updated/corrected/added tests as necessary.
>> 	* tests/utilities/20.tuple.creation.cpp: Added simple tie()
>> 	test.
>> 	* tests/utilities/20.tuple.h: Minor stylistic changes.
>> 	* tests/utilities/20.tuple.helpers.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.h
>>    stdcxx/branches/4.3.x/tests/utilities/20.tuple.helpers.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=675044&r1=675043&r2=675044&view=diff
>> ===============================================================
>> ===============
>> --- stdcxx/branches/4.3.x/include/rw/_tuple.h (original)
>> +++ stdcxx/branches/4.3.x/include/rw/_tuple.h Tue Jul  8 16:13:36 2008
>> @@ -174,7 +174,14 @@
>> };
>>
>>
>> -struct __rw_ignore { /* empty */ };
>> +struct __rw_ignore
>> +{
>> +    template <class _TypeT>
>> +    inline __rw_ignore const&
>> +    operator= (const _TypeT& /*unused*/) const {
>> +        return *this;
>> +    }
>> +};
>>
> 
> I think the commented out parameter name should be removed. I don't see
> this in existing code, and I personally find it a bit distracting.

I agree. Without a name, it's obvious that the parameter
is unused. Saying it's unused in a comment is like adding
a /* return; */ comment to the end of void functions, or
adding an /* extern */ in front of the definition of non
member function definitions. IMO, all of these represent
unnecessary redundancies that are liable to make readers
wonder about their purpose rather than providing any
helpful insight. It would be much more helpful to document
the purpose of the unusual assignment operator than the
unused argument :)

> 
> This can probably be changed to use a void return type, which will
> simplify the code further. You only really need the return type to chain
> assignments or to call a function on the result, none of which we should
> be doing.

Good idea! Also, the inline specifier is redundant and should
be removed.

> 
[...]
>> @@ -377,7 +381,7 @@
>> // 20.3.1.5, element access:
>>
>> template <_RWSTD_SIZE_T _Index, class _Head, class... _Tail>
>> -_TYPENAME tuple_element<_Index, tuple<_Head, _Tail...> >::_Ref
>> +inline _TYPENAME tuple_element<_Index, tuple<_Head, _Tail...> >::_Ref
>> get (tuple<_Head, _Tail...>& __tuple)
>> {
>>     typedef tuple_element<_Index, tuple<_Head, _Tail...> > _Tuple;
> 
> In the recent past Martin recommended not using the _TYPENAME macro. It
> isn't hurting anything, but it could probably be removed. I know that I
> no longer use it in the traits code. I also noticed the _EXPLICIT macro
> above. I think that one should be added to the list. Martin?

I agree. We can start using typename and explicit in all new
code on 4.3.x and replace _TYPENAME and _EXPLICIT with the
real keywords. Ditto for _RWSTD_SPECIALIZED_FUNCTION and
_RWSTD_SPECIALIZED_CLASS.

> 
[...]
>> @@ -396,59 +400,67 @@
>> // 20.3.1.6, relational operators:
>>
>> template <class... _TypesT, class... _TypesU>
>> -bool operator== (const tuple<_TypesT...>& __x,
>> -                 const tuple<_TypesU...>& __y)
>> +inline bool
>> +operator== (const tuple<_TypesT...>& __x,
>> +            const tuple<_TypesU...>& __y)
>> {
>>     return _RWSTD_STATIC_CAST (const 
>> _RW::__rw_tuple<_TypesT...>&, __x)
>>            == _RWSTD_STATIC_CAST (const 
>> _RW::__rw_tuple<_TypesU...>&, __y);
> 
> I think there is a formatting issue here. The prevailing style is for
> the operator to start of the next line, but for the operands to be lined
> up on their left. As an example
> 
>   return    __some_really_long_expression_1
>          == __some_really_long_expression_2;

Right. We're not 100% consistent (and I can't say I'm crazy
about this style, either) but I find it more readable than
any of the alternatives I've seen.

Martin


RE: svn commit: r675044 - in /stdcxx/branches/4.3.x: include/rw/_tuple.h include/tuple tests/utilities/20.tuple.cnstr.cpp tests/utilities/20.tuple.creation.cpp tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp

Posted by Eric Lemings <Er...@roguewave.com>.
 

> -----Original Message-----
> From: Travis Vitek [mailto:Travis.Vitek@roguewave.com] 
> Sent: Wednesday, July 09, 2008 12:28 PM
> To: dev@stdcxx.apache.org
> Subject: RE: svn commit: r675044 - in /stdcxx/branches/4.3.x: 
> include/rw/_tuple.h include/tuple 
> tests/utilities/20.tuple.cnstr.cpp 
> tests/utilities/20.tuple.creation.cpp 
> tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp
> 
>  
> 
> Eric Lemings wrote:
> >
> >> Travis Vitek wrote:
> >>
> >> >Modified: 
> >stdcxx/branches/4.3.x/tests/utilities/20.tuple.creation.cpp
> >...
> >> >+    rw_assert (0 == std::strcmp (s, "string"), __FILE__, 
> __LINE__,
> >> >+               "s == \"string\", got false, expected true");
> >> 
> >> The tuple is holding the original pointer (not a copy), so I 
> >think you
> >> can check the actual pointer here.
> >
> >True.  But if that assumption became invalid for whatever reason, the
> >code above would still work.
> >
> >Assumptions are bad.  Robustness is good.  :)
> 
> As I see it, the tuple implementation is required to hold a copy of an
> object of the specified type (const char* in this case). If you don't
> verify the value held is indeed a copy, you are not actually verifying
> the requirements. This is wrong, and wrong is much worse than bad. :)

Good point.

Re: svn commit: r675044 - in /stdcxx/branches/4.3.x: include/rw/_tuple.h include/tuple tests/utilities/20.tuple.cnstr.cpp tests/utilities/20.tuple.creation.cpp tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp

Posted by Martin Sebor <se...@roguewave.com>.
Eric Lemings wrote:
>  
[...]
> With the following change:
> 
> 	Index:
> /work/stdcxx/branches/4.3.x/tests/utilities/20.tuple.cnstr.cpp
> 	
> ===================================================================
> 	---
> /work/stdcxx/branches/4.3.x/tests/utilities/20.tuple.cnstr.cpp
> (revision 675050)
> 	+++
> /work/stdcxx/branches/4.3.x/tests/utilities/20.tuple.cnstr.cpp
> (working copy)
> 	@@ -74,18 +73,20 @@
[...]
> It appears that pointer values are not guaranteed to be equal when
> converting between pointer types.

They must be. I see the assertions in the test but the small
program below works fine.

On an unrelated note, though: While working with the test
I found the heavy use of macros and globals quite confusing.
It makes it very difficult to find and track the tested
values, and virtually impossible to extend with new test
cases.

The approach I've found to work better is splitting up the
test into one or some other small number of worker functions
parametrized on all the arguments and expected values and
their types (if necessary) and other higher level functions,
for example one for each overload of the tested function,
with individual test cases and literal values of arguments
and expected results. You can find examples of such tests
in the tests/localization directory, such as all the
22.locale.{money,num,time}.{get,put}.cpp tests. I suggest
you follow this example in the tuple tests as well.

Martin

#include <cassert>
#include <tuple>

int main ()
{
     const char* s = "string";

     {
         std::tuple<const char*> x (s);
         const char* const y = std::get<0>(x);

         assert (y == s);
     }
     {
         std::tuple<long, const char*> x (0, s);
         const char* const y = std::get<1>(x);

         assert (y == s);
     }
}


RE: svn commit: r675044 - in /stdcxx/branches/4.3.x: include/rw/_tuple.h include/tuple tests/utilities/20.tuple.cnstr.cpp tests/utilities/20.tuple.creation.cpp tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp

Posted by Eric Lemings <Er...@roguewave.com>.
 

> -----Original Message-----
> From: Eric Lemings [mailto:Eric.Lemings@roguewave.com] 
> Sent: Wednesday, July 09, 2008 12:40 PM
> To: dev@stdcxx.apache.org
> Subject: RE: svn commit: r675044 - in /stdcxx/branches/4.3.x: 
> include/rw/_tuple.h include/tuple 
> tests/utilities/20.tuple.cnstr.cpp 
> tests/utilities/20.tuple.creation.cpp 
> tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp
> 
>  
...
> > 
> > As I see it, the tuple implementation is required to hold a 
> copy of an
> > object of the specified type (const char* in this case). If 
> you don't
> > verify the value held is indeed a copy, you are not 
> actually verifying
> > the requirements. This is wrong, and wrong is much worse 
> than bad. :)
> 
> Question:
> 
> const char* s1 = "string";
> const char* s2 = "string";
> // s1 guaranteed to equal s2?

With the following change:

	Index:
/work/stdcxx/branches/4.3.x/tests/utilities/20.tuple.cnstr.cpp
	
===================================================================
	---
/work/stdcxx/branches/4.3.x/tests/utilities/20.tuple.cnstr.cpp
(revision 675050)
	+++
/work/stdcxx/branches/4.3.x/tests/utilities/20.tuple.cnstr.cpp
(working copy)
	@@ -74,18 +73,20 @@
	
	
	 #define LONG_VALUE      INT_VALUE
	-#define STRING_VALUE    "string"
	+#define STRING_VALUE    str_value
	
	+static const char* str_value = "string";
	+
	 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);
	+    rw_assert (std::get<1> (pt) == STRING_VALUE, __FILE__,
__LINE__,
	+               "std::get<1> (pt), got %p \"%s\", expected %p
\"%s\"",
	+               std::get<1> (pt), std::get<1> (pt),
	+               STRING_VALUE, STRING_VALUE);
	 }

I get the following assertions:

	...
	# ASSERTION (S7) (5 lines):
	# TEXT: std::get<1> (pt), got 000000000f18d8c0 "string",
expected 000000000042796e "string"
	# CLAUSE: [tuple.cnstr]
	# FILE: 20.tuple.cnstr.cpp
	# LINE: 86

	# INFO (S1) (5 lines):
	# TEXT: move constructor (heterogenous tuples)
	# CLAUSE: [tuple.cnstr]
	# FILE: 20.tuple.cnstr.cpp
	# LINE: 458

	# ASSERTION (S7) (5 lines):
	# TEXT: std::get<1> (pt), got 000000000f18d8c0 "string",
expected 000000000042796e "string"
	# CLAUSE: [tuple.cnstr]
	# FILE: 20.tuple.cnstr.cpp
	# LINE: 86

	# INFO (S1) (5 lines):
	# TEXT: copy assignment operator (heterogenous tuples)
	# CLAUSE: [tuple.cnstr]
	# FILE: 20.tuple.cnstr.cpp
	# LINE: 480

	# ASSERTION (S7) (5 lines):
	# TEXT: std::get<1> (pt), got 000000000f18d8c0 "string",
expected 000000000042796e "string"
	# CLAUSE: [tuple.cnstr]
	# FILE: 20.tuple.cnstr.cpp
	# LINE: 86

	# INFO (S1) (5 lines):
	# TEXT: move assignment operator (heterogenous tuples)
	# CLAUSE: [tuple.cnstr]
	# FILE: 20.tuple.cnstr.cpp
	# LINE: 504

	# ASSERTION (S7) (5 lines):
	# TEXT: std::get<1> (pt), got 000000000f18d8c0 "string",
expected 000000000042796e "string"
	# CLAUSE: [tuple.cnstr]
	# FILE: 20.tuple.cnstr.cpp
	# LINE: 86
	...

It appears that pointer values are not guaranteed to be equal when
converting between pointer types.

Brad.

RE: svn commit: r675044 - in /stdcxx/branches/4.3.x: include/rw/_tuple.h include/tuple tests/utilities/20.tuple.cnstr.cpp tests/utilities/20.tuple.creation.cpp tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp

Posted by Travis Vitek <Tr...@roguewave.com>.
 

Martin Sebor wrote:
>
>Eric Lemings wrote:
>>  
>> 
>>> Travis Vitek wrote:
>>>  
>>>
>>> Eric Lemings wrote:
>>>>> Travis Vitek wrote:
>>>>>
>>>>> The tuple is holding the original pointer (not a copy), so I 
>>>>> think you can check the actual pointer here.
>>>>
>>>> True.  But if that assumption became invalid for whatever
>>>> reason, the code above would still work.
>>>>
>>>> Assumptions are bad.  Robustness is good.  :)
>>>
>>> As I see it, the tuple implementation is required to hold a 
>>> copy of an object of the specified type (const char* in this
>>> case). If you don't verify the value held is indeed a copy,
>>> you are not actually verifying the requirements. This is wrong,
>>> and wrong is much worse than bad. :)
>> 
>> Question:
>> 
>> const char* s1 = "string";
>> const char* s2 = "string";
>> // s1 guaranteed to equal s2?
>
>It's unspecified. The compiler is allowed to merge strings.
>It's allowed to even go as far as to point s2 at (s1 + 1)
>in the snippet below:
>
>     const char* s1 = "Xstring";
>     const char* s2 = "string";
>

Just so we're clear, the case that should be happening with tuple is the
following...

  const char* s1 = "string";
  const char* s2 (s1);

  assert (s1 == s2);

The following code works just fine with both the gnu tuple
implementation and ours. I'm not sure why the Brad is seeing the
assertion failure.

  $ cat t.cpp && g++ -std=gnu++0x t.cpp && ./a.out && echo good
  #include <tuple>
  #include <assert.h>

  static const char* s = "hello world";

  int main ()
  {
    const std::tuple<const char*> t (s);
    assert (std::get<0>(t) == s);

    return 0;
  }
  $ good

  $ gmake t && ./t && echo good
  gcc -c -I/amd/devco/vitek/stdcxx/4.3.x/include/ansi -D_RWSTDDEBUG
-D_RWSTD_EXT_CXX_0X -I/amd/devco/vitek/stdcxx/4.3.x/include
-I/build/vitek/4.3.0/11S/include
-I/amd/devco/vitek/stdcxx/4.3.x/tests/include -pedantic -nostdinc++ -g
-std=gnu++0x -W -Wall -Wcast-qual -Winline -Wshadow -Wwrite-strings
-Wno-long-long -Wcast-align -Wno-empty-body -Wno-parentheses t.cpp
  gcc t.o -o t -L/build/vitek/4.3.0/11S/rwtest -lrwtest11S
-L/build/vitek/4.3.0/11S/lib -lstd11S -lsupc++ -lm
  good

>Martin
>
>

Re: svn commit: r675044 - in /stdcxx/branches/4.3.x: include/rw/_tuple.h include/tuple tests/utilities/20.tuple.cnstr.cpp tests/utilities/20.tuple.creation.cpp tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp

Posted by Martin Sebor <se...@roguewave.com>.
Eric Lemings wrote:
>  
> 
>> -----Original Message-----
>> From: Travis Vitek [mailto:Travis.Vitek@roguewave.com] 
>> Sent: Wednesday, July 09, 2008 12:28 PM
>> To: dev@stdcxx.apache.org
>> Subject: RE: svn commit: r675044 - in /stdcxx/branches/4.3.x: 
>> include/rw/_tuple.h include/tuple 
>> tests/utilities/20.tuple.cnstr.cpp 
>> tests/utilities/20.tuple.creation.cpp 
>> tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp
>>
>>  
>>
>> Eric Lemings wrote:
>>>> Travis Vitek wrote:
>>>>
>>>>> Modified: 
>>> stdcxx/branches/4.3.x/tests/utilities/20.tuple.creation.cpp
>>> ...
>>>>> +    rw_assert (0 == std::strcmp (s, "string"), __FILE__, 
>> __LINE__,
>>>>> +               "s == \"string\", got false, expected true");
>>>> The tuple is holding the original pointer (not a copy), so I 
>>> think you
>>>> can check the actual pointer here.
>>> True.  But if that assumption became invalid for whatever reason, the
>>> code above would still work.
>>>
>>> Assumptions are bad.  Robustness is good.  :)
>> As I see it, the tuple implementation is required to hold a copy of an
>> object of the specified type (const char* in this case). If you don't
>> verify the value held is indeed a copy, you are not actually verifying
>> the requirements. This is wrong, and wrong is much worse than bad. :)
> 
> Question:
> 
> const char* s1 = "string";
> const char* s2 = "string";
> // s1 guaranteed to equal s2?

It's unspecified. The compiler is allowed to merge strings.
It's allowed to even go as far as to point s2 at (s1 + 1)
in the snippet below:

     const char* s1 = "Xstring";
     const char* s2 = "string";

Martin


RE: svn commit: r675044 - in /stdcxx/branches/4.3.x: include/rw/_tuple.h include/tuple tests/utilities/20.tuple.cnstr.cpp tests/utilities/20.tuple.creation.cpp tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp

Posted by Eric Lemings <Er...@roguewave.com>.
 

> -----Original Message-----
> From: Travis Vitek [mailto:Travis.Vitek@roguewave.com] 
> Sent: Wednesday, July 09, 2008 12:28 PM
> To: dev@stdcxx.apache.org
> Subject: RE: svn commit: r675044 - in /stdcxx/branches/4.3.x: 
> include/rw/_tuple.h include/tuple 
> tests/utilities/20.tuple.cnstr.cpp 
> tests/utilities/20.tuple.creation.cpp 
> tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp
> 
>  
> 
> Eric Lemings wrote:
> >
> >> Travis Vitek wrote:
> >>
> >> >Modified: 
> >stdcxx/branches/4.3.x/tests/utilities/20.tuple.creation.cpp
> >...
> >> >+    rw_assert (0 == std::strcmp (s, "string"), __FILE__, 
> __LINE__,
> >> >+               "s == \"string\", got false, expected true");
> >> 
> >> The tuple is holding the original pointer (not a copy), so I 
> >think you
> >> can check the actual pointer here.
> >
> >True.  But if that assumption became invalid for whatever reason, the
> >code above would still work.
> >
> >Assumptions are bad.  Robustness is good.  :)
> 
> As I see it, the tuple implementation is required to hold a copy of an
> object of the specified type (const char* in this case). If you don't
> verify the value held is indeed a copy, you are not actually verifying
> the requirements. This is wrong, and wrong is much worse than bad. :)

Question:

const char* s1 = "string";
const char* s2 = "string";
// s1 guaranteed to equal s2?

Brad.

RE: svn commit: r675044 - in /stdcxx/branches/4.3.x: include/rw/_tuple.h include/tuple tests/utilities/20.tuple.cnstr.cpp tests/utilities/20.tuple.creation.cpp tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp

Posted by Travis Vitek <Tr...@roguewave.com>.
 

Eric Lemings wrote:
>
>> Travis Vitek wrote:
>>
>> >Modified: 
>stdcxx/branches/4.3.x/tests/utilities/20.tuple.creation.cpp
>...
>> >+    rw_assert (0 == std::strcmp (s, "string"), __FILE__, __LINE__,
>> >+               "s == \"string\", got false, expected true");
>> 
>> The tuple is holding the original pointer (not a copy), so I 
>think you
>> can check the actual pointer here.
>
>True.  But if that assumption became invalid for whatever reason, the
>code above would still work.
>
>Assumptions are bad.  Robustness is good.  :)

As I see it, the tuple implementation is required to hold a copy of an
object of the specified type (const char* in this case). If you don't
verify the value held is indeed a copy, you are not actually verifying
the requirements. This is wrong, and wrong is much worse than bad. :)

>
>Brad.
>

RE: svn commit: r675044 - in /stdcxx/branches/4.3.x: include/rw/_tuple.h include/tuple tests/utilities/20.tuple.cnstr.cpp tests/utilities/20.tuple.creation.cpp tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp

Posted by Eric Lemings <Er...@roguewave.com>.
 

> -----Original Message-----
> From: Travis Vitek [mailto:Travis.Vitek@roguewave.com] 
> Sent: Tuesday, July 08, 2008 6:04 PM
> To: dev@stdcxx.apache.org
> Subject: RE: svn commit: r675044 - in /stdcxx/branches/4.3.x: 
> include/rw/_tuple.h include/tuple 
> tests/utilities/20.tuple.cnstr.cpp 
> tests/utilities/20.tuple.creation.cpp 
> tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp
> 
>  
...
> 
> The commented unused argument names again. Also, I think the
> _RWSTD_SPECIALIZED_FUNCTION macro can be eliminated. If I remember
> correctly Martin asked that it be removed from the traits 
> implementation (which I've done).

I've been using _TYPENAME, _EXPLICIT, and _RWSTD_SPECIALIZED_FUNCTION
just to be consistent with existing code.  Is there a good reason not to
do this anymore?  (Actually I can think of one but I'll see if anyone
else can think of it and/or another.)

> 
...
> Is there any way that we could write a routine to generate a tuple and
> then test it, so as to avoid always using the same few types 
> and values
> hidden behind the *_VALUE macros? The usage would be something like
> this...
> 
>   TEST_TUPLE (1, 3.14f, 'a', "abc");

This might work for homogenous tuples where the element types can be
deduced from the values.  Not sure exactly how you would fit
user-defined (e.g. UserClass) values into it.  Also, you'd need an
expanded form for heterogenous tuples where the compatible/convertible
types would have to be explicitly specified.

For this latest update, I really wanted to just get a complete set of
tests in there however verbose they may be.

> 
> >-    int i = 1;
> >-    IntTuple it1 (i); _RWSTD_UNUSED (it1);
> >-    const IntTuple it2 (i); _RWSTD_UNUSED (it2);
> >-    ConstIntTuple ct (i); _RWSTD_UNUSED (ct);
> >-    IntRefTuple rt (i); _RWSTD_UNUSED (rt);
> > 
> >-    NestedTuple nt (it2); _RWSTD_UNUSED (nt);
> >+#define USER_VALUE      user_val
> 
> I'm being a nit-picker, but this seems like an awful simple 
> thing to be
> wrapping a macro around. Is there a reason to do so?

Like the other value macros, to hide the actual value being used and to
provide a single point of definition where it can be modified.

> 
> >Modified: stdcxx/branches/4.3.x/tests/utilities/20.tuple.creation.cpp
...
> >+    rw_assert (0 == std::strcmp (s, "string"), __FILE__, __LINE__,
> >+               "s == \"string\", got false, expected true");
> 
> The tuple is holding the original pointer (not a copy), so I think you
> can check the actual pointer here.

True.  But if that assumption became invalid for whatever reason, the
code above would still work.

Assumptions are bad.  Robustness is good.  :)

Brad.

RE: svn commit: r675044 - in /stdcxx/branches/4.3.x: include/rw/_tuple.h include/tuple tests/utilities/20.tuple.cnstr.cpp tests/utilities/20.tuple.creation.cpp tests/utilities/20.tuple.h tests/utilities/20.tuple.helpers.cpp

Posted by Travis Vitek <Tr...@roguewave.com>.
 

>Author: elemings
>Date: Tue Jul  8 16:13:36 2008
>New Revision: 675044
>
>URL: http://svn.apache.org/viewvc?rev=675044&view=rev
>Log:
>2008-07-08  Eric Lemings <er...@roguewave.com>
>
>	STDCXX-958
>	* include/tuple: Second parameter in value move ctor of pair
>	specialization missing rvalue reference.
>	(make_tuple, get, relational operators): Explicitly declare
>	as inline functions.
>	(tie): Implemented.
>	* include/rw/_tuple.h: Fix move semantics in heterogenous move
>	assignment operator.
>	(__rw_ignore): Add assignment operator to ignore all values.
>	* tests/utilities/20.tuple.cnstr.cpp: Added V&V for tuple
>	state and invariants.  Manually inspected proper construction
>	of all test tuples.  Updated/corrected/added tests as necessary.
>	* tests/utilities/20.tuple.creation.cpp: Added simple tie()
>	test.
>	* tests/utilities/20.tuple.h: Minor stylistic changes.
>	* tests/utilities/20.tuple.helpers.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.h
>    stdcxx/branches/4.3.x/tests/utilities/20.tuple.helpers.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=675044&r1=675043&r2=675044&view=diff
>===============================================================
>===============
>--- stdcxx/branches/4.3.x/include/rw/_tuple.h (original)
>+++ stdcxx/branches/4.3.x/include/rw/_tuple.h Tue Jul  8 16:13:36 2008
>@@ -174,7 +174,14 @@
> };
> 
> 
>-struct __rw_ignore { /* empty */ };
>+struct __rw_ignore
>+{
>+    template <class _TypeT>
>+    inline __rw_ignore const&
>+    operator= (const _TypeT& /*unused*/) const {
>+        return *this;
>+    }
>+};
>

I think the commented out parameter name should be removed. I don't see
this in existing code, and I personally find it a bit distracting.

This can probably be changed to use a void return type, which will
simplify the code further. You only really need the return type to chain
assignments or to call a function on the result, none of which we should
be doing.

>Modified: stdcxx/branches/4.3.x/include/tuple
>URL: 
>http://svn.apache.org/viewvc/stdcxx/branches/4.3.x/include/tupl
>e?rev=675044&r1=675043&r2=675044&view=diff
>===============================================================
>===============
>--- stdcxx/branches/4.3.x/include/tuple (original)
>+++ stdcxx/branches/4.3.x/include/tuple Tue Jul  8 16:13:36 2008
>@@ -211,7 +211,7 @@
> #    if !defined _RWSTD_NO_RVALUE_REFERENCES
> 
>     template <class _TypeU1, class _TypeU2>
>-    _EXPLICIT tuple (_TypeU1&& __x, _TypeU2 __y)
>+    _EXPLICIT tuple (_TypeU1&& __x, _TypeU2&& __y)
>         : _Base (_RWSTD_FORWARD (_TypeU1, __x),
>                  _RWSTD_FORWARD (_TypeU2, __y)) { /* empty */ }

Same here with the comment describing the empty function body.

>@@ -377,7 +381,7 @@
> // 20.3.1.5, element access:
> 
> template <_RWSTD_SIZE_T _Index, class _Head, class... _Tail>
>-_TYPENAME tuple_element<_Index, tuple<_Head, _Tail...> >::_Ref
>+inline _TYPENAME tuple_element<_Index, tuple<_Head, _Tail...> >::_Ref
> get (tuple<_Head, _Tail...>& __tuple)
> {
>     typedef tuple_element<_Index, tuple<_Head, _Tail...> > _Tuple;

In the recent past Martin recommended not using the _TYPENAME macro. It
isn't hurting anything, but it could probably be removed. I know that I
no longer use it in the traits code. I also noticed the _EXPLICIT macro
above. I think that one should be added to the list. Martin?

>@@ -385,7 +389,7 @@
> }
> 
> template <_RWSTD_SIZE_T _Index, class _Head, class... _Tail>
>-_TYPENAME tuple_element<_Index, tuple<_Head, _Tail...> >::_ConstRef
>+inline _TYPENAME tuple_element<_Index, tuple<_Head, _Tail...> 
>>::_ConstRef
> get (const tuple<_Head, _Tail...>& __tuple)
> {
>     typedef tuple_element<_Index, tuple<_Head, _Tail...> > _Tuple;
>@@ -396,59 +400,67 @@
> // 20.3.1.6, relational operators:
> 
> template <class... _TypesT, class... _TypesU>
>-bool operator== (const tuple<_TypesT...>& __x,
>-                 const tuple<_TypesU...>& __y)
>+inline bool
>+operator== (const tuple<_TypesT...>& __x,
>+            const tuple<_TypesU...>& __y)
> {
>     return _RWSTD_STATIC_CAST (const 
>_RW::__rw_tuple<_TypesT...>&, __x)
>            == _RWSTD_STATIC_CAST (const 
>_RW::__rw_tuple<_TypesU...>&, __y);

I think there is a formatting issue here. The prevailing style is for
the operator to start of the next line, but for the operands to be lined
up on their left. As an example

  return    __some_really_long_expression_1
         == __some_really_long_expression_2;

I don't really like it all that much, but I'm using it in the traits
code all over the place.

> }
> 
> _RWSTD_SPECIALIZED_FUNCTION
>-bool operator== (const tuple<>& /*__x*/,
>-                 const tuple<>& /*__y*/)
>+inline bool
>+operator== (const tuple<>& /*__x*/,
>+            const tuple<>& /*__y*/)
> {
>     return true;
> }

The commented unused argument names again. Also, I think the
_RWSTD_SPECIALIZED_FUNCTION macro can be eliminated. If I remember
correctly Martin asked that it be removed from the traits implementation
(which I've done).

> 
> template <class... _TypesT, class... _TypesU>
>-bool operator< (const tuple<_TypesT...>& __x,
>-                const tuple<_TypesU...>& __y)
>+inline bool
>+operator< (const tuple<_TypesT...>& __x,
>+           const tuple<_TypesU...>& __y)
> {
>     return _RWSTD_STATIC_CAST (const 
>_RW::__rw_tuple<_TypesT...>&, __x)
>            < _RWSTD_STATIC_CAST (const 
>_RW::__rw_tuple<_TypesU...>&, __y);
> }

Again with the formatting of the first line of the function body. :)

> 
> _RWSTD_SPECIALIZED_FUNCTION
>-bool operator< (const tuple<>& /*__x*/,
>-                const tuple<>& /*__y*/)
>+inline bool
>+operator< (const tuple<>& /*__x*/,
>+           const tuple<>& /*__y*/)
> {
>     return false;
> }

And again with the names... :P

>
>Modified: stdcxx/branches/4.3.x/tests/utilities/20.tuple.cnstr.cpp
>URL: 
>http://svn.apache.org/viewvc/stdcxx/branches/4.3.x/tests/utilit
>ies/20.tuple.cnstr.cpp?rev=675044&r1=675043&r2=675044&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 
>Tue Jul  8 16:13:36 2008
>@@ -32,8 +32,11 @@
> #if    !defined (_RWSTD_NO_EXT_CXX_0X) \
>     && !defined(_RWSTD_NO_RVALUE_REFERENCES)
> 
>+#include <cstring>              // for strcmp
> #include <tuple>
> 
>+#include <rw_valcmp.h>          // for rw_dblcmp
>+
> #include "20.tuple.h"
> 
> 
>/**************************************************************
>************/
>@@ -46,7 +49,7 @@
>     EmptyTuple et; _RWSTD_UNUSED (et);
>     IntTuple it; _RWSTD_UNUSED (it);
>     ConstIntTuple ct; _RWSTD_UNUSED (ct);
>-    //IntRefTuple rt; _RWSTD_UNUSED (rt); // ill-formed for references
>+    // ill-formed for tuples with element types containing references
>     PairTuple pt; _RWSTD_UNUSED (pt);
>     NestedTuple nt; _RWSTD_UNUSED (nt);
>     BigTuple bt; _RWSTD_UNUSED (bt);
>@@ -57,80 +60,174 @@
>     rw_assert (1 == UserClass::n_total_def_ctor_, __FILE__, __LINE__,
>                "tuple<UserClass>::tuple() called %d default ctors, "
>                "expected 1", UserClass::n_total_def_ctor_);
>-    rw_assert (0 == UserClass::n_total_copy_ctor_, __FILE__, __LINE__,
>-               "tuple<UserClass>::tuple() called %d copy ctors, "
>-               "expected 0", UserClass::n_total_copy_ctor_);
> }
> 
> 
>/**************************************************************
>************/
> 
>+#define INT_VALUE       int ('a')
>+
>+// 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);
>+
>+
>+#define LONG_VALUE      INT_VALUE
>+#define STRING_VALUE    "string"
>+
> static void
>-test_value_copy_ctor ()
>+verify_tuple (const PairTuple& pt)
> {
>-    rw_info (0, __FILE__, __LINE__, "value copy constructor");
>+    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);
>+}

Is there any way that we could write a routine to generate a tuple and
then test it, so as to avoid always using the same few types and values
hidden behind the *_VALUE macros? The usage would be something like
this...

  TEST_TUPLE (1, 3.14f, 'a', "abc");

>-    int i = 1;
>-    IntTuple it1 (i); _RWSTD_UNUSED (it1);
>-    const IntTuple it2 (i); _RWSTD_UNUSED (it2);
>-    ConstIntTuple ct (i); _RWSTD_UNUSED (ct);
>-    IntRefTuple rt (i); _RWSTD_UNUSED (rt);
> 
>-    NestedTuple nt (it2); _RWSTD_UNUSED (nt);
>+#define USER_VALUE      user_val

I'm being a nit-picker, but this seems like an awful simple thing to be
wrapping a macro around. Is there a reason to do so?

>Modified: stdcxx/branches/4.3.x/tests/utilities/20.tuple.creation.cpp
>URL: 
>http://svn.apache.org/viewvc/stdcxx/branches/4.3.x/tests/utilit
>ies/20.tuple.creation.cpp?rev=675044&r1=675043&r2=675044&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 
>Tue Jul  8 16:13:36 2008
>@@ -63,11 +63,23 @@
> 
> 
>/**************************************************************
>************/
> 
>+#include <cstring>
>+
> static void
> test_tie ()
> {
>     rw_info (0, __FILE__, __LINE__, "tie");
> 
>+    int i = 0; double d = 0.0; const char* s = 0;
>+    std::tie (i, std::ignore, s)
>+        = std::make_tuple (256, 3.14159, "string");
>+
>+    rw_assert (i == 256, __FILE__, __LINE__,
>+               "i == 256, got false, expected true");
>+    rw_assert (d == 0.0, __FILE__, __LINE__,
>+               "d == 0.0, got false, expected true");
>+    rw_assert (0 == std::strcmp (s, "string"), __FILE__, __LINE__,
>+               "s == \"string\", got false, expected true");

The tuple is holding the original pointer (not a copy), so I think you
can check the actual pointer here.



>