regex_raw_buffer.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /*
  2. *
  3. * Copyright (c) 1998-2002
  4. * John Maddock
  5. *
  6. * Use, modification and distribution are subject to the
  7. * Boost Software License, Version 1.0. (See accompanying file
  8. * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. *
  10. */
  11. /*
  12. * LOCATION: see http://www.boost.org for most recent version.
  13. * FILE regex_raw_buffer.hpp
  14. * VERSION see <boost/version.hpp>
  15. * DESCRIPTION: Raw character buffer for regex code.
  16. * Note this is an internal header file included
  17. * by regex.hpp, do not include on its own.
  18. */
  19. #ifndef BOOST_REGEX_RAW_BUFFER_HPP
  20. #define BOOST_REGEX_RAW_BUFFER_HPP
  21. #ifndef BOOST_REGEX_CONFIG_HPP
  22. #include <boost/regex/config.hpp>
  23. #endif
  24. #include <algorithm>
  25. #include <cstddef>
  26. namespace boost{
  27. namespace BOOST_REGEX_DETAIL_NS{
  28. #ifdef BOOST_MSVC
  29. #pragma warning(push)
  30. #pragma warning(disable: 4103)
  31. #endif
  32. #ifdef BOOST_HAS_ABI_HEADERS
  33. # include BOOST_ABI_PREFIX
  34. #endif
  35. #ifdef BOOST_MSVC
  36. #pragma warning(pop)
  37. #endif
  38. struct empty_padding{};
  39. union padding
  40. {
  41. void* p;
  42. unsigned int i;
  43. };
  44. template <int N>
  45. struct padding3
  46. {
  47. enum{
  48. padding_size = 8,
  49. padding_mask = 7
  50. };
  51. };
  52. template<>
  53. struct padding3<2>
  54. {
  55. enum{
  56. padding_size = 2,
  57. padding_mask = 1
  58. };
  59. };
  60. template<>
  61. struct padding3<4>
  62. {
  63. enum{
  64. padding_size = 4,
  65. padding_mask = 3
  66. };
  67. };
  68. template<>
  69. struct padding3<8>
  70. {
  71. enum{
  72. padding_size = 8,
  73. padding_mask = 7
  74. };
  75. };
  76. template<>
  77. struct padding3<16>
  78. {
  79. enum{
  80. padding_size = 16,
  81. padding_mask = 15
  82. };
  83. };
  84. enum{
  85. padding_size = padding3<sizeof(padding)>::padding_size,
  86. padding_mask = padding3<sizeof(padding)>::padding_mask
  87. };
  88. //
  89. // class raw_storage
  90. // basically this is a simplified vector<unsigned char>
  91. // this is used by basic_regex for expression storage
  92. //
  93. class raw_storage
  94. {
  95. public:
  96. typedef std::size_t size_type;
  97. typedef unsigned char* pointer;
  98. private:
  99. pointer last, start, end;
  100. public:
  101. raw_storage();
  102. raw_storage(size_type n);
  103. ~raw_storage()
  104. {
  105. ::operator delete(start);
  106. }
  107. void BOOST_REGEX_CALL resize(size_type n)
  108. {
  109. size_type newsize = start ? last - start : 1024;
  110. while (newsize < n)
  111. newsize *= 2;
  112. size_type datasize = end - start;
  113. // extend newsize to WORD/DWORD boundary:
  114. newsize = (newsize + padding_mask) & ~(padding_mask);
  115. // allocate and copy data:
  116. pointer ptr = static_cast<pointer>(::operator new(newsize));
  117. BOOST_REGEX_NOEH_ASSERT(ptr)
  118. if (start)
  119. std::memcpy(ptr, start, datasize);
  120. // get rid of old buffer:
  121. ::operator delete(start);
  122. // and set up pointers:
  123. start = ptr;
  124. end = ptr + datasize;
  125. last = ptr + newsize;
  126. }
  127. void* BOOST_REGEX_CALL extend(size_type n)
  128. {
  129. if(size_type(last - end) < n)
  130. resize(n + (end - start));
  131. pointer result = end;
  132. end += n;
  133. return result;
  134. }
  135. void* BOOST_REGEX_CALL insert(size_type pos, size_type n)
  136. {
  137. BOOST_REGEX_ASSERT(pos <= size_type(end - start));
  138. if (size_type(last - end) < n)
  139. resize(n + (end - start));
  140. void* result = start + pos;
  141. std::memmove(start + pos + n, start + pos, (end - start) - pos);
  142. end += n;
  143. return result;
  144. }
  145. size_type BOOST_REGEX_CALL size()
  146. {
  147. return size_type(end - start);
  148. }
  149. size_type BOOST_REGEX_CALL capacity()
  150. {
  151. return size_type(last - start);
  152. }
  153. void* BOOST_REGEX_CALL data()const
  154. {
  155. return start;
  156. }
  157. size_type BOOST_REGEX_CALL index(void* ptr)
  158. {
  159. return size_type(static_cast<pointer>(ptr) - static_cast<pointer>(data()));
  160. }
  161. void BOOST_REGEX_CALL clear()
  162. {
  163. end = start;
  164. }
  165. void BOOST_REGEX_CALL align()
  166. {
  167. // move end up to a boundary:
  168. end = start + (((end - start) + padding_mask) & ~padding_mask);
  169. }
  170. void swap(raw_storage& that)
  171. {
  172. std::swap(start, that.start);
  173. std::swap(end, that.end);
  174. std::swap(last, that.last);
  175. }
  176. };
  177. inline raw_storage::raw_storage()
  178. {
  179. last = start = end = 0;
  180. }
  181. inline raw_storage::raw_storage(size_type n)
  182. {
  183. start = end = static_cast<pointer>(::operator new(n));
  184. BOOST_REGEX_NOEH_ASSERT(start)
  185. last = start + n;
  186. }
  187. #ifdef BOOST_MSVC
  188. #pragma warning(push)
  189. #pragma warning(disable: 4103)
  190. #endif
  191. #ifdef BOOST_HAS_ABI_HEADERS
  192. # include BOOST_ABI_SUFFIX
  193. #endif
  194. #ifdef BOOST_MSVC
  195. #pragma warning(pop)
  196. #endif
  197. } // namespace BOOST_REGEX_DETAIL_NS
  198. } // namespace boost
  199. #endif