Counter Strike : Global Offensive Source Code
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.

139 lines
4.1 KiB

  1. //===-- StringPool.h - Interned string pool ---------------------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file declares an interned string pool, which helps reduce the cost of
  11. // strings by using the same storage for identical strings.
  12. //
  13. // To intern a string:
  14. //
  15. // StringPool Pool;
  16. // PooledStringPtr Str = Pool.intern("wakka wakka");
  17. //
  18. // To use the value of an interned string, use operator bool and operator*:
  19. //
  20. // if (Str)
  21. // cerr << "the string is" << *Str << "\n";
  22. //
  23. // Pooled strings are immutable, but you can change a PooledStringPtr to point
  24. // to another instance. So that interned strings can eventually be freed,
  25. // strings in the string pool are reference-counted (automatically).
  26. //
  27. //===----------------------------------------------------------------------===//
  28. #ifndef LLVM_SUPPORT_STRINGPOOL_H
  29. #define LLVM_SUPPORT_STRINGPOOL_H
  30. #include "llvm/ADT/StringMap.h"
  31. #include <cassert>
  32. #include <new>
  33. namespace llvm {
  34. class PooledStringPtr;
  35. /// StringPool - An interned string pool. Use the intern method to add a
  36. /// string. Strings are removed automatically as PooledStringPtrs are
  37. /// destroyed.
  38. class StringPool {
  39. /// PooledString - This is the value of an entry in the pool's interning
  40. /// table.
  41. struct PooledString {
  42. StringPool *Pool; ///< So the string can remove itself.
  43. unsigned Refcount; ///< Number of referencing PooledStringPtrs.
  44. public:
  45. PooledString() : Pool(0), Refcount(0) { }
  46. };
  47. friend class PooledStringPtr;
  48. typedef StringMap<PooledString> table_t;
  49. typedef StringMapEntry<PooledString> entry_t;
  50. table_t InternTable;
  51. public:
  52. StringPool();
  53. ~StringPool();
  54. /// intern - Adds a string to the pool and returns a reference-counted
  55. /// pointer to it. No additional memory is allocated if the string already
  56. /// exists in the pool.
  57. PooledStringPtr intern(StringRef Str);
  58. /// empty - Checks whether the pool is empty. Returns true if so.
  59. ///
  60. inline bool empty() const { return InternTable.empty(); }
  61. };
  62. /// PooledStringPtr - A pointer to an interned string. Use operator bool to
  63. /// test whether the pointer is valid, and operator * to get the string if so.
  64. /// This is a lightweight value class with storage requirements equivalent to
  65. /// a single pointer, but it does have reference-counting overhead when
  66. /// copied.
  67. class PooledStringPtr {
  68. typedef StringPool::entry_t entry_t;
  69. entry_t *S;
  70. public:
  71. PooledStringPtr() : S(0) {}
  72. explicit PooledStringPtr(entry_t *E) : S(E) {
  73. if (S) ++S->getValue().Refcount;
  74. }
  75. PooledStringPtr(const PooledStringPtr &That) : S(That.S) {
  76. if (S) ++S->getValue().Refcount;
  77. }
  78. PooledStringPtr &operator=(const PooledStringPtr &That) {
  79. if (S != That.S) {
  80. clear();
  81. S = That.S;
  82. if (S) ++S->getValue().Refcount;
  83. }
  84. return *this;
  85. }
  86. void clear() {
  87. if (!S)
  88. return;
  89. if (--S->getValue().Refcount == 0) {
  90. S->getValue().Pool->InternTable.remove(S);
  91. S->Destroy();
  92. }
  93. S = 0;
  94. }
  95. ~PooledStringPtr() { clear(); }
  96. inline const char *begin() const {
  97. assert(*this && "Attempt to dereference empty PooledStringPtr!");
  98. return S->getKeyData();
  99. }
  100. inline const char *end() const {
  101. assert(*this && "Attempt to dereference empty PooledStringPtr!");
  102. return S->getKeyData() + S->getKeyLength();
  103. }
  104. inline unsigned size() const {
  105. assert(*this && "Attempt to dereference empty PooledStringPtr!");
  106. return S->getKeyLength();
  107. }
  108. inline const char *operator*() const { return begin(); }
  109. inline operator bool() const { return S != 0; }
  110. inline bool operator==(const PooledStringPtr &That) { return S == That.S; }
  111. inline bool operator!=(const PooledStringPtr &That) { return S != That.S; }
  112. };
  113. } // End llvm namespace
  114. #endif