Imported Upstream version 1.64.0
[platform/upstream/boost.git] / boost / hana / fwd / unfold_left.hpp
1 /*!
2 @file
3 Forward declares `boost::hana::unfold_left`.
4
5 @copyright Louis Dionne 2013-2017
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_FWD_UNFOLD_LEFT_HPP
11 #define BOOST_HANA_FWD_UNFOLD_LEFT_HPP
12
13 #include <boost/hana/config.hpp>
14 #include <boost/hana/core/when.hpp>
15
16
17 BOOST_HANA_NAMESPACE_BEGIN
18     //! Dual operation to `fold_left` for sequences.
19     //! @ingroup group-Sequence
20     //!
21     //! While `fold_left` reduces a structure to a summary value from the left,
22     //! `unfold_left` builds a sequence from a seed value and a function,
23     //! starting from the left.
24     //!
25     //!
26     //! Signature
27     //! ---------
28     //! Given a `Sequence` `S`, an initial value `state` of tag `I`, an
29     //! arbitrary Product `P` and a function \f$ f : I \to P(I, T) \f$,
30     //! `unfold_left<S>` has the following signature:
31     //! \f[
32     //!     \mathtt{unfold\_left}_S : I \times (I \to P(I, T)) \to S(T)
33     //! \f]
34     //!
35     //! @tparam S
36     //! The tag of the sequence to build up.
37     //!
38     //! @param state
39     //! An initial value to build the sequence from.
40     //!
41     //! @param f
42     //! A function called as `f(state)`, where `state` is an initial value,
43     //! and returning
44     //! 1. `nothing` if it is done producing the sequence.
45     //! 2. otherwise, `just(make<P>(state, x))`, where `state` is the new
46     //!    initial value used in the next call to `f`, `x` is an element to
47     //!    be appended to the resulting sequence, and `P` is an arbitrary
48     //!    `Product`.
49     //!
50     //!
51     //! Fun fact
52     //! ---------
53     //! In some cases, `unfold_left` can undo a `fold_left` operation:
54     //! @code
55     //!     unfold_left<S>(fold_left(xs, state, f), g) == xs
56     //! @endcode
57     //!
58     //! if the following holds
59     //! @code
60     //!     g(f(x, y)) == just(make_pair(x, y))
61     //!     g(state) == nothing
62     //! @endcode
63     //!
64     //!
65     //! Example
66     //! -------
67     //! @include example/unfold_left.cpp
68 #ifdef BOOST_HANA_DOXYGEN_INVOKED
69     template <typename S>
70     constexpr auto unfold_left = [](auto&& state, auto&& f) {
71         return tag-dispatched;
72     };
73 #else
74     template <typename S, typename = void>
75     struct unfold_left_impl : unfold_left_impl<S, when<true>> { };
76
77     template <typename S>
78     struct unfold_left_t;
79
80     template <typename S>
81     constexpr unfold_left_t<S> unfold_left{};
82 #endif
83 BOOST_HANA_NAMESPACE_END
84
85 #endif // !BOOST_HANA_FWD_UNFOLD_LEFT_HPP