StringView.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #pragma once
  2. #include <string>
  3. namespace il2cpp
  4. {
  5. namespace utils
  6. {
  7. template<typename CharType>
  8. class StringView
  9. {
  10. private:
  11. const CharType* m_String;
  12. size_t m_Length;
  13. // Intended to only be used by Empty()
  14. inline StringView() :
  15. m_String(NULL),
  16. m_Length(0)
  17. {
  18. }
  19. public:
  20. template<size_t Length>
  21. inline StringView(const CharType(&str)[Length]) :
  22. m_String(str), m_Length(Length - 1)
  23. {
  24. }
  25. inline StringView(const CharType* str, size_t length) :
  26. m_String(str), m_Length(length)
  27. {
  28. IL2CPP_ASSERT(str != NULL);
  29. }
  30. inline StringView(const StringView<CharType>& str, size_t startIndex, size_t length) :
  31. m_String(str.Str() + startIndex),
  32. m_Length(length)
  33. {
  34. IL2CPP_ASSERT(startIndex + length <= str.Length());
  35. }
  36. template<typename CharTraits, typename StringAlloc>
  37. inline StringView(const std::basic_string<CharType, CharTraits, StringAlloc>& str) :
  38. m_String(str.c_str()), m_Length(str.length())
  39. {
  40. }
  41. // This will prevent accidentally assigning temporary values (like function return values)
  42. // to a string view. While this protection will only be enabled on C++11 compiles, even those
  43. // are enough to catch the bug in our runtime
  44. #if IL2CPP_HAS_DELETED_FUNCTIONS
  45. template<typename CharTraits, typename StringAlloc>
  46. StringView(std::basic_string<CharType, CharTraits, StringAlloc>&&) = delete;
  47. #endif
  48. inline const CharType* Str() const
  49. {
  50. return m_String;
  51. }
  52. inline size_t Length() const
  53. {
  54. return m_Length;
  55. }
  56. inline CharType operator[](size_t index) const
  57. {
  58. return m_String[index];
  59. }
  60. inline bool IsNullTerminated() const
  61. {
  62. return m_String[m_Length] == 0;
  63. }
  64. inline bool IsEmpty() const
  65. {
  66. return Length() == 0;
  67. }
  68. static inline StringView<CharType> Empty()
  69. {
  70. return StringView<CharType>();
  71. }
  72. inline size_t RFind(CharType c) const
  73. {
  74. for (const CharType* ptr = m_String + m_Length - 1; ptr >= m_String; ptr--)
  75. {
  76. if (*ptr == c)
  77. return ptr - m_String;
  78. }
  79. return NPos();
  80. }
  81. inline static size_t NPos()
  82. {
  83. return static_cast<size_t>(-1);
  84. }
  85. };
  86. #define StringViewAsNullTerminatedStringOf(CharType, stringView, variableName) \
  87. const CharType* variableName; \
  88. do \
  89. { \
  90. if (stringView.IsNullTerminated()) \
  91. { \
  92. variableName = stringView.Str(); \
  93. } \
  94. else \
  95. { \
  96. CharType* buffer = static_cast<CharType*>(alloca((stringView.Length() + 1) * sizeof(CharType))); \
  97. memcpy(buffer, stringView.Str(), stringView.Length() * sizeof(CharType)); \
  98. buffer[stringView.Length()] = 0; \
  99. variableName = buffer; \
  100. } \
  101. } \
  102. while (false)
  103. }
  104. }