DGtal 1.4.0
Loading...
Searching...
No Matches
exampleFunctorHolder.cpp
Go to the documentation of this file.
1
32// Inclusions
33#include <iostream>
34#include <numeric>
35#include <iterator>
36#include <utility>
37
38#include "DGtal/base/FunctorHolder.h"
39#include "DGtal/kernel/PointVector.h"
40
41#include "DGtal/base/Common.h"
42#include "DGtal/helpers/StdDefs.h"
43#include "ConfigExamples.h"
44#include "DGtal/io/readers/PGMReader.h"
45#include "DGtal/io/readers/GenericReader.h"
46#include "DGtal/images/ImageContainerBySTLVector.h"
47#include "DGtal/kernel/BasicPointPredicates.h"
48
50
53{
54 return pt.norm() - 1.;
55}
57
59template <typename Point>
60inline
61typename Point::Component
63{
64 return pt.norm() - typename Point::Component(1);
65}
67
69template <typename Point>
70struct SignedDistToCircle
71{
72 using Real = typename Point::Component;
73
74 Point center;
75 Real radius;
76
77 SignedDistToCircle(Point const& pt, Real r)
78 : center(pt), radius(r)
79 {}
80
81 inline
82 Real operator() (Point const& pt) const
83 {
84 return (pt - center).norm() - radius;
85 }
86};
88
90template <typename T>
91struct Binarizer
92{
93 T threshold;
94 explicit Binarizer(T v) : threshold(v) {}
95 Binarizer& operator= (Binarizer const&) = delete; // This is not a model of boost::Assignable
96 bool operator() (T v) const { return v <= threshold; }
97};
98
99template <typename T>
100inline
101decltype(DGtal::functors::holdFunctor(Binarizer<T>(128))) // Deduced return type
103{
104 return DGtal::functors::holdFunctor( Binarizer<T>(128) );
105}
107
109template <typename Iterator>
110auto get_mean_binarizer_from_range(Iterator first, Iterator last) // auto as return type
111 -> decltype(DGtal::functors::holdFunctor(Binarizer<decltype(*first / std::distance(first, last))>(0)))
112 // with trailing return type specification using ->
113{
114 using value_type = typename std::iterator_traits<Iterator>::value_type;
115 auto const mean = std::accumulate(first, last, value_type(0));
116 auto const size = std::distance(first, last);
117 return DGtal::functors::holdFunctor(Binarizer<decltype(mean / size)>(mean / size));
118}
120
122template <typename Image>
123auto get_mean_binarizer_from_an_image(std::string const& file_name)
125 std::declval<Image>().begin(), std::declval<Image>().end() ))
126{
127 Image const image = DGtal::GenericReader<Image>::import(file_name);
128 return get_mean_binarizer_from_range(image.begin(), image.end());
129}
131
132#if __cplusplus >= 201402L
134template <typename Iterator>
135auto get_mean_binarizer_from_range_cpp14(Iterator first, Iterator last)
136{
137 using value_type = typename std::iterator_traits<Iterator>::value_type;
138 auto const mean = std::accumulate(first, last, value_type(0));
139 auto const size = std::distance(first, last);
140 return DGtal::functors::holdFunctor(Binarizer<decltype(mean / size)>(mean / size));
141}
143#endif
144
146template <typename T>
147inline
148Binarizer<T> makeBinarizer( T const& v ) // T auto-deduced from the parameter v
149{
150 return Binarizer<T>(v);
151}
153
154#if 0
156template <
157 typename PointFunctor,
158 typename Predicate
159>
164{
166}
168#endif
169
171template <
172 typename PointFunctor,
173 typename Predicate
174>
176makePointFunctorPredicate_Example( PointFunctor const& aFun, Predicate const& aPred )
177{
179}
181
183template <
184 typename PointFunctor,
185 typename Predicate
186>
188 typename std::decay<PointFunctor>::type,
189 typename std::decay<Predicate>::type
190>
191makePointFunctorPredicate_Example2( PointFunctor && aFun, Predicate && aPred )
192{
194 typename std::decay<PointFunctor>::type,
195 typename std::decay<Predicate>::type
196 >(
197 std::forward<PointFunctor>(aFun),
198 std::forward<Predicate>(aPred)
199 );
200}
202
204int main()
205{
206
208 // Holding a function
209
210 {
211 std::cout << "Holding a function" << std::endl;
215 std::cout << fn( Point(1, 1) ) << std::endl;
217 }
218
219 {
220 std::cout << "Holding a templated function" << std::endl;
224 std::cout << fn( Point(1, 1) ) << std::endl;
226 }
227
228 {
229 std::cout << "Holding a function through a lambda" << std::endl;
232 auto fn = DGtal::functors::holdFunctor( [] (Point const& pt) { return signed_dist_to_unit_circle(pt); } );
233 std::cout << fn( Point(1, 1) ) << std::endl;
235 }
236
237 {
238 std::cout << "Holding a templated function through a lambda" << std::endl;
241 auto fn = DGtal::functors::holdFunctor( [] (Point const& pt) { return templated_signed_dist_to_unit_circle(pt); } );
242 std::cout << fn( Point(1, 1) ) << std::endl;
244 }
245
246#if __cplusplus >= 201402L
247 {
248 std::cout << "Holding a templated function through a C++14 lambda" << std::endl;
250 auto fn = DGtal::functors::holdFunctor( [] (auto const& pt) { return templated_signed_dist_to_unit_circle(pt); } );
252 std::cout << fn( Point(1, 1) ) << std::endl; // <- template parameter is resolved to Point
254 }
255#endif
256
258 // Holding a functor
259
260 {
261 std::cout << "Holding a functor by (lvalue) reference" << std::endl;
264 SignedDistToCircle<Point> dist(Point(0, 1), 2);
265 auto fn = DGtal::functors::holdFunctor( dist );
266 std::cout << fn( Point(1, 1) ) << std::endl;
268 }
269
270 {
271 std::cout << "Holding a functor by rvalue reference" << std::endl;
274 auto fn = DGtal::functors::holdFunctor( SignedDistToCircle<Point>( Point(0, 1), 2 ) );
275 std::cout << fn( Point(1, 1) ) << std::endl;
277 }
278
279 {
280 std::cout << "Holding a functor by moving it" << std::endl;
283 SignedDistToCircle<Point> dist(Point(0, 1), 2);
284 auto fn = DGtal::functors::holdFunctor( std::move(dist) );
285 std::cout << fn( Point(1, 1) ) << std::endl;
287 }
288
290 // Holding a lambda
291
292 {
293 std::cout << "Holding a lambda" << std::endl;
296 Point center(0, 1);
297 double radius = 2;
298
300 [&center, &radius] (Point const& pt) {
301 return (pt - center).norm() - radius;
302 }
303 );
304 std::cout << fn( Point(1, 1) ) << std::endl;
306 }
307
308 {
309 std::cout << "Holding a non-unary lambda" << std::endl;
312
313 auto dist = [] (Point const& pt, Point const& center, double radius)
314 {
315 return (pt - center).norm() - radius;
316 };
317
318 auto fn = DGtal::functors::holdFunctor( dist );
319
320 std::cout << fn( Point(1, 1), Point(0, 1), 2 ) << std::endl;
322 }
323
325 // Copying
326
327 {
328 std::cout << "Copying a functor held by lvalue reference" << std::endl;
331 SignedDistToCircle<Point> dist(Point(0, 1), 2);
332 auto fn = DGtal::functors::holdFunctor( dist );
333 auto fn2 = fn;
334
335 std::cout << fn( Point(1, 1) ) << std::endl; // Output: -1
336 std::cout << fn2( Point(1, 1) ) << std::endl; // Output: -1
337
338 dist.radius = 3; // fn and fn2 both refer to the same functor dist.
339
340 std::cout << fn( Point(1, 1) ) << std::endl; // Output: -2
341 std::cout << fn2( Point(1, 1) ) << std::endl; // Output: -2
343 }
344
345 {
346 std::cout << "Copying a lambda held by rvalue reference" << std::endl;
348 int init_cnt = 0;
349 auto fn = DGtal::functors::holdFunctor( [init_cnt] () mutable { return ++init_cnt; } );
350 std::cout << fn() << std::endl; // Output: 1
351 auto fn2 = fn;
352 std::cout << fn2() << std::endl; // Output: 2
353 std::cout << fn() << std::endl; // Output: 3
355 }
356
358 // Type of FunctorHolder
359
360 {
361 std::cout << "Storing a FunctorHolder" << std::endl;
362
365 auto fn = DGtal::functors::holdFunctor( SignedDistToCircle<Point>( Point(0, 1), 2 ) );
367 }
368
369 {
370 std::cout << "Passing a FunctorHolder" << std::endl;
371
372 //image import
374 using Point = Image::Point;
375 std::string filename = examplesPath + "samples/contourS.pgm";
377
379 auto binarizer = DGtal::functors::holdFunctor( [] (Image::Value v) { return v <= 135; } );
380 DGtal::functors::PointFunctorPredicate<Image, decltype(binarizer)> predicate(image, binarizer);
382
383 Point const pt(50, 25);
384 std::cout << "binarizer(" << image( pt ) << ") = " << predicate( pt ) << std::endl;
385 }
386
387 {
388 std::cout << "Returning a functor" << std::endl;
390 auto binarizer = get_trivial_binarizer<int>();
392 std::cout << "binarizer(120) = " << binarizer(120) << std::endl;
393 }
394
395 {
396 std::cout << "Returning a functor using trailing return syntax" << std::endl;
397
398 //image import
400 using Point = Image::Point;
401 std::string filename = examplesPath + "samples/contourS.pgm";
403
405 auto binarizer = get_mean_binarizer_from_range(image.begin(), image.end());
406 DGtal::functors::PointFunctorPredicate<Image, decltype(binarizer)> predicate(image, binarizer);
408
409 Point const pt(50, 25);
410 std::cout << "binarizer(" << image( pt ) << ") = " << predicate( pt ) << std::endl;
411 }
412
413 {
414 std::cout << "Returning a functor using trailing return syntax and declval" << std::endl;
415
416 //image import
418 std::string filename = examplesPath + "samples/contourS.pgm";
419
420 auto binarizer = get_mean_binarizer_from_an_image<Image>(filename);
421
422 std::cout << "binarizer(120) = " << binarizer(120) << std::endl;
423 }
424
425 #if __cplusplus >= 201402L
426 {
427 std::cout << "Returning a functor using auto in C++14" << std::endl;
428
429 //image import
431 using Point = Image::Point;
432 std::string filename = examplesPath + "samples/contourS.pgm";
434
435 auto binarizer = get_mean_binarizer_from_range_cpp14(image.begin(), image.end());
436 DGtal::functors::PointFunctorPredicate<Image, decltype(binarizer)> predicate(image, binarizer);
437
438 Point const pt(50, 25);
439 std::cout << "binarizer(" << image( pt ) << ") = " << predicate( pt ) << std::endl;
440 }
441 #endif
442
443 {
444 std::cout << "Usage of Binarizer factory" << std::endl;
445
446 //image import
448 using Point = Image::Point;
449 std::string filename = examplesPath + "samples/contourS.pgm";
451
453 auto binarizer = DGtal::functors::holdFunctor( makeBinarizer(135) );
454 DGtal::functors::PointFunctorPredicate<Image, decltype(binarizer)> predicate(image, binarizer);
456
457 Point const pt(50, 25);
458 std::cout << "binarizer(" << image( pt ) << ") = " << predicate( pt ) << std::endl;
459 }
460
461
462 #if __cplusplus >= 201703L
463 {
464 std::cout << "Binarizer factory using deduction guides of C++17" << std::endl;
465
466 //image import
468 using Point = Image::Point;
469 std::string filename = examplesPath + "samples/contourS.pgm";
471
473 auto binarizer = DGtal::functors::holdFunctor( Binarizer(135) ); // Binarizer template parameter is not specified.
474 DGtal::functors::PointFunctorPredicate<Image, decltype(binarizer)> predicate(image, binarizer);
476
477 Point const pt(50, 25);
478 std::cout << "binarizer(" << image( pt ) << ") = " << predicate( pt ) << std::endl;
479 }
480 #endif
481
482 {
483 std::cout << "Usage of PointFunctorPredicate factory" << std::endl;
484
485 //image import
487 using Point = Image::Point;
488 std::string filename = examplesPath + "samples/contourS.pgm";
490
492 auto binarizer = DGtal::functors::holdFunctor( makeBinarizer(135) );
493 auto predicate = makePointFunctorPredicate_Example( image, binarizer );
495
496 Point const pt(50, 25);
497 std::cout << "binarizer(" << image( pt ) << ") = " << predicate( pt ) << std::endl;
498 }
499
500 {
501 std::cout << "Usage of PointFunctorPredicate factory with perfect forwarding" << std::endl;
502
503 //image import
505 using Point = Image::Point;
506 std::string filename = examplesPath + "samples/contourS.pgm";
508
509 auto binarizer = DGtal::functors::holdFunctor( makeBinarizer(135) );
510 auto predicate = makePointFunctorPredicate_Example2( image, binarizer );
511
512 Point const pt(50, 25);
513 std::cout << "binarizer(" << image( pt ) << ") = " << predicate( pt ) << std::endl;
514 }
515 return 0;
516}
Aim: This class encapsulates its parameter class so that to indicate to the user that the object/poin...
Definition ConstAlias.h:187
Aim: Implements basic operations that will be used in Point and Vector classes.
double norm(const NormType type=L_2) const
auto get_mean_binarizer_from_an_image(std::string const &file_name) -> decltype(get_mean_binarizer_from_range(std::declval< Image >().begin(), std::declval< Image >().end()))
[Returning a FunctorHolder using trailing return]
Binarizer< T > makeBinarizer(T const &v)
[Returning a FunctorHolder using trailing return and declval]
decltype(DGtal::functors::holdFunctor(Binarizer< T >(128))) get_trivial_binarizer()
double signed_dist_to_unit_circle(DGtal::PointVector< 2, double > const &pt)
[signed_dist_to_unit_circle]
DGtal::functors::PointFunctorPredicate< PointFunctor, Predicate > makePointFunctorPredicate_Example(PointFunctor const &aFun, Predicate const &aPred)
[Factory of Binarizer]
Point::Component templated_signed_dist_to_unit_circle(Point const &pt)
[signed_dist_to_unit_circle]
DGtal::functors::PointFunctorPredicate< typename std::decay< PointFunctor >::type, typename std::decay< Predicate >::type > makePointFunctorPredicate_Example2(PointFunctor &&aFun, Predicate &&aPred)
[Factory of PointFunctorPredicate]
auto get_mean_binarizer_from_range(Iterator first, Iterator last) -> decltype(DGtal::functors::holdFunctor(Binarizer< decltype(*first/std::distance(first, last))>(0)))
[Returning a FunctorHolder]
int main()
[Factory of PointFunctorPredicate using perfect forwarding]
Point center(const std::vector< Point > &points)
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.
static TContainer import(const std::string &filename, std::vector< unsigned int > dimSpace=std::vector< unsigned int >())
static ImageContainer importPGM(const std::string &aFilename, const Functor &aFunctor=Functor(), bool topbotomOrder=true)
Aim: The predicate returns true when the predicate returns true for the value assigned to a given poi...
MyPointD Point
ImageContainerBySTLVector< Domain, Value > Image