Commit 6b2d55ec authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

Test constexpr_strlen, constexpr_strcmp fallbacks

Summary: [Folly] Test `constexpr_strlen`, `constexpr_strcmp` fallback implementations alongside the main implementations, since the main implementations may fall back to the fallback implementations on some platforms but not on others, and we may only be testing on the other platforms.

Differential Revision: D23432301

fbshipit-source-id: 271705cb8c2b1ab6d11c1be20e2c3023cacab583
parent 3b18d435
......@@ -41,21 +41,28 @@ constexpr size_t constexpr_strlen_internal(const Char* s, size_t len) {
constexpr_strlen_internal(s + 8, len + 8);
// clang-format on
}
template <typename Char>
constexpr size_t constexpr_strlen_fallback(const Char* s) {
return constexpr_strlen_internal(s, 0);
}
static_assert(
constexpr_strlen_internal("123456789", 0) == 9,
constexpr_strlen_fallback("123456789") == 9,
"Someone appears to have broken constexpr_strlen...");
template <typename Char>
constexpr int constexpr_strcmp_internal(const Char* s1, const Char* s2) {
constexpr int constexpr_strcmp_fallback(const Char* s1, const Char* s2) {
return (*s1 == '\0' || *s1 != *s2)
? (static_cast<int>(*s1 - *s2))
: constexpr_strcmp_internal(s1 + 1, s2 + 1);
: constexpr_strcmp_fallback(s1 + 1, s2 + 1);
}
} // namespace detail
template <typename Char>
constexpr size_t constexpr_strlen(const Char* s) {
return detail::constexpr_strlen_internal(s, 0);
return detail::constexpr_strlen_fallback(s);
}
template <>
......@@ -67,13 +74,13 @@ constexpr size_t constexpr_strlen(const char* s) {
// strlen() happens to already be constexpr under gcc
return std::strlen(s);
#else
return detail::constexpr_strlen_internal(s, 0);
return detail::constexpr_strlen_fallback(s);
#endif
}
template <typename Char>
constexpr int constexpr_strcmp(const Char* s1, const Char* s2) {
return detail::constexpr_strcmp_internal(s1, s2);
return detail::constexpr_strcmp_fallback(s1, s2);
}
template <>
......@@ -85,7 +92,7 @@ constexpr int constexpr_strcmp(const char* s1, const char* s2) {
// strcmp() happens to already be constexpr under gcc
return std::strcmp(s1, s2);
#else
return detail::constexpr_strcmp_internal(s1, s2);
return detail::constexpr_strcmp_fallback(s1, s2);
#endif
}
} // namespace folly
......@@ -19,19 +19,36 @@
#include <folly/portability/GTest.h>
using folly::constexpr_strcmp;
using folly::constexpr_strlen;
using folly::detail::constexpr_strcmp_fallback;
using folly::detail::constexpr_strlen_fallback;
TEST(ConstexprTest, constexpr_strlen_cstr) {
constexpr auto v = "hello";
constexpr auto a = folly::constexpr_strlen(v);
EXPECT_EQ(5, a);
EXPECT_TRUE((std::is_same<const size_t, decltype(a)>::value));
{
constexpr auto a = constexpr_strlen(v);
EXPECT_EQ(5, a);
EXPECT_TRUE((std::is_same<const size_t, decltype(a)>::value));
}
{
constexpr auto a = constexpr_strlen_fallback(v);
EXPECT_EQ(5, a);
EXPECT_TRUE((std::is_same<const size_t, decltype(a)>::value));
}
}
TEST(ConstexprTest, constexpr_strlen_ints) {
constexpr int v[] = {5, 3, 4, 0, 7};
constexpr auto a = folly::constexpr_strlen(v);
EXPECT_EQ(3, a);
EXPECT_TRUE((std::is_same<const size_t, decltype(a)>::value));
{
constexpr auto a = constexpr_strlen(v);
EXPECT_EQ(3, a);
EXPECT_TRUE((std::is_same<const size_t, decltype(a)>::value));
}
{
constexpr auto a = constexpr_strlen_fallback(v);
EXPECT_EQ(3, a);
EXPECT_TRUE((std::is_same<const size_t, decltype(a)>::value));
}
}
TEST(ConstexprTest, constexpr_strcmp_ints) {
......@@ -39,6 +56,10 @@ TEST(ConstexprTest, constexpr_strcmp_ints) {
constexpr int v1[] = {6, 4};
static_assert(constexpr_strcmp(v1, v) > 0, "constexpr_strcmp is broken");
static_assert(constexpr_strcmp(v, v) == 0, "constexpr_strcmp is broken");
static_assert(
constexpr_strcmp_fallback(v1, v) > 0, "constexpr_strcmp is broken");
static_assert(
constexpr_strcmp_fallback(v, v) == 0, "constexpr_strcmp is broken");
}
static_assert(
......@@ -49,3 +70,21 @@ static_assert(constexpr_strcmp("abc", "def") < 0, "constexpr_strcmp is broken");
static_assert(constexpr_strcmp("xyz", "abc") > 0, "constexpr_strcmp is broken");
static_assert(constexpr_strcmp("a", "abc") < 0, "constexpr_strcmp is broken");
static_assert(constexpr_strcmp("abc", "a") > 0, "constexpr_strcmp is broken");
static_assert(
constexpr_strcmp_fallback("abc", "abc") == 0,
"constexpr_strcmp is broken");
static_assert(
constexpr_strcmp_fallback("", "") == 0,
"constexpr_strcmp is broken");
static_assert(
constexpr_strcmp_fallback("abc", "def") < 0,
"constexpr_strcmp is broken");
static_assert(
constexpr_strcmp_fallback("xyz", "abc") > 0,
"constexpr_strcmp is broken");
static_assert(
constexpr_strcmp_fallback("a", "abc") < 0,
"constexpr_strcmp is broken");
static_assert(
constexpr_strcmp_fallback("abc", "a") > 0,
"constexpr_strcmp is broken");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment