| // Copyright 2016 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef FBL_STRING_PIECE_H_ |
| #define FBL_STRING_PIECE_H_ |
| |
| #include <string.h> |
| #include <type_traits> |
| |
| #include <fbl/string_traits.h> |
| |
| namespace fbl { |
| |
| constexpr static size_t constexpr_strlen(const char* str) { |
| #if defined(_MSC_VER) |
| #error "__builtin_strlen not defined for MSVC++" |
| #else |
| return __builtin_strlen(str); |
| #endif |
| } |
| |
| // A string-like object that points to a sized piece of memory. |
| // |
| // fbl::StringPiece is designed to resemble std::string_view. |
| // |
| // |length()| does NOT include a trailing NUL and no guarantee is made that |
| // you can check |data()[length()]| to see if a NUL is there. |
| // |
| // Basically, these aren't C strings, don't think otherwise. |
| // The string piece does not own the data it points to. |
| class StringPiece { |
| public: |
| constexpr StringPiece() |
| : data_(nullptr), length_(0U) {} |
| |
| constexpr StringPiece(const char* data) |
| : data_(data), length_(data != nullptr ? constexpr_strlen(data) : 0U) {} |
| |
| constexpr StringPiece(const char* data, size_t length) |
| : data_(data), length_(length) {} |
| |
| constexpr StringPiece(const StringPiece& other) = default; |
| constexpr StringPiece(StringPiece&& other) = default; |
| |
| // Creates a string piece from a string-like object. |
| // |
| // Works with various string types including fbl::String, fbl::StringView, |
| // std::string, and std::string_view. |
| template <typename T, typename = typename std::enable_if<is_string_like<T>::value>::type> |
| constexpr StringPiece(const T& value) |
| : StringPiece(GetStringData(value), GetStringLength(value)) {} |
| |
| constexpr const char* data() const { return data_; } |
| |
| constexpr size_t length() const { return length_; } |
| constexpr size_t size() const { return length_; } |
| constexpr bool empty() const { return length_ == 0U; } |
| |
| constexpr const char* begin() const { return data_; } |
| constexpr const char* cbegin() const { return data_; } |
| constexpr const char* end() const { return data_ + length_; } |
| constexpr const char* cend() const { return data_ + length_; } |
| |
| constexpr const char& operator[](size_t pos) const { return data_[pos]; } |
| |
| int compare(const StringPiece& other) const; |
| |
| void clear() { |
| data_ = nullptr; |
| length_ = 0U; |
| } |
| |
| constexpr StringPiece& operator=(const StringPiece& other) = default; |
| constexpr StringPiece& operator=(StringPiece&& other) = default; |
| |
| template <typename T, typename = typename std::enable_if<is_string_like<T>::value>::type> |
| constexpr StringPiece& operator=(const T& value) { |
| set(GetStringData(value), GetStringLength(value)); |
| return *this; |
| } |
| |
| void set(const char* data) { |
| data_ = data; |
| length_ = data != nullptr ? constexpr_strlen(data) : 0U; |
| } |
| |
| void set(const char* data, size_t length) { |
| data_ = data; |
| length_ = length; |
| } |
| |
| private: |
| // Pointer to string data, not necessarily null terminated. |
| const char* data_; |
| |
| // Length of the string data. |
| size_t length_; |
| }; |
| |
| bool operator==(const StringPiece& lhs, const StringPiece& rhs); |
| |
| inline bool operator!=(const StringPiece& lhs, const StringPiece& rhs) { |
| return !(lhs == rhs); |
| } |
| |
| inline bool operator<(const StringPiece& lhs, const StringPiece& rhs) { |
| return lhs.compare(rhs) < 0; |
| } |
| |
| inline bool operator>(const StringPiece& lhs, const StringPiece& rhs) { |
| return lhs.compare(rhs) > 0; |
| } |
| |
| inline bool operator<=(const StringPiece& lhs, const StringPiece& rhs) { |
| return lhs.compare(rhs) <= 0; |
| } |
| |
| inline bool operator>=(const StringPiece& lhs, const StringPiece& rhs) { |
| return lhs.compare(rhs) >= 0; |
| } |
| |
| } // namespace fbl |
| |
| #endif // FBL_STRING_PIECE_H_ |