Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

185 lines
4.2 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. /*
  9. *
  10. * Copyright (c) 1998-9
  11. * Dr John Maddock
  12. *
  13. * Permission to use, copy, modify, distribute and sell this software
  14. * and its documentation for any purpose is hereby granted without fee,
  15. * provided that the above copyright notice appear in all copies and
  16. * that both that copyright notice and this permission notice appear
  17. * in supporting documentation. Dr John Maddock makes no representations
  18. * about the suitability of this software for any purpose.
  19. * It is provided "as is" without express or implied warranty.
  20. *
  21. */
  22. /*
  23. * FILE re_raw.h
  24. * VERSION 2.12
  25. */
  26. #ifndef RE_RAW_H
  27. #define RE_RAW_H
  28. #ifndef JM_CFG_H
  29. #include <jm/jm_cfg.h>
  30. #endif
  31. JM_NAMESPACE(__JM)
  32. union padding
  33. {
  34. void* p;
  35. unsigned int i;
  36. };
  37. //
  38. // class raw_storage
  39. // basically this is a simplified vector<unsigned char>
  40. // this is used by reg_expression for expression storage
  41. //
  42. template <class Allocator>
  43. class raw_storage
  44. {
  45. public:
  46. typedef Allocator alloc_type;
  47. typedef typename REBIND_TYPE(unsigned char, alloc_type)::size_type size_type;
  48. typedef JM_MAYBE_TYPENAME REBIND_TYPE(unsigned char, alloc_type) alloc_inst_type;
  49. typedef typename REBIND_TYPE(unsigned char, alloc_type)::pointer pointer;
  50. private:
  51. //
  52. // empty member optimisation:
  53. struct alloc_data : public alloc_inst_type
  54. {
  55. pointer last;
  56. alloc_data(const Allocator& a) : alloc_inst_type(a){}
  57. } alloc_inst;
  58. pointer start, end;
  59. public:
  60. raw_storage(const Allocator& a = Allocator());
  61. raw_storage(size_type n, const Allocator& a = Allocator());
  62. ~raw_storage()
  63. {
  64. alloc_inst.deallocate(start, (alloc_inst.last - start));
  65. }
  66. void RE_CALL resize(size_type n);
  67. void* RE_CALL extend(size_type n)
  68. {
  69. if(size_type(alloc_inst.last - end) < n)
  70. resize(n + (end - start));
  71. register void* result = end;
  72. end += n;
  73. return result;
  74. }
  75. void* RE_CALL insert(size_type pos, size_type n);
  76. size_type RE_CALL size()
  77. {
  78. return end - start;
  79. }
  80. size_type RE_CALL capacity()
  81. {
  82. return alloc_inst.last - start;
  83. }
  84. void* RE_CALL data()const
  85. {
  86. return start;
  87. }
  88. size_type RE_CALL index(void* ptr)
  89. {
  90. return (unsigned char*)ptr - start;
  91. }
  92. void RE_CALL clear()
  93. {
  94. end = start;
  95. }
  96. void RE_CALL align()
  97. {
  98. // move end up to a boundary:
  99. end = (unsigned char*)((long)(end + sizeof(padding) - 1) & ~((long)sizeof(padding) - 1));
  100. }
  101. Allocator RE_CALL allocator()const;
  102. };
  103. template <class Allocator>
  104. CONSTRUCTOR_INLINE raw_storage<Allocator>::raw_storage(const Allocator& a)
  105. : alloc_inst(a)
  106. {
  107. start = end = alloc_inst.allocate(1024);
  108. alloc_inst.last = start + 1024;
  109. }
  110. template <class Allocator>
  111. CONSTRUCTOR_INLINE raw_storage<Allocator>::raw_storage(size_type n, const Allocator& a)
  112. : alloc_inst(a)
  113. {
  114. start = end = alloc_inst.allocate(n);
  115. alloc_inst.last = start + n;
  116. }
  117. template <class Allocator>
  118. Allocator RE_CALL raw_storage<Allocator>::allocator()const
  119. {
  120. return alloc_inst;
  121. }
  122. template <class Allocator>
  123. void RE_CALL raw_storage<Allocator>::resize(size_type n)
  124. {
  125. register size_type newsize = (alloc_inst.last - start) * 2;
  126. register size_type datasize = end - start;
  127. if(newsize < n)
  128. newsize = n;
  129. // extend newsize to WORD/DWORD boundary:
  130. newsize = (newsize + (sizeof(padding) - 1)) & ~(sizeof(padding) - 1);
  131. // allocate and copy data:
  132. register unsigned char* ptr = alloc_inst.allocate(newsize);
  133. memcpy(ptr, start, datasize);
  134. // get rid of old buffer:
  135. alloc_inst.deallocate(start, (alloc_inst.last - start));
  136. // and set up pointers:
  137. start = ptr;
  138. end = ptr + datasize;
  139. alloc_inst.last = ptr + newsize;
  140. }
  141. template <class Allocator>
  142. void* RE_CALL raw_storage<Allocator>::insert(size_type pos, size_type n)
  143. {
  144. jm_assert(pos <= size_type(end - start));
  145. if(size_type(alloc_inst.last - end) < n)
  146. resize(n + (end - start));
  147. register void* result = start + pos;
  148. memmove(start + pos + n, start + pos, (end - start) - pos);
  149. end += n;
  150. return result;
  151. }
  152. JM_END_NAMESPACE
  153. #endif