regex_raw_buffer.hpp 4.0 KB

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