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