mirror of
https://github.com/abseil/abseil-cpp.git
synced 2026-06-04 12:07:05 +08:00
[meta] Add constexpr testing helper.
PiperOrigin-RevId: 846383067 Change-Id: Ia8dbbb805f59eb4cb5334290c3e24e0117777ca2
This commit is contained in:
committed by
Copybara-Service
parent
641721e94f
commit
ab8fec82ff
@@ -34,6 +34,32 @@ package(
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
cc_library(
|
||||
name = "constexpr_testing",
|
||||
testonly = 1,
|
||||
hdrs = ["internal/constexpr_testing.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
visibility = [
|
||||
"//absl:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"//absl/base:config",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "constexpr_testing_test",
|
||||
srcs = ["internal/constexpr_testing_test.cc"],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
":constexpr_testing",
|
||||
"@googletest//:gtest",
|
||||
"@googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "requires",
|
||||
hdrs = ["internal/requires.h"],
|
||||
|
||||
@@ -14,6 +14,29 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
absl_cc_library(
|
||||
NAME
|
||||
constexpr_testing_internal
|
||||
HDRS
|
||||
"internal/constexpr_testing.h"
|
||||
COPTS
|
||||
${ABSL_DEFAULT_COPTS}
|
||||
DEPS
|
||||
absl::config
|
||||
)
|
||||
|
||||
absl_cc_test(
|
||||
NAME
|
||||
constexpr_testing_test
|
||||
SRCS
|
||||
"internal/constexpr_testing_test.cc"
|
||||
COPTS
|
||||
${ABSL_TEST_COPTS}
|
||||
DEPS
|
||||
absl::constexpr_testing_internal
|
||||
GTest::gmock_main
|
||||
)
|
||||
|
||||
absl_cc_library(
|
||||
NAME
|
||||
requires_internal
|
||||
|
||||
73
absl/meta/internal/constexpr_testing.h
Normal file
73
absl/meta/internal/constexpr_testing.h
Normal file
@@ -0,0 +1,73 @@
|
||||
// Copyright 2025 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_META_INTERNAL_CONSTEXPR_TESTING_H_
|
||||
#define ABSL_META_INTERNAL_CONSTEXPR_TESTING_H_
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace meta_internal {
|
||||
|
||||
// HasConstexprEvaluation([] { ... }) will evaluate to `true` if the
|
||||
// lambda can be evaluated in a constant expression and `false`
|
||||
// otherwise.
|
||||
// The return type of the lambda is not relevant, as long as the whole
|
||||
// evaluation works in a constant expression.
|
||||
template <typename F>
|
||||
constexpr bool HasConstexprEvaluation(F f);
|
||||
|
||||
/// Implementation details below ///
|
||||
|
||||
namespace internal_constexpr_evaluation {
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wuninitialized"
|
||||
#endif
|
||||
// This will give a constexpr instance of `F`.
|
||||
// This works for captureless lambdas because they have no state and the copy
|
||||
// constructor does not look at the input reference.
|
||||
template <typename F>
|
||||
constexpr F default_instance = default_instance<F>;
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
template <typename F>
|
||||
constexpr std::integral_constant<bool, (default_instance<F>(), true)> Tester(
|
||||
int) {
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
constexpr std::false_type Tester(char) {
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace internal_constexpr_evaluation
|
||||
|
||||
template <typename F>
|
||||
constexpr bool HasConstexprEvaluation(F) {
|
||||
return internal_constexpr_evaluation::Tester<F>(0);
|
||||
}
|
||||
|
||||
} // namespace meta_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_META_INTERNAL_CONSTEXPR_TESTING_H_
|
||||
40
absl/meta/internal/constexpr_testing_test.cc
Normal file
40
absl/meta/internal/constexpr_testing_test.cc
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright 2025 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/meta/internal/constexpr_testing.h"
|
||||
|
||||
#include <map>
|
||||
#include <string_view>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(ConstexprTesting, Basic) {
|
||||
using absl::meta_internal::HasConstexprEvaluation;
|
||||
|
||||
EXPECT_TRUE(HasConstexprEvaluation([] {}));
|
||||
static constexpr int const_global = 7;
|
||||
EXPECT_TRUE(HasConstexprEvaluation([] { return const_global; }));
|
||||
EXPECT_TRUE(HasConstexprEvaluation([] { return 0; }));
|
||||
EXPECT_TRUE(HasConstexprEvaluation([] { return std::string_view{}; }));
|
||||
|
||||
static int nonconst_global;
|
||||
EXPECT_FALSE(HasConstexprEvaluation([] { return nonconst_global; }));
|
||||
EXPECT_FALSE(HasConstexprEvaluation([] { std::abort(); }));
|
||||
EXPECT_FALSE(HasConstexprEvaluation([] { return std::map<int, int>(); }));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user