#include <stdarg.h>
#include <string>
#include <boost/type_traits.hpp>
+#include <boost/regex/pending/unicode_iterator.hpp>
#ifdef FOLLY_HAVE_DEPRECATED_ASSOC
#ifdef _GLIBCXX_SYMVER
toLowerAscii(str.begin(), str.size());
}
+template <class Iterator = const char*,
+ class Base = folly::Range<boost::u8_to_u32_iterator<Iterator>>>
+class UTF8Range : public Base {
+ public:
+ /* implicit */ UTF8Range(const folly::Range<Iterator> baseRange)
+ : Base(boost::u8_to_u32_iterator<Iterator>(
+ baseRange.begin(), baseRange.begin(), baseRange.end()),
+ boost::u8_to_u32_iterator<Iterator>(
+ baseRange.end(), baseRange.begin(), baseRange.end())) {}
+};
+
+using UTF8StringPiece = UTF8Range<const char*>;
+
} // namespace folly
// Hook into boost's type traits
EXPECT_EQ("", rtrimWhitespace("\r "));
}
+const folly::StringPiece kTestUTF8 = "This is \U0001F602 stuff!";
+
+TEST(UTF8StringPiece, valid_utf8) {
+ folly::StringPiece sp = kTestUTF8;
+ UTF8StringPiece utf8 = sp;
+ // utf8.size() not available since it's not a random-access range
+ EXPECT_EQ(16, utf8.walk_size());
+}
+
+TEST(UTF8StringPiece, valid_suffix) {
+ UTF8StringPiece utf8 = kTestUTF8.subpiece(8);
+ EXPECT_EQ(8, utf8.walk_size());
+}
+
+TEST(UTF8StringPiece, empty_mid_codepoint) {
+ UTF8StringPiece utf8 = kTestUTF8.subpiece(9, 0); // okay since it's empty
+ EXPECT_EQ(0, utf8.walk_size());
+}
+
+TEST(UTF8StringPiece, invalid_mid_codepoint) {
+ EXPECT_THROW(UTF8StringPiece(kTestUTF8.subpiece(9, 1)), std::out_of_range);
+}
+
int main(int argc, char *argv[]) {
testing::InitGoogleTest(&argc, argv);
gflags::ParseCommandLineFlags(&argc, &argv, true);