Skip to content

Commit

Permalink
Move boiler plate code for implicit presence check to MessageLite.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 626137024
  • Loading branch information
protobuf-github-bot authored and copybara-github committed Apr 18, 2024
1 parent 8bace99 commit 6537b22
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 12 deletions.
14 changes: 2 additions & 12 deletions src/google/protobuf/compiler/cpp/message.cc
Original file line number Diff line number Diff line change
Expand Up @@ -208,21 +208,11 @@ bool EmitFieldNonDefaultCondition(io::Printer* p, const std::string& prefix,
)cc");
} else if (field->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT) {
p->Emit(R"cc(
static_assert(sizeof(::uint32_t) == sizeof(float),
"Code assumes ::uint32_t and float are the same size.");
float tmp_$name$ = $prefix$_internal_$name$();
::uint32_t raw_$name$;
memcpy(&raw_$name$, &tmp_$name$, sizeof(tmp_$name$));
if (raw_$name$ != 0) {
if (!IsDefaultImplicitPresence($prefix$_internal_$name$())) {
)cc");
} else if (field->cpp_type() == FieldDescriptor::CPPTYPE_DOUBLE) {
p->Emit(R"cc(
static_assert(sizeof(::uint64_t) == sizeof(double),
"Code assumes ::uint64_t and double are the same size.");
double tmp_$name$ = $prefix$_internal_$name$();
::uint64_t raw_$name$;
memcpy(&raw_$name$, &tmp_$name$, sizeof(tmp_$name$));
if (raw_$name$ != 0) {
if (!IsDefaultImplicitPresence($prefix$_internal_$name$())) {
)cc");
} else {
p->Emit(R"cc(
Expand Down
17 changes: 17 additions & 0 deletions src/google/protobuf/message_lite.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <climits>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <iosfwd>
#include <string>

Expand Down Expand Up @@ -506,6 +507,22 @@ class PROTOBUF_EXPORT MessageLite {
return internal::InternalVisibility{};
}

// Returns true if "value" is default (0), which implicitly checks presence.
static inline bool IsDefaultImplicitPresence(float value) {
static_assert(sizeof(uint32_t) == sizeof(float),
"Code assumes uint32_t and float are the same size.");
uint32_t raw;
memcpy(&raw, &value, sizeof(value));
return raw == 0;
}
static inline bool IsDefaultImplicitPresence(double value) {
static_assert(sizeof(uint64_t) == sizeof(double),
"Code assumes uint64_t and double are the same size.");
uint64_t raw;
memcpy(&raw, &value, sizeof(value));
return raw == 0;
}

template <typename T>
PROTOBUF_ALWAYS_INLINE static T* DefaultConstruct(Arena* arena) {
return static_cast<T*>(Arena::DefaultConstruct<T>(arena));
Expand Down

0 comments on commit 6537b22

Please sign in to comment.