allocatorstringstorage.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. ////////////////////////////////////////////////////////////////////////////////
  2. // flex_string
  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. ////////////////////////////////////////////////////////////////////////////////
  12. #ifndef DAHUA_ALLOCATOR_STRING_STORAGE_INC_
  13. #define DAHUA_ALLOCATOR_STRING_STORAGE_INC_
  14. // revision 1008
  15. /* This is the template for a storage policy
  16. ////////////////////////////////////////////////////////////////////////////////
  17. template <typename E, class A = @>
  18. class StoragePolicy
  19. {
  20. typedef E value_type;
  21. typedef @ iterator;
  22. typedef @ const_iterator;
  23. typedef A allocator_type;
  24. typedef @ size_type;
  25. StoragePolicy(const StoragePolicy& s);
  26. StoragePolicy(const A&);
  27. StoragePolicy(const E* s, size_type len, const A&);
  28. StoragePolicy(size_type len, E c, const A&);
  29. ~StoragePolicy();
  30. iterator begin();
  31. const_iterator begin() const;
  32. iterator end();
  33. const_iterator end() const;
  34. size_type size() const;
  35. size_type max_size() const;
  36. size_type capacity() const;
  37. void reserve(size_type res_arg);
  38. template <class ForwardIterator>
  39. void append(ForwardIterator b, ForwardIterator e);
  40. void resize(size_type newSize, E fill);
  41. void swap(StoragePolicy& rhs);
  42. const E* c_str() const;
  43. const E* data() const;
  44. A get_allocator() const;
  45. };
  46. ////////////////////////////////////////////////////////////////////////////////
  47. */
  48. #include <memory>
  49. #include <algorithm>
  50. #include <functional>
  51. #include <cassert>
  52. #include <limits>
  53. #include <stdexcept>
  54. #include "flex_string_details.h"
  55. #include "simplestringstorage.h"
  56. namespace Dahua {
  57. namespace Infra {
  58. ////////////////////////////////////////////////////////////////////////////////
  59. // class template AllocatorStringStorage
  60. // Allocates with your allocator
  61. // Takes advantage of the Empty Base Optimization if available
  62. ////////////////////////////////////////////////////////////////////////////////
  63. template <typename E, class A = std::allocator<E> >
  64. class AllocatorStringStorage : public A
  65. {
  66. typedef typename A::size_type size_type;
  67. typedef typename SimpleStringStorage<E, A>::Data Data;
  68. void* Alloc(size_type sz, const void* p = 0)
  69. {
  70. return A::allocate(1 + (sz - 1) / sizeof(E),
  71. static_cast<const char*>(p));
  72. }
  73. void* Realloc(void* p, size_type oldSz, size_type newSz)
  74. {
  75. void* r = Alloc(newSz);
  76. flex_string_details::pod_copy(p, p + Min(oldSz, newSz), r);
  77. Free(p, oldSz);
  78. return r;
  79. }
  80. void Free(void* p, size_type sz)
  81. {
  82. A::deallocate(static_cast<E*>(p), sz);
  83. }
  84. Data* pData_;
  85. void Init(size_type size, size_type cap)
  86. {
  87. assert(size <= cap);
  88. if (cap == 0)
  89. {
  90. pData_ = const_cast<Data*>(
  91. &SimpleStringStorage<E, A>::emptyString_);
  92. }
  93. else
  94. {
  95. pData_ = static_cast<Data*>(Alloc(
  96. cap * sizeof(E) + sizeof(Data)));
  97. pData_->pEnd_ = pData_->buffer_ + size;
  98. pData_->pEndOfMem_ = pData_->buffer_ + cap;
  99. }
  100. }
  101. public:
  102. typedef E value_type;
  103. typedef A allocator_type;
  104. typedef typename A::pointer iterator;
  105. typedef typename A::const_pointer const_iterator;
  106. AllocatorStringStorage()
  107. : A(), pData_(0)
  108. {
  109. }
  110. AllocatorStringStorage(const AllocatorStringStorage& rhs)
  111. : A(rhs.get_allocator())
  112. {
  113. const size_type sz = rhs.size();
  114. Init(sz, sz);
  115. if (sz) flex_string_details::pod_copy(rhs.begin(), rhs.end(), begin());
  116. }
  117. AllocatorStringStorage(const AllocatorStringStorage& s,
  118. flex_string_details::Shallow)
  119. : A(s.get_allocator())
  120. {
  121. pData_ = s.pData_;
  122. }
  123. AllocatorStringStorage(const A& a) : A(a)
  124. {
  125. pData_ = const_cast<Data*>(
  126. &SimpleStringStorage<E, A>::emptyString_);
  127. }
  128. AllocatorStringStorage(const E* s, size_type len, const A& a)
  129. : A(a)
  130. {
  131. Init(len, len);
  132. flex_string_details::pod_copy(s, s + len, begin());
  133. }
  134. AllocatorStringStorage(size_type len, E c, const A& a)
  135. : A(a)
  136. {
  137. Init(len, len);
  138. flex_string_details::pod_fill(&*begin(), &*end(), c);
  139. }
  140. AllocatorStringStorage& operator=(const AllocatorStringStorage& rhs)
  141. {
  142. const size_type sz = rhs.size();
  143. reserve(sz);
  144. flex_string_details::pod_copy(&*rhs.begin(), &*rhs.end(), begin());
  145. pData_->pEnd_ = &*begin() + rhs.size();
  146. return *this;
  147. }
  148. ~AllocatorStringStorage()
  149. {
  150. if (capacity())
  151. {
  152. Free(pData_,
  153. sizeof(Data) + capacity() * sizeof(E));
  154. }
  155. }
  156. iterator begin()
  157. { return pData_->buffer_; }
  158. const_iterator begin() const
  159. { return pData_->buffer_; }
  160. iterator end()
  161. { return pData_->pEnd_; }
  162. const_iterator end() const
  163. { return pData_->pEnd_; }
  164. size_type size() const
  165. { return size_type(end() - begin()); }
  166. size_type max_size() const
  167. { return A::max_size(); }
  168. size_type capacity() const
  169. { return size_type(pData_->pEndOfMem_ - pData_->buffer_); }
  170. void resize(size_type n, E c)
  171. {
  172. reserve(n);
  173. iterator newEnd = begin() + n;
  174. iterator oldEnd = end();
  175. if (newEnd > oldEnd)
  176. {
  177. // Copy the characters
  178. flex_string_details::pod_fill(oldEnd, newEnd, c);
  179. }
  180. if (capacity()) pData_->pEnd_ = newEnd;
  181. }
  182. void reserve(size_type res_arg)
  183. {
  184. if (res_arg <= capacity())
  185. {
  186. // @@@ shrink to fit here
  187. return;
  188. }
  189. A& myAlloc = *this;
  190. AllocatorStringStorage newStr(myAlloc);
  191. newStr.Init(size(), res_arg);
  192. flex_string_details::pod_copy(begin(), end(), newStr.begin());
  193. swap(newStr);
  194. }
  195. template <class ForwardIterator>
  196. void append(ForwardIterator b, ForwardIterator e)
  197. {
  198. const size_type
  199. sz = std::distance(b, e),
  200. neededCapacity = size() + sz;
  201. if (capacity() < neededCapacity)
  202. {
  203. static std::less_equal<const E*> le;
  204. (void) le;
  205. assert(!(le(begin(), &*b) && le(&*b, end())));
  206. reserve(neededCapacity);
  207. }
  208. std::copy(b, e, end());
  209. pData_->pEnd_ += sz;
  210. }
  211. void swap(AllocatorStringStorage& rhs)
  212. {
  213. // @@@ The following line is commented due to a bug in MSVC
  214. //std::swap(lhsAlloc, rhsAlloc);
  215. std::swap(pData_, rhs.pData_);
  216. }
  217. const E* c_str() const
  218. {
  219. if (pData_ != &SimpleStringStorage<E, A>::emptyString_)
  220. {
  221. *pData_->pEnd_ = E();
  222. }
  223. return &*begin();
  224. }
  225. const E* data() const
  226. { return &*begin(); }
  227. A get_allocator() const
  228. { return *this; }
  229. };
  230. } // namespace Infra
  231. } // namespace Dahua
  232. #endif // DAHUA_ALLOCATOR_STRING_STORAGE_INC_