diff options
Diffstat (limited to 'boost/hana/unfold_left.hpp')
-rw-r--r-- | boost/hana/unfold_left.hpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/boost/hana/unfold_left.hpp b/boost/hana/unfold_left.hpp new file mode 100644 index 0000000000..fff29f77ca --- /dev/null +++ b/boost/hana/unfold_left.hpp @@ -0,0 +1,71 @@ +/*! +@file +Defines `boost::hana::unfold_left`. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_UNFOLD_LEFT_HPP +#define BOOST_HANA_UNFOLD_LEFT_HPP + +#include <boost/hana/fwd/unfold_left.hpp> + +#include <boost/hana/append.hpp> +#include <boost/hana/concept/sequence.hpp> +#include <boost/hana/config.hpp> +#include <boost/hana/core/dispatch.hpp> +#include <boost/hana/empty.hpp> +#include <boost/hana/first.hpp> +#include <boost/hana/functional/partial.hpp> +#include <boost/hana/optional.hpp> +#include <boost/hana/second.hpp> + + +BOOST_HANA_NAMESPACE_BEGIN + //! @cond + template <typename S> + struct unfold_left_t { + #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS + static_assert(hana::Sequence<S>::value, + "hana::unfold_left<S> requires 'S' to be a Sequence"); + #endif + + template <typename State, typename F> + constexpr auto operator()(State&& state, F&& f) const { + return unfold_left_impl<S>::apply( + static_cast<State&&>(state), + static_cast<F&&>(f) + ); + } + }; + //! @endcond + + template <typename S, bool condition> + struct unfold_left_impl<S, when<condition>> : default_ { + struct unfold_left_helper { + template <typename F, typename P> + constexpr auto operator()(F&& f, P&& p) const { + return hana::append( + unfold_left_impl::apply( + hana::first(static_cast<P&&>(p)), + static_cast<F&&>(f) + ), + hana::second(static_cast<P&&>(p)) + ); + } + }; + + template <typename Init, typename F> + static constexpr auto apply(Init&& init, F&& f) { + decltype(auto) elt = f(static_cast<Init&&>(init)); + return hana::maybe(empty<S>(), + hana::partial(unfold_left_helper{}, static_cast<F&&>(f)), + static_cast<decltype(elt)&&>(elt) + ); + } + }; +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_UNFOLD_LEFT_HPP |