STL Allocator using Partial Specialization (Revision 1) ------------------------------------------ 8-Mar-95 by Nathan Myers X3J16/95-0019R1 Rogue Wave Software WG21/N0619R1 1. Whither Member Templates? At Valley Forge we accepted a form of STL allocator which was based on a language feature, member class templates, accepted and added to the WP in November 1993. Some implementors mentioned at Valley Forge that they had not noticed that member class templates had been accepted. The extensions group has identified a number of restrictions on member templates that make them an undesirable basis for these library features. Fortunately, the run-time variable allocator facility can be recast, mechanically, in terms of partial specialization. At Valley Forge I took an action item to come forward with a proposal for this recasting. This is that proposal. The following definitions are provided in a standard header: namespace std { template class pointers { typedef T* pointer; typedef T const* const_pointer; typedef T& reference; typedef T const& const_reference; typedef T value_type; }; template class pointers { public: typedef void* pointer; typedef void const* const_pointer; typedef void value_type; }; ...along with the default allocator, which may simply delegate to the global operator new (or may perform optimizations of its own): class allocator { public: typedef size_t size_type; typedef ptrdiff_t difference_type; allocator() {} ~allocator() {} size_type max_size() const; }; inline void* operator new(size_t N, allocator& a) { return allocate(N, 0, a); } STL Allocator using Partial Specialization 8-Mar-95 Page 2 of 3 ------------------------------------------ 95-0019R1/N0619R1 Here are the function templates that were members of allocator, and were lifted out by simple mechanical substitution: template typename pointers::pointer address(typename pointers::reference x, Allocator&) const template typename pointers::const_pointer address(typename pointers::const_reference x, Allocator&) const; template typename pointers::pointer allocate(size_type howmany, typename pointers::const_pointer hint, Allocator&); template void deallocate(typename pointers::pointer p, Allocator&); The following are generalizations of the templates removed in 95-0039R1 as agreed in WG discussion. If that proposal is accepted, this is the form of the generalization. The transformation is similarly mechanical. template inline void construct(types::pointer p, const T2& value, Allocator& = Allocator()); template inline void destroy(types::pointer pointer, Allocator& = Allocator()); template inline void destroy(T* pointer, allocator& = allocator()) { pointer->~T(); } template pair::pointer, types::size_type> get_temporary_buffer(types::size_type, types::pointer, Allocator& = Allocator()); } // namespace std STL Allocator using Partial Specialization 8-Mar-95 Page 3 of 3 ------------------------------------------ 95-0019R1/N0619R1 Users (e.g. object database vendors) may also define allocators of their own with compatible interfaces, and (partially) specialize these templates for their allocators. It is assumed that any pointer types have a (possibly lossy) conversion to void*, yielding a pointer sufficient for use as the "this" value in a constructor or destructor, and conversions to (and from?) pointers::pointer (for appropriate A) as well, for use by A::deallocate(). Collections are parameterized exactly as in the previous proposals. I also recommend adding a remark: "The standard library containers and string templates manage non-temporary storage using only their Allocator parameter, and templates instantiated on that parameter." This ensures that any specializations provided by a user will be used by the standard collections. 2. Member allocator::init_page_size() As a separate issue, I propose to remove the member class allocator { ... template size_type init_page_size() const; }; as obsolete. I have ascertained that it was intended for use by collections to manage blocks of storage elements; this is now the responsibility of allocator itself, or of specializations of the member allocator::allocate(...). If this member is not simply removed, it suffers the same problem as other member function templates, and should be replaced by the nonmember template: template typename Allocator::size_type init_page_size(Allocator&) const;