| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834 | 
							
- //              Copyright Catch2 Authors
 
- // Distributed under the Boost Software License, Version 1.0.
 
- //   (See accompanying file LICENSE_1_0.txt or copy at
 
- //        https://www.boost.org/LICENSE_1_0.txt)
 
- // SPDX-License-Identifier: BSL-1.0
 
- #include <catch2/catch_test_macros.hpp>
 
- #include <catch2/matchers/catch_matchers_container_properties.hpp>
 
- #include <catch2/matchers/catch_matchers_contains.hpp>
 
- #include <catch2/matchers/catch_matchers_floating_point.hpp>
 
- #include <catch2/matchers/catch_matchers_quantifiers.hpp>
 
- #include <catch2/matchers/catch_matchers_predicate.hpp>
 
- #include <catch2/matchers/catch_matchers_string.hpp>
 
- #include <cmath>
 
- #include <initializer_list>
 
- #include <list>
 
- #include <map>
 
- #include <type_traits>
 
- #include <vector>
 
- #include <memory>
 
- namespace {
 
- namespace unrelated {
 
-     template <typename T>
 
-     class needs_ADL_begin {
 
-         std::vector<T> m_elements;
 
-     public:
 
-         using iterator = typename std::vector<T>::iterator;
 
-         using const_iterator = typename std::vector<T>::const_iterator;
 
-         needs_ADL_begin(std::initializer_list<T> init) : m_elements(init) {}
 
-         const_iterator Begin() const { return m_elements.begin(); }
 
-         const_iterator End() const { return m_elements.end(); }
 
-         friend const_iterator begin(needs_ADL_begin const& lhs) {
 
-             return lhs.Begin();
 
-         }
 
-         friend const_iterator end(needs_ADL_begin const& rhs) {
 
-             return rhs.End();
 
-         }
 
-     };
 
- } // end unrelated namespace
 
- #if defined(__clang__)
 
- #  pragma clang diagnostic push
 
- #  pragma clang diagnostic ignored "-Wunused-function"
 
- #endif
 
- template <typename T>
 
- class has_different_begin_end_types {
 
-     // Using std::vector<T> leads to annoying issues when T is bool
 
-     // so we just use list because the perf is not critical and ugh.
 
-     std::list<T> m_elements;
 
-     // Different type for the "end" iterator
 
-     struct iterator_end {};
 
-     // Fake-ish forward iterator that only compares to a different type
 
-     class iterator {
 
-         using underlying_iter = typename std::list<T>::const_iterator;
 
-         underlying_iter m_start;
 
-         underlying_iter m_end;
 
-     public:
 
-         iterator( underlying_iter start, underlying_iter end ):
 
-             m_start( start ), m_end( end ) {}
 
-         using iterator_category = std::forward_iterator_tag;
 
-         using difference_type = std::ptrdiff_t;
 
-         using value_type = T;
 
-         using const_reference = T const&;
 
-         using pointer = T const*;
 
-         friend bool operator==( iterator iter, iterator_end ) {
 
-             return iter.m_start == iter.m_end;
 
-         }
 
-         friend bool operator!=( iterator iter, iterator_end ) {
 
-             return iter.m_start != iter.m_end;
 
-         }
 
-         iterator& operator++() {
 
-             ++m_start;
 
-             return *this;
 
-         }
 
-         iterator operator++(int) {
 
-             auto tmp(*this);
 
-             ++m_start;
 
-             return tmp;
 
-         }
 
-         const_reference operator*() const {
 
-             return *m_start;
 
-         }
 
-         pointer operator->() const {
 
-             return m_start;
 
-         }
 
-     };
 
- public:
 
-     explicit has_different_begin_end_types( std::initializer_list<T> init ):
 
-         m_elements( init ) {}
 
-     iterator begin() const {
 
-         return { m_elements.begin(), m_elements.end() };
 
-     }
 
-     iterator_end end() const {
 
-         return {};
 
-     }
 
- };
 
- #if defined(__clang__)
 
- #  pragma clang diagnostic pop
 
- #endif
 
- template <typename T> struct with_mocked_iterator_access {
 
-     std::vector<T> m_elements;
 
-     // use plain arrays to have nicer printouts with CHECK(...)
 
-     mutable std::unique_ptr<bool[]> m_derefed;
 
-     // We want to check which elements were dereferenced when iterating, so
 
-     // we can check whether iterator-using code traverses range correctly
 
-     template <bool is_const> class basic_iterator {
 
-         template <typename U>
 
-         using constify_t = std::conditional_t<is_const, std::add_const_t<U>, U>;
 
-         constify_t<with_mocked_iterator_access>* m_origin;
 
-         size_t m_origin_idx;
 
-     public:
 
-         using iterator_category = std::forward_iterator_tag;
 
-         using difference_type = std::ptrdiff_t;
 
-         using value_type = constify_t<T>;
 
-         using const_reference = typename std::vector<T>::const_reference;
 
-         using reference = typename std::vector<T>::reference;
 
-         using pointer = typename std::vector<T>::pointer;
 
-         basic_iterator( constify_t<with_mocked_iterator_access>* origin,
 
-                         std::size_t origin_idx ):
 
-             m_origin{ origin }, m_origin_idx{ origin_idx } {}
 
-         friend bool operator==( basic_iterator lhs, basic_iterator rhs ) {
 
-             return lhs.m_origin == rhs.m_origin &&
 
-                    lhs.m_origin_idx == rhs.m_origin_idx;
 
-         }
 
-         friend bool operator!=( basic_iterator lhs, basic_iterator rhs ) {
 
-             return !( lhs == rhs );
 
-         }
 
-         basic_iterator& operator++() {
 
-             ++m_origin_idx;
 
-             return *this;
 
-         }
 
-         basic_iterator operator++( int ) {
 
-             auto tmp( *this );
 
-             ++( *this );
 
-             return tmp;
 
-         }
 
-         const_reference operator*() const {
 
-             assert( m_origin_idx < m_origin->m_elements.size() && "Attempted to deref invalid position" );
 
-             m_origin->m_derefed[m_origin_idx] = true;
 
-             return m_origin->m_elements[m_origin_idx];
 
-         }
 
-         pointer operator->() const {
 
-             assert( m_origin_idx < m_origin->m_elements.size() && "Attempted to deref invalid position" );
 
-             return &m_origin->m_elements[m_origin_idx];
 
-         }
 
-     };
 
-     using iterator = basic_iterator<false>;
 
-     using const_iterator = basic_iterator<true>;
 
-     with_mocked_iterator_access( std::initializer_list<T> init ):
 
-         m_elements( init ),
 
-         m_derefed( std::make_unique<bool[]>( m_elements.size() ) ) {}
 
-     const_iterator begin() const { return { this, 0 }; }
 
-     const_iterator end() const { return { this, m_elements.size() }; }
 
-     iterator begin() { return { this, 0 }; }
 
-     iterator end() { return { this, m_elements.size() }; }
 
- };
 
- } // end anon namespace
 
- namespace Catch {
 
-     // make sure with_mocked_iterator_access is not considered a range by Catch,
 
-     // so that below StringMaker is used instead of the default one for ranges
 
-     template <typename T>
 
-     struct is_range<with_mocked_iterator_access<T>> : std::false_type {};
 
-     template <typename T>
 
-     struct StringMaker<with_mocked_iterator_access<T>> {
 
-         static std::string
 
-         convert( with_mocked_iterator_access<T> const& access ) {
 
-             // We have to avoid the type's iterators, because we check
 
-             // their use in tests
 
-             return ::Catch::Detail::stringify( access.m_elements );
 
-         }
 
-     };
 
- } // namespace Catch
 
- struct MoveOnlyTestElement {
 
-     int num = 0;
 
-     MoveOnlyTestElement(int n) :num(n) {}
 
-     MoveOnlyTestElement(MoveOnlyTestElement&& rhs) = default;
 
-     MoveOnlyTestElement& operator=(MoveOnlyTestElement&& rhs) = default;
 
-     friend bool operator==(MoveOnlyTestElement const& lhs, MoveOnlyTestElement const& rhs) {
 
-         return lhs.num == rhs.num;
 
-     }
 
-     friend std::ostream& operator<<(std::ostream& out, MoveOnlyTestElement const& elem) {
 
-         out << elem.num;
 
-         return out;
 
-     }
 
- };
 
- TEST_CASE("Basic use of the Contains range matcher", "[matchers][templated][contains]") {
 
-     using Catch::Matchers::Contains;
 
-     SECTION("Different argument ranges, same element type, default comparison") {
 
-         std::array<int, 3> a{ { 1,2,3 } };
 
-         std::vector<int> b{ 0,1,2 };
 
-         std::list<int> c{ 4,5,6 };
 
-         // A contains 1
 
-         REQUIRE_THAT(a,  Contains(1));
 
-         // B contains 1
 
-         REQUIRE_THAT(b,  Contains(1));
 
-         // C does not contain 1
 
-         REQUIRE_THAT(c, !Contains(1));
 
-     }
 
-     SECTION("Different argument ranges, same element type, custom comparison") {
 
-         std::array<int, 3> a{ { 1,2,3 } };
 
-         std::vector<int> b{ 0,1,2 };
 
-         std::list<int> c{ 4,5,6 };
 
-         auto close_enough = [](int lhs, int rhs) { return std::abs(lhs - rhs) <= 1; };
 
-         // A contains 1, which is "close enough" to 0
 
-         REQUIRE_THAT(a,  Contains(0, close_enough));
 
-         // B contains 0 directly
 
-         REQUIRE_THAT(b,  Contains(0, close_enough));
 
-         // C does not contain anything "close enough" to 0
 
-         REQUIRE_THAT(c, !Contains(0, close_enough));
 
-     }
 
-     SECTION("Different element type, custom comparisons") {
 
-         std::array<std::string, 3> a{ { "abc", "abcd" , "abcde" } };
 
-         REQUIRE_THAT(a, Contains(4, [](auto&& lhs, size_t sz) {
 
-             return lhs.size() == sz;
 
-         }));
 
-     }
 
-     SECTION("Can handle type that requires ADL-found free function begin and end") {
 
-         unrelated::needs_ADL_begin<int> in{1, 2, 3, 4, 5};
 
-         REQUIRE_THAT(in,  Contains(1));
 
-         REQUIRE_THAT(in, !Contains(8));
 
-     }
 
-     SECTION("Initialization with move only types") {
 
-         std::array<MoveOnlyTestElement, 3> in{ { MoveOnlyTestElement{ 1 }, MoveOnlyTestElement{ 2 }, MoveOnlyTestElement{ 3 } } };
 
-         REQUIRE_THAT(in,  Contains(MoveOnlyTestElement{ 2 }));
 
-         REQUIRE_THAT(in, !Contains(MoveOnlyTestElement{ 9 }));
 
-     }
 
-     SECTION("Matching using matcher") {
 
-         std::array<double, 4> in{ {1, 2, 3} };
 
-         REQUIRE_THAT(in, Contains(Catch::Matchers::WithinAbs(0.5, 0.5)));
 
-     }
 
- }
 
- namespace {
 
-     struct has_empty {
 
-         bool empty() const { return false; }
 
-     };
 
- namespace unrelated {
 
-     struct ADL_empty {
 
-         bool Empty() const { return true; }
 
-         friend bool empty(ADL_empty e) {
 
-             return e.Empty();
 
-         }
 
-     };
 
- } // end namespace unrelated
 
- } // end unnamed namespace
 
- TEST_CASE("Basic use of the Empty range matcher", "[matchers][templated][empty]") {
 
-     using Catch::Matchers::IsEmpty;
 
-     SECTION("Simple, std-provided containers") {
 
-         std::array<int, 0> empty_array{};
 
-         std::array<double, 1> non_empty_array{};
 
-         REQUIRE_THAT(empty_array, IsEmpty());
 
-         REQUIRE_THAT(non_empty_array, !IsEmpty());
 
-         std::vector<std::string> empty_vec;
 
-         std::vector<char> non_empty_vec{ 'a', 'b', 'c' };
 
-         REQUIRE_THAT(empty_vec, IsEmpty());
 
-         REQUIRE_THAT(non_empty_vec, !IsEmpty());
 
-         std::list<std::list<std::list<int>>> inner_lists_are_empty;
 
-         inner_lists_are_empty.push_back({});
 
-         REQUIRE_THAT(inner_lists_are_empty, !IsEmpty());
 
-         REQUIRE_THAT(inner_lists_are_empty.front(), IsEmpty());
 
-     }
 
-     SECTION("Type with empty") {
 
-         REQUIRE_THAT(has_empty{}, !IsEmpty());
 
-     }
 
-     SECTION("Type requires ADL found empty free function") {
 
-         REQUIRE_THAT(unrelated::ADL_empty{}, IsEmpty());
 
-     }
 
- }
 
- namespace {
 
-     class LessThanMatcher final : public Catch::Matchers::MatcherBase<size_t> {
 
-         size_t m_target;
 
-     public:
 
-         explicit LessThanMatcher(size_t target):
 
-             m_target(target)
 
-         {}
 
-         bool match(size_t const& size) const override {
 
-             return size < m_target;
 
-         }
 
-         std::string describe() const override {
 
-             return "is less than " + std::to_string(m_target);
 
-         }
 
-     };
 
-     LessThanMatcher Lt(size_t sz) {
 
-         return LessThanMatcher{ sz };
 
-     }
 
-     namespace unrelated {
 
-         struct ADL_size {
 
-             size_t sz() const {
 
-                 return 12;
 
-             }
 
-             friend size_t size(ADL_size s) {
 
-                 return s.sz();
 
-             }
 
-         };
 
-     } // end namespace unrelated
 
-     struct has_size {
 
-         size_t size() const {
 
-             return 13;
 
-         }
 
-     };
 
- } // end unnamed namespace
 
- TEST_CASE("Usage of the SizeIs range matcher", "[matchers][templated][size]") {
 
-     using Catch::Matchers::SizeIs;
 
-     SECTION("Some with stdlib containers") {
 
-         std::vector<int> empty_vec;
 
-         REQUIRE_THAT(empty_vec,  SizeIs(0));
 
-         REQUIRE_THAT(empty_vec, !SizeIs(2));
 
-         REQUIRE_THAT(empty_vec,  SizeIs(Lt(2)));
 
-         std::array<int, 2> arr{};
 
-         REQUIRE_THAT(arr,  SizeIs(2));
 
-         REQUIRE_THAT(arr,  SizeIs( Lt(3)));
 
-         REQUIRE_THAT(arr, !SizeIs(!Lt(3)));
 
-         std::map<int, int> map{ {1, 1}, {2, 2}, {3, 3} };
 
-         REQUIRE_THAT(map, SizeIs(3));
 
-     }
 
-     SECTION("Type requires ADL found size free function") {
 
-         REQUIRE_THAT(unrelated::ADL_size{}, SizeIs(12));
 
-     }
 
-     SECTION("Type has size member") {
 
-         REQUIRE_THAT(has_size{}, SizeIs(13));
 
-     }
 
- }
 
- TEST_CASE("Usage of AllMatch range matcher", "[matchers][templated][quantifiers]") {
 
-     using Catch::Matchers::AllMatch;
 
-     using Catch::Matchers::Predicate;
 
-     SECTION("Basic usage") {
 
-         using Catch::Matchers::Contains;
 
-         using Catch::Matchers::SizeIs;
 
-         std::array<std::array<int, 5>, 5> data{{
 
-                                         {{ 0, 1, 2, 3, 5 }},
 
-                                         {{ 4,-3,-2, 5, 0 }},
 
-                                         {{ 0, 0, 0, 5, 0 }},
 
-                                         {{ 0,-5, 0, 5, 0 }},
 
-                                         {{ 1, 0, 0,-1, 5 }}
 
-         }};
 
-         REQUIRE_THAT(data,  AllMatch(SizeIs(5)));
 
-         REQUIRE_THAT(data, !AllMatch(Contains(0) && Contains(1)));
 
-     }
 
-     SECTION("Type requires ADL found begin and end") {
 
-         unrelated::needs_ADL_begin<int> needs_adl{ 1, 2, 3, 4, 5 };
 
-         REQUIRE_THAT( needs_adl, AllMatch( Predicate<int>( []( int elem ) {
 
-                           return elem < 6;
 
-                       } ) ) );
 
-     }
 
-     SECTION("Shortcircuiting") {
 
-         with_mocked_iterator_access<int> mocked{ 1, 2, 3, 4, 5 };
 
-         SECTION("All are read") {
 
-             auto allMatch = AllMatch(Predicate<int>([](int elem) {
 
-                 return elem < 10;
 
-             }));
 
-             REQUIRE_THAT(mocked, allMatch);
 
-             REQUIRE(mocked.m_derefed[0]);
 
-             REQUIRE(mocked.m_derefed[1]);
 
-             REQUIRE(mocked.m_derefed[2]);
 
-             REQUIRE(mocked.m_derefed[3]);
 
-             REQUIRE(mocked.m_derefed[4]);
 
-         }
 
-         SECTION("Short-circuited") {
 
-             auto allMatch = AllMatch(Predicate<int>([](int elem) {
 
-                 return elem < 3;
 
-             }));
 
-             REQUIRE_THAT(mocked, !allMatch);
 
-             REQUIRE(mocked.m_derefed[0]);
 
-             REQUIRE(mocked.m_derefed[1]);
 
-             REQUIRE(mocked.m_derefed[2]);
 
-             REQUIRE_FALSE(mocked.m_derefed[3]);
 
-             REQUIRE_FALSE(mocked.m_derefed[4]);
 
-         }
 
-     }
 
- }
 
- TEST_CASE("Usage of AnyMatch range matcher", "[matchers][templated][quantifiers]") {
 
-     using Catch::Matchers::AnyMatch;
 
-     using Catch::Matchers::Predicate;
 
-     SECTION("Basic usage") {
 
-         using Catch::Matchers::Contains;
 
-         using Catch::Matchers::SizeIs;
 
-         std::array<std::array<int, 5>, 5> data{ {
 
-                                         {{ 0, 1, 2, 3, 5 }},
 
-                                         {{ 4,-3,-2, 5, 0 }},
 
-                                         {{ 0, 0, 0, 5, 0 }},
 
-                                         {{ 0,-5, 0, 5, 0 }},
 
-                                         {{ 1, 0, 0,-1, 5 }}
 
-         } };
 
-         REQUIRE_THAT(data,  AnyMatch(SizeIs(5)));
 
-         REQUIRE_THAT(data, !AnyMatch(Contains(0) && Contains(10)));
 
-     }
 
-     SECTION( "Type requires ADL found begin and end" ) {
 
-         unrelated::needs_ADL_begin<int> needs_adl{ 1, 2, 3, 4, 5 };
 
-         REQUIRE_THAT( needs_adl, AnyMatch( Predicate<int>( []( int elem ) {
 
-                           return elem < 3;
 
-                       } ) ) );
 
-     }
 
-     SECTION("Shortcircuiting") {
 
-         with_mocked_iterator_access<int> mocked{ 1, 2, 3, 4, 5 };
 
-         SECTION("All are read") {
 
-             auto anyMatch = AnyMatch(
 
-                 Predicate<int>( []( int elem ) { return elem > 10; } ) );
 
-             REQUIRE_THAT( mocked, !anyMatch );
 
-             REQUIRE( mocked.m_derefed[0] );
 
-             REQUIRE( mocked.m_derefed[1] );
 
-             REQUIRE( mocked.m_derefed[2] );
 
-             REQUIRE( mocked.m_derefed[3] );
 
-             REQUIRE( mocked.m_derefed[4] );
 
-         }
 
-         SECTION("Short-circuited") {
 
-             auto anyMatch = AnyMatch(
 
-                 Predicate<int>( []( int elem ) { return elem < 3; } ) );
 
-             REQUIRE_THAT( mocked, anyMatch );
 
-             REQUIRE( mocked.m_derefed[0] );
 
-             REQUIRE_FALSE( mocked.m_derefed[1] );
 
-             REQUIRE_FALSE( mocked.m_derefed[2] );
 
-             REQUIRE_FALSE( mocked.m_derefed[3] );
 
-             REQUIRE_FALSE( mocked.m_derefed[4] );
 
-         }
 
-     }
 
- }
 
- TEST_CASE("Usage of NoneMatch range matcher", "[matchers][templated][quantifiers]") {
 
-     using Catch::Matchers::NoneMatch;
 
-     using Catch::Matchers::Predicate;
 
-     SECTION("Basic usage") {
 
-         using Catch::Matchers::Contains;
 
-         using Catch::Matchers::SizeIs;
 
-         std::array<std::array<int, 5>, 5> data{ {
 
-                                         {{ 0, 1, 2, 3, 5 }},
 
-                                         {{ 4,-3,-2, 5, 0 }},
 
-                                         {{ 0, 0, 0, 5, 0 }},
 
-                                         {{ 0,-5, 0, 5, 0 }},
 
-                                         {{ 1, 0, 0,-1, 5 }}
 
-         } };
 
-         REQUIRE_THAT(data, NoneMatch(SizeIs(6)));
 
-         REQUIRE_THAT(data, !NoneMatch(Contains(0) && Contains(1)));
 
-     }
 
-     SECTION( "Type requires ADL found begin and end" ) {
 
-         unrelated::needs_ADL_begin<int> needs_adl{ 1, 2, 3, 4, 5 };
 
-         REQUIRE_THAT( needs_adl, NoneMatch( Predicate<int>( []( int elem ) {
 
-                           return elem > 6;
 
-                       } ) ) );
 
-     }
 
-     SECTION("Shortcircuiting") {
 
-         with_mocked_iterator_access<int> mocked{ 1, 2, 3, 4, 5 };
 
-         SECTION("All are read") {
 
-             auto noneMatch = NoneMatch(
 
-                 Predicate<int>([](int elem) { return elem > 10; }));
 
-             REQUIRE_THAT(mocked, noneMatch);
 
-             REQUIRE(mocked.m_derefed[0]);
 
-             REQUIRE(mocked.m_derefed[1]);
 
-             REQUIRE(mocked.m_derefed[2]);
 
-             REQUIRE(mocked.m_derefed[3]);
 
-             REQUIRE(mocked.m_derefed[4]);
 
-         }
 
-         SECTION("Short-circuited") {
 
-             auto noneMatch = NoneMatch(
 
-                 Predicate<int>([](int elem) { return elem < 3; }));
 
-             REQUIRE_THAT(mocked, !noneMatch);
 
-             REQUIRE(mocked.m_derefed[0]);
 
-             REQUIRE_FALSE(mocked.m_derefed[1]);
 
-             REQUIRE_FALSE(mocked.m_derefed[2]);
 
-             REQUIRE_FALSE(mocked.m_derefed[3]);
 
-             REQUIRE_FALSE(mocked.m_derefed[4]);
 
-         }
 
-     }
 
- }
 
- namespace {
 
-     struct ConvertibleToBool
 
-     {
 
-         bool v;
 
-         explicit operator bool() const
 
-         {
 
-             return v;
 
-         }
 
-     };
 
- }
 
- namespace Catch {
 
-     template <>
 
-     struct StringMaker<ConvertibleToBool> {
 
-         static std::string
 
-         convert( ConvertibleToBool const& convertible_to_bool ) {
 
-             return ::Catch::Detail::stringify( convertible_to_bool.v );
 
-         }
 
-     };
 
- } // namespace Catch
 
- TEST_CASE("Usage of AllTrue range matcher", "[matchers][templated][quantifiers]") {
 
-     using Catch::Matchers::AllTrue;
 
-     SECTION( "Basic usage" ) {
 
-         SECTION( "All true evaluates to true" ) {
 
-             std::array<bool, 5> const data{ { true, true, true, true, true } };
 
-             REQUIRE_THAT( data, AllTrue() );
 
-         }
 
-         SECTION( "Empty evaluates to true" ) {
 
-             std::array<bool, 0> const data{};
 
-             REQUIRE_THAT( data, AllTrue() );
 
-         }
 
-         SECTION( "One false evalutes to false" ) {
 
-             std::array<bool, 5> const data{ { true, true, false, true, true } };
 
-             REQUIRE_THAT( data, !AllTrue() );
 
-         }
 
-         SECTION( "All false evaluates to false" ) {
 
-             std::array<bool, 5> const data{
 
-                 { false, false, false, false, false } };
 
-             REQUIRE_THAT( data, !AllTrue() );
 
-         }
 
-     }
 
-     SECTION( "Contained type is convertible to bool" ) {
 
-         SECTION( "All true evaluates to true" ) {
 
-             std::array<ConvertibleToBool, 5> const data{
 
-                 { { true }, { true }, { true }, { true }, { true } } };
 
-             REQUIRE_THAT( data, AllTrue() );
 
-         }
 
-         SECTION( "One false evalutes to false" ) {
 
-             std::array<ConvertibleToBool, 5> const data{
 
-                 { { true }, { true }, { false }, { true }, { true } } };
 
-             REQUIRE_THAT( data, !AllTrue() );
 
-         }
 
-         SECTION( "All false evaluates to false" ) {
 
-             std::array<ConvertibleToBool, 5> const data{
 
-                 { { false }, { false }, { false }, { false }, { false } } };
 
-             REQUIRE_THAT( data, !AllTrue() );
 
-         }
 
-     }
 
-     SECTION( "Shortcircuiting" ) {
 
-         SECTION( "All are read" ) {
 
-             with_mocked_iterator_access<bool> const mocked{
 
-                 true, true, true, true, true };
 
-             REQUIRE_THAT( mocked, AllTrue() );
 
-             REQUIRE( mocked.m_derefed[0] );
 
-             REQUIRE( mocked.m_derefed[1] );
 
-             REQUIRE( mocked.m_derefed[2] );
 
-             REQUIRE( mocked.m_derefed[3] );
 
-             REQUIRE( mocked.m_derefed[4] );
 
-         }
 
-         SECTION( "Short-circuited" ) {
 
-             with_mocked_iterator_access<bool> const mocked{
 
-                 true, true, false, true, true };
 
-             REQUIRE_THAT( mocked, !AllTrue() );
 
-             REQUIRE( mocked.m_derefed[0] );
 
-             REQUIRE( mocked.m_derefed[1] );
 
-             REQUIRE( mocked.m_derefed[2] );
 
-             REQUIRE_FALSE( mocked.m_derefed[3] );
 
-             REQUIRE_FALSE( mocked.m_derefed[4] );
 
-         }
 
-     }
 
- }
 
- TEST_CASE( "Usage of NoneTrue range matcher", "[matchers][templated][quantifiers]" ) {
 
-     using Catch::Matchers::NoneTrue;
 
-     SECTION( "Basic usage" ) {
 
-         SECTION( "All true evaluates to false" ) {
 
-             std::array<bool, 5> const data{ { true, true, true, true, true } };
 
-             REQUIRE_THAT( data, !NoneTrue() );
 
-         }
 
-         SECTION( "Empty evaluates to true" ) {
 
-             std::array<bool, 0> const data{};
 
-             REQUIRE_THAT( data, NoneTrue() );
 
-         }
 
-         SECTION( "One true evalutes to false" ) {
 
-             std::array<bool, 5> const data{
 
-                 { false, false, true, false, false } };
 
-             REQUIRE_THAT( data, !NoneTrue() );
 
-         }
 
-         SECTION( "All false evaluates to true" ) {
 
-             std::array<bool, 5> const data{
 
-                 { false, false, false, false, false } };
 
-             REQUIRE_THAT( data, NoneTrue() );
 
-         }
 
-     }
 
-     SECTION( "Contained type is convertible to bool" ) {
 
-         SECTION( "All true evaluates to false" ) {
 
-             std::array<ConvertibleToBool, 5> const data{
 
-                 { { true }, { true }, { true }, { true }, { true } } };
 
-             REQUIRE_THAT( data, !NoneTrue() );
 
-         }
 
-         SECTION( "One true evalutes to false" ) {
 
-             std::array<ConvertibleToBool, 5> const data{
 
-                 { { false }, { false }, { true }, { false }, { false } } };
 
-             REQUIRE_THAT( data, !NoneTrue() );
 
-         }
 
-         SECTION( "All false evaluates to true" ) {
 
-             std::array<ConvertibleToBool, 5> const data{
 
-                 { { false }, { false }, { false }, { false }, { false } } };
 
-             REQUIRE_THAT( data, NoneTrue() );
 
-         }
 
-     }
 
-     SECTION( "Shortcircuiting" ) {
 
-         SECTION( "All are read" ) {
 
-             with_mocked_iterator_access<bool> const mocked{
 
-                 false, false, false, false, false };
 
-             REQUIRE_THAT( mocked, NoneTrue() );
 
-             REQUIRE( mocked.m_derefed[0] );
 
-             REQUIRE( mocked.m_derefed[1] );
 
-             REQUIRE( mocked.m_derefed[2] );
 
-             REQUIRE( mocked.m_derefed[3] );
 
-             REQUIRE( mocked.m_derefed[4] );
 
-         }
 
-         SECTION( "Short-circuited" ) {
 
-             with_mocked_iterator_access<bool> const mocked{
 
-                 false, false, true, true, true };
 
-             REQUIRE_THAT( mocked, !NoneTrue() );
 
-             REQUIRE( mocked.m_derefed[0] );
 
-             REQUIRE( mocked.m_derefed[1] );
 
-             REQUIRE( mocked.m_derefed[2] );
 
-             REQUIRE_FALSE( mocked.m_derefed[3] );
 
-             REQUIRE_FALSE( mocked.m_derefed[4] );
 
-         }
 
-     }
 
- }
 
- TEST_CASE( "Usage of AnyTrue range matcher", "[matchers][templated][quantifiers]" ) {
 
-     using Catch::Matchers::AnyTrue;
 
-     SECTION( "Basic usage" ) {
 
-         SECTION( "All true evaluates to true" ) {
 
-             std::array<bool, 5> const data{ { true, true, true, true, true } };
 
-             REQUIRE_THAT( data, AnyTrue() );
 
-         }
 
-         SECTION( "Empty evaluates to false" ) {
 
-             std::array<bool, 0> const data{};
 
-             REQUIRE_THAT( data, !AnyTrue() );
 
-         }
 
-         SECTION( "One true evalutes to true" ) {
 
-             std::array<bool, 5> const data{
 
-                 { false, false, true, false, false } };
 
-             REQUIRE_THAT( data, AnyTrue() );
 
-         }
 
-         SECTION( "All false evaluates to false" ) {
 
-             std::array<bool, 5> const data{
 
-                 { false, false, false, false, false } };
 
-             REQUIRE_THAT( data, !AnyTrue() );
 
-         }
 
-     }
 
-     SECTION( "Contained type is convertible to bool" ) {
 
-         SECTION( "All true evaluates to true" ) {
 
-             std::array<ConvertibleToBool, 5> const data{
 
-                 { { true }, { true }, { true }, { true }, { true } } };
 
-             REQUIRE_THAT( data, AnyTrue() );
 
-         }
 
-         SECTION( "One true evalutes to true" ) {
 
-             std::array<ConvertibleToBool, 5> const data{
 
-                 { { false }, { false }, { true }, { false }, { false } } };
 
-             REQUIRE_THAT( data, AnyTrue() );
 
-         }
 
-         SECTION( "All false evaluates to false" ) {
 
-             std::array<ConvertibleToBool, 5> const data{
 
-                 { { false }, { false }, { false }, { false }, { false } } };
 
-             REQUIRE_THAT( data, !AnyTrue() );
 
-         }
 
-     }
 
-     SECTION( "Shortcircuiting" ) {
 
-         SECTION( "All are read" ) {
 
-             with_mocked_iterator_access<bool> const mocked{
 
-                 false, false, false, false, true };
 
-             REQUIRE_THAT( mocked, AnyTrue() );
 
-             REQUIRE( mocked.m_derefed[0] );
 
-             REQUIRE( mocked.m_derefed[1] );
 
-             REQUIRE( mocked.m_derefed[2] );
 
-             REQUIRE( mocked.m_derefed[3] );
 
-             REQUIRE( mocked.m_derefed[4] );
 
-         }
 
-         SECTION( "Short-circuited" ) {
 
-             with_mocked_iterator_access<bool> const mocked{
 
-                 false, false, true, true, true };
 
-             REQUIRE_THAT( mocked, AnyTrue() );
 
-             REQUIRE( mocked.m_derefed[0] );
 
-             REQUIRE( mocked.m_derefed[1] );
 
-             REQUIRE( mocked.m_derefed[2] );
 
-             REQUIRE_FALSE( mocked.m_derefed[3] );
 
-             REQUIRE_FALSE( mocked.m_derefed[4] );
 
-         }
 
-     }
 
- }
 
- TEST_CASE("All/Any/None True matchers support types with ADL begin",
 
-           "[approvals][matchers][quantifiers][templated]") {
 
-     using Catch::Matchers::AllTrue;
 
-     using Catch::Matchers::NoneTrue;
 
-     using Catch::Matchers::AnyTrue;
 
-     SECTION( "Type requires ADL found begin and end" ) {
 
-         unrelated::needs_ADL_begin<bool> const needs_adl{
 
-             true, true, true, true, true };
 
-         REQUIRE_THAT( needs_adl, AllTrue() );
 
-     }
 
-     SECTION( "Type requires ADL found begin and end" ) {
 
-         unrelated::needs_ADL_begin<bool> const needs_adl{
 
-             false, false, false, false, false };
 
-         REQUIRE_THAT( needs_adl, NoneTrue() );
 
-     }
 
-     SECTION( "Type requires ADL found begin and end" ) {
 
-         unrelated::needs_ADL_begin<bool> const needs_adl{
 
-             false, false, true, false, false };
 
-         REQUIRE_THAT( needs_adl, AnyTrue() );
 
-     }
 
- }
 
- // Range loop iterating over range with different types for begin and end is a
 
- // C++17 feature, and GCC refuses to compile such code unless the lang mode is
 
- // set to C++17 or later.
 
- #if defined(CATCH_CPP17_OR_GREATER)
 
- TEST_CASE( "The quantifier range matchers support types with different types returned from begin and end",
 
-            "[matchers][templated][quantifiers][approvals]" ) {
 
-     using Catch::Matchers::AllMatch;
 
-     using Catch::Matchers::AllTrue;
 
-     using Catch::Matchers::AnyMatch;
 
-     using Catch::Matchers::AnyTrue;
 
-     using Catch::Matchers::NoneMatch;
 
-     using Catch::Matchers::NoneTrue;
 
-     using Catch::Matchers::Predicate;
 
-     SECTION( "AllAnyNoneMatch" ) {
 
-         has_different_begin_end_types<int> diff_types{ 1, 2, 3, 4, 5 };
 
-         REQUIRE_THAT( diff_types, !AllMatch( Predicate<int>( []( int elem ) {
 
-                           return elem < 3;
 
-                       } ) ) );
 
-         REQUIRE_THAT( diff_types, AnyMatch( Predicate<int>( []( int elem ) {
 
-                           return elem < 2;
 
-                       } ) ) );
 
-         REQUIRE_THAT( diff_types, !NoneMatch( Predicate<int>( []( int elem ) {
 
-                           return elem < 3;
 
-                       } ) ) );
 
-     }
 
-     SECTION( "AllAnyNoneTrue" ) {
 
-         has_different_begin_end_types<bool> diff_types{ false, false, true, false, false };
 
-         REQUIRE_THAT( diff_types, !AllTrue() );
 
-         REQUIRE_THAT( diff_types, AnyTrue() );
 
-         REQUIRE_THAT( diff_types, !NoneTrue() );
 
-     }
 
- }
 
- #endif
 
 
  |