Line data Source code
1 : // Author(s): Wieger Wesselink
2 : // Copyright: see the accompanying file COPYING or copy at
3 : // https://github.com/mCRL2org/mCRL2/blob/master/COPYING
4 : //
5 : // Distributed under the Boost Software License, Version 1.0.
6 : // (See accompanying file LICENSE_1_0.txt or copy at
7 : // http://www.boost.org/LICENSE_1_0.txt)
8 : //
9 : /// \file mcrl2/utilities/sequence.h
10 : /// \brief Functions for sequences.
11 :
12 : #ifndef MCRL2_UTILITIES_SEQUENCE_H
13 : #define MCRL2_UTILITIES_SEQUENCE_H
14 :
15 : #include <iterator>
16 : #include <vector>
17 :
18 : namespace mcrl2
19 : {
20 :
21 : namespace utilities
22 : {
23 :
24 : /// \cond INTERNAL_DOCS
25 : namespace detail
26 : {
27 :
28 : /// \brief Assignment function object
29 : struct foreach_sequence_assign
30 : {
31 : /// \brief Function call operator
32 : /// \param t1 An object
33 : /// \param t2 A value
34 : template <typename T1, typename T2>
35 48 : void operator()(T1& t1, const T2& t2) const
36 : {
37 48 : t1 = t2;
38 48 : }
39 : };
40 :
41 : /// \brief Implementation of the foreach_sequence algorithm
42 : /// \param first Start of a sequence container
43 : /// \param last End of a sequence container
44 : /// \param i An output iterator to where the generated sequences are written.
45 : /// \param f Function that is called for each generated sequence
46 : /// \param assign Assignment operator for assigning a value to a sequence element
47 : template <typename Iter1, typename Iter2, typename SequenceFunction, typename Assign>
48 67 : void foreach_sequence_impl(Iter1 first, Iter1 last, Iter2 i, SequenceFunction f, Assign assign)
49 : {
50 67 : if (first == last)
51 : {
52 34 : f();
53 : }
54 : else
55 : {
56 81 : for (auto j = first->begin(); j != first->end(); ++j)
57 : {
58 48 : assign(*i, *j);
59 48 : foreach_sequence_impl(std::next(first), last, std::next(i), f, assign);
60 : }
61 : }
62 67 : }
63 :
64 : } // namespace detail
65 : /// \endcond
66 :
67 : /// \brief Algorithm for generating sequences.
68 : /// Given a sequence [X1, ..., Xn], where each element Xi is a sequence
69 : /// as well, this function generates all sequences [x1, ..., xn], where
70 : /// xi is an element of Xi for all i = 1 ... n. For each of these sequences
71 : /// the function f is called. The assign parameter gives the user control
72 : /// over how each sequence is built.
73 : /// \param X A sequence.
74 : /// \param i An output iterator to where the generated sequences are written.
75 : /// \param f A function that is called for each generated sequence.
76 : /// \param assign The assign operation is called to assign values to the generated sequence.
77 : template <typename SequenceContainer,
78 : typename OutIter,
79 : typename SequenceFunction,
80 : typename Assign>
81 19 : void foreach_sequence(const SequenceContainer& X, OutIter i, SequenceFunction f, Assign assign)
82 : {
83 19 : detail::foreach_sequence_impl(X.begin(),
84 : X.end(),
85 : i,
86 : f,
87 : assign
88 : );
89 19 : }
90 :
91 : /// \brief Algorithm for generating sequences.
92 : /// Given a sequence [X1, ..., Xn], where each element Xi is a sequence
93 : /// as well, this function generates all sequences [x1, ..., xn], where
94 : /// xi is an element of Xi for all i = 1 ... n. For each of these sequences
95 : /// the function f is called.
96 : /// \param X A sequence.
97 : /// \param i An output iterator to where the generated sequences are written.
98 : /// \param f A function that is called for each generated sequence.
99 : template <typename SequenceContainer,
100 : typename OutIter,
101 : typename SequenceFunction>
102 19 : void foreach_sequence(const SequenceContainer& X, OutIter i, SequenceFunction f)
103 : {
104 19 : foreach_sequence(X, i, f, detail::foreach_sequence_assign());
105 19 : }
106 :
107 : } // namespace utilities
108 :
109 : } // namespace mcrl2
110 :
111 : #endif // MCRL2_UTILITIES_SEQUENCE_H
|