// Boost.Geometry // Copyright (c) 2021, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html #ifndef BOOST_GEOMETRY_UTIL_ALGORITHM_HPP #define BOOST_GEOMETRY_UTIL_ALGORITHM_HPP #include #include namespace boost { namespace geometry { #ifndef DOXYGEN_NO_DETAIL namespace detail { // Other implementations can be found in the history of this file. // The discussion and benchmarks can be found here: // https://github.com/boostorg/geometry/pull/827 // O(logN) version 2 template struct for_each_index_impl2 { static const std::size_t N1 = N / 2; static const std::size_t N2 = N - N1; template constexpr static inline void apply(UnaryFunction& function) { for_each_index_impl2::template apply(function); for_each_index_impl2::template apply(function); } }; template <> struct for_each_index_impl2<3> { template constexpr static inline void apply(UnaryFunction& function) { function(util::index_constant()); function(util::index_constant()); function(util::index_constant()); } }; template <> struct for_each_index_impl2<2> { template constexpr static inline void apply(UnaryFunction& function) { function(util::index_constant()); function(util::index_constant()); } }; template <> struct for_each_index_impl2<1> { template constexpr static inline void apply(UnaryFunction& function) { function(util::index_constant()); } }; template <> struct for_each_index_impl2<0> { template constexpr static inline void apply(UnaryFunction& ) {} }; // Interface template constexpr inline UnaryFunction for_each_index(UnaryFunction function) { for_each_index_impl2 < N >::template apply<0>(function); return function; } template constexpr inline UnaryFunction for_each_dimension(UnaryFunction function) { for_each_index_impl2 < geometry::dimension::value >::template apply<0>(function); return function; } // ---------------------------------------------------------------------------- // O(logN) version 2 template struct all_indexes_of_impl2 { static const std::size_t N1 = N / 2; static const std::size_t N2 = N - N1; template constexpr static inline bool apply(UnaryPredicate& predicate) { return all_indexes_of_impl2::template apply(predicate) && all_indexes_of_impl2::template apply(predicate); } }; template <> struct all_indexes_of_impl2<3> { template constexpr static inline bool apply(UnaryPredicate& predicate) { return predicate(util::index_constant()) && predicate(util::index_constant()) && predicate(util::index_constant()); } }; template <> struct all_indexes_of_impl2<2> { template constexpr static inline bool apply(UnaryPredicate& predicate) { return predicate(util::index_constant()) && predicate(util::index_constant()); } }; template <> struct all_indexes_of_impl2<1> { template constexpr static inline bool apply(UnaryPredicate& predicate) { return predicate(util::index_constant()); } }; template <> struct all_indexes_of_impl2<0> { template constexpr static inline bool apply(UnaryPredicate& ) { return true; } }; // Interface template constexpr inline bool all_indexes_of(UnaryPredicate predicate) { return all_indexes_of_impl2::template apply<0>(predicate); } template constexpr inline bool all_dimensions_of(UnaryPredicate predicate) { return all_indexes_of_impl2 < geometry::dimension::value >::template apply<0>(predicate); } // ---------------------------------------------------------------------------- // O(logN) version 2 template struct any_index_of_impl2 { static const std::size_t N1 = N / 2; static const std::size_t N2 = N - N1; template constexpr static inline bool apply(UnaryPredicate& predicate) { return any_index_of_impl2::template apply(predicate) || any_index_of_impl2::template apply(predicate); } }; template <> struct any_index_of_impl2<3> { template constexpr static inline bool apply(UnaryPredicate& predicate) { return predicate(util::index_constant()) || predicate(util::index_constant()) || predicate(util::index_constant()); } }; template <> struct any_index_of_impl2<2> { template constexpr static inline bool apply(UnaryPredicate& predicate) { return predicate(util::index_constant()) || predicate(util::index_constant()); } }; template <> struct any_index_of_impl2<1> { template constexpr static inline bool apply(UnaryPredicate& predicate) { return predicate(util::index_constant()); } }; template <> struct any_index_of_impl2<0> { template constexpr static inline bool apply(UnaryPredicate& ) { return false; } }; // Interface template constexpr inline bool any_index_of(UnaryPredicate predicate) { return any_index_of_impl2::template apply<0>(predicate); } template constexpr inline bool any_dimension_of(UnaryPredicate predicate) { return any_index_of_impl2 < geometry::dimension::value >::template apply<0>(predicate); } template constexpr inline bool none_index_of(UnaryPredicate predicate) { return ! any_index_of_impl2::template apply<0>(predicate); } template constexpr inline bool none_dimension_of(UnaryPredicate predicate) { return ! any_index_of_impl2 < geometry::dimension::value >::template apply<0>(predicate); } // ---------------------------------------------------------------------------- } // namespace detail #endif // DOXYGEN_NO_DETAIL }} // namespace boost::geometry #endif // BOOST_GEOMETRY_UTIL_ALGORITHM_HPP