Parcourir la source

Adding unkeyed_iterator - an iterator for associative types that discards keys, allowing it to be treated like a non-associative array of values.
unkeyed_iterator<std::map<K, V>::iterator> can be though of as an equivalent concept as Java's Map<K, V>::values().iterator()

Samuel Jaffe il y a 8 ans
Parent
commit
307fba398a
3 fichiers modifiés avec 78 ajouts et 1 suppressions
  1. 6 1
      iterator.xcodeproj/project.pbxproj
  2. 49 0
      unkeyed_iterator.hpp
  3. 23 0
      unkeyed_iterator.t.h

+ 6 - 1
iterator.xcodeproj/project.pbxproj

@@ -29,6 +29,8 @@
 		CD21AE2C1E4A3EC100536178 /* join_iterator.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = join_iterator.hpp; sourceTree = "<group>"; };
 		CD21AE2E1E4A3F8E00536178 /* end_aware_iterator.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = end_aware_iterator.hpp; sourceTree = "<group>"; };
 		CD21AE2F1E4A428D00536178 /* end_aware_iterator.t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = end_aware_iterator.t.h; sourceTree = "<group>"; };
+		CD595EDF1E5BA27300FC25BB /* unkeyed_iterator.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = unkeyed_iterator.hpp; sourceTree = "<group>"; };
+		CD595EE01E5BA3D300FC25BB /* unkeyed_iterator.t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = unkeyed_iterator.t.h; sourceTree = "<group>"; };
 		CD679D721E5D127600F9F843 /* recursive_iterator_meta.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = recursive_iterator_meta.hpp; sourceTree = "<group>"; };
 		CD679D731E5D19B900F9F843 /* recursive_iterator_accessors.t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = recursive_iterator_accessors.t.h; sourceTree = "<group>"; };
 		CD7172E91E57C6580048DFFF /* recursive_iterator.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = recursive_iterator.hpp; sourceTree = "<group>"; };
@@ -75,6 +77,7 @@
 				CD7172ED1E58BC930048DFFF /* recursive_iterator_nested_map.t.h */,
 				CD7172EE1E58C9930048DFFF /* recursive_iterator_mixed_container.t.h */,
 				CD679D731E5D19B900F9F843 /* recursive_iterator_accessors.t.h */,
+				CD595EE01E5BA3D300FC25BB /* unkeyed_iterator.t.h */,
 				CD21AE291E4A3EB000536178 /* iterator_tc.cpp */,
 			);
 			name = test;
@@ -88,6 +91,7 @@
 				CD21AE2C1E4A3EC100536178 /* join_iterator.hpp */,
 				CD7172E91E57C6580048DFFF /* recursive_iterator.hpp */,
 				CD679D721E5D127600F9F843 /* recursive_iterator_meta.hpp */,
+				CD595EDF1E5BA27300FC25BB /* unkeyed_iterator.hpp */,
 			);
 			name = src;
 			sourceTree = "<group>";
@@ -157,13 +161,14 @@
 				"$(SRCROOT)/recursive_iterator_nested_map.t.h",
 				"$(SRCROOT)/recursive_iterator_mixed_container.t.h",
 				"$(SRCROOT)/recursive_iterator_accessors.t.h",
+				"$(SRCROOT)/unkeyed_iterator.t.h",
 			);
 			outputPaths = (
 				"$(SRCROOT)/iterator_tc.cpp",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "cxxtestgen --error-printer -o iterator_tc.cpp end_aware_iterator.t.h join_iterator.t.h recursive_iterator_one_dimension.t.h recursive_iterator_nested_map.t.h recursive_iterator_mixed_container.t.h recursive_iterator_accessors.t.h";
+			shellScript = "cxxtestgen --error-printer -o iterator_tc.cpp end_aware_iterator.t.h join_iterator.t.h recursive_iterator_one_dimension.t.h recursive_iterator_nested_map.t.h recursive_iterator_mixed_container.t.h recursive_iterator_accessors.t.h unkeyed_iterator.t.h";
 		};
 /* End PBXShellScriptBuildPhase section */
 

+ 49 - 0
unkeyed_iterator.hpp

@@ -0,0 +1,49 @@
+//
+//  unkeyed_iterator.hpp
+//  iterator
+//
+//  Created by Sam Jaffe on 2/20/17.
+//
+
+#pragma once
+
+#include <iterator>
+
+namespace iterator {
+  template <typename Iterator>
+  class unkeyed_iterator {
+  private:
+    using impl_value_type = typename std::iterator_traits<Iterator>::value_type;
+    using impl_reference = typename std::iterator_traits<Iterator>::reference;
+    static constexpr std::size_t const value_index = std::tuple_size<impl_value_type>::value - 1;
+  public:
+    using value_type = typename std::remove_reference<decltype(std::get<value_index>(std::declval<impl_value_type>()))>::type;
+    using reference = decltype(std::get<value_index>(std::declval<impl_reference>()));
+    using pointer = value_type *;
+    using difference_type = typename std::iterator_traits<Iterator>::difference_type;
+    using iterator_category = typename std::iterator_traits<Iterator>::iterator_category;
+    
+    unkeyed_iterator() = default;
+    unkeyed_iterator(Iterator it) : base(it) {}
+    
+    reference operator*() const { return std::get<value_index>(*base); }
+    pointer operator->() const { return std::addressof(operator*()); }
+    unkeyed_iterator & operator++() { ++base; return *this; }
+    unkeyed_iterator operator++(int) { unkeyed_iterator tmp{*this}; operator++(); return tmp; }
+    
+    unkeyed_iterator & operator--() { --base; return *this; }
+    unkeyed_iterator operator--(int) { unkeyed_iterator tmp{*this}; operator--(); return tmp; }
+    
+    unkeyed_iterator operator+(difference_type n) const { return unkeyed_iterator{*this} += n; }
+    unkeyed_iterator & operator+=(difference_type n) { base += n; return *this; }
+    unkeyed_iterator operator-(difference_type n) const { return unkeyed_iterator{*this} -= n; }
+    unkeyed_iterator & operator-=(difference_type n) { base -= n;return *this; }
+    
+    bool operator==(unkeyed_iterator const & other) const { return base == other.base; }
+    bool operator!=(unkeyed_iterator const & other) const { return base != other.base; }
+    bool operator< (unkeyed_iterator const & other) const { return base < other.base; }
+    bool operator<=(unkeyed_iterator const & other) const { return operator<() || operator==(); }
+  private:
+    Iterator base;
+  };
+}

+ 23 - 0
unkeyed_iterator.t.h

@@ -0,0 +1,23 @@
+//
+//  unkeyed_iterator.t.h
+//  iterator
+//
+//  Created by Sam Jaffe on 2/20/17.
+//
+
+#pragma once
+
+#include <cxxtest/TestSuite.h>
+
+#include "unkeyed_iterator.hpp"
+
+class unkeyed_iterator_TestSuite : public CxxTest::TestSuite {
+public:
+  void test_unkeyed_iterator_discards_key_map() {
+    using map_t = std::map<int, int>;
+    map_t map{{1, 2}, {2, 3}};
+    iterator::unkeyed_iterator<map_t::iterator> uit{map.begin()};
+    *uit = 4;
+    TS_ASSERT_EQUALS(map[1], 4);
+  }
+};