diff --git a/libs/algorithm/test/all_of_equal.cpp b/libs/algorithm/test/all_of_equal.cpp new file mode 100644 index 00000000..7233a536 --- /dev/null +++ b/libs/algorithm/test/all_of_equal.cpp @@ -0,0 +1,40 @@ +#ifndef SPROUT_LIBS_ALGORITHM_TEST_ALL_OF_EQUAL_CPP +#define SPROUT_LIBS_ALGORITHM_TEST_ALL_OF_EQUAL_CPP + +#include +#include +#include +#include + +namespace testspr { + static void algorithm_all_of_equal_test() { + using namespace sprout; + { + SPROUT_STATIC_CONSTEXPR auto arr1 = array{{1, 1, 1, 1, 1, 10, 10, 10, 10, 10}}; + + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::all_of_equal( + sprout::begin(arr1), + sprout::end(arr1), + 1 + ); + TESTSPR_BOTH_ASSERT(!result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::all_of_equal( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + 1 + ); + TESTSPR_BOTH_ASSERT(result); + } + } + } +} // namespace testspr + +#ifndef TESTSPR_CPP_INCLUDE +# define TESTSPR_TEST_FUNCTION testspr::algorithm_all_of_equal_test +# include +#endif + +#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_ALL_OF_EQUAL_CPP diff --git a/libs/algorithm/test/any_of_equal.cpp b/libs/algorithm/test/any_of_equal.cpp new file mode 100644 index 00000000..2026b344 --- /dev/null +++ b/libs/algorithm/test/any_of_equal.cpp @@ -0,0 +1,56 @@ +#ifndef SPROUT_LIBS_ALGORITHM_TEST_ANY_OF_EQUAL_CPP +#define SPROUT_LIBS_ALGORITHM_TEST_ANY_OF_EQUAL_CPP + +#include +#include +#include +#include + +namespace testspr { + static void algorithm_any_of_equal_test() { + using namespace sprout; + { + SPROUT_STATIC_CONSTEXPR auto arr1 = array{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}; + + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::any_of_equal( + sprout::begin(arr1), + sprout::end(arr1), + 10 + ); + TESTSPR_BOTH_ASSERT(result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::any_of_equal( + sprout::begin(arr1), + sprout::end(arr1), + 11 + ); + TESTSPR_BOTH_ASSERT(!result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::any_of_equal( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + 10 + ); + TESTSPR_BOTH_ASSERT(!result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::any_of_equal( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + 11 + ); + TESTSPR_BOTH_ASSERT(!result); + } + } + } +} // namespace testspr + +#ifndef TESTSPR_CPP_INCLUDE +# define TESTSPR_TEST_FUNCTION testspr::algorithm_any_of_equal_test +# include +#endif + +#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_ANY_OF_EQUAL_CPP diff --git a/libs/algorithm/test/non_modifying.cpp b/libs/algorithm/test/non_modifying.cpp index 3e95cc59..7ac63545 100644 --- a/libs/algorithm/test/non_modifying.cpp +++ b/libs/algorithm/test/non_modifying.cpp @@ -41,6 +41,10 @@ #include "./max_element.cpp" #include "./minmax_element.cpp" #include "./lexicographical_compare.cpp" +#include "./all_of_equal.cpp" +#include "./any_of_equal.cpp" +#include "./none_of_equal.cpp" +#include "./one_of_equal.cpp" #ifdef TESTSPR_CPP_INCLUDE_DISABLE_SPROUT_LIBS_ALGORITHM_TEST_NON_MODIFYIING_CPP # undef TESTSPR_CPP_INCLUDE @@ -83,6 +87,10 @@ namespace testspr { testspr::algorithm_max_element_test(); testspr::algorithm_minmax_element_test(); testspr::algorithm_lexicographical_compare_test(); + testspr::algorithm_all_of_equal_test(); + testspr::algorithm_any_of_equal_test(); + testspr::algorithm_none_of_equal_test(); + testspr::algorithm_one_of_equal_test(); } } // namespace testspr diff --git a/libs/algorithm/test/none_of_equal.cpp b/libs/algorithm/test/none_of_equal.cpp new file mode 100644 index 00000000..07068150 --- /dev/null +++ b/libs/algorithm/test/none_of_equal.cpp @@ -0,0 +1,56 @@ +#ifndef SPROUT_LIBS_ALGORITHM_TEST_NONE_OF_EQUAL_CPP +#define SPROUT_LIBS_ALGORITHM_TEST_NONE_OF_EQUAL_CPP + +#include +#include +#include +#include + +namespace testspr { + static void algorithm_none_of_equal_test() { + using namespace sprout; + { + SPROUT_STATIC_CONSTEXPR auto arr1 = array{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}; + + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::none_of_equal( + sprout::begin(arr1), + sprout::end(arr1), + 10 + ); + TESTSPR_BOTH_ASSERT(!result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::none_of_equal( + sprout::begin(arr1), + sprout::end(arr1), + 11 + ); + TESTSPR_BOTH_ASSERT(result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::none_of_equal( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + 10 + ); + TESTSPR_BOTH_ASSERT(result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::none_of_equal( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + 11 + ); + TESTSPR_BOTH_ASSERT(result); + } + } + } +} // namespace testspr + +#ifndef TESTSPR_CPP_INCLUDE +# define TESTSPR_TEST_FUNCTION testspr::algorithm_none_of_equal_test +# include +#endif + +#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_NONE_OF_EQUAL_CPP diff --git a/libs/algorithm/test/one_of_equal.cpp b/libs/algorithm/test/one_of_equal.cpp new file mode 100644 index 00000000..a8479899 --- /dev/null +++ b/libs/algorithm/test/one_of_equal.cpp @@ -0,0 +1,56 @@ +#ifndef SPROUT_LIBS_ALGORITHM_TEST_ONE_OF_EQUAL_CPP +#define SPROUT_LIBS_ALGORITHM_TEST_ONE_OF_EQUAL_CPP + +#include +#include +#include +#include + +namespace testspr { + static void algorithm_one_of_equal_test() { + using namespace sprout; + { + SPROUT_STATIC_CONSTEXPR auto arr1 = array{{1, 2, 3, 4, 5, 5, 5, 5, 5, 10}}; + + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::one_of_equal( + sprout::begin(arr1), + sprout::end(arr1), + 5 + ); + TESTSPR_BOTH_ASSERT(!result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::one_of_equal( + sprout::begin(arr1), + sprout::end(arr1), + 10 + ); + TESTSPR_BOTH_ASSERT(result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::one_of_equal( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + 5 + ); + TESTSPR_BOTH_ASSERT(result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::one_of_equal( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + 10 + ); + TESTSPR_BOTH_ASSERT(!result); + } + } + } +} // namespace testspr + +#ifndef TESTSPR_CPP_INCLUDE +# define TESTSPR_TEST_FUNCTION testspr::algorithm_one_of_equal_test +# include +#endif + +#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_ONE_OF_EQUAL_CPP diff --git a/sprout/algorithm/all_of_equal.hpp b/sprout/algorithm/all_of_equal.hpp index 79f4e131..2b3b8f14 100644 --- a/sprout/algorithm/all_of_equal.hpp +++ b/sprout/algorithm/all_of_equal.hpp @@ -1,19 +1,73 @@ #ifndef SPROUT_ALGORITHM_ALL_OF_EQUAL_HPP #define SPROUT_ALGORITHM_ALL_OF_EQUAL_HPP +#include #include #include +#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT namespace sprout { + namespace detail { + template + inline SPROUT_CONSTEXPR bool + all_of_equal_impl_ra( + RandomAccessIterator first, RandomAccessIterator last, T const& value, + typename std::iterator_traits::difference_type pivot + ) + { + return pivot == 0 ? *first == value + : sprout::detail::all_of_equal_impl_ra( + first, sprout::next(first, pivot), value, + pivot / 2 + ) + && sprout::detail::all_of_equal_impl_ra( + sprout::next(first, pivot), last, value, + (NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) - pivot) / 2 + ) + ; + } + template + inline SPROUT_CONSTEXPR bool + all_of_equal( + RandomAccessIterator first, RandomAccessIterator last, T const& value, + std::random_access_iterator_tag* + ) + { + return first == last ? true + : sprout::detail::all_of_equal_impl_ra(first, last, value, NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) / 2) + ; + } + + template + inline SPROUT_CONSTEXPR bool + all_of_equal_impl(InputIterator first, InputIterator last, T const& value) { + return first == last ? true + : *first == value && sprout::detail::all_of_equal_impl(sprout::next(first), last, value) + ; + } + template + inline SPROUT_CONSTEXPR bool + all_of_equal( + InputIterator first, InputIterator last, T const& value, + void* + ) + { + return sprout::detail::all_of_equal_impl(first, last, value); + } + } //namespace detail + // // all_of_equal // + // recursion depth: + // [first, last) is RandomAccessIterator -> O(log N) + // otherwise -> O(N) + // template inline SPROUT_CONSTEXPR bool all_of_equal(InputIterator first, InputIterator last, T const& value) { - return first == last ? true - : *first == value && sprout::all_of_equal(sprout::next(first), last, value) - ; + typedef typename std::iterator_traits::iterator_category* category; + return sprout::detail::all_of_equal(first, last, value, category()); } } // namespace sprout diff --git a/sprout/algorithm/any_of_equal.hpp b/sprout/algorithm/any_of_equal.hpp index 2bc6e03c..ea73f4e6 100644 --- a/sprout/algorithm/any_of_equal.hpp +++ b/sprout/algorithm/any_of_equal.hpp @@ -1,19 +1,73 @@ #ifndef SPROUT_ALGORITHM_ANY_OF_EQUAL_HPP #define SPROUT_ALGORITHM_ANY_OF_EQUAL_HPP +#include #include #include +#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT namespace sprout { + namespace detail { + template + inline SPROUT_CONSTEXPR bool + any_of_equal_impl_ra( + RandomAccessIterator first, RandomAccessIterator last, T const& value, + typename std::iterator_traits::difference_type pivot + ) + { + return pivot == 0 ? *first == value + : sprout::detail::any_of_equal_impl_ra( + first, sprout::next(first, pivot), value, + pivot / 2 + ) + || sprout::detail::any_of_equal_impl_ra( + sprout::next(first, pivot), last, value, + (NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) - pivot) / 2 + ) + ; + } + template + inline SPROUT_CONSTEXPR bool + any_of_equal( + RandomAccessIterator first, RandomAccessIterator last, T const& value, + std::random_access_iterator_tag* + ) + { + return first == last ? false + : sprout::detail::any_of_equal_impl_ra(first, last, value, NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) / 2) + ; + } + + template + inline SPROUT_CONSTEXPR bool + any_of_equal_impl(InputIterator first, InputIterator last, T const& value) { + return first == last ? false + : *first == value || sprout::detail::any_of_equal_impl(sprout::next(first), last, value) + ; + } + template + inline SPROUT_CONSTEXPR bool + any_of_equal( + InputIterator first, InputIterator last, T const& value, + void* + ) + { + return sprout::detail::any_of_equal_impl(first, last, value); + } + } //namespace detail + // // any_of_equal // + // recursion depth: + // [first, last) is RandomAccessIterator -> O(log N) + // otherwise -> O(N) + // template inline SPROUT_CONSTEXPR bool any_of_equal(InputIterator first, InputIterator last, T const& value) { - return first == last ? false - : *first == value || sprout::any_of_equal(sprout::next(first), last, value) - ; + typedef typename std::iterator_traits::iterator_category* category; + return sprout::detail::any_of_equal(first, last, value, category()); } } // namespace sprout diff --git a/sprout/algorithm/none_of.hpp b/sprout/algorithm/none_of.hpp index 5abe3dfb..4dbf3a4a 100644 --- a/sprout/algorithm/none_of.hpp +++ b/sprout/algorithm/none_of.hpp @@ -1,8 +1,10 @@ #ifndef SPROUT_ALGORITHM_NONE_OF_HPP #define SPROUT_ALGORITHM_NONE_OF_HPP +#include #include #include +#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT namespace sprout { namespace detail { diff --git a/sprout/algorithm/none_of_equal.hpp b/sprout/algorithm/none_of_equal.hpp index 36c3b0ef..ac64f67d 100644 --- a/sprout/algorithm/none_of_equal.hpp +++ b/sprout/algorithm/none_of_equal.hpp @@ -1,19 +1,73 @@ #ifndef SPROUT_ALGORITHM_NONE_OF_EQUAL_HPP #define SPROUT_ALGORITHM_NONE_OF_EQUAL_HPP +#include #include #include +#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT namespace sprout { + namespace detail { + template + inline SPROUT_CONSTEXPR bool + none_of_equal_impl_ra( + RandomAccessIterator first, RandomAccessIterator last, T const& value, + typename std::iterator_traits::difference_type pivot + ) + { + return pivot == 0 ? !(*first == value) + : sprout::detail::none_of_equal_impl_ra( + first, sprout::next(first, pivot), value, + pivot / 2 + ) + && sprout::detail::none_of_equal_impl_ra( + sprout::next(first, pivot), last, value, + (NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) - pivot) / 2 + ) + ; + } + template + inline SPROUT_CONSTEXPR bool + none_of_equal( + RandomAccessIterator first, RandomAccessIterator last, T const& value, + std::random_access_iterator_tag* + ) + { + return first == last ? true + : sprout::detail::none_of_equal_impl_ra(first, last, value, NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) / 2) + ; + } + + template + inline SPROUT_CONSTEXPR bool + none_of_equal_impl(InputIterator first, InputIterator last, T const& value) { + return first == last ? true + : !(*first == value) && sprout::detail::none_of_equal_impl(sprout::next(first), last, value) + ; + } + template + inline SPROUT_CONSTEXPR bool + none_of_equal( + InputIterator first, InputIterator last, T const& value, + void* + ) + { + return sprout::detail::none_of_equal_impl(first, last, value); + } + } //namespace detail + // // none_of_equal // + // recursion depth: + // [first, last) is RandomAccessIterator -> O(log N) + // otherwise -> O(N) + // template inline SPROUT_CONSTEXPR bool none_of_equal(InputIterator first, InputIterator last, T const& value) { - return first == last ? true - : !(*first == value) && sprout::none_of_equal(sprout::next(first), last, value) - ; + typedef typename std::iterator_traits::iterator_category* category; + return sprout::detail::none_of_equal(first, last, value, category()); } } // namespace sprout diff --git a/sprout/algorithm/one_of_equal.hpp b/sprout/algorithm/one_of_equal.hpp index 029d00cc..0362fbb1 100644 --- a/sprout/algorithm/one_of_equal.hpp +++ b/sprout/algorithm/one_of_equal.hpp @@ -16,9 +16,14 @@ namespace sprout { ; } } // namespace detail + // // one_of_equal // + // recursion depth: + // [first, last) is RandomAccessIterator -> O(log N) + // otherwise -> O(N) + // template inline SPROUT_CONSTEXPR bool one_of_equal(InputIterator first, InputIterator last, T const& value) {