xref: /aosp_15_r20/external/angle/src/compiler/translator/ImmutableString.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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 "common/utilities.h"
17 #include "compiler/translator/Common.h"
18 
19 namespace sh
20 {
21 
22 class ImmutableString
23 {
24   public:
25     // The data pointer passed in must be one of:
26     //  1. nullptr (only valid with length 0).
27     //  2. a null-terminated static char array like a string literal.
28     //  3. a null-terminated pool allocated char array. This can't be c_str() of a local TString,
29     //     since when a TString goes out of scope it clears its first character.
ImmutableString(const char * data)30     explicit constexpr ImmutableString(const char *data)
31         : mData(data), mLength(angle::ConstStrLen(data))
32     {}
33 
ImmutableString(const char * data,size_t length)34     constexpr ImmutableString(const char *data, size_t length) : mData(data), mLength(length) {}
35 
ImmutableString(const std::string & str)36     ImmutableString(const std::string &str)
37         : mData(AllocatePoolCharArray(str.c_str(), str.size())), mLength(str.size())
38     {}
39 
40     constexpr ImmutableString(const ImmutableString &) = default;
41 
42     ImmutableString &operator=(const ImmutableString &) = default;
43 
data()44     constexpr const char *data() const { return mData ? mData : ""; }
length()45     constexpr size_t length() const { return mLength; }
46 
47     char operator[](size_t index) const { return data()[index]; }
48 
empty()49     constexpr bool empty() const { return mLength == 0; }
beginsWith(const char * prefix)50     constexpr bool beginsWith(const char *prefix) const
51     {
52         return beginsWith(ImmutableString(prefix));
53     }
beginsWith(const ImmutableString & prefix)54     constexpr bool beginsWith(const ImmutableString &prefix) const
55     {
56         return mLength >= prefix.length() && memcmp(data(), prefix.data(), prefix.length()) == 0;
57     }
contains(const char * substr)58     bool contains(const char *substr) const { return strstr(data(), substr) != nullptr; }
59 
60     constexpr bool operator==(const ImmutableString &b) const
61     {
62         if (mLength != b.mLength)
63         {
64             return false;
65         }
66         return memcmp(data(), b.data(), mLength) == 0;
67     }
68     constexpr bool operator!=(const ImmutableString &b) const { return !(*this == b); }
69     constexpr bool operator==(const char *b) const
70     {
71         if (b == nullptr)
72         {
73             return empty();
74         }
75         return strcmp(data(), b) == 0;
76     }
77     constexpr bool operator!=(const char *b) const { return !(*this == b); }
78     bool operator==(const std::string &b) const
79     {
80         return mLength == b.length() && memcmp(data(), b.c_str(), mLength) == 0;
81     }
82     bool operator!=(const std::string &b) const { return !(*this == b); }
83 
84     constexpr bool operator<(const ImmutableString &b) const
85     {
86         if (mLength < b.mLength)
87         {
88             return true;
89         }
90         if (mLength > b.mLength)
91         {
92             return false;
93         }
94         return (memcmp(data(), b.data(), mLength) < 0);
95     }
96 
97     template <size_t hashBytes>
98     struct FowlerNollVoHash
99     {
100         static const size_t kFnvOffsetBasis;
101         static const size_t kFnvPrime;
102 
operatorFowlerNollVoHash103         constexpr size_t operator()(const ImmutableString &a) const
104         {
105             const char *data = a.data();
106             size_t hash      = kFnvOffsetBasis;
107             while ((*data) != '\0')
108             {
109                 hash = hash ^ (*data);
110                 hash = hash * kFnvPrime;
111                 ++data;
112             }
113             return hash;
114         }
115     };
116 
117     // Perfect hash functions
118     uint32_t mangledNameHash() const;
119     uint32_t unmangledNameHash() const;
120 
121   private:
122     const char *mData;
123     size_t mLength;
124 };
125 
126 constexpr ImmutableString kEmptyImmutableString("");
127 
128 std::ostream &operator<<(std::ostream &os, const ImmutableString &str);
129 
130 }  // namespace sh
131 
132 #endif  // COMPILER_TRANSLATOR_IMMUTABLESTRING_H_
133