unfold_left.hpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /*!
  2. @file
  3. Defines `boost::hana::unfold_left`.
  4. @copyright Louis Dionne 2013-2017
  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_UNFOLD_LEFT_HPP
  9. #define BOOST_HANA_UNFOLD_LEFT_HPP
  10. #include <boost/hana/fwd/unfold_left.hpp>
  11. #include <boost/hana/append.hpp>
  12. #include <boost/hana/concept/sequence.hpp>
  13. #include <boost/hana/config.hpp>
  14. #include <boost/hana/core/dispatch.hpp>
  15. #include <boost/hana/empty.hpp>
  16. #include <boost/hana/first.hpp>
  17. #include <boost/hana/functional/partial.hpp>
  18. #include <boost/hana/optional.hpp>
  19. #include <boost/hana/second.hpp>
  20. BOOST_HANA_NAMESPACE_BEGIN
  21. //! @cond
  22. template <typename S>
  23. struct unfold_left_t {
  24. #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
  25. static_assert(hana::Sequence<S>::value,
  26. "hana::unfold_left<S> requires 'S' to be a Sequence");
  27. #endif
  28. template <typename State, typename F>
  29. constexpr auto operator()(State&& state, F&& f) const {
  30. return unfold_left_impl<S>::apply(
  31. static_cast<State&&>(state),
  32. static_cast<F&&>(f)
  33. );
  34. }
  35. };
  36. //! @endcond
  37. template <typename S, bool condition>
  38. struct unfold_left_impl<S, when<condition>> : default_ {
  39. struct unfold_left_helper {
  40. template <typename F, typename P>
  41. constexpr auto operator()(F&& f, P&& p) const {
  42. return hana::append(
  43. unfold_left_impl::apply(
  44. hana::first(static_cast<P&&>(p)),
  45. static_cast<F&&>(f)
  46. ),
  47. hana::second(static_cast<P&&>(p))
  48. );
  49. }
  50. };
  51. template <typename Init, typename F>
  52. static constexpr auto apply(Init&& init, F&& f) {
  53. decltype(auto) elt = f(static_cast<Init&&>(init));
  54. return hana::maybe(empty<S>(),
  55. hana::partial(unfold_left_helper{}, static_cast<F&&>(f)),
  56. static_cast<decltype(elt)&&>(elt)
  57. );
  58. }
  59. };
  60. BOOST_HANA_NAMESPACE_END
  61. #endif // !BOOST_HANA_UNFOLD_LEFT_HPP