| #include <algorithm> |
| #include <optional> |
| #include <string> |
| #include <vector> |
| |
| #include "absl/strings/string_view.h" |
| #include "absl/types/optional.h" |
| |
| template<typename T> |
| void Ref(T&&); |
| |
| #if 0 |
| using std::string; |
| #else |
| // To make the disassembly easier to read, here's a string class that doesn't get inlined. |
| struct string { |
| string() : size_(0), data_(nullptr) {} |
| string(absl::string_view); |
| string(string &&x) { |
| size_ = x.size_; |
| data_ = x.data_; |
| x.size_ = 0; |
| x.data_ = nullptr; |
| } |
| string(const string&); |
| |
| string& operator=(string &&x) { |
| std::swap(size_, x.size_); |
| std::swap(data_, x.data_); |
| return *this; |
| } |
| //string& operator=(absl::string_view x); // not in c++14 string |
| |
| ~string(); |
| |
| string& assign(const char*, size_t); |
| |
| ptrdiff_t size_; |
| char *data_; |
| }; |
| #endif |
| |
| //// END OF BOILERPLATE //// |
| |
| class C { |
| ::absl::optional<string> value_; |
| void SetValue(::absl::optional<::absl::string_view> value); |
| }; |
| |
| void C::SetValue(::absl::optional<::absl::string_view> value) { |
| #if 0 // c++17's string has operator= for string_view, so just do this. |
| value_ = value; |
| #else // In c++14, we have to do more work to avoid reallocation. |
| if (value) { |
| if (value_) { |
| value_->assign(value->data(), value->size()); |
| } else { |
| value_.emplace(*value); |
| } |
| } else { |
| value_ = ::absl::nullopt; |
| } |
| #endif |
| } |