1 /*******************************************************************************
2 * tests/meta/function_stack_test.cpp
3 *
4 * Part of tlx - http://panthema.net/tlx
5 *
6 * Copyright (C) 2015 Sebastian Lamm <seba.lamm@gmail.com>
7 * Copyright (C) 2015-2017 Timo Bingmann <tb@panthema.net>
8 *
9 * All rights reserved. Published under the Boost Software License, Version 1.0
10 ******************************************************************************/
11
12 #include <tlx/meta/function_stack.hpp>
13
14 #include <tlx/die.hpp>
15
16 #include <iostream>
17 #include <string>
18 #include <vector>
19
test_stack1()20 static void test_stack1() {
21
22 std::vector<double> elements;
23
24 // User-defined functions
25 auto fmap_fn =
26 [=](double input, auto emit_func) {
27 emit_func(input);
28 emit_func(input);
29 };
30
31 auto map_fn =
32 [=](double input) {
33 return 2 * input;
34 };
35
36 auto filter_fn =
37 [=](double input) {
38 return input > 80;
39 };
40
41 double total = 0;
42
43 auto save_fn =
44 [&total](double input) {
45 // elements.push_back(input);
46 total += input;
47 };
48
49 // Converted emitter functions
50 auto conv_map_fn =
51 [=](double input, auto emit_func) {
52 emit_func(map_fn(input));
53 };
54
55 auto conv_filter_fn =
56 [=](double input, auto emit_func) {
57 if (filter_fn(input)) emit_func(input);
58 };
59
60 auto empty_stack = tlx::FunctionStack<double>();
61 static_assert(empty_stack.empty, "FunctionStack::empty is wrong");
62
63 auto new_stack = tlx::make_function_stack<double>(fmap_fn);
64 static_assert(!new_stack.empty, "FunctionStack::empty is wrong");
65
66 auto new_stack2 = new_stack.push(conv_map_fn);
67 auto new_stack3 = new_stack2.push(conv_filter_fn);
68 auto new_stack4 = new_stack3.push(save_fn);
69 auto composed_function = new_stack4.fold();
70
71 for (size_t i = 0; i != 1000; ++i) {
72 composed_function(42);
73 composed_function(2);
74 composed_function(50);
75 }
76
77 die_unequal(total, 368000u);
78 }
79
test_simple_deduction_test()80 static void test_simple_deduction_test() {
81
82 auto fmap_fn1 =
83 [=](int input, auto emit_func) {
84 emit_func(std::to_string(input));
85 };
86
87 auto fmap_fn2 =
88 [=](const std::string& input, auto emit_func) {
89 emit_func(input + " Hello");
90 emit_func(10);
91 };
92
93 auto new_stack1 = tlx::make_function_stack<int>(fmap_fn1);
94 auto new_stack2 = new_stack1.push(fmap_fn2);
95
96 std::vector<std::string> output;
97
98 auto save_output = [&](auto) {
99 output.emplace_back("123");
100 };
101
102 auto new_stack3 = new_stack2.push(save_output);
103 new_stack3.fold()(42);
104
105 die_unequal(output.size(), 2u);
106 die_unequal(output[0], "123");
107 die_unequal(output[1], "123");
108 }
109
test_stack_maker()110 static void test_stack_maker() {
111
112 std::vector<std::string> out;
113
114 auto result =
115 tlx::FunctionStack<double>()
116 & ([](const int& d, auto emit) { emit(d + 1); })
117 & ([](const int& d, auto emit) { emit(std::to_string(2 * d)); })
118 & ([](const std::string& s, auto emit) { emit(s + "2"); })
119 & ([&](const std::string& s) { out.emplace_back(s); });
120
121 auto x = result.fold();
122 x(5);
123 die_unequal(out.front(), "122");
124 }
125
main()126 int main() {
127 test_stack1();
128 test_simple_deduction_test();
129 test_stack_maker();
130
131 return 0;
132 }
133
134 /******************************************************************************/
135