Nano
A C++ template metaprogramming library
higher_order_functions.hpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------------------------------------
2 /// @file higher_order_functions.hpp
3 /// @brief Header file for nano higher order functions. \n
4 /// \n
5 /// Higher order functions are functions which satisfy at least one of the following properties: \n
6 /// \n
7 /// \begin{itemize}
8 /// \item{ Takes one or more functions as an input }
9 /// \item{ Outputs a function }
10 /// \end{itemize}
11 /// \n
12 /// So this header find contains all functions which fit that definition.
13 // ----------------------------------------------------------------------------------------------------------
14 
15 /*
16  * ----------------------------------------------------------------------------------------------------------
17  * list header file for nano library.
18  * Copyright (C) 2015 Rob Clucas
19  *
20  * This program is free software; you can redistribute it and/or modify
21  * it under the terms of the GNU General Public License as published by
22  * the Free Software Foundation; either version 2 of the License, or
23  * (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28  * GNU General Public License for more details.
29  *
30  * You should have received a copy of the GNU General Public License along
31  * with this program; if not, write to the Free Software Foundation, Inc.,
32  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33  * ----------------------------------------------------------------------------------------------------------
34  */
35 
36 #ifndef NANO_HIGHER_ORDER_FUNCTIONS
37 #define NANO_HIGHER_ORDER_FUNCTIONS
38 
39 #include <nano/list.hpp>
40 
41 namespace nano {
42 
43 // ----------------------------------------------------------------------------------------------------------
44 /// @struct filter
45 /// @brief Takes a list and an evaluation function, which itself takes the list and a parameter to
46 /// evaluate if each element of the list must be filtered
47 /// @tparam Evaluator The function that determines if an element is filtered or not
48 /// @tparam List1 The list to filter
49 /// @param List2 The list to use for filtering (to help Evaluator)
50 /// @tparam Passed The elements that have passed the Evaluator
51 // ----------------------------------------------------------------------------------------------------------
52 template <template <typename...> class Evaluator, typename List1, typename List2, typename Passed>
53 struct filter;
54 
55 // Specialization for when Args is a list
56 template <template <typename, typename> class Evaluator ,
57  typename Head1 ,
58  typename... Tail1 ,
59  typename Head2 ,
60  typename... Tail2 ,
61  typename... Passed >
62 struct filter<Evaluator, list<Head1, Tail1...>, list<Head2, Tail2...>, list<Passed...>>
63 {
64  using passed = typename std::conditional<
65  Evaluator<Head1, list<Head2, Tail2...>>::result ,
66  list<Passed..., Head1> ,
67  list<Passed...>
68  >::type;
69 
70  // Check if the evaluator uses a constant filter (2nd) list
71  // or if the filter list must drop the head element
72  using filter_list = typename std::conditional<
73  Evaluator<Head1, list<Head2, Tail2...>>::constant_list ,
74  list<Head2, Tail2...> ,
75  list<Tail2...>
76  >::type;
77 
78  using result = typename filter<Evaluator, list<Tail1...>, filter_list, passed>::result;
79 };
80 
81 // Base case - when all the elements have been evaluated
82 template <template <typename, typename> class Evaluator ,
83  typename... Tail2 ,
84  typename... Passed >
85 struct filter<Evaluator, empty_list, list<Tail2...>, list<Passed...>>
86 {
87  using result = list<Passed...>;
88 };
89 
90 // ----------------------------------------------------------------------------------------------------------
91 /// @struct zip
92 /// @brief Takes two lists, and zips the corresponding elements into a list of 2 elements if the function
93 /// to determine if the elements should be zips succeeds, otherwise the elements are not zipped.
94 /// @tparam Evaluator A function which operates on corresponding elements from the 2 lists to
95 /// determine if the elements should be zipped.
96 /// @tparam List1 First list for zipping.
97 /// @tparam List2 Second list for zipping.
98 /// @tparam Passed The elements which have 'passed' the functions test and have been added to the
99 /// zipped list.
100 // ----------------------------------------------------------------------------------------------------------
101 template <template <typename...> class Evaluator ,
102  typename List1 ,
103  typename List2 ,
104  typename... Passed >
105 struct zip;
106 
107 // Recursize case - when the whole list has not been traversed
108 template <template <typename...> class Evaluator ,
109  typename Head1 ,
110  typename... Tail1 ,
111  typename Head2 ,
112  typename... Tail2 ,
113  typename... Passed >
114 struct zip<Evaluator, list<Head1, Tail1...>, list<Head2, Tail2...>, list<Passed...>>
115 {
116  using passed = typename std::conditional<
117  Evaluator<Head1, Head2>::result , // Check if we must zip
118  list<Passed..., list<Head1, Head2>> , // Zip head elements if true
119  list<Passed...> // Don't zip if false
120  >::type;
121 
122  // Recurse until we reach the base case (pattern)
123  using result = typename zip<Evaluator, list<Tail1...>, list<Tail2...>, passed>::result;
124 };
125 
126 // Base case - not more elements to check in List1 or List 2
127 template <template <typename...> class Evaluator, typename... Passed>
128 struct zip<Evaluator, empty_list, empty_list, list<Passed...>>
129 {
130  using result = list<Passed...>;
131 };
132 
133 
134 } // End namespace nano
135 
136 #endif // NANO_HIGHER_ORDER_FUNCTIONS
Header file for the list metaclass to provide compile time lists.
typename std::conditional< Evaluator< Head1, Head2 >::result, list< Passed..., list< Head1, Head2 >>, list< Passed...> >::type passed
Definition: higher_order_functions.hpp:120
Takes two lists, and zips the corresponding elements into a list of 2 elements if the function to det...
Definition: higher_order_functions.hpp:105
typename std::conditional< Evaluator< Head1, list< Head2, Tail2...>>::constant_list, list< Head2, Tail2...>, list< Tail2...> >::type filter_list
Definition: higher_order_functions.hpp:76
typename std::conditional< Evaluator< Head1, list< Head2, Tail2...>>::result, list< Passed..., Head1 >, list< Passed...> >::type passed
Definition: higher_order_functions.hpp:68
typename filter< Evaluator, list< Tail1...>, filter_list, passed >::result result
Definition: higher_order_functions.hpp:78
Definition: containers.hpp:34
Meta class that holds types, and allows functions to be applied to the elements of the list using the...
Definition: list.hpp:51
Takes a list and an evaluation function, which itself takes the list and a parameter to evaluate if e...
Definition: higher_order_functions.hpp:53
typename zip< Evaluator, list< Tail1...>, list< Tail2...>, passed >::result result
Definition: higher_order_functions.hpp:123