This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Advice on specialization in a different namespace


Gabriel Dos Reis wrote:

> | What do you suggest?
>
> Hi Paolo,
>
> Specializations for extensions, by the letter of the standard, should
> remain in std::.  You can't do anything against that.   And actually,
> there is no harm in putting those specializations in std::, since the
> template arguments used in the specialisations unambigously identify
> the entities being designated.  However we have to make sure those
> specializations are not available in standard headers.
>
> Since all that is an ABI change in the libary, we should probably put
> words to that effect in the documentation.

Thank you very much Gaby.
By the end of the day I hope to be able to post a complete patch. This is what I
have right now (mostly ok, I hope, currently testing) which implements your advices:
if you spot something obviously wrong in it, please inform me ASAP!

Cheers,
Paolo.

////////////////

diff -prN libstdc++-v3-orig/include/ext/hash_map libstdc++-v3/include/ext/hash_map
*** libstdc++-v3-orig/include/ext/hash_map Tue Nov 20 01:51:37 2001
--- libstdc++-v3/include/ext/hash_map Sat Dec 29 15:44:47 2001
***************
*** 64,71 ****
  #include <ext/stl_hashtable.h>
  #include <bits/concept_check.h>

! namespace std
  {

  // Forward declaration of equality operator; needed for friend declaration.

--- 64,75 ----
  #include <ext/stl_hashtable.h>
  #include <bits/concept_check.h>

! namespace __gnu_cxx
  {
+ using std::equal_to;
+ using std::allocator;
+ using std::pair;
+ using std::_Select1st;

  // Forward declaration of equality operator; needed for friend declaration.

*************** swap(hash_multimap<_Key,_Tp,_HashFcn,_Eq
*** 371,379 ****
--- 375,388 ----
    __hm1.swap(__hm2);
  }

+ } // namespace __gnu_cxx

+ namespace std
+ {
  // Specialization of insert_iterator so that it will work for hash_map
  // and hash_multimap.
+ using __gnu_cxx::hash_map;
+ using __gnu_cxx::hash_multimap;

  template <class _Key, class _Tp, class _HashFn,  class _EqKey, class _Alloc>
  class insert_iterator<hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc> > {
diff -prN libstdc++-v3-orig/include/ext/hash_set libstdc++-v3/include/ext/hash_set
*** libstdc++-v3-orig/include/ext/hash_set Tue Nov 20 01:51:37 2001
--- libstdc++-v3/include/ext/hash_set Sat Dec 29 15:45:10 2001
***************
*** 64,71 ****
  #include <ext/stl_hashtable.h>
  #include <bits/concept_check.h>

! namespace std
  {

  // Forward declaration of equality operator; needed for friend declaration.

--- 64,75 ----
  #include <ext/stl_hashtable.h>
  #include <bits/concept_check.h>

! namespace __gnu_cxx
  {
+ using std::equal_to;
+ using std::allocator;
+ using std::pair;
+ using std::_Identity;

  // Forward declaration of equality operator; needed for friend declaration.

*************** swap(hash_multiset<_Val,_HashFcn,_EqualK
*** 361,368 ****
--- 365,378 ----
    __hs1.swap(__hs2);
  }

+ } // namespace __gnu_cxx
+
+ namespace std
+ {
  // Specialization of insert_iterator so that it will work for hash_set
  // and hash_multiset.
+ using __gnu_cxx::hash_set;
+ using __gnu_cxx::hash_multiset;

  template <class _Value, class _HashFcn, class _EqualKey, class _Alloc>
  class insert_iterator<hash_set<_Value, _HashFcn, _EqualKey, _Alloc> > {
diff -prN libstdc++-v3-orig/include/ext/ropeimpl.h
libstdc++-v3/include/ext/ropeimpl.h
*** libstdc++-v3-orig/include/ext/ropeimpl.h Thu Dec 13 01:41:02 2001
--- libstdc++-v3/include/ext/ropeimpl.h Sat Dec 29 13:08:54 2001
***************
*** 49,56 ****
  #include <bits/std_iostream.h>
  #include <bits/functexcept.h>

! namespace std
  {

  // Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf
  // if necessary.  Assumes _M_path_end[leaf_index] and leaf_pos are correct.
--- 49,62 ----
  #include <bits/std_iostream.h>
  #include <bits/functexcept.h>

! namespace __gnu_cxx
  {
+ using std::size_t;
+ using std::printf;
+ using std::basic_ostream;
+ using std::__throw_length_error;
+ using std::__alloc;
+ using std::uninitialized_copy_n;

  // Set buf_start, buf_end, and buf_ptr appropriately, filling tmp_buf
  // if necessary.  Assumes _M_path_end[leaf_index] and leaf_pos are correct.
*************** basic_ostream<_CharT, _Traits>& operator
*** 901,907 ****
                                              const rope<_CharT, _Alloc>& __r)
  {
      size_t __w = __o.width();
!     bool __left = bool(__o.flags() & ios::left);
      size_t __pad_len;
      size_t __rope_len = __r.size();
        _Rope_insert_char_consumer<_CharT, _Traits> __c(__o);
--- 907,913 ----
                                              const rope<_CharT, _Alloc>& __r)
  {
      size_t __w = __o.width();
!     bool __left = bool(__o.flags() & std::ios::left);
      size_t __pad_len;
      size_t __rope_len = __r.size();
        _Rope_insert_char_consumer<_CharT, _Traits> __c(__o);
*************** rope<_CharT,_Alloc>::_S_flatten(_RopeRep
*** 974,980 ****
   case _RopeRep::_S_leaf:
       {
    _RopeLeaf* __l = (_RopeLeaf*)__r;
!   return copy_n(__l->_M_data, __l->_M_size, __buffer).second;
       }
   case _RopeRep::_S_function:
   case _RopeRep::_S_substringfn:
--- 980,986 ----
   case _RopeRep::_S_leaf:
       {
    _RopeLeaf* __l = (_RopeLeaf*)__r;
!   return std::copy_n(__l->_M_data, __l->_M_size, __buffer).second;
       }
   case _RopeRep::_S_function:
   case _RopeRep::_S_substringfn:
*************** inline void rotate(
*** 1530,1536 ****
  }
  # endif

! } // namespace std

  // Local Variables:
  // mode:C++
--- 1536,1542 ----
  }
  # endif

! } // namespace __gnu_cxx

  // Local Variables:
  // mode:C++
diff -prN libstdc++-v3-orig/include/ext/slist libstdc++-v3/include/ext/slist
*** libstdc++-v3-orig/include/ext/slist Tue Nov 20 01:51:37 2001
--- libstdc++-v3/include/ext/slist Sat Dec 29 15:44:19 2001
***************
*** 55,62 ****
  #include <bits/stl_uninitialized.h>
  #include <bits/concept_check.h>

! namespace std
  {

  struct _Slist_node_base
  {
--- 55,65 ----
  #include <bits/stl_uninitialized.h>
  #include <bits/concept_check.h>

! namespace __gnu_cxx
  {
+ using std::size_t;
+ using std::ptrdiff_t;
+ //using std::insert_iterator;

  struct _Slist_node_base
  {
*************** struct _Slist_node : public _Slist_node_
*** 145,153 ****

  struct _Slist_iterator_base
  {
!   typedef size_t               size_type;
!   typedef ptrdiff_t            difference_type;
!   typedef forward_iterator_tag iterator_category;

    _Slist_node_base* _M_node;

--- 148,156 ----

  struct _Slist_iterator_base
  {
!   typedef size_t                    size_type;
!   typedef ptrdiff_t                 difference_type;
!   typedef std::forward_iterator_tag iterator_category;

    _Slist_node_base* _M_node;

*************** class slist : private _Slist_base<_Tp,_A
*** 297,303 ****
  private:
    typedef _Slist_base<_Tp,_Alloc> _Base;
  public:
!   typedef _Tp                value_type;
    typedef value_type*       pointer;
    typedef const value_type* const_pointer;
    typedef value_type&       reference;
--- 300,306 ----
  private:
    typedef _Slist_base<_Tp,_Alloc> _Base;
  public:
!   typedef _Tp               value_type;
    typedef value_type*       pointer;
    typedef const value_type* const_pointer;
    typedef value_type&       reference;
*************** void slist<_Tp,_Alloc>::sort(_StrictWeak
*** 897,904 ****
--- 900,912 ----
    }
  }

+ } // namespace __gnu_cxx
+
+ namespace std
+ {
  // Specialization of insert_iterator so that insertions will be constant
  // time rather than linear time.
+ using __gnu_cxx::slist;

  template <class _Tp, class _Alloc>
  class insert_iterator<slist<_Tp, _Alloc> > {
*************** public:
*** 932,938 ****
    insert_iterator<_Container>& operator++(int) { return *this; }
  };

! } // namespace std

  #endif /* __SGI_STL_INTERNAL_SLIST_H */

--- 940,946 ----
    insert_iterator<_Container>& operator++(int) { return *this; }
  };

! } // namespace std

  #endif /* __SGI_STL_INTERNAL_SLIST_H */

diff -prN libstdc++-v3-orig/include/ext/stl_hash_fun.h
libstdc++-v3/include/ext/stl_hash_fun.h
*** libstdc++-v3-orig/include/ext/stl_hash_fun.h Tue Nov 20 01:51:37 2001
--- libstdc++-v3/include/ext/stl_hash_fun.h Sat Dec 29 11:35:41 2001
***************
*** 63,70 ****

  #include <bits/std_cstddef.h>

! namespace std
  {

  template <class _Key> struct hash { };

--- 63,71 ----

  #include <bits/std_cstddef.h>

! namespace __gnu_cxx
  {
+ using std::size_t;

  template <class _Key> struct hash { };

*************** template<> struct hash<unsigned long> {
*** 115,121 ****
    size_t operator()(unsigned long __x) const { return __x; }
  };

! } // namespace std

  #endif /* _CPP_BITS_STL_HASH_FUN_H */

--- 116,122 ----
    size_t operator()(unsigned long __x) const { return __x; }
  };

! } // namespace __gnu_cxx

  #endif /* _CPP_BITS_STL_HASH_FUN_H */

diff -prN libstdc++-v3-orig/include/ext/stl_hashtable.h
libstdc++-v3/include/ext/stl_hashtable.h
*** libstdc++-v3-orig/include/ext/stl_hashtable.h Thu Dec  6 21:29:31 2001
--- libstdc++-v3/include/ext/stl_hashtable.h Sat Dec 29 12:11:29 2001
***************
*** 74,81 ****
  #include <bits/stl_vector.h>
  #include <ext/stl_hash_fun.h>

! namespace std
  {

  template <class _Val>
  struct _Hashtable_node
--- 74,88 ----
  #include <bits/stl_vector.h>
  #include <ext/stl_hash_fun.h>

! namespace __gnu_cxx
  {
+ using std::size_t;
+ using std::ptrdiff_t;
+ using std::forward_iterator_tag;
+ using std::input_iterator_tag;
+ using std::_Alloc_traits;
+ using std::vector;
+ using std::pair;

  template <class _Val>
  struct _Hashtable_node
*************** struct _Hashtable_node
*** 85,91 ****
  };

  template <class _Val, class _Key, class _HashFcn,
!           class _ExtractKey, class _EqualKey, class _Alloc = __alloc>
  class hashtable;

  template <class _Val, class _Key, class _HashFcn,
--- 92,98 ----
  };

  template <class _Val, class _Key, class _HashFcn,
!           class _ExtractKey, class _EqualKey, class _Alloc = std::__alloc>
  class hashtable;

  template <class _Val, class _Key, class _HashFcn,
*************** inline unsigned long __stl_next_prime(un
*** 188,194 ****
  {
    const unsigned long* __first = __stl_prime_list;
    const unsigned long* __last = __stl_prime_list + (int)__stl_num_primes;
!   const unsigned long* pos = lower_bound(__first, __last, __n);
    return pos == __last ? *(__last - 1) : *pos;
  }

--- 195,201 ----
  {
    const unsigned long* __first = __stl_prime_list;
    const unsigned long* __last = __stl_prime_list + (int)__stl_num_primes;
!   const unsigned long* pos = std::lower_bound(__first, __last, __n);
    return pos == __last ? *(__last - 1) : *pos;
  }

*************** void hashtable<_Val,_Key,_HF,_Ex,_Eq,_Al
*** 964,970 ****
      }
  }

! } // namespace std

  #endif /* __SGI_STL_INTERNAL_HASHTABLE_H */

--- 971,977 ----
      }
  }

! } // namespace __gnu_cxx

  #endif /* __SGI_STL_INTERNAL_HASHTABLE_H */

diff -prN libstdc++-v3-orig/include/ext/stl_rope.h
libstdc++-v3/include/ext/stl_rope.h
*** libstdc++-v3-orig/include/ext/stl_rope.h Fri Dec 21 14:08:35 2001
--- libstdc++-v3/include/ext/stl_rope.h Sat Dec 29 13:18:24 2001
***************
*** 61,68 ****
  #   define __GC_CONST   // constant except for deallocation
  # endif

! namespace std
  {

  // The _S_eos function is used for those functions that
  // convert to/from C-like strings to detect the end of the string.
--- 61,75 ----
  #   define __GC_CONST   // constant except for deallocation
  # endif

! namespace __gnu_cxx
  {
+ using std::size_t;
+ using std::ptrdiff_t;
+ using std::allocator;
+ using std::iterator;
+ using std::reverse_iterator;
+ using std::_Alloc_traits;
+ using std::uninitialized_copy_n;

  // The _S_eos function is used for those functions that
  // convert to/from C-like strings to detect the end of the string.
*************** class char_producer {
*** 122,128 ****
  // little like containers.

  template<class _Sequence, size_t _Buf_sz = 100>
! class sequence_buffer : public iterator<output_iterator_tag,void,void,void,void>
  {
      public:
          typedef typename _Sequence::value_type value_type;
--- 129,135 ----
  // little like containers.

  template<class _Sequence, size_t _Buf_sz = 100>
! class sequence_buffer : public
iterator<std::output_iterator_tag,void,void,void,void>
  {
      public:
          typedef typename _Sequence::value_type value_type;
*************** rope<_CharT,_Alloc> operator+ (const rop
*** 316,322 ****
  // The result has refcount 0.
  template<class _CharT, class _Alloc>
  struct _Rope_Concat_fn
!        : public binary_function<rope<_CharT,_Alloc>, rope<_CharT,_Alloc>,
                                       rope<_CharT,_Alloc> > {
          rope<_CharT,_Alloc> operator() (const rope<_CharT,_Alloc>& __x,
                                  const rope<_CharT,_Alloc>& __y) {
--- 323,329 ----
  // The result has refcount 0.
  template<class _CharT, class _Alloc>
  struct _Rope_Concat_fn
!        : public std::binary_function<rope<_CharT,_Alloc>, rope<_CharT,_Alloc>,
                                       rope<_CharT,_Alloc> > {
          rope<_CharT,_Alloc> operator() (const rope<_CharT,_Alloc>& __x,
                                  const rope<_CharT,_Alloc>& __y) {
*************** struct _Rope_RopeConcatenation : public
*** 601,607 ****
                               allocator_type __a)

        : _Rope_RopeRep<_CharT,_Alloc>(_S_concat,
!                                      max(__l->_M_depth, __r->_M_depth) + 1,
                                       false,
                                       __l->_M_size + __r->_M_size, __a),
          _M_left(__l), _M_right(__r)
--- 608,614 ----
                               allocator_type __a)

        : _Rope_RopeRep<_CharT,_Alloc>(_S_concat,
!                                      std::max(__l->_M_depth, __r->_M_depth) + 1,
                                       false,
                                       __l->_M_size + __r->_M_size, __a),
          _M_left(__l), _M_right(__r)
*************** class _Rope_char_ptr_proxy {
*** 838,844 ****

  template<class _CharT, class _Alloc>
  class _Rope_iterator_base
!   : public iterator<random_access_iterator_tag, _CharT>
  {
      friend class rope<_CharT,_Alloc>;
    public:
--- 845,851 ----

  template<class _CharT, class _Alloc>
  class _Rope_iterator_base
!   : public iterator<std::random_access_iterator_tag, _CharT>
  {
      friend class rope<_CharT,_Alloc>;
    public:
*************** inline bool operator!= (const _Rope_char
*** 2429,2436 ****
  }

  template<class _CharT, class _Traits, class _Alloc>
! basic_ostream<_CharT, _Traits>& operator<<
!                                         (basic_ostream<_CharT, _Traits>& __o,
                                           const rope<_CharT, _Alloc>& __r);

  typedef rope<char> crope;
--- 2436,2443 ----
  }

  template<class _CharT, class _Traits, class _Alloc>
! std::basic_ostream<_CharT, _Traits>& operator<<
!                                         (std::basic_ostream<_CharT, _Traits>& __o,

                                           const rope<_CharT, _Alloc>& __r);

  typedef rope<char> crope;
*************** template<> struct hash<wrope>
*** 2475,2481 ****
    }
  };

! } // namespace std

  # include <ext/ropeimpl.h>

--- 2482,2488 ----
    }
  };

! } // namespace __gnu_cxx

  # include <ext/ropeimpl.h>

diff -prN libstdc++-v3-orig/testsuite/ext/rope.cc libstdc++-v3/testsuite/ext/rope.cc

*** libstdc++-v3-orig/testsuite/ext/rope.cc Wed Oct  3 23:19:31 2001
--- libstdc++-v3/testsuite/ext/rope.cc Sat Dec 29 11:12:34 2001
***************
*** 25,31 ****

  void test01()
  {
!   std::crope foo;
    foo += "bar";
    const char* data = foo.c_str();
    std::cout << data << std::endl;
--- 25,31 ----

  void test01()
  {
!   __gnu_cxx::crope foo;
    foo += "bar";
    const char* data = foo.c_str();
    std::cout << data << std::endl;






Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]