Uploaded image for project: 'C++ Standard Library'
  1. C++ Standard Library
  2. STDCXX-995

__rw_new_capacity() doesn't control map, set

Details

    • Bug
    • Status: Open
    • Minor
    • Resolution: Unresolved
    • 4.1.2, 4.1.3, 4.1.4, 4.2.0, 4.2.1
    • 4.2.2
    • 23. Containers
    • None
    • Patch Available
    • Incorrect Behavior

    Description

      -------- Original Message --------
      Subject: Re: Controlling allocation policy of STL set.
      Date: Thu, 17 Jul 2008 17:18:17 -0700 (PDT)
      From: Dennis Handly <dhandly AT cup DOT hp DOT com>
      To: sebor AT roguewave DOT com
      CC: boris.gubenko AT hp DOT com, dhandly AT cup DOT hp DOT com, premanand.rao AT hp DOT com

      We had this question from a user recently. I was able to reverse engineer
      how to do this with map/set.

      Is this level of difficulty known?

      Here is a link where we mention the info about __rw_new_capacity:
      http://docs.hp.com/en/10946/libs.htm#container_alloc

      I would be nice if we could just use the private typedef
      std::map<K,V>::__rep_type.

      Then we could just use:

      #include <set>
      
      typedef std::set<key_type> BlagPset;
      typedef BlagPset::__rep_type BlagPtree;
      // forward
      template<>
      inline size_t __rw::__rw_new_capacity<BlagPtree>(size_t size, BlagPtree const*);
      

      Do you see any issues with making __rep_type public?

      (Your Apache code still has it private but as _C_repT.)

      ===========================================================================
      Do you know why the following code fragment does not work for me?
      i.e it controls the vector's allocation policy as I expect, but not the
      set's. I can believe there is some stupid mistake in there, but I have been
      staring at it for a while now...

      #include <stdio.h>
      #include <vector>
      #include <set>
      class Blag { int a; };
      std::vector<Blag*> bvec;
      std::set<Blag*> bset;
      
      template<>
      inline size_t __rw::__rw_new_capacity<std::vector<Blag*> >(size_t size,
                                            std::vector<Blag*> const*) {
          if (size == 0) {
              fprintf(stderr, "Initial size will be 8 for vector\n");
              return 8;
          } else
              return size * 2;
      }
      
      template<>
      inline size_t __rw::__rw_new_capacity<std::set<Blag*> >(size_t size,
                                             std::set<Blag*> const*) {
          if (size == 0) {
              fprintf(stderr, "Initial size will be 8 for set\n");
              return 8;
          } else
              return size * 2;
      }
      int main() {
          bset.insert(0);
          bvec.push_back(0);
      }
      

      ===========================================================================
      >From: Dennis Handly <dhandly AT cup DOT hp DOT com>

      >Do you know why the following code fragment does not work for me?

      Storage isn't allocated for the set but by the __rbtree.

      >I can believe there is some stupid mistake in there

      It isn't easy, you have to find the __rw_new_capacity call.

      #include <stdio.h>
      #include <vector>
      
      class Blag { int a; };
      typedef Blag* key_type;
      
      // start kludge
      #include <functional>
      namespace __rw {
      template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
      class __rb_tree;
      template <class _TypeT, class _TypeU>
      struct __ident;
      } // namespace __rw
      typedef __rw::__rb_tree<key_type, key_type, __rw::__ident<key_type, key_type>,
                              std::less<key_type>, std::allocator<key_type> >
                              BlagPtree;
      // forward
      template<>
      inline size_t __rw::__rw_new_capacity<BlagPtree>(size_t size, BlagPtree const*);
      // end kludge
      
      #include <set>
      
      typedef std::vector<key_type> BlagPvec;
      typedef std::set<key_type> BlagPset;
      BlagPvec bvec;
      BlagPset bset;
      
      template<>
      inline size_t __rw::__rw_new_capacity<BlagPvec>(size_t size, BlagPvec const*) {
          if (size == 0) {
              fprintf(stderr, "Initial size will be 8 for vector\n");
              return 8;
          } else
              return size * 2;
      }
      // useless
      template<>
      inline size_t __rw::__rw_new_capacity<BlagPset>(size_t size, BlagPset const*) {
          if (size == 0) {
              fprintf(stderr, "Initial size will be 8 for set\n");
              return 8;
          } else
              return size * 2;
      }
      template<>
      inline size_t __rw::__rw_new_capacity<BlagPtree>(size_t size, BlagPtree const*){
          if (size == 0) {
              fprintf(stderr, "Initial size will be 8 for tree\n");
              return 8;
          } else
              return size * 2;
      }
      
      int main() {
          bset.insert(0);
          bvec.push_back(0);
      }
      

      Attachments

        1. stdcxx-995.patch
          16 kB
          Farid Zaripov

        Activity

          No work has yet been logged on this issue.

          People

            Unassigned Unassigned
            sebor Martin Sebor
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:

              Time Tracking

                Estimated:
                Original Estimate - 2h
                2h
                Remaining:
                Remaining Estimate - 2h
                2h
                Logged:
                Time Spent - Not Specified
                Not Specified