Commit 515bf2bb authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

A generic tag type

Summary: [Folly] A generic tag type for all your generic tag-related needs. With naming following the pattern of `std::in_place_t` and `std::in_place`.

Reviewed By: kirkshoop

Differential Revision: D13855499

fbshipit-source-id: 50b7e41fbbb843c6c9b766f8b66484d6aa23c167
parent 91bc2fbe
......@@ -134,6 +134,16 @@
namespace folly {
template <typename...>
struct tag_t {};
#if __cplusplus >= 201703L
template <typename... T>
inline constexpr tag_t<T...> tag;
#endif
#if __cpp_lib_bool_constant || _MSC_VER
using std::bool_constant;
......
......@@ -1445,14 +1445,15 @@ TEST(Range, LiteralSuffixContainsNulBytes) {
EXPECT_EQ(5u, literalPiece.size());
}
class tag {};
namespace {
class fake_tag {};
class fake_string_view {
private:
StringPiece piece_;
public:
using size_type = std::size_t;
explicit fake_string_view(char const* s, size_type c, tag = {})
explicit fake_string_view(char const* s, size_type c, fake_tag = {})
: piece_(s, c) {}
/* implicit */ operator StringPiece() const {
return piece_;
......@@ -1461,6 +1462,7 @@ class fake_string_view {
return rhs == lhs.piece_;
}
};
} // namespace
TEST(Range, StringPieceExplicitConversionOperator) {
using PieceM = StringPiece;
......@@ -1514,8 +1516,8 @@ TEST(Range, StringPieceExplicitConversionOperator) {
EXPECT_EQ("hello", fake_string_view{piecec});
EXPECT_EQ("hello", piecem.to<fake_string_view>());
EXPECT_EQ("hello", piecec.to<fake_string_view>());
EXPECT_EQ("hello", piecem.to<fake_string_view>(tag{}));
EXPECT_EQ("hello", piecec.to<fake_string_view>(tag{}));
EXPECT_EQ("hello", piecem.to<fake_string_view>(fake_tag{}));
EXPECT_EQ("hello", piecec.to<fake_string_view>(fake_tag{}));
}
TEST(Range, MutableStringPieceExplicitConversionOperator) {
......@@ -1570,8 +1572,8 @@ TEST(Range, MutableStringPieceExplicitConversionOperator) {
EXPECT_EQ("hello", fake_string_view{piecec});
EXPECT_EQ("hello", piecem.to<fake_string_view>());
EXPECT_EQ("hello", piecec.to<fake_string_view>());
EXPECT_EQ("hello", piecem.to<fake_string_view>(tag{}));
EXPECT_EQ("hello", piecec.to<fake_string_view>(tag{}));
EXPECT_EQ("hello", piecem.to<fake_string_view>(fake_tag{}));
EXPECT_EQ("hello", piecec.to<fake_string_view>(fake_tag{}));
}
#if FOLLY_HAS_STRING_VIEW
......
......@@ -223,6 +223,26 @@ TEST(Traits, actuallyRelocatable) {
testIsRelocatable<std::vector<char>>(5, 'g');
}
struct inspects_tag {
template <typename T>
std::false_type is_char(tag_t<T>) const {
return {};
}
std::true_type is_char(tag_t<char>) const {
return {};
}
};
TEST(Traits, tag) {
inspects_tag f;
EXPECT_FALSE(f.is_char(tag_t<int>{}));
EXPECT_TRUE(f.is_char(tag_t<char>{}));
#if __cplusplus >= 201703L
EXPECT_FALSE(f.is_char(tag<int>));
EXPECT_TRUE(f.is_char(tag<char>));
#endif
}
namespace {
// has_value_type<T>::value is true if T has a nested type `value_type`
template <class T, class = void>
......
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