You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@stdcxx.apache.org by "Martin Sebor (JIRA)" <ji...@apache.org> on 2006/01/07 21:16:24 UTC

[jira] Updated: (STDCXX-16) __rb_tree::operator=() does not store rhs' comparison object in lhs

     [ http://issues.apache.org/jira/browse/STDCXX-16?page=all ]

Martin Sebor updated STDCXX-16:
-------------------------------

    Fix Version: 4.1.4
                     (was: 4.1.3)

> __rb_tree::operator=() does not store rhs' comparison object in lhs
> -------------------------------------------------------------------
>
>          Key: STDCXX-16
>          URL: http://issues.apache.org/jira/browse/STDCXX-16
>      Project: STDCXX
>         Type: Bug
>   Components: 23. Containers
>     Versions: 4.1.2
>  Environment: All
>     Reporter: Martin Sebor
>      Fix For: 4.1.4

>
> -------- Original Message --------
> Subject: tree::operator=() does not store rhs' comparison object in lhs
> Date: Mon, 8 Aug 2005 21:48:50 -0400
> From: Boris Gubenko
> To: Martin Sebor <se...@roguewave.com>
> A customer reported a problem with set STL container using a program
> from "The C++ Standard Library - A Tutorial and Reference" by Nicolai
> Josuttis. See attached. The program generates expected result with
> STLPort and gnu libstdc++, but generates a wrong result with any
> version of RW library I tried it with.
> The problem is that tree' assignment operator does not store rhs'
> comparison object in lhs (I'd expect map container to have the same
> problem). As a result, after assignment, the target container continues
> to use the comparison object that it used before the assignement. It
> violates 23.1.2 - Associative containers [lib.associative.reqmts],
> para 11:
>  -11- When an associative container is constructed by passing a
>  comparison object the container shall not store a pointer or
>  reference to the passed object, even if that object is passed by
>  reference. When an associative container is copied, either through
>  a copy constructor or an assignment operator, the target container
>  shall then use the comparison object from the container being copied,
>  as if that comparison object had been passed to the target container
>  in its constructor.
> The proposed fix is the same one-liner for any version of RW library,
> just the name of the member is different. See below for HP-UX.
> Thanks,
>  Boris
> granite> aCC -V
> aCC: HP aC++/ANSI C B3910B A.05.50 [May 15 2003]
> granite> aCC setcmp.cpp && a.out
> coll1: 1 2 4 5 6 7
> coll2: 7 6 5 4 2 1
> coll1: 3 7 6 5 4 2 1
> coll1 and coll2 have different sorting criterion
> granite> aCC setcmp.cpp -I. && a.out
> coll1: 1 2 4 5 6 7
> coll2: 7 6 5 4 2 1
> coll1: 7 6 5 4 3 2 1
> coll1 and coll2 have same sorting criterion
> granite> diff rw/tree.cc /opt/aCC/include_std/rw/tree.cc
> 83,85d82
> < #if !defined(__FIXCXXL1932)
> <     _C_key_compare = __x._C_key_compare;
> < #endif
> granite>
> print.hpp
> ---------
> /* The following code example is taken from the book
> * "The C++ Standard Library - A Tutorial and Reference"
> * by Nicolai M. Josuttis, Addison-Wesley, 1999
> *
> * (C) Copyright Nicolai M. Josuttis 1999.
> * Permission to copy, use, modify, sell and distribute this software
> * is granted provided this copyright notice appears in all copies.
> * This software is provided "as is" without express or implied
> * warranty, and with no claim as to its suitability for any purpose.
> */
> #include <iostream>
> /* PRINT_ELEMENTS()
> * - prints optional C-string optcstr followed by
> * - all elements of the collection coll
> * - separated by spaces
> */
> template <class T>
> inline void PRINT_ELEMENTS (const T& coll, const char* optcstr="")
> {
>    typename T::const_iterator pos;
>    std::cout << optcstr;
>    for (pos=coll.begin(); pos!=coll.end(); ++pos) {
>        std::cout << *pos << ' ';
>    }
>    std::cout << std::endl;
> }
> setcmp.cpp
> ----------
> /* The following code example is taken from the book
> * "The C++ Standard Library - A Tutorial and Reference"
> * by Nicolai M. Josuttis, Addison-Wesley, 1999
> *
> * (C) Copyright Nicolai M. Josuttis 1999.
> * Permission to copy, use, modify, sell and distribute this software
> * is granted provided this copyright notice appears in all copies.
> * This software is provided "as is" without express or implied
> * warranty, and with no claim as to its suitability for any purpose.
> */
> #include <iostream>
> #include <set>
> #include "print.hpp"
> using namespace std;
> // type for sorting criterion
> template <class T>
> class RuntimeCmp {
>  public:
>    enum cmp_mode {normal, reverse};
>  private:
>    cmp_mode mode;
>  public:
>    // constructor for sorting criterion
>    // - default criterion uses value normal
>    RuntimeCmp (cmp_mode m=normal) : mode(m) {
>    }
>    // comparison of elements
>    bool operator() (const T& t1, const T& t2) const {
>        return mode == normal ? t1 < t2 : t2 < t1;
>    }
>    // comparison of sorting criteria
>    bool operator== (const RuntimeCmp& rc) {
>        return mode == rc.mode;
>    }
> };
> // type of a set that uses this sorting criterion
> typedef set<int,RuntimeCmp<int> > IntSet;
> // forward declaration
> void fill (IntSet& set);
> int main()
> {
>    // create, fill, and print set with normal element order
>    // - uses default sorting criterion
>    IntSet coll1;
>    fill(coll1);
>    PRINT_ELEMENTS (coll1, "coll1: ");
>    // create sorting criterion with reverse element order
>    RuntimeCmp<int> reverse_order(RuntimeCmp<int>::reverse);
>    // create, fill, and print set with reverse element order
>    IntSet coll2(reverse_order);
>    fill(coll2);
>    PRINT_ELEMENTS (coll2, "coll2: ");
>    // assign elements AND sorting criterion
>    coll1 = coll2;
>    coll1.insert(3);
>    PRINT_ELEMENTS (coll1, "coll1: ");
>    // just to make sure...
>    if (coll1.value_comp() == coll2.value_comp()) {
>        cout << "coll1 and coll2 have same sorting criterion"
>             << endl;
>    }
>    else {
>        cout << "coll1 and coll2 have different sorting criterion"
>             << endl;
>    }
> }
> void fill (IntSet& set)
> {
>    // fill insert elements in random order
>    set.insert(4);
>    set.insert(7);
>    set.insert(5);
>    set.insert(1);
>    set.insert(6);
>    set.insert(2);
>    set.insert(5);
> }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira