Commit c339019b authored by Kenton Varda's avatar Kenton Varda

Allow implicit convertion between StringPtr/Text::Reader and std::string.

parent 34897e78
......@@ -115,5 +115,17 @@ TEST(Blob, Compare) {
EXPECT_FALSE(Text::Reader("foo") > Text::Reader("foobar"));
}
#if KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP
TEST(Blob, StlInterop) {
std::string foo = "foo";
Text::Reader reader = foo;
EXPECT_EQ("foo", reader);
std::string bar = reader;
EXPECT_EQ("foo", bar);
}
#endif
} // namespace
} // namespace capnp
......@@ -76,6 +76,14 @@ public:
inline Reader(const char* value, size_t size): StringPtr(value, size) {}
inline Reader(const kj::String& value): StringPtr(value) {}
inline Reader(const StringPtr& value): StringPtr(value) {}
#if KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP
template <typename T, typename = decltype(kj::instance<T>().c_str())>
inline Reader(const T& t): StringPtr(t) {}
// Allow implicit conversion from any class that has a c_str() method (namely, std::string).
// We use a template trick to detect std::string in order to avoid including the header for
// those who don't want it.
#endif
};
class Data::Builder: public kj::ArrayPtr<byte> {
......
......@@ -49,6 +49,20 @@ TEST(String, StartsEndsWith) {
EXPECT_TRUE(StringPtr("foobar").endsWith(""));
}
#if KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP
TEST(String, StlInterop) {
std::string foo = "foo";
StringPtr ptr = foo;
EXPECT_EQ("foo", ptr);
std::string bar = ptr;
EXPECT_EQ("foo", bar);
EXPECT_EQ("foo", kj::str(foo));
EXPECT_EQ("foo", kj::heapString(foo));
}
#endif
} // namespace
} // namespace _ (private)
} // namespace kj
......@@ -35,6 +35,12 @@ class String;
class StringTree; // string-tree.h
// Our STL string SFINAE trick does not work with GCC 4.7, but it works with Clang and GCC 4.8, so
// we'll just preprocess it out if not supported.
#if __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
#define KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP 1
#endif
// =======================================================================================
// StringPtr -- A NUL-terminated ArrayPtr<const char> containing UTF-8 text.
//
......@@ -53,6 +59,20 @@ public:
inline StringPtr(const char* begin, const char* end): StringPtr(begin, end - begin) {}
inline StringPtr(const String& value);
#if KJ_COMPILER_SUPPORTS_STL_STRING_INTEROP
template <typename T, typename = decltype(instance<T>().c_str())>
inline StringPtr(const T& t): StringPtr(t.c_str()) {}
// Allow implicit conversion from any class that has a c_str() method (namely, std::string).
// We use a template trick to detect std::string in order to avoid including the header for
// those who don't want it.
template <typename T, typename = decltype(instance<T>().c_str())>
inline operator T() const { return cStr(); }
// Allow implicit conversion to any class that has a c_str() method (namely, std::string).
// We use a template trick to detect std::string in order to avoid including the header for
// those who don't want it.
#endif
inline operator ArrayPtr<const char>() const;
inline ArrayPtr<const char> asArray() const;
// Result does not include NUL terminator.
......
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