FBString iomanip fix.
authorNicholas Ormrod <njormrod@fb.com>
Tue, 10 Dec 2013 22:14:00 +0000 (14:14 -0800)
committerJordan DeLong <jdelong@fb.com>
Fri, 20 Dec 2013 21:05:15 +0000 (13:05 -0800)
Summary:
D1090936 noticed some problems with fbstring iomanip behavior.
The root cause is that os.write(ostream, char*, size_t) is an
UnformattedOutputFunction, so disregards setw(), setfill(), and
left/right alignment.

The use of os.write instead of os << str.data() is intentional:
D367009 switched from the latter to the former so that strings
containing a '\0' are printed properly.

There does not seem to be a public function to write with formatting.
Where needed in libgcc, the function __ostream_insert is used. Since
FBString already uses such 'private' functions, __ostream_insert is an
appropriate solution.

@override-unit-failures

Test Plan:
Added test cases to FBStringTest.cpp to cover iomanip.
fbconfig -r folly && fbmake opt && fbmake runtests_opt

Reviewed By: andrei.alexandrescu@fb.com

FB internal diff: D1091474

folly/FBString.h
folly/test/FBStringTest.cpp

index 6f5ea13194978aad661e2227f6fcc34e90ba8d26..b75db3d4b79465a76cfdd4fef23fd0bd7f9caa87 100644 (file)
@@ -2309,7 +2309,7 @@ operator<<(
   std::basic_ostream<typename basic_fbstring<E, T, A, S>::value_type,
   typename basic_fbstring<E, T, A, S>::traits_type>& os,
     const basic_fbstring<E, T, A, S>& str) {
-  os.write(str.data(), str.size());
+  std::__ostream_insert(os, str.data(), str.size());
   return os;
 }
 
index 4f0aa89af1e5fb9f78f727f5228ca0e0df360be7..d3b321185367d0e92b617312a76542ed51665a06 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <list>
 #include <fstream>
+#include <iomanip>
 #include <boost/algorithm/string.hpp>
 #include <boost/random.hpp>
 #include <gtest/gtest.h>
@@ -1181,6 +1182,31 @@ TEST(FBString, noexcept) {
 #endif
 }
 
+TEST(FBString, iomanip) {
+  stringstream ss;
+  fbstring fbstr("Hello");
+
+  ss << setw(6) << fbstr;
+  EXPECT_EQ(ss.str(), " Hello");
+  ss.str("");
+
+  ss << left << setw(6) << fbstr;
+  EXPECT_EQ(ss.str(), "Hello ");
+  ss.str("");
+
+  ss << right << setw(6) << fbstr;
+  EXPECT_EQ(ss.str(), " Hello");
+  ss.str("");
+
+  ss << setw(4) << fbstr;
+  EXPECT_EQ(ss.str(), "Hello");
+  ss.str("");
+
+  ss << setfill('^') << setw(6) << fbstr;
+  EXPECT_EQ(ss.str(), "^Hello");
+  ss.str("");
+}
+
 int main(int argc, char** argv) {
   testing::InitGoogleTest(&argc, argv);
   google::ParseCommandLineFlags(&argc, &argv, true);