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 SIMPLE_STRING_STORAGE_INC_
14 #define SIMPLE_STRING_STORAGE_INC_
16 // $Id: simplestringstorage.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 ////////////////////////////////////////////////////////////////////////////////
70 ////////////////////////////////////////////////////////////////////////////////
71 // class template SimpleStringStorage
72 // Allocates memory with malloc
73 ////////////////////////////////////////////////////////////////////////////////
75 template <typename E, class A = std::allocator<E> >
76 class SimpleStringStorage
78 // The "public" below exists because MSVC can't do template typedefs
82 Data() : pEnd_(buffer_), pEndOfMem_(buffer_)
91 static const Data emptyString_;
93 typedef typename A::size_type size_type;
98 void Init(size_type size, size_type capacity)
100 assert(size <= capacity);
103 pData_ = const_cast<Data *>(&emptyString_);
107 // 11-17-2000: comment added:
108 // No need to allocate (capacity + 1) to
109 // accomodate the terminating 0, because Data already
110 // has one one character in there
111 pData_ = static_cast<Data *>(
112 malloc(sizeof(Data) + capacity * sizeof(E)));
113 if (!pData_) throw std::bad_alloc();
114 pData_->pEnd_ = pData_->buffer_ + size;
115 pData_->pEndOfMem_ = pData_->buffer_ + capacity;
120 // Warning - this doesn't initialize pData_. Used in reserve()
121 SimpleStringStorage()
125 typedef E value_type;
127 typedef const E *const_iterator;
128 typedef A allocator_type;
129 typedef typename A::reference reference;
132 SimpleStringStorage(const SimpleStringStorage &rhs)
134 const size_type sz = rhs.size();
136 if (sz) flex_string_details::pod_copy(rhs.begin(), rhs.end(), begin());
139 SimpleStringStorage(const SimpleStringStorage &s,
140 flex_string_details::Shallow)
145 SimpleStringStorage(const A &)
147 pData_ = const_cast<Data *>(&emptyString_);
150 SimpleStringStorage(const E *s, size_type len, const A &)
153 flex_string_details::pod_copy(s, s + len, begin());
156 SimpleStringStorage(size_type len, E c, const A &)
159 flex_string_details::pod_fill(begin(), end(), c);
162 SimpleStringStorage &operator=(const SimpleStringStorage &rhs)
164 const size_type sz = rhs.size();
166 flex_string_details::pod_copy(&*rhs.begin(), &*rhs.end(), begin());
167 pData_->pEnd_ = &*begin() + sz;
171 ~SimpleStringStorage()
173 assert(begin() <= end());
174 if (pData_ != &emptyString_) free(pData_);
179 return pData_->buffer_;
182 const_iterator begin() const
184 return pData_->buffer_;
189 return pData_->pEnd_;
192 const_iterator end() const
194 return pData_->pEnd_;
197 size_type size() const
199 return pData_->pEnd_ - pData_->buffer_;
202 size_type max_size() const
204 return size_t(-1) / sizeof(E) - sizeof(Data) - 1;
207 size_type capacity() const
209 return pData_->pEndOfMem_ - pData_->buffer_;
212 void reserve(size_type res_arg)
214 if (res_arg <= capacity())
216 // @@@ insert shrinkage here if you wish
220 if (pData_ == &emptyString_)
226 const size_type sz = size();
228 void *p = realloc(pData_,
229 sizeof(Data) + res_arg * sizeof(E));
230 if (!p) throw std::bad_alloc();
234 pData_ = static_cast<Data *>(p);
235 pData_->pEnd_ = pData_->buffer_ + sz;
237 pData_->pEndOfMem_ = pData_->buffer_ + res_arg;
241 template <class InputIterator>
242 void append(InputIterator b, InputIterator e)
245 sz = std::distance(b, e),
246 neededCapacity = size() + sz;
247 if (capacity() < neededCapacity)
249 static std::less_equal<const E *> le;
251 assert(!(le(begin(), &*b) && le(&*b, end()))); // no aliasing
252 reserve(neededCapacity);
254 std::copy(b, e, end());
258 void resize(size_type newSize, E fill)
260 const int delta = int(newSize - size());
261 if (delta == 0) return;
265 if (newSize > capacity())
270 flex_string_details::pod_fill(e, e + delta, fill);
272 pData_->pEnd_ = pData_->buffer_ + newSize;
275 void swap(SimpleStringStorage &rhs)
277 std::swap(pData_, rhs.pData_);
280 const E *c_str() const
282 if (pData_ != &emptyString_) *pData_->pEnd_ = E();
283 return pData_->buffer_;
286 const E *data() const
288 return pData_->buffer_;
291 A get_allocator() const
297 template <typename E, class A>
298 const typename SimpleStringStorage<E, A>::Data
299 SimpleStringStorage<E, A>::emptyString_;
301 // const_cast<E*>(SimpleStringStorage<E, A>::emptyString_.buffer_),
302 // const_cast<E*>(SimpleStringStorage<E, A>::emptyString_.buffer_),
308 #endif // SIMPLE_STRING_STORAGE_INC_