Line data Source code
1 : /*! 2 : @file 3 : Defines `boost::hana::for_each`. 4 : 5 : Copyright Louis Dionne 2013-2022 6 : Distributed under the Boost Software License, Version 1.0. 7 : (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) 8 : */ 9 : 10 : #ifndef BOOST_HANA_FOR_EACH_HPP 11 : #define BOOST_HANA_FOR_EACH_HPP 12 : 13 : #include <boost/hana/fwd/for_each.hpp> 14 : 15 : #include <boost/hana/concept/foldable.hpp> 16 : #include <boost/hana/config.hpp> 17 : #include <boost/hana/core/dispatch.hpp> 18 : #include <boost/hana/unpack.hpp> 19 : 20 : 21 : namespace boost { namespace hana { 22 : //! @cond 23 : template <typename Xs, typename F> 24 983945 : constexpr void for_each_t::operator()(Xs&& xs, F&& f) const { 25 : using S = typename hana::tag_of<Xs>::type; 26 : using ForEach = BOOST_HANA_DISPATCH_IF(for_each_impl<S>, 27 : hana::Foldable<S>::value 28 : ); 29 : 30 : #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS 31 : static_assert(hana::Foldable<S>::value, 32 : "hana::for_each(xs, f) requires 'xs' to be Foldable"); 33 : #endif 34 : 35 983945 : return ForEach::apply(static_cast<Xs&&>(xs), static_cast<F&&>(f)); 36 : } 37 : //! @endcond 38 : 39 : namespace detail { 40 : template <typename F> 41 : struct on_each { 42 : F f; 43 : template <typename ...Xs> 44 983945 : constexpr void operator()(Xs&& ...xs) const { 45 : using Swallow = int[]; 46 983945 : (void)Swallow{0, ((void)(*f)(static_cast<Xs&&>(xs)), 0)...}; 47 983945 : } 48 : }; 49 : } 50 : 51 : template <typename T, bool condition> 52 : struct for_each_impl<T, when<condition>> : default_ { 53 : template <typename Xs, typename F> 54 983945 : static constexpr void apply(Xs&& xs, F&& f) { 55 : // We use a pointer instead of a reference to avoid a Clang ICE. 56 1967890 : hana::unpack(static_cast<Xs&&>(xs), 57 983945 : detail::on_each<decltype(&f)>{&f}); 58 983945 : } 59 : }; 60 : }} // end namespace boost::hana 61 : 62 : #endif // !BOOST_HANA_FOR_EACH_HPP