Listing 3: Extract from stlsoft_auto_buffer.h.
/* ///////////////////////////////////////////////////////////// * Extract from stlsoft_auto_buffer.h * www: http://www.stlsoft.org/ * Copyright (C) 2002-2003, Synesis Software Pty Ltd. * (Licensed under the Synesis Software Standard Source License: * http://www.synesis.com.au/licenses/ssssl.html) * ////////////////////////////////////////////////////////// */ // class auto_buffer template< typename T , typename A , size_t SPACE = 512 > class auto_buffer #ifndef __STLSOFT_COMPILER_IS_BORLAND : protected A #endif /* !__STLSOFT_COMPILER_IS_BORLAND */ { public: typedef T value_type; typedef A allocator_type; typedef size_t size_type; typedef auto_buffer<T, A, SPACE> class_type; typedef value_type *pointer; typedef value_type const *const_pointer; typedef value_type *iterator; typedef value_type const *const_iterator; // Implementation private: #ifdef __STLSOFT_COMPILER_IS_BORLAND static allocator_type &_get_ator() { static allocator_type s_allocator; return s_allocator; } #else allocator_type &_get_ator() { return *this; } #endif /* __STLSOFT_COMPILER_IS_BORLAND */ // Construction public: explicit auto_buffer(size_type cItems) : m_buffer( (space < cItems) ? _get_ator().allocate(cItems, 0) : m_internal) , m_cItems( (m_buffer != 0) ? cItems : 0) { // These assertions ensure that the member ordering is not // changed, invalidating the initialisation logic of // m_buffer and m_cItems. The runtime assert is included // for compilers that don't implement compile-time asserts. stlsoft_static_assert( stlsoft_raw_offsetof(class_type, m_buffer) < stlsoft_raw_offsetof(class_type, m_cItems)); stlsoft_message_assert( "m_buffer must be before m_cItems in the auto_buffer definition", stlsoft_raw_offsetof(class_type, m_buffer) < stlsoft_raw_offsetof(class_type, m_cItems)); #ifndef _STLSOFT_AUTO_BUFFER_ALLOW_NON_POD // Use the type_is_non_class_or_trivial_class constraint to ensure that // no type is managed in auto_buffer which would result in dangerous // mismanagement of instances lifetimes. // Preprocessor specification of _STLSOFT_AUTO_BUFFER_ALLOW_NON_POD // prevents this, but the natural rules of the language will // still prevent non POD types being placed in m_internal[]. stlsoft_constraint_type_is_non_class_or_trivial_class(value_type); #endif /* _STLSOFT_AUTO_BUFFER_ALLOW_NON_POD */ } ~auto_buffer() { if(space < m_cItems) { stlsoft_assert(m_buffer != 0); _get_ator().deallocate(m_buffer, m_cItems); } } // Operators public: operator pointer () { return m_buffer; } #ifdef _STLSOFT_AUTO_BUFFER_ALLOW_CONST_CONVERSION_OPERATOR operator const_pointer () const; #endif /* _STLSOFT_AUTO_BUFFER_ALLOW_CONST_CONVERSION_OPERATOR */ // Iteration public: const_iterator begin() const { return m_buffer; } const_iterator end() const { return m_buffer + m_cItems; } iterator begin(); iterator end(); // Attributes public: size_type size() const { return m_cItems; } // Members protected: enum { space = SPACE }; value_type *const m_buffer; // Pointer to used buffer size_type const m_cItems; // Number of items in buffer value_type m_internal[space]; // Internal storage // Not to be implemented private: auto_buffer(class_type const &rhs); auto_buffer const &operator =(class_type const &rhs); }; /* ///////////////////////////////////////////////////////////// */