blob: d59f586d18994f2703928f2e40561dc81a9689a1 [file] [log] [blame]
// 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_