cleanup includes in folly/Format.h
authorPhilip Pronin <philipp@fb.com>
Sun, 28 Jun 2015 01:09:24 +0000 (18:09 -0700)
committerSara Golemon <sgolemon@fb.com>
Mon, 29 Jun 2015 18:00:33 +0000 (11:00 -0700)
Summary: `folly/Format.h` pulls in `folly/small_vector.h` and
`folly/FBVector.h`, which (according to @​oleksandr's analysis)
are the most expensive includes for multiple fbcode projects.

Reviewed By: @ot

Differential Revision: D2198904

folly/FBVector.h
folly/Format-inl.h
folly/Format.h
folly/FormatTraits.h [new file with mode: 0644]
folly/Makefile.am
folly/small_vector.h
folly/test/FormatOtherTest.cpp

index 754ebfef5f48a93d6a703d34ea58d6ae4c8162ae..b4e253ed1dd24e024d384978dfa44aa07a953187 100644 (file)
@@ -36,6 +36,7 @@
 #include <type_traits>
 #include <utility>
 
+#include <folly/FormatTraits.h>
 #include <folly/Likely.h>
 #include <folly/Malloc.h>
 #include <folly/Traits.h>
@@ -1586,6 +1587,16 @@ void swap(fbvector<T, A>& lhs, fbvector<T, A>& rhs) noexcept {
 //-----------------------------------------------------------------------------
 // other
 
+namespace detail {
+
+// Format support.
+template <class T, class A>
+struct IndexableTraits<fbvector<T, A>>
+  : public IndexableTraitsSeq<fbvector<T, A>> {
+};
+
+}  // namespace detail
+
 template <class T, class A>
 void compactResize(fbvector<T, A>* v, size_t sz) {
   v->resize(sz);
index 6205a5682eb6e7a09c3fa124bc1913ba967e2a04..1239188cbe987900c047602c4dccb37a1f974e0e 100644 (file)
 #error This file may only be included from Format.h.
 #endif
 
+#include <array>
+#include <deque>
+#include <map>
+#include <unordered_map>
+#include <vector>
+
 #include <folly/Exception.h>
+#include <folly/FormatTraits.h>
 #include <folly/Traits.h>
 
 // Ignore -Wformat-nonliteral warnings within this file
@@ -770,45 +777,6 @@ class FormatValue<
 
 namespace detail {
 
-// Shortcut, so we don't have to use enable_if everywhere
-struct FormatTraitsBase {
-  typedef void enabled;
-};
-
-// Traits that define enabled, value_type, and at() for anything
-// indexable with integral keys: pointers, arrays, vectors, and maps
-// with integral keys
-template <class T, class Enable=void> struct IndexableTraits;
-
-// Base class for sequences (vectors, deques)
-template <class C>
-struct IndexableTraitsSeq : public FormatTraitsBase {
-  typedef C container_type;
-  typedef typename C::value_type value_type;
-  static const value_type& at(const C& c, int idx) {
-    return c.at(idx);
-  }
-
-  static const value_type& at(const C& c, int idx,
-                              const value_type& dflt) {
-    return (idx >= 0 && size_t(idx) < c.size()) ? c.at(idx) : dflt;
-  }
-};
-
-// Base class for associative types (maps)
-template <class C>
-struct IndexableTraitsAssoc : public FormatTraitsBase {
-  typedef typename C::value_type::second_type value_type;
-  static const value_type& at(const C& c, int idx) {
-    return c.at(static_cast<typename C::key_type>(idx));
-  }
-  static const value_type& at(const C& c, int idx,
-                              const value_type& dflt) {
-    auto pos = c.find(static_cast<typename C::key_type>(idx));
-    return pos != c.end() ? pos->second : dflt;
-  }
-};
-
 // std::array
 template <class T, size_t N>
 struct IndexableTraits<std::array<T, N>>
@@ -827,18 +795,6 @@ struct IndexableTraits<std::deque<T, A>>
   : public IndexableTraitsSeq<std::deque<T, A>> {
 };
 
-// fbvector
-template <class T, class A>
-struct IndexableTraits<fbvector<T, A>>
-  : public IndexableTraitsSeq<fbvector<T, A>> {
-};
-
-// small_vector
-template <class T, size_t M, class A, class B, class C>
-struct IndexableTraits<small_vector<T, M, A, B, C>>
-  : public IndexableTraitsSeq<small_vector<T, M, A, B, C>> {
-};
-
 // std::map with integral keys
 template <class K, class T, class C, class A>
 struct IndexableTraits<
index 4afe7e4035148d24a885a9afff57e27e9eaf7e4f..02e5d1a893083e63f6864e9e52397963b7643173 100644 (file)
 #ifndef FOLLY_FORMAT_H_
 #define FOLLY_FORMAT_H_
 
-#include <array>
 #include <cstdio>
 #include <tuple>
 #include <type_traits>
-#include <vector>
-#include <deque>
-#include <map>
-#include <unordered_map>
 
-#include <folly/FBVector.h>
 #include <folly/Conv.h>
 #include <folly/Range.h>
 #include <folly/Traits.h>
-#include <folly/Likely.h>
 #include <folly/String.h>
-#include <folly/small_vector.h>
 #include <folly/FormatArg.h>
 
 // Ignore shadowing warnings within this file, so includers can use -Wshadow.
diff --git a/folly/FormatTraits.h b/folly/FormatTraits.h
new file mode 100644 (file)
index 0000000..7ca2ae5
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2015 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FOLLY_FORMAT_TRAITS_H_
+#define FOLLY_FORMAT_TRAITS_H_
+
+#include <type_traits>
+
+namespace folly { namespace detail {
+
+// Shortcut, so we don't have to use enable_if everywhere
+struct FormatTraitsBase {
+  typedef void enabled;
+};
+
+// Traits that define enabled, value_type, and at() for anything
+// indexable with integral keys: pointers, arrays, vectors, and maps
+// with integral keys
+template <class T, class Enable = void> struct IndexableTraits;
+
+// Base class for sequences (vectors, deques)
+template <class C>
+struct IndexableTraitsSeq : public FormatTraitsBase {
+  typedef C container_type;
+  typedef typename C::value_type value_type;
+
+  static const value_type& at(const C& c, int idx) {
+    return c.at(idx);
+  }
+
+  static const value_type& at(const C& c, int idx, const value_type& dflt) {
+    return (idx >= 0 && size_t(idx) < c.size()) ? c.at(idx) : dflt;
+  }
+};
+
+// Base class for associative types (maps)
+template <class C>
+struct IndexableTraitsAssoc : public FormatTraitsBase {
+  typedef typename C::value_type::second_type value_type;
+
+  static const value_type& at(const C& c, int idx) {
+    return c.at(static_cast<typename C::key_type>(idx));
+  }
+
+  static const value_type& at(const C& c, int idx, const value_type& dflt) {
+    auto pos = c.find(static_cast<typename C::key_type>(idx));
+    return pos != c.end() ? pos->second : dflt;
+  }
+};
+
+}}  // namespaces
+
+#endif /* FOLLY_FORMAT_TRAITS_H_ */
index e615a7336e04ab574539a84ef59cffff00c57bbe..c8e14e614a9d0194ddc767a0d7c433bdb8907a50 100644 (file)
@@ -123,6 +123,7 @@ nobase_follyinclude_HEADERS = \
        folly-config.h \
        Foreach.h \
        FormatArg.h \
+       FormatTraits.h \
        Format.h \
        Format-inl.h \
        futures/Deprecated.h \
index 318fcbfdf7ece46dc425c9ef5abbe484a1d87493..ca62f1471ad22fb2d27d551f4da4d9fc19e569ad 100644 (file)
@@ -23,8 +23,6 @@
 #ifndef FOLLY_SMALL_VECTOR_H_
 #define FOLLY_SMALL_VECTOR_H_
 
-#include <folly/Portability.h>
-
 #include <stdexcept>
 #include <cstdlib>
 #include <type_traits>
@@ -46,7 +44,9 @@
 #include <boost/mpl/count.hpp>
 #include <boost/mpl/max.hpp>
 
+#include <folly/FormatTraits.h>
 #include <folly/Malloc.h>
+#include <folly/Portability.h>
 
 #if defined(__GNUC__) && FOLLY_X64
 # include <folly/SmallLocks.h>
@@ -1141,7 +1141,17 @@ void swap(small_vector<T,MaxInline,A,B,C>& a,
 
 //////////////////////////////////////////////////////////////////////
 
-}
+namespace detail {
+
+// Format support.
+template <class T, size_t M, class A, class B, class C>
+struct IndexableTraits<small_vector<T, M, A, B, C>>
+  : public IndexableTraitsSeq<small_vector<T, M, A, B, C>> {
+};
+
+}  // namespace detail
+
+}  // namespace folly
 
 #pragma GCC diagnostic pop
 
index c41f1f060798477512322812ae6467c775af96d8..97d2db102e38439d9862f653882b4d336328cc78 100644 (file)
 
 #include <folly/Format.h>
 
+#include <folly/FBVector.h>
 #include <folly/FileUtil.h>
-#include <folly/json.h>
 #include <folly/dynamic.h>
+#include <folly/json.h>
+#include <folly/small_vector.h>
 
 #include <glog/logging.h>
 #include <gflags/gflags.h>
@@ -76,6 +78,28 @@ TEST(FormatOther, dynamic) {
   EXPECT_EQ("(null)", sformat("{}", dynamic(nullptr)));
 }
 
+namespace {
+
+template <class T>
+void testFormatSeq() {
+  T v{10, 20, 30};
+  EXPECT_EQ("30 10", sformat("{0[2]} {0[0]}", v));
+  EXPECT_EQ("0020", sformat("{0[1]:04}", v));
+  EXPECT_EQ("0020", svformat("{1:04}", v));
+  EXPECT_EQ("10 20", svformat("{} {}", v));
+  EXPECT_EQ("10 20 0030", svformat("{} {} {:04}", v));
+}
+
+}  // namespace
+
+TEST(FormatOther, fbvector) {
+  testFormatSeq<fbvector<int>>();
+}
+
+TEST(FormatOther, small_vector) {
+  testFormatSeq<small_vector<int, 2>>();
+}
+
 int main(int argc, char *argv[]) {
   testing::InitGoogleTest(&argc, argv);
   gflags::ParseCommandLineFlags(&argc, &argv, true);