Port C++20 Requires to it's C++17 equivalent for reuse across protos

PiperOrigin-RevId: 635894605
pull/16904/head
Hong Shin 6 months ago committed by Copybara-Service
parent 696b5a3554
commit b94e117faa
  1. 6
      protos/BUILD
  2. 17
      protos/requires.h
  3. 1
      protos_generator/tests/BUILD
  4. 8
      protos_generator/tests/test_generated.cc

@ -167,3 +167,9 @@ cc_test(
"@com_google_googletest//:gtest_main",
],
)
cc_library(
name = "requires",
hdrs = ["requires.h"],
visibility = ["//visibility:public"],
)

@ -0,0 +1,17 @@
#ifndef THIRD_PARTY_UPB_PROTOS_REQUIRES_H_
#define THIRD_PARTY_UPB_PROTOS_REQUIRES_H_
#include <type_traits>
namespace protos::internal {
// Ports C++20 `requires` to C++17.
// C++20 ideal:
// if constexpr (requires { t.foo(); }) { ... }
// Our C++17 stopgap solution:
// if constexpr (Requires<T>([](auto x) -> decltype(x.foo()) {})) { ... }
template <typename... T, typename F>
constexpr bool Requires(F) {
return std::is_invocable_v<F, T...>;
}
} // namespace protos::internal
#endif // THIRD_PARTY_UPB_PROTOS_REQUIRES_H_

@ -131,6 +131,7 @@ cc_test(
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
"//protos",
"//protos:requires",
"//upb:mem",
"//protos:repeated_field",
],

@ -21,6 +21,7 @@
#include "protos/protos.h"
#include "protos/repeated_field.h"
#include "protos/repeated_field_iterator.h"
#include "protos/requires.h"
#include "protos_generator/tests/child_model.upb.proto.h"
#include "protos_generator/tests/no_package.upb.proto.h"
#include "protos_generator/tests/test_model.upb.proto.h"
@ -29,6 +30,7 @@
namespace {
using ::protos::internal::Requires;
using ::protos_generator::test::protos::ChildModel1;
using ::protos_generator::test::protos::container_ext;
using ::protos_generator::test::protos::ContainerExtension;
@ -44,12 +46,6 @@ using ::protos_generator::test::protos::theme;
using ::protos_generator::test::protos::ThemeExtension;
using ::testing::ElementsAre;
// C++17 port of C++20 `requires`
template <typename... T, typename F>
constexpr bool Requires(F) {
return std::is_invocable_v<F, T...>;
}
TEST(CppGeneratedCode, Constructor) { TestModel test_model; }
TEST(CppGeneratedCode, MessageEnum) { EXPECT_EQ(5, TestModel_Category_IMAGES); }

Loading…
Cancel
Save