Make inline strings constant initialized when supported by language version.

PiperOrigin-RevId: 653688195
pull/17498/head
Protobuf Team Bot 4 months ago committed by Copybara-Service
parent b84942022d
commit bf8a9fc73f
  1. 33
      src/google/protobuf/inlined_string_field.h

@ -85,16 +85,28 @@ namespace internal {
// For more details of the donating states transitions, go/pd-inlined-string. // For more details of the donating states transitions, go/pd-inlined-string.
class PROTOBUF_EXPORT InlinedStringField { class PROTOBUF_EXPORT InlinedStringField {
public: public:
InlinedStringField() { Init(); } InlinedStringField() : str_() {}
InlinedStringField(const InlinedStringField&) = delete; InlinedStringField(const InlinedStringField&) = delete;
InlinedStringField& operator=(const InlinedStringField&) = delete; InlinedStringField& operator=(const InlinedStringField&) = delete;
inline void Init() { new (get_mutable()) std::string(); } #if defined(__cpp_lib_constexpr_string) && __cpp_lib_constexpr_string >= 201907L
// No need to do dynamic initialization here.
constexpr void Init() {}
// Add the dummy parameter just to make InlinedStringField(nullptr) // Add the dummy parameter just to make InlinedStringField(nullptr)
// unambiguous. // unambiguous.
constexpr InlinedStringField( constexpr InlinedStringField(
const ExplicitlyConstructed<std::string>* /*default_value*/, const ExplicitlyConstructed<std::string>* /*default_value*/,
bool /*dummy*/) bool /*dummy*/)
: value_{} {} : str_{} {}
#else
inline void Init() { ::new (static_cast<void*>(&str_)) std::string(); }
// Add the dummy parameter just to make InlinedStringField(nullptr)
// unambiguous.
constexpr InlinedStringField(
const ExplicitlyConstructed<std::string>* /*default_value*/,
bool /*dummy*/)
: dummy_{} {}
#endif
explicit InlinedStringField(const std::string& default_value); explicit InlinedStringField(const std::string& default_value);
explicit InlinedStringField(Arena* arena); explicit InlinedStringField(Arena* arena);
InlinedStringField(Arena* arena, const InlinedStringField& rhs); InlinedStringField(Arena* arena, const InlinedStringField& rhs);
@ -346,7 +358,10 @@ class PROTOBUF_EXPORT InlinedStringField {
PROTOBUF_NDEBUG_INLINE std::string* get_mutable(); PROTOBUF_NDEBUG_INLINE std::string* get_mutable();
PROTOBUF_NDEBUG_INLINE const std::string* get_const() const; PROTOBUF_NDEBUG_INLINE const std::string* get_const() const;
alignas(std::string) char value_[sizeof(std::string)]; union {
std::string str_;
char dummy_;
};
std::string* MutableSlow(::google::protobuf::Arena* arena, bool donated, std::string* MutableSlow(::google::protobuf::Arena* arena, bool donated,
uint32_t* donating_states, uint32_t mask, uint32_t* donating_states, uint32_t mask,
@ -359,12 +374,10 @@ class PROTOBUF_EXPORT InlinedStringField {
typedef void DestructorSkippable_; typedef void DestructorSkippable_;
}; };
inline std::string* InlinedStringField::get_mutable() { inline std::string* InlinedStringField::get_mutable() { return &str_; }
return reinterpret_cast<std::string*>(&value_);
}
inline const std::string* InlinedStringField::get_const() const { inline const std::string* InlinedStringField::get_const() const {
return reinterpret_cast<const std::string*>(&value_); return &str_;
} }
inline InlinedStringField::InlinedStringField( inline InlinedStringField::InlinedStringField(
@ -386,12 +399,12 @@ inline void InternalRegisterArenaDtor(Arena* arena, void* object,
} }
#endif // GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE #endif // GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE
inline InlinedStringField::InlinedStringField(Arena* /*arena*/) { Init(); } inline InlinedStringField::InlinedStringField(Arena* /*arena*/) : str_() {}
inline InlinedStringField::InlinedStringField(Arena* arena, inline InlinedStringField::InlinedStringField(Arena* arena,
const InlinedStringField& rhs) { const InlinedStringField& rhs) {
const std::string& src = *rhs.get_const(); const std::string& src = *rhs.get_const();
new (value_) std::string(src); ::new (static_cast<void*>(&str_)) std::string(src);
} }
inline const std::string& InlinedStringField::GetNoArena() const { inline const std::string& InlinedStringField::GetNoArena() const {

Loading…
Cancel
Save