ImmutableString.h (4191B)
1 // 2 // Copyright 2018 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 // ImmutableString.h: Wrapper for static or pool allocated char arrays, that are guaranteed to be 7 // valid and unchanged for the duration of the compilation. 8 // 9 10 #ifndef COMPILER_TRANSLATOR_IMMUTABLESTRING_H_ 11 #define COMPILER_TRANSLATOR_IMMUTABLESTRING_H_ 12 13 #include <string> 14 15 #include "common/string_utils.h" 16 #include "compiler/translator/Common.h" 17 18 namespace sh 19 { 20 21 namespace 22 { 23 constexpr size_t constStrlen(const char *str) 24 { 25 if (str == nullptr) 26 { 27 return 0u; 28 } 29 size_t len = 0u; 30 while (*(str + len) != '\0') 31 { 32 ++len; 33 } 34 return len; 35 } 36 } // namespace 37 38 class ImmutableString 39 { 40 public: 41 // The data pointer passed in must be one of: 42 // 1. nullptr (only valid with length 0). 43 // 2. a null-terminated static char array like a string literal. 44 // 3. a null-terminated pool allocated char array. This can't be c_str() of a local TString, 45 // since when a TString goes out of scope it clears its first character. 46 explicit constexpr ImmutableString(const char *data) : mData(data), mLength(constStrlen(data)) 47 {} 48 49 constexpr ImmutableString(const char *data, size_t length) : mData(data), mLength(length) {} 50 51 ImmutableString(const std::string &str) 52 : mData(AllocatePoolCharArray(str.c_str(), str.size())), mLength(str.size()) 53 {} 54 55 constexpr ImmutableString(const ImmutableString &) = default; 56 57 ImmutableString &operator=(const ImmutableString &) = default; 58 59 constexpr const char *data() const { return mData ? mData : ""; } 60 constexpr size_t length() const { return mLength; } 61 62 char operator[](size_t index) const { return data()[index]; } 63 64 constexpr bool empty() const { return mLength == 0; } 65 bool beginsWith(const char *prefix) const { return angle::BeginsWith(data(), prefix); } 66 constexpr bool beginsWith(const ImmutableString &prefix) const 67 { 68 return mLength >= prefix.length() && memcmp(data(), prefix.data(), prefix.length()) == 0; 69 } 70 bool contains(const char *substr) const { return strstr(data(), substr) != nullptr; } 71 72 constexpr bool operator==(const ImmutableString &b) const 73 { 74 if (mLength != b.mLength) 75 { 76 return false; 77 } 78 return memcmp(data(), b.data(), mLength) == 0; 79 } 80 constexpr bool operator!=(const ImmutableString &b) const { return !(*this == b); } 81 constexpr bool operator==(const char *b) const 82 { 83 if (b == nullptr) 84 { 85 return empty(); 86 } 87 return strcmp(data(), b) == 0; 88 } 89 constexpr bool operator!=(const char *b) const { return !(*this == b); } 90 bool operator==(const std::string &b) const 91 { 92 return mLength == b.length() && memcmp(data(), b.c_str(), mLength) == 0; 93 } 94 bool operator!=(const std::string &b) const { return !(*this == b); } 95 96 constexpr bool operator<(const ImmutableString &b) const 97 { 98 if (mLength < b.mLength) 99 { 100 return true; 101 } 102 if (mLength > b.mLength) 103 { 104 return false; 105 } 106 return (memcmp(data(), b.data(), mLength) < 0); 107 } 108 109 template <size_t hashBytes> 110 struct FowlerNollVoHash 111 { 112 static const size_t kFnvOffsetBasis; 113 static const size_t kFnvPrime; 114 115 constexpr size_t operator()(const ImmutableString &a) const 116 { 117 const char *data = a.data(); 118 size_t hash = kFnvOffsetBasis; 119 while ((*data) != '\0') 120 { 121 hash = hash ^ (*data); 122 hash = hash * kFnvPrime; 123 ++data; 124 } 125 return hash; 126 } 127 }; 128 129 // Perfect hash functions 130 uint32_t mangledNameHash() const; 131 uint32_t unmangledNameHash() const; 132 133 private: 134 const char *mData; 135 size_t mLength; 136 }; 137 138 constexpr ImmutableString kEmptyImmutableString(""); 139 } // namespace sh 140 141 std::ostream &operator<<(std::ostream &os, const sh::ImmutableString &str); 142 143 #endif // COMPILER_TRANSLATOR_IMMUTABLESTRING_H_