I have seen the StringPiece class in some open source projects, say muduo network library and pcre. The implement StringPiece class is as follows:
// You can use StringPiece as a function or method parameter. A StringPiece
// parameter can receive a double-quoted std::string literal argument, a “const
// char*” argument, a std::string argument, or a StringPiece argument with no
// data copying. Systematic use of StringPiece for arguments reduces data
// copies and strlen() calls.
class StringPiece {
public:
StringPiece() : ptr_(nullptr), length_(0) {}
StringPiece(const char* str) : ptr_(str), length_(strlen(str)) {}
StringPiece(const unsigned char* str)
: ptr_(reinterpret_cast<const char*>(str)), length_(strlen(ptr_)) {}
StringPiece(const std::string& str)
: ptr_(str.c_str()), length_(str.size()) {}
StringPiece(const char* offset, int len) : ptr_(offset), length_(len) {}
const char* data() const { return ptr_; }
size_t size() const { return length_; }
bool empty() const { return length_ == 0; }
const char* begin() const { return ptr_; }
const char* end() const { return ptr_ + length_; }
void clear() {
ptr_ = nullptr;
length_ = 0;
}
void set(const char* buf, size_t len) {
ptr_ = buf;
length_ = len;
}
void set(const char* buf) {
ptr_ = buf;
length_ = strlen(ptr_);
}
void set(const void* buf) {
ptr_ = static_cast<const char*>(buf);
length_ = strlen(ptr_);
}
void remove_prefix(size_t n) {
assert(n < length_);
ptr_ += n;
length_ -= n;
}
void remove_suffix(size_t n) {
assert(n < length_);
length_ -= n;
}
char operator[](size_t i) const { return ptr_[i]; }
bool operator==(const StringPiece& str) const {
return ((str.length_ == length_) && (memcmp(ptr_, str.ptr_, length_) == 0));
}
bool operator!=(const StringPiece& str) const { return !(*this == str); }
std::string as_string() const { return std::string(ptr_, length_); }
bool start_with(const StringPiece& str) const {
return (length_ >= str.length_) &&
(0 == memcmp(ptr_, str.ptr_, str.length_));
}
#define STRINGPIECE_BINARY_PREDICATE(cmp, auxcmp) \
bool operator cmp(const StringPiece& str) const { \
int r = \
memcmp(ptr_, str.ptr_, length_ < str.length_ ? length_ : str.length_); \
return ((r auxcmp 0)) || ((0 == r) && (length_ cmp str.length_)); \
}
STRINGPIECE_BINARY_PREDICATE(<, <)
STRINGPIECE_BINARY_PREDICATE(<=, <)
STRINGPIECE_BINARY_PREDICATE(>, >)
STRINGPIECE_BINARY_PREDICATE(>=, >)
#undef STRINGPIECE_BINARY_PREDICATE
int compare(const StringPiece& str) {
int r =
memcmp(ptr_, str.ptr_, length_ < str.length_ ? length_ : str.length_);
if (0 == r) {
if (length_ < str.length_)
r = -1;
else if (length_ > str.length_)
r = 1;
}
return r;
}
private:
const char* ptr_;
size_t length_;
};
As the comment mentioned above, the StringPiece is designed to 1)save some unnecessary data copying and 2) receive two different type parameter in an object. I write some code to learn how to use StringPiece, I got some error. My code is as follow:
#include "StringPiece.h"
#include <iostream>
using namespace std;
void foo1(string&& str){
cout << str << endl;
}
void foo1(const StringPiece& str){
cout << str.as_string() << endl;
}
int main(void){
foo1("1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
return 0;
}
In my opinion, StringPiece is a little bit like a boost::string_ref. It can give you a glimpse of the string it doesn't own. So I think it is necessary to provide an overload version of foo1 which receive a rvalue string parameter. Is any to work around this problem here? I means that only in the case when I use unnamed string object as parameter, the foo1(string&&) will be called. And in other case, including use const char* as parameter, the foo1(const StringPiece&) will be called.

Aucun commentaire:
Enregistrer un commentaire