tap.hpp 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. /*!
  2. @file
  3. Defines `boost::hana::tap`.
  4. Copyright Louis Dionne 2013-2022
  5. Distributed under the Boost Software License, Version 1.0.
  6. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  7. */
  8. #ifndef BOOST_HANA_TAP_HPP
  9. #define BOOST_HANA_TAP_HPP
  10. #include <boost/hana/fwd/tap.hpp>
  11. #include <boost/hana/concept/monad.hpp>
  12. #include <boost/hana/config.hpp>
  13. #include <boost/hana/core/dispatch.hpp>
  14. #include <boost/hana/functional/partial.hpp>
  15. #include <boost/hana/lift.hpp>
  16. namespace boost { namespace hana {
  17. //! @cond
  18. template <typename M>
  19. template <typename F>
  20. constexpr auto tap_t<M>::operator()(F&& f) const {
  21. #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
  22. static_assert(hana::Monad<M>::value,
  23. "hana::tap<M> requires 'M' to be a Monad");
  24. #endif
  25. using Tap = BOOST_HANA_DISPATCH_IF(tap_impl<M>,
  26. hana::Monad<M>::value
  27. );
  28. return Tap::apply(static_cast<F&&>(f));
  29. }
  30. //! @endcond
  31. namespace detail {
  32. template <typename M>
  33. struct tap_helper {
  34. template <typename F, typename X>
  35. constexpr auto operator()(F&& f, X&& x) const {
  36. (void)static_cast<F&&>(f)(x);
  37. return hana::lift<M>(static_cast<X&&>(x));
  38. }
  39. };
  40. }
  41. template <typename M, bool condition>
  42. struct tap_impl<M, when<condition>> : default_ {
  43. template <typename F>
  44. static constexpr auto apply(F&& f)
  45. { return hana::partial(detail::tap_helper<M>{}, static_cast<F&&>(f)); }
  46. };
  47. }} // end namespace boost::hana
  48. #endif // !BOOST_HANA_TAP_HPP