From 9dd605034fbb6b30722f5aa7deb6e14418b54c0a Mon Sep 17 00:00:00 2001
From: Steve O'Brien <steveo@fb.com>
Date: Thu, 28 Jun 2018 16:17:33 -0700
Subject: [PATCH] folly: iterator classes (2/3): avoid expensive boost iterator
 headers in `dynamic`

Summary:
In the same vein as some previous diffs: some `boost` headers are expensive.  These `iterator_facade` and related headers (which include -facade.h) are examples of super expensive ones.

`boost/iterator/iterator_adaptor.hpp` in particular shows up as being responsible for appx. 7.5% (avg) of translation units built.

The solution here is: since this bloats `folly/dynamic-inl.h`, in that "private" impl file, I added a workalike class, which is minimal and works well enough to do the job for dynamic's iterators.

Reviewed By: yfeldblum

Differential Revision: D8329532

fbshipit-source-id: deaab7b52d110cd29c613d687a6a74c6a42b515d
---
 folly/dynamic-inl.h | 96 +++++++++++++++++++++++++--------------------
 1 file changed, 53 insertions(+), 43 deletions(-)

diff --git a/folly/dynamic-inl.h b/folly/dynamic-inl.h
index 810b8c469..ffcb015f7 100644
--- a/folly/dynamic-inl.h
+++ b/folly/dynamic-inl.h
@@ -17,13 +17,11 @@
 
 #include <functional>
 
-#include <boost/iterator/iterator_adaptor.hpp>
-#include <boost/iterator/iterator_facade.hpp>
-
 #include <folly/CPortability.h>
 #include <folly/Conv.h>
 #include <folly/Format.h>
 #include <folly/Likely.h>
+#include <folly/detail/Iterators.h>
 
 //////////////////////////////////////////////////////////////////////
 
@@ -198,79 +196,91 @@ inline dynamic::ObjectMaker dynamic::object(dynamic a, dynamic b) {
 
 //////////////////////////////////////////////////////////////////////
 
-struct dynamic::item_iterator : boost::iterator_adaptor<
+struct dynamic::item_iterator : detail::IteratorAdaptor<
                                     dynamic::item_iterator,
-                                    dynamic::ObjectImpl::iterator> {
-  /* implicit */ item_iterator(base_type b) : iterator_adaptor_(b) {}
+                                    dynamic::ObjectImpl::iterator,
+                                    std::pair<dynamic const, dynamic>> {
+  using Super = detail::IteratorAdaptor<
+      dynamic::item_iterator,
+      dynamic::ObjectImpl::iterator,
+      std::pair<dynamic const, dynamic>>;
+  /* implicit */ item_iterator(dynamic::ObjectImpl::iterator b) : Super(b) {}
 
   using object_type = dynamic::ObjectImpl;
-
- private:
-  friend class boost::iterator_core_access;
 };
 
-struct dynamic::value_iterator : boost::iterator_adaptor<
+struct dynamic::value_iterator : detail::IteratorAdaptor<
                                      dynamic::value_iterator,
                                      dynamic::ObjectImpl::iterator,
                                      dynamic> {
-  /* implicit */ value_iterator(base_type b) : iterator_adaptor_(b) {}
+  using Super = detail::IteratorAdaptor<
+      dynamic::value_iterator,
+      dynamic::ObjectImpl::iterator,
+      dynamic>;
+  /* implicit */ value_iterator(dynamic::ObjectImpl::iterator b) : Super(b) {}
 
   using object_type = dynamic::ObjectImpl;
 
- private:
   dynamic& dereference() const {
-    return base_reference()->second;
+    return base()->second;
   }
-  friend class boost::iterator_core_access;
 };
 
 struct dynamic::const_item_iterator
-  : boost::iterator_adaptor<dynamic::const_item_iterator,
-                            dynamic::ObjectImpl::const_iterator> {
-  /* implicit */ const_item_iterator(base_type b) : iterator_adaptor_(b) { }
-  /* implicit */ const_item_iterator(item_iterator i)
-      : iterator_adaptor_(i.base()) {}
-  /* implicit */ const_item_iterator(dynamic::ObjectImpl::iterator i)
-      : iterator_adaptor_(i) {}
+    : detail::IteratorAdaptor<
+          dynamic::const_item_iterator,
+          dynamic::ObjectImpl::const_iterator,
+          std::pair<dynamic const, dynamic> const> {
+  using Super = detail::IteratorAdaptor<
+      dynamic::const_item_iterator,
+      dynamic::ObjectImpl::const_iterator,
+      std::pair<dynamic const, dynamic> const>;
+  /* implicit */ const_item_iterator(dynamic::ObjectImpl::const_iterator b)
+      : Super(b) {}
+  /* implicit */ const_item_iterator(const_item_iterator const& i)
+      : Super(i.base()) {}
+  /* implicit */ const_item_iterator(item_iterator i) : Super(i.base()) {}
 
   using object_type = dynamic::ObjectImpl const;
-
- private:
-  friend class boost::iterator_core_access;
 };
 
-struct dynamic::const_key_iterator
-  : boost::iterator_adaptor<dynamic::const_key_iterator,
-                            dynamic::ObjectImpl::const_iterator,
-                            dynamic const> {
-  /* implicit */ const_key_iterator(base_type b) : iterator_adaptor_(b) { }
+struct dynamic::const_key_iterator : detail::IteratorAdaptor<
+                                         dynamic::const_key_iterator,
+                                         dynamic::ObjectImpl::const_iterator,
+                                         dynamic const> {
+  using Super = detail::IteratorAdaptor<
+      dynamic::const_key_iterator,
+      dynamic::ObjectImpl::const_iterator,
+      dynamic const>;
+  /* implicit */ const_key_iterator(dynamic::ObjectImpl::const_iterator b)
+      : Super(b) {}
 
   using object_type = dynamic::ObjectImpl const;
 
- private:
   dynamic const& dereference() const {
-    return base_reference()->first;
+    return base()->first;
   }
-  friend class boost::iterator_core_access;
 };
 
-struct dynamic::const_value_iterator
-  : boost::iterator_adaptor<dynamic::const_value_iterator,
-                            dynamic::ObjectImpl::const_iterator,
-                            dynamic const> {
-  /* implicit */ const_value_iterator(base_type b) : iterator_adaptor_(b) { }
-  /* implicit */ const_value_iterator(value_iterator i)
-      : iterator_adaptor_(i.base()) {}
+struct dynamic::const_value_iterator : detail::IteratorAdaptor<
+                                           dynamic::const_value_iterator,
+                                           dynamic::ObjectImpl::const_iterator,
+                                           dynamic const> {
+  using Super = detail::IteratorAdaptor<
+      dynamic::const_value_iterator,
+      dynamic::ObjectImpl::const_iterator,
+      dynamic const>;
+  /* implicit */ const_value_iterator(dynamic::ObjectImpl::const_iterator b)
+      : Super(b) {}
+  /* implicit */ const_value_iterator(value_iterator i) : Super(i.base()) {}
   /* implicit */ const_value_iterator(dynamic::ObjectImpl::iterator i)
-      : iterator_adaptor_(i) {}
+      : Super(i) {}
 
   using object_type = dynamic::ObjectImpl const;
 
- private:
   dynamic const& dereference() const {
-    return base_reference()->second;
+    return base()->second;
   }
-  friend class boost::iterator_core_access;
 };
 
 //////////////////////////////////////////////////////////////////////
-- 
2.26.2