//////////////////////////////////////////////////////////////////////////////// // flex_string // Copyright (c) 2001 by Andrei Alexandrescu // Permission to use, copy, modify, distribute and sell this software for any // purpose is hereby granted without fee, provided that the above copyright // notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. // The author makes no representations about the // suitability of this software for any purpose. It is provided "as is" // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// #ifndef VECTOR_STRING_STORAGE_INC_ #define VECTOR_STRING_STORAGE_INC_ /* This is the template for a storage policy //////////////////////////////////////////////////////////////////////////////// template class StoragePolicy { typedef E value_type; typedef @ iterator; typedef @ const_iterator; typedef A allocator_type; typedef @ size_type; StoragePolicy(const StoragePolicy& s); StoragePolicy(const A&); StoragePolicy(const E* s, size_type len, const A&); StoragePolicy(size_type len, E c, const A&); ~StoragePolicy(); iterator begin(); const_iterator begin() const; iterator end(); const_iterator end() const; size_type size() const; size_type max_size() const; size_type capacity() const; void reserve(size_type res_arg); void append(const E* s, size_type sz); template void append(InputIterator b, InputIterator e); void resize(size_type newSize, E fill); void swap(StoragePolicy& rhs); const E* c_str() const; const E* data() const; A get_allocator() const; }; //////////////////////////////////////////////////////////////////////////////// */ #include #include #include #include #include #include #include //////////////////////////////////////////////////////////////////////////////// // class template VectorStringStorage // Uses std::vector // Takes advantage of the Empty Base Optimization if available //////////////////////////////////////////////////////////////////////////////// template > class VectorStringStorage : protected std::vector { typedef std::vector base; public: // protected: typedef E value_type; typedef typename base::iterator iterator; typedef typename base::const_iterator const_iterator; typedef A allocator_type; typedef typename A::size_type size_type; typedef typename A::reference reference; VectorStringStorage(const VectorStringStorage& s) : base(s) { } VectorStringStorage(const A& a) : base(1, value_type(), a) { } VectorStringStorage(const value_type* s, size_type len, const A& a) : base(a) { base::reserve(len + 1); base::insert(base::end(), s, s + len); // Terminating zero base::push_back(value_type()); } VectorStringStorage(size_type len, E c, const A& a) : base(len + 1, c, a) { // Terminating zero base::back() = value_type(); } VectorStringStorage& operator=(const VectorStringStorage& rhs) { base& v = *this; v = rhs; return *this; } iterator begin() { return base::begin(); } const_iterator begin() const { return base::begin(); } iterator end() { return base::end() - 1; } const_iterator end() const { return base::end() - 1; } size_type size() const { return base::size() - 1; } size_type max_size() const { return base::max_size() - 1; } size_type capacity() const { return base::capacity() - 1; } void reserve(size_type res_arg) { assert(res_arg < max_size()); base::reserve(res_arg + 1); } template void append(ForwardIterator b, ForwardIterator e) { const typename std::iterator_traits::difference_type sz = std::distance(b, e); assert(sz >= 0); if (sz == 0) return; base::reserve(base::size() + sz); const value_type & v = *b; struct OnBlockExit { VectorStringStorage * that; ~OnBlockExit() { that->base::push_back(value_type()); } } onBlockExit = { this }; (void) onBlockExit; assert(!base::empty()); assert(base::back() == value_type()); base::back() = v; base::insert(base::end(), ++b, e); } void resize(size_type n, E c) { base::reserve(n + 1); base::back() = c; base::resize(n + 1, c); base::back() = E(); } void swap(VectorStringStorage& rhs) { base::swap(rhs); } const E* c_str() const { return &*begin(); } const E* data() const { return &*begin(); } A get_allocator() const { return base::get_allocator(); } }; #endif // VECTOR_STRING_STORAGE_INC_