Browse Source

chore: update clang-format

Sam Jaffe 2 years ago
parent
commit
b9c86f03a3

+ 1 - 1
.clang-format

@@ -75,7 +75,7 @@ KeepEmptyLinesAtTheStartOfBlocks: true
 MacroBlockBegin: ''
 MacroBlockEnd:   ''
 MaxEmptyLinesToKeep: 1
-NamespaceIndentation: All
+NamespaceIndentation: Inner
 ObjCBlockIndentWidth: 2
 ObjCSpaceAfterProperty: false
 ObjCSpaceBeforeProtocolList: true

+ 6 - 6
include/iterator/detail/arrow_proxy.h

@@ -4,11 +4,11 @@
 #pragma once
 
 namespace iterator::detail {
-  template <typename Reference> struct arrow_proxy {
-    arrow_proxy(Reference r) : r(std::move(r)) {}
-    Reference r;
-    Reference * operator->() { return std::addressof(r); }
-  };
+template <typename Reference> struct arrow_proxy {
+  arrow_proxy(Reference r) : r(std::move(r)) {}
+  Reference r;
+  Reference * operator->() { return std::addressof(r); }
+};
 
-  template <typename R> arrow_proxy(R r) -> arrow_proxy<R>;
+template <typename R> arrow_proxy(R r) -> arrow_proxy<R>;
 }

+ 43 - 44
include/iterator/detail/recursive_traits.h

@@ -5,48 +5,47 @@
 #include "traits.h"
 
 namespace iterator::recursive {
-  // Type deduction guides for constructing recursive iterators.
-  enum class recursion_type { END, THRU, ASSOC };
-
-  // Helpers for condensing type deductions
-  template <typename It>
-  using value = decltype(std::begin(*std::declval<It>()));
-
-  template <typename It>
-  using mapped = decltype(std::begin(std::declval<It>()->second));
-
-  template <typename T> using val_key_t = typename T::value_type::first_type;
-
-  // Type trait to identify value_type ~~ std::pair<K const, V>, which is
-  // a safe bet towards 'this is an associative container type'
-  template <typename T, typename = void>
-  struct is_associative : std::false_type {};
-  template <typename T>
-  struct is_associative<T, std::enable_if_t<std::is_const_v<val_key_t<T>>>>
-      : std::true_type {};
-
-  template <typename T, typename = void> struct typeclass_t {
-    static constexpr recursion_type const value{recursion_type::END};
-  };
-
-  template <typename T> struct is_string_iter : std::false_type {};
-  template <> struct is_string_iter<std::string::iterator> : std::true_type {};
-  template <>
-  struct is_string_iter<std::string::const_iterator> : std::true_type {};
-
-  template <typename T> constexpr bool is_string_iter_v = is_string_iter<T>{};
-
-  template <typename T>
-  struct typeclass_t<T, std::enable_if_t<!is_string_iter_v<value<T>>>> {
-    constexpr static recursion_type value{recursion_type::THRU};
-  };
-
-  template <typename T>
-  struct typeclass_t<T, std::enable_if_t<is_string_iter_v<value<T>>>> {
-    constexpr static recursion_type value{recursion_type::END};
-  };
-
-  template <typename T> struct typeclass_t<T, detail::void_t<mapped<T>>> {
-    constexpr static recursion_type value{recursion_type::ASSOC};
-  };
+// Type deduction guides for constructing recursive iterators.
+enum class recursion_type { END, THRU, ASSOC };
+
+// Helpers for condensing type deductions
+template <typename It> using value = decltype(std::begin(*std::declval<It>()));
+
+template <typename It>
+using mapped = decltype(std::begin(std::declval<It>()->second));
+
+template <typename T> using val_key_t = typename T::value_type::first_type;
+
+// Type trait to identify value_type ~~ std::pair<K const, V>, which is
+// a safe bet towards 'this is an associative container type'
+template <typename T, typename = void>
+struct is_associative : std::false_type {};
+template <typename T>
+struct is_associative<T, std::enable_if_t<std::is_const_v<val_key_t<T>>>>
+    : std::true_type {};
+
+template <typename T, typename = void> struct typeclass_t {
+  static constexpr recursion_type const value{recursion_type::END};
+};
+
+template <typename T> struct is_string_iter : std::false_type {};
+template <> struct is_string_iter<std::string::iterator> : std::true_type {};
+template <>
+struct is_string_iter<std::string::const_iterator> : std::true_type {};
+
+template <typename T> constexpr bool is_string_iter_v = is_string_iter<T>{};
+
+template <typename T>
+struct typeclass_t<T, std::enable_if_t<!is_string_iter_v<value<T>>>> {
+  constexpr static recursion_type value{recursion_type::THRU};
+};
+
+template <typename T>
+struct typeclass_t<T, std::enable_if_t<is_string_iter_v<value<T>>>> {
+  constexpr static recursion_type value{recursion_type::END};
+};
+
+template <typename T> struct typeclass_t<T, detail::void_t<mapped<T>>> {
+  constexpr static recursion_type value{recursion_type::ASSOC};
+};
 }

+ 18 - 18
include/iterator/detail/traits.h

@@ -4,25 +4,25 @@
 #define exists(expr) void_t<decltype(expr)>
 
 namespace iterator::detail {
-  template <typename> using void_t = void;
+template <typename> using void_t = void;
 
-  template <typename T, typename = void> struct reference_helper {
-    using type = decltype(*std::declval<T>());
-  };
-  template <typename T>
-  struct reference_helper<T, void_t<typename T::reference>> {
-    using type = typename T::reference;
-  };
+template <typename T, typename = void> struct reference_helper {
+  using type = decltype(*std::declval<T>());
+};
+template <typename T>
+struct reference_helper<T, void_t<typename T::reference>> {
+  using type = typename T::reference;
+};
 
-  template <typename T, typename = void> struct value_type_helper {
-    using reference = typename reference_helper<T>::type;
-    using type = std::remove_cv_t<std::remove_reference_t<reference>>;
-  };
-  template <typename T>
-  struct value_type_helper<T, void_t<typename T::value_type>> {
-    using type = typename T::value_type;
-  };
+template <typename T, typename = void> struct value_type_helper {
+  using reference = typename reference_helper<T>::type;
+  using type = std::remove_cv_t<std::remove_reference_t<reference>>;
+};
+template <typename T>
+struct value_type_helper<T, void_t<typename T::value_type>> {
+  using type = typename T::value_type;
+};
 
-  template <typename T> using value_type = typename value_type_helper<T>::type;
-  template <typename T> using reference = typename reference_helper<T>::type;
+template <typename T> using value_type = typename value_type_helper<T>::type;
+template <typename T> using reference = typename reference_helper<T>::type;
 }

+ 37 - 37
include/iterator/end_aware_iterator.hpp

@@ -12,43 +12,43 @@
 #include "facade.h"
 
 namespace iterator {
-  /**
-   * @class end_aware_iterator
-   * @brief An iterator that keeps track of the relative end of the range.
-   *
-   * @tparam It The underlying iterator type
-   */
-  template <typename It>
-  class end_aware_iterator : public facade<end_aware_iterator<It>> {
-  public:
-    using value_type = typename It::value_type;
-    struct sentinel_type {};
-    static constexpr sentinel_type sentinel;
-
-  public:
-    end_aware_iterator() = default;
-    end_aware_iterator(It it, It end) : curr_(it), end_(end) {}
-    end_aware_iterator(It end) : curr_(end), end_(end) {}
-
-    template <typename I>
-    end_aware_iterator(end_aware_iterator<I> const & other)
-        : curr_(other.curr_), end_(other.end_) {}
-
-    decltype(auto) dereference() const { return *curr_; }
-    void increment() { ++curr_; }
-    bool at_end() const { return curr_ == end_; }
-    bool equal_to(end_aware_iterator const & other) const {
-      // TODO: Fix this clause
-      return (at_end() && other.at_end()) || curr_ == other.curr_;
-    }
-
-  private:
-    template <typename O> friend class end_aware_iterator;
-    It curr_, end_;
-  };
-
-  template <typename It> end_aware_iterator(It) -> end_aware_iterator<It>;
-  template <typename It> end_aware_iterator(It, It) -> end_aware_iterator<It>;
+/**
+ * @class end_aware_iterator
+ * @brief An iterator that keeps track of the relative end of the range.
+ *
+ * @tparam It The underlying iterator type
+ */
+template <typename It>
+class end_aware_iterator : public facade<end_aware_iterator<It>> {
+public:
+  using value_type = typename It::value_type;
+  struct sentinel_type {};
+  static constexpr sentinel_type sentinel;
+
+public:
+  end_aware_iterator() = default;
+  end_aware_iterator(It it, It end) : curr_(it), end_(end) {}
+  end_aware_iterator(It end) : curr_(end), end_(end) {}
+
+  template <typename I>
+  end_aware_iterator(end_aware_iterator<I> const & other)
+      : curr_(other.curr_), end_(other.end_) {}
+
+  decltype(auto) dereference() const { return *curr_; }
+  void increment() { ++curr_; }
+  bool at_end() const { return curr_ == end_; }
+  bool equal_to(end_aware_iterator const & other) const {
+    // TODO: Fix this clause
+    return (at_end() && other.at_end()) || curr_ == other.curr_;
+  }
+
+private:
+  template <typename O> friend class end_aware_iterator;
+  It curr_, end_;
+};
+
+template <typename It> end_aware_iterator(It) -> end_aware_iterator<It>;
+template <typename It> end_aware_iterator(It, It) -> end_aware_iterator<It>;
 }
 
 MAKE_ITERATOR_FACADE_TYPEDEFS_T(::iterator::end_aware_iterator);

+ 215 - 217
include/iterator/facade.h

@@ -7,232 +7,230 @@
 #include "detail/traits.h"
 
 namespace iterator::detail {
-  template <typename, typename = void> struct has_equal_to : std::false_type {};
-  template <typename T>
-  struct has_equal_to<T, exists(_val(T).equal_to(_val(T)))> : std::true_type {};
-
-  template <typename, typename = void>
-  struct has_distance_to : std::false_type {};
-  template <typename T>
-  struct has_distance_to<T, exists(_val(T).distance_to(_val(T)))>
-      : std::true_type {};
-
-  template <typename, typename = void>
-  struct is_advanceable_iterator : std::false_type {};
-  template <typename T>
-  struct is_advanceable_iterator<T, exists(_val(T).advance({}))>
-      : std::true_type {};
-
-  template <typename, typename = void>
-  struct is_single_pass_iterator : std::false_type {};
-  template <typename T>
-  struct is_single_pass_iterator<T, void_t<typename T::single_pass_iterator>>
-      : std::true_type {};
-
-  template <typename, typename = void>
-  struct has_increment : std::false_type {};
-  template <typename T>
-  struct has_increment<T, exists(_val(T).increment())> : std::true_type {};
-
-  template <typename, typename = void>
-  struct has_decrement : std::false_type {};
-  template <typename T>
-  struct has_decrement<T, exists(_val(T).decrement())> : std::true_type {};
-
-  template <typename, typename = void> struct distance_to {
-    using type = std::ptrdiff_t;
-  };
-
-  template <typename T>
-  struct distance_to<T, std::enable_if_t<has_distance_to<T>{}>> {
-    using type = decltype(_val(T).distance_to(_val(T)));
-  };
-
-  template <typename, typename = void> struct sentinal_type {
-    using type = void;
-  };
-
-  template <typename T>
-  struct sentinal_type<T, void_t<typename T::sentinal_type>> {
-    using type = typename T::sentinal_type;
-  };
-
-  template <typename T> using distance_to_t = typename distance_to<T>::type;
-  template <typename T> using sentinal_type_t = typename sentinal_type<T>::type;
-  template <typename T> constexpr bool has_equal_to_v = has_equal_to<T>{};
-  template <typename T> constexpr bool has_distance_to_v = has_distance_to<T>{};
-  template <typename T> constexpr bool has_increment_v = has_increment<T>{};
-  template <typename T> constexpr bool has_decrement_v = has_decrement<T>{};
-  template <typename T>
-  constexpr bool is_advanceable_iterator_v = is_advanceable_iterator<T>{};
-
-  template <typename T>
-  constexpr bool is_random_access_iterator_v =
-      has_distance_to_v<T> && is_advanceable_iterator_v<T>;
-  template <typename T>
-  constexpr bool is_bidirectional_iterator_v =
-      has_decrement_v<T> && has_increment_v<T> && has_equal_to_v<T>;
-  template <typename T>
-  constexpr bool is_single_pass_iterator_v = is_single_pass_iterator<T>{};
-
-  template <typename T>
-  using iterator_category_t = std::conditional_t<
-      is_random_access_iterator_v<T>, std::random_access_iterator_tag,
-      std::conditional_t<is_bidirectional_iterator_v<T>,
-                         std::bidirectional_iterator_tag,
-                         std::conditional_t<is_single_pass_iterator_v<T>,
-                                            std::input_iterator_tag,
-                                            std::forward_iterator_tag>>>;
-}
-
-#undef _val
-#undef exists
+template <typename, typename = void> struct has_equal_to : std::false_type {};
+template <typename T>
+struct has_equal_to<T, exists(_val(T).equal_to(_val(T)))> : std::true_type {};
+
+template <typename, typename = void>
+struct has_distance_to : std::false_type {};
+template <typename T>
+struct has_distance_to<T, exists(_val(T).distance_to(_val(T)))>
+    : std::true_type {};
+
+template <typename, typename = void>
+struct is_advanceable_iterator : std::false_type {};
+template <typename T>
+struct is_advanceable_iterator<T, exists(_val(T).advance({}))>
+    : std::true_type {};
+
+template <typename, typename = void>
+struct is_single_pass_iterator : std::false_type {};
+template <typename T>
+struct is_single_pass_iterator<T, void_t<typename T::single_pass_iterator>>
+    : std::true_type {};
+
+template <typename, typename = void> struct has_increment : std::false_type {};
+template <typename T>
+struct has_increment<T, exists(_val(T).increment())> : std::true_type {};
+
+template <typename, typename = void> struct has_decrement : std::false_type {};
+template <typename T>
+struct has_decrement<T, exists(_val(T).decrement())> : std::true_type {};
+
+template <typename, typename = void> struct distance_to {
+  using type = std::ptrdiff_t;
+};
 
-namespace iterator {
-  template <typename D, typename T>
-  using difference_type_arg_t =
-      std::enable_if_t<std::is_convertible_v<D, detail::distance_to_t<T>>>;
-
-  template <typename D, typename T>
-  using sentinel_type_arg_t =
-      std::enable_if_t<std::is_same_v<D, detail::sentinal_type_t<T>>>;
-
-  template <typename self_type> class facade {
-  public:
-    decltype(auto) operator*() const { return self().dereference(); }
-
-    decltype(auto) operator->() const {
-      if constexpr (std::is_reference<decltype(**this)>{}) {
-        return std::addressof(**this);
-      } else {
-        return detail::arrow_proxy{**this};
-      }
-    }
+template <typename T>
+struct distance_to<T, std::enable_if_t<has_distance_to<T>{}>> {
+  using type = decltype(_val(T).distance_to(_val(T)));
+};
 
-    template <typename D, typename = difference_type_arg_t<D, self_type>>
-    decltype(auto) operator[](D off) const {
-      return *(self() + off);
-    }
+template <typename, typename = void> struct sentinal_type {
+  using type = void;
+};
 
-    self_type & operator++() {
-      if constexpr (detail::is_advanceable_iterator_v<self_type>) {
-        self() += 1;
-      } else {
-        self().increment();
-      }
-      return self();
-    }
+template <typename T>
+struct sentinal_type<T, void_t<typename T::sentinal_type>> {
+  using type = typename T::sentinal_type;
+};
 
-    auto operator++(int) {
-      if constexpr (detail::is_single_pass_iterator_v<self_type>) {
-        ++*this;
-      } else {
-        auto tmp = self();
-        ++*this;
-        return tmp;
-      }
-    }
+template <typename T> using distance_to_t = typename distance_to<T>::type;
+template <typename T> using sentinal_type_t = typename sentinal_type<T>::type;
+template <typename T> constexpr bool has_equal_to_v = has_equal_to<T>{};
+template <typename T> constexpr bool has_distance_to_v = has_distance_to<T>{};
+template <typename T> constexpr bool has_increment_v = has_increment<T>{};
+template <typename T> constexpr bool has_decrement_v = has_decrement<T>{};
+template <typename T>
+constexpr bool is_advanceable_iterator_v = is_advanceable_iterator<T>{};
+
+template <typename T>
+constexpr bool is_random_access_iterator_v =
+    has_distance_to_v<T> && is_advanceable_iterator_v<T>;
+template <typename T>
+constexpr bool is_bidirectional_iterator_v =
+    has_decrement_v<T> && has_increment_v<T> && has_equal_to_v<T>;
+template <typename T>
+constexpr bool is_single_pass_iterator_v = is_single_pass_iterator<T>{};
+
+template <typename T>
+using iterator_category_t = std::conditional_t<
+    is_random_access_iterator_v<T>, std::random_access_iterator_tag,
+    std::conditional_t<is_bidirectional_iterator_v<T>,
+                       std::bidirectional_iterator_tag,
+                       std::conditional_t<is_single_pass_iterator_v<T>,
+                                          std::input_iterator_tag,
+                                          std::forward_iterator_tag>>>;
+}
 
-    self_type & operator--() {
-      if constexpr (detail::is_advanceable_iterator_v<self_type>) {
-        self() -= 1;
-      } else {
-        self().decrement();
-      }
-      return self();
-    }
+#undef _val
+#undef exists
 
-    self_type operator--(int) {
+namespace iterator {
+template <typename D, typename T>
+using difference_type_arg_t =
+    std::enable_if_t<std::is_convertible_v<D, detail::distance_to_t<T>>>;
+
+template <typename D, typename T>
+using sentinel_type_arg_t =
+    std::enable_if_t<std::is_same_v<D, detail::sentinal_type_t<T>>>;
+
+template <typename self_type> class facade {
+public:
+  decltype(auto) operator*() const { return self().dereference(); }
+
+  decltype(auto) operator->() const {
+    if constexpr (std::is_reference<decltype(**this)>{}) {
+      return std::addressof(**this);
+    } else {
+      return detail::arrow_proxy{**this};
+    }
+  }
+
+  template <typename D, typename = difference_type_arg_t<D, self_type>>
+  decltype(auto) operator[](D off) const {
+    return *(self() + off);
+  }
+
+  self_type & operator++() {
+    if constexpr (detail::is_advanceable_iterator_v<self_type>) {
+      self() += 1;
+    } else {
+      self().increment();
+    }
+    return self();
+  }
+
+  auto operator++(int) {
+    if constexpr (detail::is_single_pass_iterator_v<self_type>) {
+      ++*this;
+    } else {
       auto tmp = self();
-      --*this;
+      ++*this;
       return tmp;
     }
-
-    template <typename D, typename = difference_type_arg_t<D, self_type>>
-    friend self_type & operator+=(self_type & self, D off) {
-      static_assert(detail::is_advanceable_iterator_v<self_type>,
-                    "must be advancable");
-      self.advance(off);
-      return self;
-    }
-
-    template <typename D, typename = difference_type_arg_t<D, self_type>>
-    friend self_type & operator-=(self_type & self, D off) {
-      static_assert(detail::is_advanceable_iterator_v<self_type>,
-                    "must be advancable");
-      self.advance(-off);
-      return self;
-    }
-
-    template <typename D, typename = difference_type_arg_t<D, self_type>>
-    friend auto operator+(self_type self, D off) {
-      static_assert(detail::is_advanceable_iterator_v<self_type>,
-                    "must be advancable");
-      return self += off;
-    }
-
-    template <typename D, typename = difference_type_arg_t<D, self_type>>
-    friend auto operator+(D off, self_type self) {
-      static_assert(detail::is_advanceable_iterator_v<self_type>,
-                    "must be advancable");
-      return self += off;
-    }
-
-    template <typename D, typename = difference_type_arg_t<D, self_type>>
-    friend auto operator-(self_type self, D off) {
-      static_assert(detail::is_advanceable_iterator_v<self_type>,
-                    "must be advancable");
-      return self -= off;
-    }
-
-    friend auto operator-(self_type const & left, self_type const & right) {
-      return right.distance_to(left);
-    }
-
-    friend bool operator==(self_type const & left, self_type const & right) {
-      if constexpr (detail::has_distance_to_v<self_type>) {
-        return (left - right) == 0;
-      } else {
-        return left.equal_to(right);
-      }
-    }
-
-    template <typename S, typename = sentinel_type_arg_t<S, self_type>>
-    friend auto operator==(self_type self, S) {
-      return self.at_end();
-    }
-
-    template <typename S, typename = sentinel_type_arg_t<S, self_type>>
-    friend auto operator!=(self_type self, S) {
-      return !self.at_end();
-    }
-
-    friend bool operator!=(self_type const & left, self_type const & right) {
-      return !(left == right);
-    }
-
-    friend bool operator<(self_type const & left, self_type const & right) {
-      return (left - right) < 0;
-    }
-
-    friend bool operator<=(self_type const & left, self_type const & right) {
-      return (left - right) <= 0;
-    }
-
-    friend bool operator>(self_type const & left, self_type const & right) {
-      return (left - right) > 0;
-    }
-
-    friend bool operator>=(self_type const & left, self_type const & right) {
-      return (left - right) >= 0;
-    }
-
-  private:
-    self_type & self() { return *static_cast<self_type *>(this); }
-    self_type const & self() const {
-      return *static_cast<self_type const *>(this);
-    }
-  };
+  }
+
+  self_type & operator--() {
+    if constexpr (detail::is_advanceable_iterator_v<self_type>) {
+      self() -= 1;
+    } else {
+      self().decrement();
+    }
+    return self();
+  }
+
+  self_type operator--(int) {
+    auto tmp = self();
+    --*this;
+    return tmp;
+  }
+
+  template <typename D, typename = difference_type_arg_t<D, self_type>>
+  friend self_type & operator+=(self_type & self, D off) {
+    static_assert(detail::is_advanceable_iterator_v<self_type>,
+                  "must be advancable");
+    self.advance(off);
+    return self;
+  }
+
+  template <typename D, typename = difference_type_arg_t<D, self_type>>
+  friend self_type & operator-=(self_type & self, D off) {
+    static_assert(detail::is_advanceable_iterator_v<self_type>,
+                  "must be advancable");
+    self.advance(-off);
+    return self;
+  }
+
+  template <typename D, typename = difference_type_arg_t<D, self_type>>
+  friend auto operator+(self_type self, D off) {
+    static_assert(detail::is_advanceable_iterator_v<self_type>,
+                  "must be advancable");
+    return self += off;
+  }
+
+  template <typename D, typename = difference_type_arg_t<D, self_type>>
+  friend auto operator+(D off, self_type self) {
+    static_assert(detail::is_advanceable_iterator_v<self_type>,
+                  "must be advancable");
+    return self += off;
+  }
+
+  template <typename D, typename = difference_type_arg_t<D, self_type>>
+  friend auto operator-(self_type self, D off) {
+    static_assert(detail::is_advanceable_iterator_v<self_type>,
+                  "must be advancable");
+    return self -= off;
+  }
+
+  friend auto operator-(self_type const & left, self_type const & right) {
+    return right.distance_to(left);
+  }
+
+  friend bool operator==(self_type const & left, self_type const & right) {
+    if constexpr (detail::has_distance_to_v<self_type>) {
+      return (left - right) == 0;
+    } else {
+      return left.equal_to(right);
+    }
+  }
+
+  template <typename S, typename = sentinel_type_arg_t<S, self_type>>
+  friend auto operator==(self_type self, S) {
+    return self.at_end();
+  }
+
+  template <typename S, typename = sentinel_type_arg_t<S, self_type>>
+  friend auto operator!=(self_type self, S) {
+    return !self.at_end();
+  }
+
+  friend bool operator!=(self_type const & left, self_type const & right) {
+    return !(left == right);
+  }
+
+  friend bool operator<(self_type const & left, self_type const & right) {
+    return (left - right) < 0;
+  }
+
+  friend bool operator<=(self_type const & left, self_type const & right) {
+    return (left - right) <= 0;
+  }
+
+  friend bool operator>(self_type const & left, self_type const & right) {
+    return (left - right) > 0;
+  }
+
+  friend bool operator>=(self_type const & left, self_type const & right) {
+    return (left - right) >= 0;
+  }
+
+private:
+  self_type & self() { return *static_cast<self_type *>(this); }
+  self_type const & self() const {
+    return *static_cast<self_type const *>(this);
+  }
+};
 }
 
 // In C++20, a concept/requires could be used to eschew the need for the below

+ 40 - 40
include/iterator/filter_iterator.hpp

@@ -15,54 +15,54 @@
 template <typename C> using iter = decltype(std::begin(std::declval<C>()));
 
 namespace iterator {
-  template <typename Iter>
-  class filter_iterator : public facade<filter_iterator<Iter>> {
-  public:
-    using super = end_aware_iterator<Iter>;
-    using reference = decltype(*std::declval<super>());
-    using value_type = std::remove_cv_t<std::remove_reference_t<reference>>;
-    using difference_type = std::ptrdiff_t;
-    using iterator_category = std::forward_iterator_tag;
-    using predicate_t = std::function<bool(value_type const &)>;
+template <typename Iter>
+class filter_iterator : public facade<filter_iterator<Iter>> {
+public:
+  using super = end_aware_iterator<Iter>;
+  using reference = decltype(*std::declval<super>());
+  using value_type = std::remove_cv_t<std::remove_reference_t<reference>>;
+  using difference_type = std::ptrdiff_t;
+  using iterator_category = std::forward_iterator_tag;
+  using predicate_t = std::function<bool(value_type const &)>;
 
-  public:
-    filter_iterator() = default;
+public:
+  filter_iterator() = default;
 
-    template <typename C>
-    filter_iterator(predicate_t pred, C && c)
-        : filter_iterator(std::move(pred), std::begin(c), std::end(c)) {}
+  template <typename C>
+  filter_iterator(predicate_t pred, C && c)
+      : filter_iterator(std::move(pred), std::begin(c), std::end(c)) {}
 
-    filter_iterator(predicate_t pred, Iter curr, Iter end)
-        : filter_iterator(std::move(pred), end_aware_iterator(curr, end)) {}
+  filter_iterator(predicate_t pred, Iter curr, Iter end)
+      : filter_iterator(std::move(pred), end_aware_iterator(curr, end)) {}
 
-    filter_iterator(predicate_t pred, end_aware_iterator<Iter> curr)
-        : base_(curr), pred_(std::move(pred)) {
-      if (should_advance()) { increment(); }
-    }
+  filter_iterator(predicate_t pred, end_aware_iterator<Iter> curr)
+      : base_(curr), pred_(std::move(pred)) {
+    if (should_advance()) { increment(); }
+  }
 
-    decltype(auto) dereference() const { return base_.dereference(); }
-    void increment() {
-      do {
-        base_.increment();
-      } while (should_advance());
-    }
-    bool equal_to(filter_iterator const & other) const {
-      return base_ == other.base_;
-    }
+  decltype(auto) dereference() const { return base_.dereference(); }
+  void increment() {
+    do {
+      base_.increment();
+    } while (should_advance());
+  }
+  bool equal_to(filter_iterator const & other) const {
+    return base_ == other.base_;
+  }
 
-  public:
-    bool should_advance() { return !base_.at_end() && !pred_(dereference()); }
+public:
+  bool should_advance() { return !base_.at_end() && !pred_(dereference()); }
 
-    end_aware_iterator<Iter> base_;
-    predicate_t pred_;
-  };
+  end_aware_iterator<Iter> base_;
+  predicate_t pred_;
+};
 
-  template <typename P, typename C>
-  filter_iterator(P, C &&) -> filter_iterator<iter<C>>;
-  template <typename P, typename It>
-  filter_iterator(P, end_aware_iterator<It>) -> filter_iterator<It>;
-  template <typename P, typename It>
-  filter_iterator(P, It, It) -> filter_iterator<It>;
+template <typename P, typename C>
+filter_iterator(P, C &&) -> filter_iterator<iter<C>>;
+template <typename P, typename It>
+filter_iterator(P, end_aware_iterator<It>) -> filter_iterator<It>;
+template <typename P, typename It>
+filter_iterator(P, It, It) -> filter_iterator<It>;
 }
 
 MAKE_ITERATOR_FACADE_TYPEDEFS_T(::iterator::filter_iterator);

+ 40 - 40
include/iterator/indexed_iterator.hpp

@@ -12,46 +12,46 @@
 #include "iterator/facade.h"
 
 namespace iterator {
-  template <typename It>
-  class indexed_iterator : public facade<indexed_iterator<It>> {
-  public:
-    using reference =
-        std::pair<size_t, typename std::iterator_traits<It>::reference>;
-    using difference_type = typename std::iterator_traits<It>::difference_type;
-
-  public:
-    indexed_iterator() = default;
-    indexed_iterator(It base) : base_(base) {}
-    indexed_iterator(It base, size_t idx) : base_(base), index_(idx) {}
-
-    template <typename O>
-    indexed_iterator(indexed_iterator<O> const & oiter)
-        : base_(oiter.base_), index_(oiter.index_) {}
-
-    reference dereference() const { return {index_, *base_}; }
-
-    void advance(difference_type off) {
-      base_ += off;
-      index_ += off;
-    }
-
-    // SFINAE means that if Iterator is not random access, then this still works
-    // TODO: Investigate using _index for comparisons instead of _base
-    bool equal_to(indexed_iterator const & other) const {
-      return base_ == other.base_;
-    }
-    difference_type distance_to(indexed_iterator const & other) const {
-      return other.base_ - base_;
-    }
-
-  private:
-    template <typename O> friend class indexed_iterator;
-    It base_;
-    size_t index_{0};
-  };
-
-  template <typename It> indexed_iterator(It) -> indexed_iterator<It>;
-  template <typename It> indexed_iterator(It, size_t) -> indexed_iterator<It>;
+template <typename It>
+class indexed_iterator : public facade<indexed_iterator<It>> {
+public:
+  using reference =
+      std::pair<size_t, typename std::iterator_traits<It>::reference>;
+  using difference_type = typename std::iterator_traits<It>::difference_type;
+
+public:
+  indexed_iterator() = default;
+  indexed_iterator(It base) : base_(base) {}
+  indexed_iterator(It base, size_t idx) : base_(base), index_(idx) {}
+
+  template <typename O>
+  indexed_iterator(indexed_iterator<O> const & oiter)
+      : base_(oiter.base_), index_(oiter.index_) {}
+
+  reference dereference() const { return {index_, *base_}; }
+
+  void advance(difference_type off) {
+    base_ += off;
+    index_ += off;
+  }
+
+  // SFINAE means that if Iterator is not random access, then this still works
+  // TODO: Investigate using _index for comparisons instead of _base
+  bool equal_to(indexed_iterator const & other) const {
+    return base_ == other.base_;
+  }
+  difference_type distance_to(indexed_iterator const & other) const {
+    return other.base_ - base_;
+  }
+
+private:
+  template <typename O> friend class indexed_iterator;
+  It base_;
+  size_t index_{0};
+};
+
+template <typename It> indexed_iterator(It) -> indexed_iterator<It>;
+template <typename It> indexed_iterator(It, size_t) -> indexed_iterator<It>;
 }
 
 MAKE_ITERATOR_FACADE_TYPEDEFS_T(::iterator::indexed_iterator);

+ 11 - 11
include/iterator/iterator_fwd.hpp

@@ -10,19 +10,19 @@
 #include <cstdlib>
 
 namespace iterator::recursive {
-  struct unbounded;
-  template <size_t N, size_t I = 1> struct bounded;
-  template <typename Iter, typename = unbounded> class rimpl;
+struct unbounded;
+template <size_t N, size_t I = 1> struct bounded;
+template <typename Iter, typename = unbounded> class rimpl;
 }
 
 namespace iterator {
-  template <typename Iter> class end_aware_iterator;
-  template <typename Iter> class filter_iterator;
-  template <typename Iter> class joining_iterator;
-  template <typename Iter> class unkeyed_iterator;
-  template <typename... Iters> class zip_iterator;
+template <typename Iter> class end_aware_iterator;
+template <typename Iter> class filter_iterator;
+template <typename Iter> class joining_iterator;
+template <typename Iter> class unkeyed_iterator;
+template <typename... Iters> class zip_iterator;
 
-  template <typename Iter> using recursive_iterator = recursive::rimpl<Iter>;
-  template <typename Iter, std::size_t N>
-  using recursive_iterator_n = recursive::rimpl<Iter, recursive::bounded<N>>;
+template <typename Iter> using recursive_iterator = recursive::rimpl<Iter>;
+template <typename Iter, std::size_t N>
+using recursive_iterator_n = recursive::rimpl<Iter, recursive::bounded<N>>;
 }

+ 56 - 56
include/iterator/join_iterator.hpp

@@ -15,68 +15,68 @@
 #include "facade.h"
 
 namespace iterator {
-  template <typename MetaIterator>
-  class joining_iterator : public facade<joining_iterator<MetaIterator>> {
-  public:
-    using join_iter = MetaIterator;
-    using joinable_type = typename join_iter::value_type;
-    using iter_type = decltype(std::begin(*std::declval<join_iter>()));
-
-    using value_type = typename std::iterator_traits<iter_type>::value_type;
-    using reference = typename std::iterator_traits<iter_type>::reference;
-    using pointer = typename std::iterator_traits<iter_type>::pointer;
-    using difference_type =
-        typename std::iterator_traits<iter_type>::difference_type;
-    using iterator_category = std::forward_iterator_tag;
-
-  public:
-    explicit joining_iterator() = default;
-
-    template <typename I>
-    joining_iterator(joining_iterator<I> const & other)
-        : joiner_(other.join_iterator()), iterator_(other.element_iterator()) {}
-
-    joining_iterator(end_aware_iterator<join_iter> join)
-        : joining_iterator(join, {}, true) {}
-    joining_iterator(end_aware_iterator<join_iter> join,
-                     end_aware_iterator<iter_type> elem, bool update = false)
-        : joiner_(join), iterator_(elem) {
-      if (update) { update_iterator(); }
+template <typename MetaIterator>
+class joining_iterator : public facade<joining_iterator<MetaIterator>> {
+public:
+  using join_iter = MetaIterator;
+  using joinable_type = typename join_iter::value_type;
+  using iter_type = decltype(std::begin(*std::declval<join_iter>()));
+
+  using value_type = typename std::iterator_traits<iter_type>::value_type;
+  using reference = typename std::iterator_traits<iter_type>::reference;
+  using pointer = typename std::iterator_traits<iter_type>::pointer;
+  using difference_type =
+      typename std::iterator_traits<iter_type>::difference_type;
+  using iterator_category = std::forward_iterator_tag;
+
+public:
+  explicit joining_iterator() = default;
+
+  template <typename I>
+  joining_iterator(joining_iterator<I> const & other)
+      : joiner_(other.join_iterator()), iterator_(other.element_iterator()) {}
+
+  joining_iterator(end_aware_iterator<join_iter> join)
+      : joining_iterator(join, {}, true) {}
+  joining_iterator(end_aware_iterator<join_iter> join,
+                   end_aware_iterator<iter_type> elem, bool update = false)
+      : joiner_(join), iterator_(elem) {
+    if (update) { update_iterator(); }
+  }
+
+  void increment() {
+    if ((iterator_++).at_end()) {
+      ++joiner_;
+      update_iterator();
     }
+  }
 
-    void increment() {
-      if ((iterator_++).at_end()) {
-        ++joiner_;
-        update_iterator();
-      }
-    }
-
-    decltype(auto) dereference() const { return *iterator_; }
+  decltype(auto) dereference() const { return *iterator_; }
 
-    bool equal_to(joining_iterator const & other) const {
-      return joiner_ == other.joiner_ && iterator_ == other.iterator_;
-    }
+  bool equal_to(joining_iterator const & other) const {
+    return joiner_ == other.joiner_ && iterator_ == other.iterator_;
+  }
 
-    end_aware_iterator<join_iter> join_iterator() const { return joiner_; }
-    end_aware_iterator<iter_type> element_iterator() const { return iterator_; }
+  end_aware_iterator<join_iter> join_iterator() const { return joiner_; }
+  end_aware_iterator<iter_type> element_iterator() const { return iterator_; }
 
-  private:
-    void update_iterator() {
-      while (!joiner_.at_end() && make_end_aware_iterator(*joiner_).at_end()) {
-        ++joiner_;
-      }
-      if (!joiner_.at_end()) { iterator_ = make_end_aware_iterator(*joiner_); }
+private:
+  void update_iterator() {
+    while (!joiner_.at_end() && make_end_aware_iterator(*joiner_).at_end()) {
+      ++joiner_;
     }
-
-    end_aware_iterator<join_iter> joiner_;
-    end_aware_iterator<iter_type> iterator_;
-  };
-
-  template <typename JI>
-  joining_iterator(end_aware_iterator<JI>) -> joining_iterator<JI>;
-  template <typename JI, typename IT>
-  joining_iterator(end_aware_iterator<JI>, end_aware_iterator<IT>)
-      -> joining_iterator<JI>;
+    if (!joiner_.at_end()) { iterator_ = make_end_aware_iterator(*joiner_); }
+  }
+
+  end_aware_iterator<join_iter> joiner_;
+  end_aware_iterator<iter_type> iterator_;
+};
+
+template <typename JI>
+joining_iterator(end_aware_iterator<JI>) -> joining_iterator<JI>;
+template <typename JI, typename IT>
+joining_iterator(end_aware_iterator<JI>, end_aware_iterator<IT>)
+    -> joining_iterator<JI>;
 }
 
 MAKE_ITERATOR_FACADE_TYPEDEFS_T(::iterator::joining_iterator);

+ 88 - 91
include/iterator/proxy.h

@@ -5,95 +5,92 @@
 #include "facade.h"
 
 namespace iterator {
-  template <typename Iter, typename Self,
-            typename Category =
-                typename std::iterator_traits<Iter>::iterator_category>
-  class proxy;
-
-  template <typename Iter, typename Self>
-  class proxy<Iter, Self, std::input_iterator_tag> : public facade<Self> {
-  public:
-    using single_pass_iterator = void;
-
-  private:
-    Iter impl_;
-
-  public:
-    proxy(Iter impl = {}) : impl_(impl) {}
-    template <typename... Args>
-    proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
-
-    decltype(auto) dereference() const { return *impl_; }
-    void increment() { ++impl_; }
-    bool equal_to(Self const & other) const { return impl_ == other.impl_; }
-
-  protected:
-    auto & impl() const { return impl_; }
-  };
-
-  template <typename Iter, typename Self>
-  class proxy<Iter, Self, std::forward_iterator_tag> : public facade<Self> {
-  private:
-    Iter impl_;
-
-  public:
-    proxy(Iter impl = {}) : impl_(impl) {}
-    template <typename... Args>
-    proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
-
-    decltype(auto) dereference() const { return *impl_; }
-    void increment() { ++impl_; }
-    bool equal_to(Self const & other) const { return impl_ == other.impl_; }
-
-  protected:
-    auto & impl() const { return impl_; }
-  };
-
-  template <typename Iter, typename Self>
-  class proxy<Iter, Self, std::bidirectional_iterator_tag>
-      : public facade<Self> {
-  private:
-    Iter impl_;
-
-  public:
-    proxy(Iter impl = {}) : impl_(impl) {}
-    template <typename... Args>
-    proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
-
-    decltype(auto) dereference() const { return *impl_; }
-    void increment() { ++impl_; }
-    void decrement() { --impl_; }
-    bool equal_to(Self const & other) const { return impl_ == other.impl_; }
-
-  protected:
-    auto & impl() const { return impl_; }
-  };
-
-  template <typename Iter, typename Self>
-  class proxy<Iter, Self, std::random_access_iterator_tag>
-      : public facade<Self> {
-  public:
-    using difference_type =
-        typename std::iterator_traits<Iter>::difference_type;
-
-  private:
-    Iter impl_;
-
-  public:
-    proxy(Iter impl = {}) : impl_(impl) {}
-    template <typename... Args>
-    proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
-
-    decltype(auto) dereference() const { return *impl_; }
-    void advance(difference_type off) { impl_ += off; }
-    // This shouldn't need to be implemented, but for some reason my traits
-    // are not correctly deducing here.
-    bool equal_to(Self const & other) const { return distance_to(other) == 0; }
-    difference_type distance_to(Self const & other) const {
-      return other.impl_ - impl_;
-    }
-
-  protected:
-    auto & impl() const { return impl_; }
-  };
+template <typename Iter, typename Self,
+          typename Category =
+              typename std::iterator_traits<Iter>::iterator_category>
+class proxy;
+
+template <typename Iter, typename Self>
+class proxy<Iter, Self, std::input_iterator_tag> : public facade<Self> {
+public:
+  using single_pass_iterator = void;
+
+private:
+  Iter impl_;
+
+public:
+  proxy(Iter impl = {}) : impl_(impl) {}
+  template <typename... Args>
+  proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
+
+  decltype(auto) dereference() const { return *impl_; }
+  void increment() { ++impl_; }
+  bool equal_to(Self const & other) const { return impl_ == other.impl_; }
+
+protected:
+  auto & impl() const { return impl_; }
+};
+
+template <typename Iter, typename Self>
+class proxy<Iter, Self, std::forward_iterator_tag> : public facade<Self> {
+private:
+  Iter impl_;
+
+public:
+  proxy(Iter impl = {}) : impl_(impl) {}
+  template <typename... Args>
+  proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
+
+  decltype(auto) dereference() const { return *impl_; }
+  void increment() { ++impl_; }
+  bool equal_to(Self const & other) const { return impl_ == other.impl_; }
+
+protected:
+  auto & impl() const { return impl_; }
+};
+
+template <typename Iter, typename Self>
+class proxy<Iter, Self, std::bidirectional_iterator_tag> : public facade<Self> {
+private:
+  Iter impl_;
+
+public:
+  proxy(Iter impl = {}) : impl_(impl) {}
+  template <typename... Args>
+  proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
+
+  decltype(auto) dereference() const { return *impl_; }
+  void increment() { ++impl_; }
+  void decrement() { --impl_; }
+  bool equal_to(Self const & other) const { return impl_ == other.impl_; }
+
+protected:
+  auto & impl() const { return impl_; }
+};
+
+template <typename Iter, typename Self>
+class proxy<Iter, Self, std::random_access_iterator_tag> : public facade<Self> {
+public:
+  using difference_type = typename std::iterator_traits<Iter>::difference_type;
+
+private:
+  Iter impl_;
+
+public:
+  proxy(Iter impl = {}) : impl_(impl) {}
+  template <typename... Args>
+  proxy(Args &&... args) : impl_(std::forward<Args>(args)...) {}
+
+  decltype(auto) dereference() const { return *impl_; }
+  void advance(difference_type off) { impl_ += off; }
+  // This shouldn't need to be implemented, but for some reason my traits
+  // are not correctly deducing here.
+  bool equal_to(Self const & other) const { return distance_to(other) == 0; }
+  difference_type distance_to(Self const & other) const {
+    return other.impl_ - impl_;
+  }
+
+protected:
+  auto & impl() const { return impl_; }
+};
 }

+ 148 - 149
include/iterator/recursive_iterator.hpp

@@ -18,173 +18,172 @@
 #include "facade.h"
 
 namespace iterator::recursive {
-  template <size_t N, size_t I> struct bounded {
-    template <typename It>
-    static constexpr recursion_type const value =
-        I == N ? recursion_type::END : typeclass_t<It>::value;
-    using next = std::conditional_t<I == N, void, bounded<N, I + 1>>;
-    static constexpr size_t size = N;
-  };
-
-  struct unbounded {
-    template <typename It>
-    static constexpr recursion_type const value = typeclass_t<It>::value;
-    using next = unbounded;
-    static constexpr size_t size = std::numeric_limits<size_t>::max();
-  };
-
-  template <typename It, typename Bnd = unbounded,
-            recursion_type = Bnd::template value<It>>
-  struct tuple;
-
-  template <typename It, typename Bnd>
-  struct tuple<It, Bnd, recursion_type::END> {
-    using iter = std::tuple<end_aware_iterator<It>>;
-    decltype(auto) get(It iter) const {
-      if constexpr (is_associative<It>{}) {
-        return std::tie(iter->first, iter->second);
-      } else {
-        return std::tie(*iter);
-      }
-    }
-  };
-
-  template <typename... Ts>
-  using tuple_cat_t = decltype(std::tuple_cat(std::declval<Ts>()...));
-
-  template <typename It, typename Bnd>
-  struct tuple<It, Bnd, recursion_type::THRU> {
-    using next = decltype(std::begin(*std::declval<It>()));
-    using iter = tuple_cat_t<std::tuple<end_aware_iterator<It>>,
-                             typename tuple<next, typename Bnd::next>::iter>;
-    auto get(It) const { return std::make_tuple(); }
-  };
-
-  template <typename It, typename Bnd>
-  struct tuple<It, Bnd, recursion_type::ASSOC> {
-    using next = decltype(std::begin(std::declval<It>()->second));
-    using iter = tuple_cat_t<std::tuple<end_aware_iterator<It>>,
-                             typename tuple<next, typename Bnd::next>::iter>;
-    auto get(It iter) const { return std::tie(iter->first); };
-  };
-
-  /**
-   * @brief An iterator type for nested collections, allowing you to treat it as
-   * a single-layer collection.
-   *
-   * In order to provide a simple interface, if an associative container is used
-   * in the chain, the type returned by operator*() is a tuple. If multiple
-   * associative containers are nested, then the tuple will be of the form
-   * std::tuple<key1, key2, ..., keyN, value>. To avoid copies, and allow
-   * editting of underlying values, the tuple contains references.
-   *
-   * @tparam It The iterator type of the top-level collection.
-   * @tparam Bnd The bounding type, representing how many layers this iterator
-   * is willing to delve in the parent object.
-   */
-  template <typename It, typename Bnd>
-  class rimpl : public facade<rimpl<It, Bnd>> {
-  private:
-    typename tuple<It, Bnd>::iter impl_;
-
-  public:
-    static constexpr size_t size =
-        std::min(std::tuple_size_v<typename tuple<It, Bnd>::iter>, Bnd::size);
-
-    rimpl() = default;
-    rimpl(end_aware_iterator<It> iter) { assign<0>(iter); }
-    template <typename Ot>
-    rimpl(end_aware_iterator<Ot> other)
-        : rimpl(end_aware_iterator<It>(other)) {}
-    template <typename Ot>
-    rimpl(rimpl<Ot, Bnd> other) : rimpl(end_aware_iterator<Ot>(other)) {}
-
-    template <typename T> operator end_aware_iterator<T>() const {
-      return std::get<end_aware_iterator<T>>(impl_);
+template <size_t N, size_t I> struct bounded {
+  template <typename It>
+  static constexpr recursion_type const value =
+      I == N ? recursion_type::END : typeclass_t<It>::value;
+  using next = std::conditional_t<I == N, void, bounded<N, I + 1>>;
+  static constexpr size_t size = N;
+};
+
+struct unbounded {
+  template <typename It>
+  static constexpr recursion_type const value = typeclass_t<It>::value;
+  using next = unbounded;
+  static constexpr size_t size = std::numeric_limits<size_t>::max();
+};
+
+template <typename It, typename Bnd = unbounded,
+          recursion_type = Bnd::template value<It>>
+struct tuple;
+
+template <typename It, typename Bnd>
+struct tuple<It, Bnd, recursion_type::END> {
+  using iter = std::tuple<end_aware_iterator<It>>;
+  decltype(auto) get(It iter) const {
+    if constexpr (is_associative<It>{}) {
+      return std::tie(iter->first, iter->second);
+    } else {
+      return std::tie(*iter);
     }
+  }
+};
+
+template <typename... Ts>
+using tuple_cat_t = decltype(std::tuple_cat(std::declval<Ts>()...));
+
+template <typename It, typename Bnd>
+struct tuple<It, Bnd, recursion_type::THRU> {
+  using next = decltype(std::begin(*std::declval<It>()));
+  using iter = tuple_cat_t<std::tuple<end_aware_iterator<It>>,
+                           typename tuple<next, typename Bnd::next>::iter>;
+  auto get(It) const { return std::make_tuple(); }
+};
+
+template <typename It, typename Bnd>
+struct tuple<It, Bnd, recursion_type::ASSOC> {
+  using next = decltype(std::begin(std::declval<It>()->second));
+  using iter = tuple_cat_t<std::tuple<end_aware_iterator<It>>,
+                           typename tuple<next, typename Bnd::next>::iter>;
+  auto get(It iter) const { return std::tie(iter->first); };
+};
+
+/**
+ * @brief An iterator type for nested collections, allowing you to treat it as
+ * a single-layer collection.
+ *
+ * In order to provide a simple interface, if an associative container is used
+ * in the chain, the type returned by operator*() is a tuple. If multiple
+ * associative containers are nested, then the tuple will be of the form
+ * std::tuple<key1, key2, ..., keyN, value>. To avoid copies, and allow
+ * editting of underlying values, the tuple contains references.
+ *
+ * @tparam It The iterator type of the top-level collection.
+ * @tparam Bnd The bounding type, representing how many layers this iterator
+ * is willing to delve in the parent object.
+ */
+template <typename It, typename Bnd>
+class rimpl : public facade<rimpl<It, Bnd>> {
+private:
+  typename tuple<It, Bnd>::iter impl_;
+
+public:
+  static constexpr size_t size =
+      std::min(std::tuple_size_v<typename tuple<It, Bnd>::iter>, Bnd::size);
+
+  rimpl() = default;
+  rimpl(end_aware_iterator<It> iter) { assign<0>(iter); }
+  template <typename Ot>
+  rimpl(end_aware_iterator<Ot> other) : rimpl(end_aware_iterator<It>(other)) {}
+  template <typename Ot>
+  rimpl(rimpl<Ot, Bnd> other) : rimpl(end_aware_iterator<Ot>(other)) {}
+
+  template <typename T> operator end_aware_iterator<T>() const {
+    return std::get<end_aware_iterator<T>>(impl_);
+  }
 
-    decltype(auto) dereference() const {
-      // Special Case Handling for circumstances where at least everything up to
-      // the deepest nested container is non-associative. In this case, we don't
-      // want to transmute our single element/association into a tuple, since
-      // there's no benefit from that.
-      if constexpr (std::tuple_size_v<decltype(this->build_tuple())> == 1) {
-        return *std::get<size - 1>(impl_);
-      } else {
-        return build_tuple();
-      }
+  decltype(auto) dereference() const {
+    // Special Case Handling for circumstances where at least everything up to
+    // the deepest nested container is non-associative. In this case, we don't
+    // want to transmute our single element/association into a tuple, since
+    // there's no benefit from that.
+    if constexpr (std::tuple_size_v<decltype(this->build_tuple())> == 1) {
+      return *std::get<size - 1>(impl_);
+    } else {
+      return build_tuple();
     }
+  }
 
-    template <size_t I = size - 1> bool increment() {
-      auto & iter = std::get<I>(impl_);
-      if (iter.at_end()) { return false; } // Make sure we don't go OOB
-      ++iter;
-      if constexpr (I > 0) {
-        while (iter.at_end() && increment<I - 1>()) {
-          assign<I>(*std::get<I - 1>(impl_));
-        }
+  template <size_t I = size - 1> bool increment() {
+    auto & iter = std::get<I>(impl_);
+    if (iter.at_end()) { return false; } // Make sure we don't go OOB
+    ++iter;
+    if constexpr (I > 0) {
+      while (iter.at_end() && increment<I - 1>()) {
+        assign<I>(*std::get<I - 1>(impl_));
       }
-      return !iter.at_end();
     }
+    return !iter.at_end();
+  }
 
-    bool at_end() const { return std::get<0>(impl_).at_end(); }
-    bool equal_to(rimpl const & other) const { return impl_ == other.impl_; }
-
-    // Used by std::get, don't use elsewhere...
-    auto const & impl() const { return impl_; }
-
-  private:
-    template <size_t I = 0> decltype(auto) build_tuple() const {
-      // In the case of a bounded recursive iterator, I need to ensure that the
-      // effectively terminal iterator is treated as such even if there is still
-      // iteration to be had.
-      auto it = std::get<I>(impl_);
-      if constexpr (I == size - 1) {
-        return tuple<decltype(it), unbounded, recursion_type::END>{}.get(it);
-      } else {
-        // Implemented as a recursive function instead of a parameter-pack
-        // because OSX has a compiler bug regarding certain forms of parameter
-        // packs...
-        return std::tuple_cat(tuple<decltype(it)>{}.get(it),
-                              build_tuple<I + 1>());
-      }
+  bool at_end() const { return std::get<0>(impl_).at_end(); }
+  bool equal_to(rimpl const & other) const { return impl_ == other.impl_; }
+
+  // Used by std::get, don't use elsewhere...
+  auto const & impl() const { return impl_; }
+
+private:
+  template <size_t I = 0> decltype(auto) build_tuple() const {
+    // In the case of a bounded recursive iterator, I need to ensure that the
+    // effectively terminal iterator is treated as such even if there is still
+    // iteration to be had.
+    auto it = std::get<I>(impl_);
+    if constexpr (I == size - 1) {
+      return tuple<decltype(it), unbounded, recursion_type::END>{}.get(it);
+    } else {
+      // Implemented as a recursive function instead of a parameter-pack
+      // because OSX has a compiler bug regarding certain forms of parameter
+      // packs...
+      return std::tuple_cat(tuple<decltype(it)>{}.get(it),
+                            build_tuple<I + 1>());
     }
+  }
 
-    template <size_t I, typename C> void assign(end_aware_iterator<C> it) {
-      std::get<I>(impl_) = it;
-      if constexpr (I < size - 1) {
-        if (!it.at_end()) { assign<I + 1>(*it); }
-      }
+  template <size_t I, typename C> void assign(end_aware_iterator<C> it) {
+    std::get<I>(impl_) = it;
+    if constexpr (I < size - 1) {
+      if (!it.at_end()) { assign<I + 1>(*it); }
     }
+  }
 
-    template <size_t I, typename C> void assign(C && collection) {
-      assign<I>(make_end_aware_iterator(std::forward<C>(collection)));
-    }
+  template <size_t I, typename C> void assign(C && collection) {
+    assign<I>(make_end_aware_iterator(std::forward<C>(collection)));
+  }
 
-    template <size_t I, typename K, typename V>
-    void assign(std::pair<K const, V> const & pair) {
-      assign<I>(pair.second);
-    }
-    template <size_t I, typename K, typename V>
-    void assign(std::pair<K const, V> & pair) {
-      assign<I>(pair.second);
-    }
-  };
+  template <size_t I, typename K, typename V>
+  void assign(std::pair<K const, V> const & pair) {
+    assign<I>(pair.second);
+  }
+  template <size_t I, typename K, typename V>
+  void assign(std::pair<K const, V> & pair) {
+    assign<I>(pair.second);
+  }
+};
 }
 
 MAKE_ITERATOR_FACADE_TYPEDEFS_T(::iterator::recursive::rimpl);
 
 namespace std {
-  template <std::size_t I, typename It>
-  auto get(::iterator::recursive_iterator<It> const & iter) {
-    return ::std::get<I>(iter.impl());
-  }
+template <std::size_t I, typename It>
+auto get(::iterator::recursive_iterator<It> const & iter) {
+  return ::std::get<I>(iter.impl());
+}
 
-  template <std::size_t I, typename It, std::size_t N>
-  auto get(::iterator::recursive_iterator_n<It, N> const & iter) {
-    static_assert(I < N, "Cannot get past bounding level");
-    return ::std::get<I>(iter.impl());
-  }
+template <std::size_t I, typename It, std::size_t N>
+auto get(::iterator::recursive_iterator_n<It, N> const & iter) {
+  static_assert(I < N, "Cannot get past bounding level");
+  return ::std::get<I>(iter.impl());
+}
 }
 
 template <typename C>

+ 26 - 26
include/iterator/unkeyed_iterator.hpp

@@ -10,33 +10,33 @@
 #include "proxy.h"
 
 namespace iterator {
-  /**
-   * At first glance, this class seems like it acts as an iterator that would be
-   * used in the C++ equivalent of Java's Map::values() function. However,
-   * notices that we do not assume that the input iterator is a map iterator.
-   * The useful feature of this iterator - and the source of its name - is its
-   * ability to be composed with recursive_iterator. This means that you can
-   * have something crazy like a four-level map and then do:
-   * \code
-   * std::map<int, std::map<std::string, std::map<int, BigType>>> object;
-   * auto const rit = make_recursive_iterator(object);
-   * for (unkeyed_iterator<decltype(rit)> it = rit, end = {}; it != end; ++it) {
-   *   // Process only BigType, discarding all of the keys that we need to walk
-   * }
-   * \endcode
-   */
-  template <typename Iterator>
-  class unkeyed_iterator : public proxy<Iterator, unkeyed_iterator<Iterator>> {
-  public:
-    using proxy<Iterator, unkeyed_iterator<Iterator>>::proxy;
-    decltype(auto) dereference() const {
-      using value_type = typename Iterator::value_type;
-      constexpr auto index = std::tuple_size<value_type>::value - 1;
-      return std::get<index>(*this->impl());
-    }
-  };
+/**
+ * At first glance, this class seems like it acts as an iterator that would be
+ * used in the C++ equivalent of Java's Map::values() function. However,
+ * notices that we do not assume that the input iterator is a map iterator.
+ * The useful feature of this iterator - and the source of its name - is its
+ * ability to be composed with recursive_iterator. This means that you can
+ * have something crazy like a four-level map and then do:
+ * \code
+ * std::map<int, std::map<std::string, std::map<int, BigType>>> object;
+ * auto const rit = make_recursive_iterator(object);
+ * for (unkeyed_iterator<decltype(rit)> it = rit, end = {}; it != end; ++it) {
+ *   // Process only BigType, discarding all of the keys that we need to walk
+ * }
+ * \endcode
+ */
+template <typename Iterator>
+class unkeyed_iterator : public proxy<Iterator, unkeyed_iterator<Iterator>> {
+public:
+  using proxy<Iterator, unkeyed_iterator<Iterator>>::proxy;
+  decltype(auto) dereference() const {
+    using value_type = typename Iterator::value_type;
+    constexpr auto index = std::tuple_size<value_type>::value - 1;
+    return std::get<index>(*this->impl());
+  }
+};
 
-  template <typename It> unkeyed_iterator(It) -> unkeyed_iterator<It>;
+template <typename It> unkeyed_iterator(It) -> unkeyed_iterator<It>;
 }
 
 MAKE_ITERATOR_FACADE_TYPEDEFS_T(::iterator::unkeyed_iterator);

+ 43 - 43
include/iterator/zip_iterator.hpp

@@ -6,61 +6,61 @@
 #include "facade.h"
 
 namespace iterator::detail {
-  template <typename Tuple, typename IS> class zip_iterator_impl;
+template <typename Tuple, typename IS> class zip_iterator_impl;
 
-  template <typename... Ts, size_t... Is>
-  class zip_iterator_impl<std::tuple<Ts...>, std::index_sequence<Is...>> {
-  public:
-    using difference_type = std::common_type_t<
-        typename std::iterator_traits<Ts>::difference_type...>;
+template <typename... Ts, size_t... Is>
+class zip_iterator_impl<std::tuple<Ts...>, std::index_sequence<Is...>> {
+public:
+  using difference_type =
+      std::common_type_t<typename std::iterator_traits<Ts>::difference_type...>;
 
-  public:
-    zip_iterator_impl() = default;
-    zip_iterator_impl(Ts... iters) : _data(iters...) {}
+public:
+  zip_iterator_impl() = default;
+  zip_iterator_impl(Ts... iters) : _data(iters...) {}
 
-    auto dereference() const {
-      return std::forward_as_tuple(*std::get<Is>(_data)...);
-    }
+  auto dereference() const {
+    return std::forward_as_tuple(*std::get<Is>(_data)...);
+  }
 
-    void increment() {
-      [[maybe_unused]] auto l = {((++std::get<Is>(_data)), 0)...};
-    }
-    void decrement() {
-      [[maybe_unused]] auto l = {((++std::get<Is>(_data)), 0)...};
-    }
-    void advance(difference_type d) {
-      [[maybe_unused]] auto l = {((std::get<Is>(_data) += d), 0)...};
-    }
+  void increment() {
+    [[maybe_unused]] auto l = {((++std::get<Is>(_data)), 0)...};
+  }
+  void decrement() {
+    [[maybe_unused]] auto l = {((++std::get<Is>(_data)), 0)...};
+  }
+  void advance(difference_type d) {
+    [[maybe_unused]] auto l = {((std::get<Is>(_data) += d), 0)...};
+  }
 
-    bool equal_to(zip_iterator_impl const & other) const {
-      return _data == other._data;
-    }
+  bool equal_to(zip_iterator_impl const & other) const {
+    return _data == other._data;
+  }
 
-    auto distance_to(zip_iterator_impl const & other) const {
-      return std::get<0>(other._data) - std::get<0>(_data);
-    }
+  auto distance_to(zip_iterator_impl const & other) const {
+    return std::get<0>(other._data) - std::get<0>(_data);
+  }
 
-  private:
-    std::tuple<Ts...> _data;
-  };
+private:
+  std::tuple<Ts...> _data;
+};
 }
 
 namespace iterator {
-  template <typename... Ts>
-  using index_sequence = decltype(std::make_index_sequence<sizeof...(Ts)>{});
-  template <typename... Ts>
-  using zip_impl =
-      detail::zip_iterator_impl<std::tuple<Ts...>, index_sequence<Ts...>>;
+template <typename... Ts>
+using index_sequence = decltype(std::make_index_sequence<sizeof...(Ts)>{});
+template <typename... Ts>
+using zip_impl =
+    detail::zip_iterator_impl<std::tuple<Ts...>, index_sequence<Ts...>>;
 
-  template <typename... Iters>
-  class zip_iterator : public zip_impl<Iters...>,
-                       public facade<zip_iterator<Iters...>> {
-  public:
-    zip_iterator() = default;
-    zip_iterator(Iters... iters) : zip_impl<Iters...>(iters...) {}
-  };
+template <typename... Iters>
+class zip_iterator : public zip_impl<Iters...>,
+                     public facade<zip_iterator<Iters...>> {
+public:
+  zip_iterator() = default;
+  zip_iterator(Iters... iters) : zip_impl<Iters...>(iters...) {}
+};
 
-  template <typename... It> zip_iterator(It...) -> zip_iterator<It...>;
+template <typename... It> zip_iterator(It...) -> zip_iterator<It...>;
 }
 
 template <typename... T>