1 ////////////////////////////////////////////////////////////////////////////////
3 // Copyright (c) 2001 by Andrei Alexandrescu
4 // Permission to use, copy, modify, distribute and sell this software for any
5 // purpose is hereby granted without fee, provided that the above copyright
6 // notice appear in all copies and that both that copyright notice and this
7 // permission notice appear in supporting documentation.
8 // The author makes no representations about the
9 // suitability of this software for any purpose. It is provided "as is"
10 // without express or implied warranty.
11 ////////////////////////////////////////////////////////////////////////////////
13 #ifndef ALLOCATOR_STRING_STORAGE_INC_
14 #define ALLOCATOR_STRING_STORAGE_INC_
16 // $Id: allocatorstringstorage.h 754 2006-10-17 19:59:11Z syntheticpp $
19 /* This is the template for a storage policy
20 ////////////////////////////////////////////////////////////////////////////////
21 template <typename E, class A = @>
26 typedef @ const_iterator;
27 typedef A allocator_type;
30 StoragePolicy(const StoragePolicy& s);
31 StoragePolicy(const A&);
32 StoragePolicy(const E* s, size_type len, const A&);
33 StoragePolicy(size_type len, E c, const A&);
37 const_iterator begin() const;
39 const_iterator end() const;
41 size_type size() const;
42 size_type max_size() const;
43 size_type capacity() const;
45 void reserve(size_type res_arg);
47 template <class ForwardIterator>
48 void append(ForwardIterator b, ForwardIterator e);
50 void resize(size_type newSize, E fill);
52 void swap(StoragePolicy& rhs);
54 const E* c_str() const;
55 const E* data() const;
57 A get_allocator() const;
59 ////////////////////////////////////////////////////////////////////////////////
68 #include "flex_string_details.h"
69 #include "simplestringstorage.h"
71 ////////////////////////////////////////////////////////////////////////////////
72 // class template AllocatorStringStorage
73 // Allocates with your allocator
74 // Takes advantage of the Empty Base Optimization if available
75 ////////////////////////////////////////////////////////////////////////////////
77 template <typename E, class A = std::allocator<E> >
78 class AllocatorStringStorage : public A
80 typedef typename A::size_type size_type;
81 typedef typename SimpleStringStorage<E, A>::Data Data;
83 void *Alloc(size_type sz, const void *p = 0)
85 return A::allocate(1 + (sz - 1) / sizeof(E),
86 static_cast<const char *>(p));
89 void *Realloc(void *p, size_type oldSz, size_type newSz)
91 void *r = Alloc(newSz);
92 flex_string_details::pod_copy(p, p + Min(oldSz, newSz), r);
97 void Free(void *p, size_type sz)
99 A::deallocate(static_cast<E *>(p), sz);
104 void Init(size_type size, size_type cap)
110 pData_ = const_cast<Data *>(
111 &SimpleStringStorage<E, A>::emptyString_);
115 pData_ = static_cast<Data *>(Alloc(
116 cap * sizeof(E) + sizeof(Data)));
117 pData_->pEnd_ = pData_->buffer_ + size;
118 pData_->pEndOfMem_ = pData_->buffer_ + cap;
123 typedef E value_type;
124 typedef A allocator_type;
125 typedef typename A::pointer iterator;
126 typedef typename A::const_pointer const_iterator;
128 AllocatorStringStorage()
133 AllocatorStringStorage(const AllocatorStringStorage &rhs)
134 : A(rhs.get_allocator())
136 const size_type sz = rhs.size();
138 if (sz) flex_string_details::pod_copy(rhs.begin(), rhs.end(), begin());
141 AllocatorStringStorage(const AllocatorStringStorage &s,
142 flex_string_details::Shallow)
143 : A(s.get_allocator())
148 AllocatorStringStorage(const A &a) : A(a)
150 pData_ = const_cast<Data *>(
151 &SimpleStringStorage<E, A>::emptyString_);
154 AllocatorStringStorage(const E *s, size_type len, const A &a)
158 flex_string_details::pod_copy(s, s + len, begin());
161 AllocatorStringStorage(size_type len, E c, const A &a)
165 flex_string_details::pod_fill(&*begin(), &*end(), c);
168 AllocatorStringStorage &operator=(const AllocatorStringStorage &rhs)
170 const size_type sz = rhs.size();
172 flex_string_details::pod_copy(&*rhs.begin(), &*rhs.end(), begin());
173 pData_->pEnd_ = &*begin() + rhs.size();
177 ~AllocatorStringStorage()
182 sizeof(Data) + capacity() * sizeof(E));
188 return pData_->buffer_;
191 const_iterator begin() const
193 return pData_->buffer_;
198 return pData_->pEnd_;
201 const_iterator end() const
203 return pData_->pEnd_;
206 size_type size() const
208 return size_type(end() - begin());
211 size_type max_size() const
213 return A::max_size();
216 size_type capacity() const
218 return size_type(pData_->pEndOfMem_ - pData_->buffer_);
221 void resize(size_type n, E c)
224 iterator newEnd = begin() + n;
225 iterator oldEnd = end();
228 // Copy the characters
229 flex_string_details::pod_fill(oldEnd, newEnd, c);
231 if (capacity()) pData_->pEnd_ = newEnd;
234 void reserve(size_type res_arg)
236 if (res_arg <= capacity())
238 // @@@ shrink to fit here
243 AllocatorStringStorage newStr(myAlloc);
244 newStr.Init(size(), res_arg);
246 flex_string_details::pod_copy(begin(), end(), newStr.begin());
251 template <class ForwardIterator>
252 void append(ForwardIterator b, ForwardIterator e)
255 sz = std::distance(b, e),
256 neededCapacity = size() + sz;
258 if (capacity() < neededCapacity)
260 static std::less_equal<const E *> le;
262 assert(!(le(begin(), &*b) && le(&*b, end())));
263 reserve(neededCapacity);
265 std::copy(b, e, end());
269 void swap(AllocatorStringStorage &rhs)
271 // @@@ The following line is commented due to a bug in MSVC
272 //std::swap(lhsAlloc, rhsAlloc);
273 std::swap(pData_, rhs.pData_);
276 const E *c_str() const
278 if (pData_ != &SimpleStringStorage<E, A>::emptyString_)
280 *pData_->pEnd_ = E();
285 const E *data() const
290 A get_allocator() const
296 #endif // ALLOCATOR_STRING_STORAGE_INC_