DGtal 1.3.0
Loading...
Searching...
No Matches
testFunctorHolder.cpp
1
28#include <functional>
29
30#include "DGtal/base/FunctorHolder.h"
31#include "DGtal/base/Common.h"
32#include "DGtal/base/CUnaryFunctor.h"
33
34#include "DGtalCatch.h"
36
37using namespace DGtal;
38using namespace DGtal::functors;
39using namespace std;
40
42// Functor and functions
43
44struct Functor
45{
46 double cst;
47
48 explicit Functor(double c) : cst(c) {}
49 inline double operator() (double v) const { return v + cst; }
50};
51
52double add(double v)
53{
54 return v + 1.5;
55}
56
57
59// Test cases
60
61TEST_CASE( "Holding a lambda", "[lambda]" )
62{
63 double cst = 1.5;
64
65 // Holding an unary lambda by mutable lvalue
66 {
67 auto fn = [&cst] (double v) { return v + cst; };
68 auto holder = holdFunctor(fn);
69 BOOST_CONCEPT_ASSERT(( boost::Assignable<decltype(holder)> ));
70 BOOST_CONCEPT_ASSERT(( concepts::CUnaryFunctor<decltype(holder), double, double> ));
71 REQUIRE( holder(0.5) == 2.0 );
72 auto holder2 = holder;
73 REQUIRE( holder2(0.5) == 2.0 );
74 }
75
76 // Holding an unary lambda by constant lvalue
77 {
78 const auto fn = [&cst] (double v) { return v + cst; };
79 auto holder = holdFunctor(fn);
80 BOOST_CONCEPT_ASSERT(( boost::Assignable<decltype(holder)> ));
81 BOOST_CONCEPT_ASSERT(( concepts::CUnaryFunctor<decltype(holder), double, double> ));
82 REQUIRE( holder(0.5) == 2.0 );
83 auto holder2 = holder;
84 REQUIRE( holder2(0.5) == 2.0 );
85 }
86
87 // Holding an unary lambda by rvalue
88 {
89 auto holder = holdFunctor( [&cst] (double v) { return v + cst; } );
90 BOOST_CONCEPT_ASSERT(( boost::Assignable<decltype(holder)> ));
91 BOOST_CONCEPT_ASSERT(( concepts::CUnaryFunctor<decltype(holder), double, double> ));
92 REQUIRE( holder(0.5) == 2.0 );
93 auto holder2 = holder;
94 REQUIRE( holder2(0.5) == 2.0 );
95 }
96
97 // Holding an unary mutable lambda by rvalue
98 {
99 auto holder = holdFunctor( [cst] (double v) mutable { return v + cst; } );
100 BOOST_CONCEPT_ASSERT(( boost::Assignable<decltype(holder)> ));
101 BOOST_CONCEPT_ASSERT(( concepts::CUnaryFunctor<decltype(holder), double, double> ));
102 REQUIRE( holder(0.5) == 2.0 );
103 auto holder2 = holder;
104 REQUIRE( holder2(0.5) == 2.0 );
105 }
106
107 // Holding a binary lambda by rvalue
108 {
109 auto holder = holdFunctor( [] (double v, double c) { return v + c; } );
110 BOOST_CONCEPT_ASSERT(( boost::Assignable<decltype(holder)> ));
111 REQUIRE( holder(0.5, 1.5) == 2.0 );
112 auto holder2 = holder;
113 REQUIRE( holder2(0.5, 1.5) == 2.0 );
114 }
115}
116
117TEST_CASE( "Holding a functor", "[functor]" )
118{
119 double cst = 1.5;
120
121 // Holding an unary functor by mutable lvalue
122 {
123 auto fn = Functor(cst);
124 auto holder = holdFunctor(fn);
125 BOOST_CONCEPT_ASSERT(( boost::Assignable<decltype(holder)> ));
126 BOOST_CONCEPT_ASSERT(( concepts::CUnaryFunctor<decltype(holder), double, double> ));
127 REQUIRE( holder(0.5) == 2.0 );
128 auto holder2 = holder;
129 REQUIRE( holder2(0.5) == 2.0 );
130 }
131
132 // Holding an unary functor by constant lvalue
133 {
134 const auto fn = Functor(cst);
135 auto holder = holdFunctor(fn);
136 BOOST_CONCEPT_ASSERT(( boost::Assignable<decltype(holder)> ));
137 BOOST_CONCEPT_ASSERT(( concepts::CUnaryFunctor<decltype(holder), double, double> ));
138 REQUIRE( holder(0.5) == 2.0 );
139 auto holder2 = holder;
140 REQUIRE( holder2(0.5) == 2.0 );
141 }
142
143 // Holding an unary functor by rvalue
144 {
145 auto holder = holdFunctor( Functor(cst) );
146 BOOST_CONCEPT_ASSERT(( boost::Assignable<decltype(holder)> ));
147 BOOST_CONCEPT_ASSERT(( concepts::CUnaryFunctor<decltype(holder), double, double> ));
148 REQUIRE( holder(0.5) == 2.0 );
149 auto holder2 = holder;
150 REQUIRE( holder2(0.5) == 2.0 );
151 }
152}
153
154TEST_CASE( "Holding a function", "[function]" )
155{
156 // Holding a function by reference
157 {
158 auto holder = holdFunctor( add );
159 BOOST_CONCEPT_ASSERT(( boost::Assignable<decltype(holder)> ));
160 BOOST_CONCEPT_ASSERT(( concepts::CUnaryFunctor<decltype(holder), double, double> ));
161 REQUIRE( holder(0.5) == 2.0 );
162 auto holder2 = holder;
163 REQUIRE( holder2(0.5) == 2.0 );
164 }
165
166 // Holding a function by address
167 {
168 auto holder = holdFunctor( &add );
169 BOOST_CONCEPT_ASSERT(( boost::Assignable<decltype(holder)> ));
170 BOOST_CONCEPT_ASSERT(( concepts::CUnaryFunctor<decltype(holder), double, double> ));
171 REQUIRE( holder(0.5) == 2.0 );
172 auto holder2 = holder;
173 REQUIRE( holder2(0.5) == 2.0 );
174 }
175}
176
177TEST_CASE( "Holding a std::function", "[std::function]" )
178{
179 double cst = 1.5;
180
181 // Holding a std::function
182 std::function<double(double)> fn = Functor(cst);
183 auto holder = holdFunctor( fn );
184 BOOST_CONCEPT_ASSERT(( boost::Assignable<decltype(holder)> ));
185 BOOST_CONCEPT_ASSERT(( concepts::CUnaryFunctor<decltype(holder), double, double> ));
186 REQUIRE( holder(0.5) == 2.0 );
187 auto holder2 = holder;
188 REQUIRE( holder2(0.5) == 2.0 );
189}
functors namespace gathers all DGtal functors.
auto holdFunctor(Function &&fn) -> decltype(holdFunctorImpl(std::forward< Function >(fn), typename std::is_lvalue_reference< Function >{}))
Hold any callable object (function, functor, lambda, ...) as a C(Unary)Functor model.
DGtal is the top-level namespace which contains all DGtal functions and types.
STL namespace.
Aim: Defines a unary functor, which associates arguments to results.
Definition: CUnaryFunctor.h:90
Go to http://www.sgi.com/tech/stl/Assignable.html.
Definition: Boost.dox:32
TEST_CASE("int container traits", "[int][traits]")
InHalfPlaneBySimple3x3Matrix< Point, double > Functor
REQUIRE(domain.isInside(aPoint))