regex_raw_buffer.hpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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. #ifndef BOOST_REGEX_AS_MODULE
  25. #include <algorithm>
  26. #include <cstddef>
  27. #include <cstring>
  28. #endif
  29. namespace boost{
  30. namespace BOOST_REGEX_DETAIL_NS{
  31. struct empty_padding{};
  32. union padding
  33. {
  34. void* p;
  35. unsigned int i;
  36. };
  37. template <int N>
  38. struct padding3
  39. {
  40. enum{
  41. padding_size = 8,
  42. padding_mask = 7
  43. };
  44. };
  45. template<>
  46. struct padding3<2>
  47. {
  48. enum{
  49. padding_size = 2,
  50. padding_mask = 1
  51. };
  52. };
  53. template<>
  54. struct padding3<4>
  55. {
  56. enum{
  57. padding_size = 4,
  58. padding_mask = 3
  59. };
  60. };
  61. template<>
  62. struct padding3<8>
  63. {
  64. enum{
  65. padding_size = 8,
  66. padding_mask = 7
  67. };
  68. };
  69. template<>
  70. struct padding3<16>
  71. {
  72. enum{
  73. padding_size = 16,
  74. padding_mask = 15
  75. };
  76. };
  77. enum{
  78. padding_size = padding3<sizeof(padding)>::padding_size,
  79. padding_mask = padding3<sizeof(padding)>::padding_mask
  80. };
  81. //
  82. // class raw_storage
  83. // basically this is a simplified vector<unsigned char>
  84. // this is used by basic_regex for expression storage
  85. //
  86. class raw_storage
  87. {
  88. public:
  89. typedef std::size_t size_type;
  90. typedef unsigned char* pointer;
  91. private:
  92. pointer last, start, end;
  93. public:
  94. raw_storage();
  95. raw_storage(size_type n);
  96. ~raw_storage()
  97. {
  98. ::operator delete(start);
  99. }
  100. void resize(size_type n)
  101. {
  102. size_type newsize = start ? last - start : 1024;
  103. while (newsize < n)
  104. newsize *= 2;
  105. size_type datasize = end - start;
  106. // extend newsize to WORD/DWORD boundary:
  107. newsize = (newsize + padding_mask) & ~(padding_mask);
  108. // allocate and copy data:
  109. pointer ptr = static_cast<pointer>(::operator new(newsize));
  110. BOOST_REGEX_NOEH_ASSERT(ptr)
  111. if (start)
  112. std::memcpy(ptr, start, datasize);
  113. // get rid of old buffer:
  114. ::operator delete(start);
  115. // and set up pointers:
  116. start = ptr;
  117. end = ptr + datasize;
  118. last = ptr + newsize;
  119. }
  120. void* extend(size_type n)
  121. {
  122. if(size_type(last - end) < n)
  123. resize(n + (end - start));
  124. pointer result = end;
  125. end += n;
  126. return result;
  127. }
  128. void* insert(size_type pos, size_type n)
  129. {
  130. BOOST_REGEX_ASSERT(pos <= size_type(end - start));
  131. if (size_type(last - end) < n)
  132. resize(n + (end - start));
  133. void* result = start + pos;
  134. std::memmove(start + pos + n, start + pos, (end - start) - pos);
  135. end += n;
  136. return result;
  137. }
  138. size_type size()
  139. {
  140. return size_type(end - start);
  141. }
  142. size_type capacity()
  143. {
  144. return size_type(last - start);
  145. }
  146. void* data()const
  147. {
  148. return start;
  149. }
  150. size_type index(void* ptr)
  151. {
  152. return size_type(static_cast<pointer>(ptr) - static_cast<pointer>(data()));
  153. }
  154. void clear()
  155. {
  156. end = start;
  157. }
  158. void align()
  159. {
  160. // move end up to a boundary:
  161. end = start + (((end - start) + padding_mask) & ~padding_mask);
  162. }
  163. void swap(raw_storage& that)
  164. {
  165. std::swap(start, that.start);
  166. std::swap(end, that.end);
  167. std::swap(last, that.last);
  168. }
  169. };
  170. inline raw_storage::raw_storage()
  171. {
  172. last = start = end = 0;
  173. }
  174. inline raw_storage::raw_storage(size_type n)
  175. {
  176. start = end = static_cast<pointer>(::operator new(n));
  177. BOOST_REGEX_NOEH_ASSERT(start)
  178. last = start + n;
  179. }
  180. } // namespace BOOST_REGEX_DETAIL_NS
  181. } // namespace boost
  182. #endif