Add a generator that takes an iterator pair
diff --git a/docs/generators.md b/docs/generators.md
index 490cfca..934a673 100644
--- a/docs/generators.md
+++ b/docs/generators.md
@@ -46,13 +46,16 @@
   * `MapGenerator<T, U, Func>` -- returns the result of applying `Func`
   on elements from a different generator
   * `ChunkGenerator<T>` -- returns chunks (inside `std::vector`) of n elements from a generator
-* 3 specific purpose generators
+* 4 specific purpose generators
   * `RandomIntegerGenerator<Integral>` -- generates random Integrals from range
   * `RandomFloatGenerator<Float>` -- generates random Floats from range
   * `RangeGenerator<T>` -- generates all values inside a specific range
+  * `IteratorGenerator<T>` -- copies and returns values from an iterator range
 
 > `ChunkGenerator<T>`, `RandomIntegerGenerator<Integral>`, `RandomFloatGenerator<Float>` and `RangeGenerator<T>` were introduced in Catch 2.7.0.
 
+> `IteratorGenerator<T>` was introduced in Catch X.Y.Z.
+
 The generators also have associated helper functions that infer their
 type, making their usage much nicer. These are
 
@@ -68,9 +71,12 @@
 * `random(IntegerOrFloat a, IntegerOrFloat b)` for `RandomIntegerGenerator` or `RandomFloatGenerator`
 * `range(start, end)` for `RangeGenerator<T>` with a step size of `1`
 * `range(start, end, step)` for `RangeGenerator<T>` with a custom step size
+* `from_range(InputIterator from, InputIterator to)` for `IteratorGenerator<T>`
 
 > `chunk()`, `random()` and both `range()` functions were introduced in Catch 2.7.0.
 
+> `from_range` has been introduced in Catch X.Y.Z
+
 And can be used as shown in the example below to create a generator
 that returns 100 odd random number:
 
diff --git a/include/internal/catch_generators_specific.hpp b/include/internal/catch_generators_specific.hpp
index 7aae06b..7985ac7 100644
--- a/include/internal/catch_generators_specific.hpp
+++ b/include/internal/catch_generators_specific.hpp
@@ -128,6 +128,39 @@
 }
 
 
+template <typename T>
+class IteratorGenerator final : public IGenerator<T> {
+    static_assert(!std::is_same<T, bool>::value,
+        "IteratorGenerator currently does not support bools"
+        "because of std::vector<bool> specialization");
+
+    std::vector<T> m_elems;
+    size_t m_current = 0;
+public:
+    template <typename InputIterator, typename InputSentinel>
+    IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) {
+        if (m_elems.empty()) {
+            Catch::throw_exception(GeneratorException("IteratorGenerator received no valid values"));
+        }
+    }
+
+    T const& get() const override {
+        return m_elems[m_current];
+    }
+
+    bool next() override {
+        ++m_current;
+        return m_current != m_elems.size();
+    }
+};
+
+template <typename InputIterator,
+          typename InputSentinel,
+          typename ResultType = typename std::iterator_traits<InputIterator>::value_type>
+GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {
+    return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(from, to));
+}
+
 } // namespace Generators
 } // namespace Catch
 
diff --git a/projects/SelfTest/Baselines/compact.sw.approved.txt b/projects/SelfTest/Baselines/compact.sw.approved.txt
index e791928..8927664 100644
--- a/projects/SelfTest/Baselines/compact.sw.approved.txt
+++ b/projects/SelfTest/Baselines/compact.sw.approved.txt
@@ -310,6 +310,12 @@
 Condition.tests.cpp:<line number>: passed: (std::numeric_limits<uint32_t>::max)() > ul for: 4294967295 (0x<hex digits>) > 4
 Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Contains("not there", Catch::CaseSensitive::No) for: "this string contains 'abc' as a substring" contains: "not there" (case insensitive)
 Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Contains("STRING") for: "this string contains 'abc' as a substring" contains: "STRING"
+Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1
+Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1
+Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1
+Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1
+Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1
+Generators.tests.cpp:<line number>: passed: elem % 2 == 1 for: 1 == 1
 Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'custom exception - not std'; expression was: throwCustom()
 Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'custom exception - not std'; expression was: throwCustom(), std::exception
 Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'custom std exception'
diff --git a/projects/SelfTest/Baselines/console.std.approved.txt b/projects/SelfTest/Baselines/console.std.approved.txt
index 7eaae82..49363a6 100644
--- a/projects/SelfTest/Baselines/console.std.approved.txt
+++ b/projects/SelfTest/Baselines/console.std.approved.txt
@@ -1380,6 +1380,6 @@
   Why would you throw a std::string?
 
 ===============================================================================
-test cases:  300 |  226 passed |  70 failed |  4 failed as expected
-assertions: 1564 | 1412 passed | 131 failed | 21 failed as expected
+test cases:  301 |  227 passed |  70 failed |  4 failed as expected
+assertions: 1570 | 1418 passed | 131 failed | 21 failed as expected
 
diff --git a/projects/SelfTest/Baselines/console.sw.approved.txt b/projects/SelfTest/Baselines/console.sw.approved.txt
index 4415fe0..9bb8721 100644
--- a/projects/SelfTest/Baselines/console.sw.approved.txt
+++ b/projects/SelfTest/Baselines/console.sw.approved.txt
@@ -2382,6 +2382,72 @@
   "this string contains 'abc' as a substring" contains: "STRING"
 
 -------------------------------------------------------------------------------
+Copy and then generate a range
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>: PASSED:
+  REQUIRE( elem % 2 == 1 )
+with expansion:
+  1 == 1
+
+-------------------------------------------------------------------------------
+Copy and then generate a range
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>: PASSED:
+  REQUIRE( elem % 2 == 1 )
+with expansion:
+  1 == 1
+
+-------------------------------------------------------------------------------
+Copy and then generate a range
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>: PASSED:
+  REQUIRE( elem % 2 == 1 )
+with expansion:
+  1 == 1
+
+-------------------------------------------------------------------------------
+Copy and then generate a range
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>: PASSED:
+  REQUIRE( elem % 2 == 1 )
+with expansion:
+  1 == 1
+
+-------------------------------------------------------------------------------
+Copy and then generate a range
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>: PASSED:
+  REQUIRE( elem % 2 == 1 )
+with expansion:
+  1 == 1
+
+-------------------------------------------------------------------------------
+Copy and then generate a range
+-------------------------------------------------------------------------------
+Generators.tests.cpp:<line number>
+...............................................................................
+
+Generators.tests.cpp:<line number>: PASSED:
+  REQUIRE( elem % 2 == 1 )
+with expansion:
+  1 == 1
+
+-------------------------------------------------------------------------------
 Custom exceptions can be translated when testing for nothrow
 -------------------------------------------------------------------------------
 Exception.tests.cpp:<line number>
@@ -12499,6 +12565,6 @@
 Misc.tests.cpp:<line number>: PASSED:
 
 ===============================================================================
-test cases:  300 |  210 passed |  86 failed |  4 failed as expected
-assertions: 1581 | 1412 passed | 148 failed | 21 failed as expected
+test cases:  301 |  211 passed |  86 failed |  4 failed as expected
+assertions: 1587 | 1418 passed | 148 failed | 21 failed as expected
 
diff --git a/projects/SelfTest/Baselines/junit.sw.approved.txt b/projects/SelfTest/Baselines/junit.sw.approved.txt
index b16b663..d1ec9db 100644
--- a/projects/SelfTest/Baselines/junit.sw.approved.txt
+++ b/projects/SelfTest/Baselines/junit.sw.approved.txt
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <testsuitesloose text artifact
 >
-  <testsuite name="<exe-name>" errors="17" failures="132" tests="1582" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
+  <testsuite name="<exe-name>" errors="17" failures="132" tests="1588" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
     <properties>
       <property name="filters" value="~[!nonportable]~[!benchmark]~[approvals]"/>
       <property name="random-seed" value="1"/>
@@ -254,6 +254,7 @@
 Matchers.tests.cpp:<line number>
       </failure>
     </testcase>
+    <testcase classname="<exe-name>.global" name="Copy and then generate a range" time="{duration}"/>
     <testcase classname="<exe-name>.global" name="Custom exceptions can be translated when testing for nothrow" time="{duration}">
       <error message="throwCustom()" type="REQUIRE_NOTHROW">
 custom exception - not std
diff --git a/projects/SelfTest/Baselines/xml.sw.approved.txt b/projects/SelfTest/Baselines/xml.sw.approved.txt
index 65e5f4b..9df2808 100644
--- a/projects/SelfTest/Baselines/xml.sw.approved.txt
+++ b/projects/SelfTest/Baselines/xml.sw.approved.txt
@@ -2816,6 +2816,57 @@
       </Expression>
       <OverallResult success="false"/>
     </TestCase>
+    <TestCase name="Copy and then generate a range" tags="[generators]" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          elem % 2 == 1
+        </Original>
+        <Expanded>
+          1 == 1
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          elem % 2 == 1
+        </Original>
+        <Expanded>
+          1 == 1
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          elem % 2 == 1
+        </Original>
+        <Expanded>
+          1 == 1
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          elem % 2 == 1
+        </Original>
+        <Expanded>
+          1 == 1
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          elem % 2 == 1
+        </Original>
+        <Expanded>
+          1 == 1
+        </Expanded>
+      </Expression>
+      <Expression success="true" type="REQUIRE" filename="projects/<exe-name>/UsageTests/Generators.tests.cpp" >
+        <Original>
+          elem % 2 == 1
+        </Original>
+        <Expanded>
+          1 == 1
+        </Expanded>
+      </Expression>
+      <OverallResult success="true"/>
+    </TestCase>
     <TestCase name="Custom exceptions can be translated when testing for nothrow" tags="[!throws][.][failing]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
       <Expression success="false" type="REQUIRE_NOTHROW" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" >
         <Original>
@@ -14872,7 +14923,7 @@
       </Section>
       <OverallResult success="true"/>
     </TestCase>
-    <OverallResults successes="1412" failures="149" expectedFailures="21"/>
+    <OverallResults successes="1418" failures="149" expectedFailures="21"/>
   </Group>
-  <OverallResults successes="1412" failures="148" expectedFailures="21"/>
+  <OverallResults successes="1418" failures="148" expectedFailures="21"/>
 </Catch>
diff --git a/projects/SelfTest/UsageTests/Generators.tests.cpp b/projects/SelfTest/UsageTests/Generators.tests.cpp
index e9b2f80..0d58186 100644
--- a/projects/SelfTest/UsageTests/Generators.tests.cpp
+++ b/projects/SelfTest/UsageTests/Generators.tests.cpp
@@ -212,3 +212,28 @@
     auto values = GENERATE_COPY(range(from, to));
     REQUIRE(values > -6);
 }
+
+namespace {
+    std::vector<int> make_data() {
+        return { 1, 3, 5, 7, 9, 11 };
+    }
+}
+
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wexit-time-destructors"
+#endif
+
+TEST_CASE("Copy and then generate a range", "[generators]") {
+    static auto data = make_data();
+
+    // It is important to notice that a generator is only initialized
+    // **once** per run. What this means is that modifying data will not
+    // modify the underlying generator.
+    auto elem = GENERATE_REF(from_range(data.begin(), data.end()));
+    REQUIRE(elem % 2 == 1);
+}
+
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif