1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
#ifndef OPENTRACING_STRING_VIEW_H
#define OPENTRACING_STRING_VIEW_H
#include <opentracing/version.h>
#include <algorithm>
#include <cstring>
#include <ostream>
#include <string>
// ===========
// string_view.h
// ===========
// class string_view - Constant reference to an external string
//
// -----------------
// String References
// -----------------
// This string references is a simplified version of the boost::string_ref.
// Its purpose is to avoid a number of efficiency problems that appear
// commonly when interacting with 'std::string' and c-strings.
//
// See the boost documentation for more background:
// http://www.boost.org/doc/libs/master/libs/utility/doc/html/string_ref.html
//
// -----
// Note:
// -----
// Although we have the ability to use wide string refs, there are side
// effects in exposing an OpenTracing interface that works with narrow and wide
// strings at the same time. Storage on the implementation will have a 'native'
// format.
//
// Exposing references to that format avoid copies means clients would be
// dependent on that format. If they're dependent on that detail and then switch
// out the implementation to a different format, there would be lots of code
// that breaks if it was expecting wstring and starts receiving string all of a
// sudden. That design issue still needs to be addressed.
namespace opentracing {
BEGIN_OPENTRACING_ABI_NAMESPACE
// ===============
// class string_view
// ===============
// Represent a constant reference to an external character array. The external
// array need not be null-terminated, if explicitly created with a known length.
//
// This class does not own the data. It is expected to be used in situations
// where the character data resides in some other buffer, whose lifetime extends
// past that of the string_view. For this reason, it is not in general safe to
// store a string_view.
class string_view {
public:
// Construct an empty string_view
string_view() noexcept : data_(nullptr), length_(0) {}
// create string reference from const character pointer
string_view(const char* str) noexcept
: data_(str), length_(std::strlen(str)) {}
// Create constant string reference from pointer and length
string_view(const std::basic_string<char>& str) noexcept
: data_(str.c_str()), length_(str.length()) {}
// Create constant string reference from pointer and length
string_view(const char* str, size_t len) noexcept
: data_(str), length_(len) {}
// Implicit conversion to std::string
operator std::string() const { return {data_, length_}; }
// Return address of the referenced string
const char* data() const noexcept { return data_; }
// Returns true if `length_` == 0
bool empty() const noexcept { return length_ == 0; }
// Return the length of the referenced string
size_t length() const noexcept { return length_; }
size_t size() const noexcept { return length_; }
// Returns a RandomAccessIterator to the first element.
const char* begin() const noexcept { return data(); }
// Returns a RandomAccessIterator for the last element.
const char* end() const noexcept { return data() + length(); }
// Returns the character in the i-th position.
const char& operator[](std::size_t i) { return *(data() + i); }
private:
const char* data_; // Pointer to external storage
size_t length_; // Length of data pointed to by 'data_'
};
inline bool operator==(string_view lhs, string_view rhs) noexcept {
return lhs.length() == rhs.length() &&
std::equal(lhs.data(), lhs.data() + lhs.length(), rhs.data());
}
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,
const opentracing::string_view& ref) {
return os.write(ref.data(), static_cast<std::streamsize>(ref.length()));
}
END_OPENTRACING_ABI_NAMESPACE
} // namespace opentracing
#endif // OPENTRACING_STRING_VIEW_H
|