.. _program_listing_file_include_opentelemetry_nostd_string_view.h: Program Listing for File string_view.h ====================================== |exhale_lsh| :ref:`Return to documentation for file ` (``include/opentelemetry/nostd/string_view.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp // Copyright 2020, OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once #ifdef HAVE_CPP_STDLIB # include "opentelemetry/std/string_view.h" #else # include # include # include # include # include # include # include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace nostd { using Traits = std::char_traits; class string_view { public: typedef std::size_t size_type; static constexpr size_type npos = static_cast(-1); string_view() noexcept : length_(0), data_(nullptr) {} string_view(const char *str) noexcept : length_(std::strlen(str)), data_(str) {} string_view(const std::basic_string &str) noexcept : length_(str.length()), data_(str.c_str()) {} string_view(const char *str, size_type len) noexcept : length_(len), data_(str) {} explicit operator std::string() const { return {data_, length_}; } const char *data() const noexcept { return data_; } bool empty() const noexcept { return length_ == 0; } size_type length() const noexcept { return length_; } size_type size() const noexcept { return length_; } const char *begin() const noexcept { return data(); } const char *end() const noexcept { return data() + length(); } const char &operator[](size_type i) { return *(data() + i); } string_view substr(size_type pos, size_type n = npos) const { if (pos > length_) { # if __EXCEPTIONS throw std::out_of_range{"opentelemetry::nostd::string_view"}; # else std::terminate(); # endif } n = (std::min)(n, length_ - pos); return string_view(data_ + pos, n); } int compare(string_view v) const noexcept { size_type len = (std::min)(size(), v.size()); int result = Traits::compare(data(), v.data(), len); if (result == 0) result = size() == v.size() ? 0 : (size() < v.size() ? -1 : 1); return result; }; int compare(size_type pos1, size_type count1, string_view v) const { return substr(pos1, count1).compare(v); }; int compare(size_type pos1, size_type count1, string_view v, size_type pos2, size_type count2) const { return substr(pos1, count1).compare(v.substr(pos2, count2)); }; int compare(const char *s) const { return compare(string_view(s)); }; int compare(size_type pos1, size_type count1, const char *s) const { return substr(pos1, count1).compare(string_view(s)); }; int compare(size_type pos1, size_type count1, const char *s, size_type count2) const { return substr(pos1, count1).compare(string_view(s, count2)); }; size_type find(char ch, size_type pos = 0) const noexcept { size_type res = npos; if (pos < length()) { auto found = Traits::find(data() + pos, length() - pos, ch); if (found) { res = found - data(); } } return res; } bool operator<(const string_view v) const noexcept { return compare(v) < 0; } bool operator>(const string_view v) const noexcept { return compare(v) > 0; } private: // Note: uses the same binary layout as libstdc++'s std::string_view // See // https://github.com/gcc-mirror/gcc/blob/e0c554e4da7310df83bb1dcc7b8e6c4c9c5a2a4f/libstdc%2B%2B-v3/include/std/string_view#L466-L467 size_type length_; const char *data_; }; inline bool operator==(string_view lhs, string_view rhs) noexcept { return lhs.length() == rhs.length() && # if _MSC_VER == 1900 // Avoid SCL error in Visual Studio 2015 (std::memcmp(lhs.data(), rhs.data(), lhs.length()) == 0); # else std::equal(lhs.data(), lhs.data() + lhs.length(), rhs.data()); # endif } inline bool operator==(string_view lhs, const std::string &rhs) noexcept { return lhs == string_view(rhs); } inline bool operator==(const std::string &lhs, string_view rhs) noexcept { return string_view(lhs) == rhs; } inline bool operator==(string_view lhs, const char *rhs) noexcept { return lhs == string_view(rhs); } inline bool operator==(const char *lhs, string_view rhs) noexcept { return string_view(lhs) == rhs; } inline bool operator!=(string_view lhs, string_view rhs) noexcept { return !(lhs == rhs); } inline bool operator!=(string_view lhs, const std::string &rhs) noexcept { return !(lhs == rhs); } inline bool operator!=(const std::string &lhs, string_view rhs) noexcept { return !(lhs == rhs); } inline bool operator!=(string_view lhs, const char *rhs) noexcept { return !(lhs == rhs); } inline bool operator!=(const char *lhs, string_view rhs) noexcept { return !(lhs == rhs); } inline std::ostream &operator<<(std::ostream &os, string_view s) { return os.write(s.data(), static_cast(s.length())); } } // namespace nostd OPENTELEMETRY_END_NAMESPACE namespace std { template <> struct hash { std::size_t operator()(const OPENTELEMETRY_NAMESPACE::nostd::string_view &k) const { // TODO: for C++17 that has native support for std::basic_string_view it would // be more performance-efficient to provide a zero-copy hash. auto s = std::string(k.data(), k.size()); return std::hash{}(s); } }; } // namespace std #endif