// Copyright 2013 The Flutter 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 FLUTTER_FML_STRING_VIEW_H_ #define FLUTTER_FML_STRING_VIEW_H_ #include #include #include #include "flutter/fml/logging.h" // MSVC 2015 doesn't support "extended constexpr" from C++14. #if __cplusplus >= 201402L // C++14 relaxed the limitation of the content of a constexpr function. #define CONSTEXPR_IN_CPP14 constexpr #else #define CONSTEXPR_IN_CPP14 #endif namespace fml { // A string-like object that points to a sized piece of memory. class StringView { public: // Types. using const_iterator = const char*; using iterator = const_iterator; using const_reverse_iterator = std::reverse_iterator; using reverse_iterator = const_reverse_iterator; constexpr static size_t npos = static_cast(-1); // Constructors. constexpr StringView() : data_(""), size_(0u) {} constexpr StringView(const StringView& string_view) : data_(string_view.data_), size_(string_view.size_) {} constexpr StringView(const char* str, size_t len) : data_(str), size_(len) {} explicit constexpr StringView(const char* str) : data_(str), size_(constexpr_strlen(str)) {} // Implicit constructor for constant C strings. template constexpr StringView(const char (&str)[N]) : data_(str), size_(constexpr_strlen(str)) {} // Implicit constructor. StringView(const std::string& str) : data_(str.data()), size_(str.size()) {} // Copy operators. StringView& operator=(const StringView& other) { data_ = other.data_; size_ = other.size_; return *this; } // Capacity methods. constexpr size_t size() const { return size_; } constexpr bool empty() const { return size_ == 0u; } // Element access methods. constexpr char operator[](size_t pos) const { return data_[pos]; }; constexpr char at(size_t pos) const { return data_[pos]; }; constexpr char front() const { return data_[0]; }; constexpr char back() const { return data_[size_ - 1]; }; constexpr const char* data() const { return data_; } // Iterators. constexpr const_iterator begin() const { return cbegin(); } constexpr const_iterator end() const { return cend(); } constexpr const_iterator cbegin() const { return data_; } constexpr const_iterator cend() const { return data_ + size_; } const_reverse_iterator rbegin() const { return const_reverse_iterator(cend()); } const_reverse_iterator rend() const { return const_reverse_iterator(cbegin()); } const_reverse_iterator crbegin() const { return const_reverse_iterator(cend()); } const_reverse_iterator crend() const { return const_reverse_iterator(cbegin()); } // Modifier methods. CONSTEXPR_IN_CPP14 void clear() { data_ = ""; size_ = 0; } CONSTEXPR_IN_CPP14 void remove_prefix(size_t n) { FML_DCHECK(n <= size_); data_ += n; size_ -= n; } CONSTEXPR_IN_CPP14 void remove_suffix(size_t n) { FML_DCHECK(n <= size_); size_ -= n; } CONSTEXPR_IN_CPP14 void swap(StringView& other) { const char* data = data_; data_ = other.data_; other.data_ = data; size_t size = size_; size_ = other.size_; other.size_ = size; } // String conversion. std::string ToString() const { return std::string(data_, size_); } // String operations. constexpr StringView substr(size_t pos = 0, size_t n = npos) const { return StringView(data_ + pos, min(n, size_ - pos)); } // Returns negative, 0, or positive when |this| is lexigraphically // less than, equal to, or greater than |other|, a la // std::basic_string_view::compare. int compare(StringView other); size_t find(StringView s, size_t pos = 0) const; size_t find(char c, size_t pos = 0) const; size_t rfind(StringView s, size_t pos = npos) const; size_t rfind(char c, size_t pos = npos) const; size_t find_first_of(StringView s, size_t pos = 0) const; size_t find_last_of(StringView s, size_t pos = npos) const; size_t find_first_not_of(StringView s, size_t pos = 0) const; size_t find_last_not_of(StringView s, size_t pos = npos) const; private: constexpr static size_t min(size_t v1, size_t v2) { return v1 < v2 ? v1 : v2; } constexpr static int constexpr_strlen(const char* str) { #if defined(_MSC_VER) return *str ? 1 + constexpr_strlen(str + 1) : 0; #else return __builtin_strlen(str); #endif } const char* data_; size_t size_; }; // Comparison. bool operator==(StringView lhs, StringView rhs); bool operator!=(StringView lhs, StringView rhs); bool operator<(StringView lhs, StringView rhs); bool operator>(StringView lhs, StringView rhs); bool operator<=(StringView lhs, StringView rhs); bool operator>=(StringView lhs, StringView rhs); // IO. std::ostream& operator<<(std::ostream& o, StringView string_view); } // namespace fml #endif // FLUTTER_FML_STRING_VIEW_H_