Edit

kc3-lang/angle/src/compiler/translator/ImmutableString.h

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2018-06-20 11:46:43
    Hash : b779b12c
    Message : Add kEmptyImmutableString. We can use this instead of ImmutableString(""). Bug: angleproject:2665 Change-Id: I8b3d5d3075838b9f2caa1627071202e48a5fdc83 Reviewed-on: https://chromium-review.googlesource.com/1108085 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Luc Ferron <lucferron@chromium.org>

  • src/compiler/translator/ImmutableString.h
  • //
    // Copyright (c) 2018 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    // ImmutableString.h: Wrapper for static or pool allocated char arrays, that are guaranteed to be
    // valid and unchanged for the duration of the compilation.
    //
    
    #ifndef COMPILER_TRANSLATOR_IMMUTABLESTRING_H_
    #define COMPILER_TRANSLATOR_IMMUTABLESTRING_H_
    
    #include <string>
    
    #include "common/string_utils.h"
    #include "compiler/translator/Common.h"
    
    namespace sh
    {
    
    namespace
    {
    constexpr size_t constStrlen(const char *str)
    {
        if (str == nullptr)
        {
            return 0u;
        }
        size_t len = 0u;
        while (*(str + len) != '\0')
        {
            ++len;
        }
        return len;
    }
    }
    
    class ImmutableString
    {
      public:
        // The data pointer passed in must be one of:
        //  1. nullptr (only valid with length 0).
        //  2. a null-terminated static char array like a string literal.
        //  3. a null-terminated pool allocated char array. This can't be c_str() of a local TString,
        //     since when a TString goes out of scope it clears its first character.
        explicit constexpr ImmutableString(const char *data) : mData(data), mLength(constStrlen(data))
        {
        }
    
        constexpr ImmutableString(const char *data, size_t length) : mData(data), mLength(length) {}
    
        ImmutableString(const std::string &str)
            : mData(AllocatePoolCharArray(str.c_str(), str.size())), mLength(str.size())
        {
        }
    
        constexpr ImmutableString(const ImmutableString &) = default;
    
        ImmutableString &operator=(const ImmutableString &) = default;
    
        constexpr const char *data() const { return mData ? mData : ""; }
        constexpr size_t length() const { return mLength; }
    
        char operator[](size_t index) const { return data()[index]; }
    
        constexpr bool empty() const { return mLength == 0; }
        bool beginsWith(const char *prefix) const { return angle::BeginsWith(data(), prefix); }
        constexpr bool beginsWith(const ImmutableString &prefix) const
        {
            return mLength >= prefix.length() && memcmp(data(), prefix.data(), prefix.length()) == 0;
        }
        bool contains(const char *substr) const { return strstr(data(), substr) != nullptr; }
    
        constexpr bool operator==(const ImmutableString &b) const
        {
            if (mLength != b.mLength)
            {
                return false;
            }
            return memcmp(data(), b.data(), mLength) == 0;
        }
        constexpr bool operator!=(const ImmutableString &b) const { return !(*this == b); }
        constexpr bool operator==(const char *b) const
        {
            if (b == nullptr)
            {
                return empty();
            }
            return strcmp(data(), b) == 0;
        }
        constexpr bool operator!=(const char *b) const { return !(*this == b); }
        bool operator==(const std::string &b) const
        {
            return mLength == b.length() && memcmp(data(), b.c_str(), mLength) == 0;
        }
        bool operator!=(const std::string &b) const { return !(*this == b); }
    
        constexpr bool operator<(const ImmutableString &b) const
        {
            if (mLength < b.mLength)
            {
                return true;
            }
            if (mLength > b.mLength)
            {
                return false;
            }
            return (memcmp(data(), b.data(), mLength) < 0);
        }
    
        template <size_t hashBytes>
        struct FowlerNollVoHash
        {
            static const size_t kFnvOffsetBasis;
            static const size_t kFnvPrime;
    
            constexpr size_t operator()(const ImmutableString &a) const
            {
                const char *data = a.data();
                size_t hash      = kFnvOffsetBasis;
                while ((*data) != '\0')
                {
                    hash = hash ^ (*data);
                    hash = hash * kFnvPrime;
                    ++data;
                }
                return hash;
            }
        };
    
        // This hash encodes the opening parentheses location (if any), name length and whether the name
        // contains { or [ characters in addition to a 19-bit hash. This way the hash is more useful for
        // lookups. The string passed in should be at most 63 characters.
        uint32_t mangledNameHash() const;
    
      private:
        const char *mData;
        size_t mLength;
    };
    
    constexpr ImmutableString kEmptyImmutableString("");
    }  // namespace sh
    
    std::ostream &operator<<(std::ostream &os, const sh::ImmutableString &str);
    
    #endif  // COMPILER_TRANSLATOR_IMMUTABLESTRING_H_