DGtal  1.4.beta
testConstImageFunctorHolder.cpp
1 
27 #include <iostream>
28 #include <cmath>
29 
30 
31 #include "DGtal/kernel/SpaceND.h"
32 #include "DGtal/kernel/domains/HyperRectDomain.h"
33 #include "DGtal/images/CConstImage.h"
34 
35 #include "DGtal/images/ConstImageFunctorHolder.h"
36 
37 #include "DGtalCatch.h"
38 
39 template < typename TPoint, typename TDomain >
40 inline
41 typename TPoint::Scalar unary_kernel( TPoint const& pt, TDomain const&, typename TPoint::Scalar cst )
42 {
43  return cst * pt.norm();
44 }
45 
46 template <typename TPoint, typename TDomain>
47 inline
48 typename TPoint::Scalar binary_kernel( TPoint const& pt, TDomain const& domain, typename TPoint::Scalar cst )
49 {
50  return cst * (pt - domain.lowerBound()).norm();
51 }
52 
53 template < typename TImage, typename TFunction >
54 void checkImage( TImage const& anImage, TFunction const& fn )
55 {
56  using Image = TImage;
57  using Domain = typename Image::Domain;
58 
59  // Image's domain
60  Domain const& domain = anImage.domain();
61  REQUIRE( !domain.isEmpty() );
62 
63  // Checks CConstImage concept.
64  BOOST_CONCEPT_ASSERT( (DGtal::concepts::CConstImage<TImage>) );
65 
66  // Checking standard services
67  std::cout << anImage << std::endl;
68  REQUIRE( anImage.isValid() );
69 
70  // Checking operator()
71  for ( auto const& pt : domain )
72  REQUIRE( anImage(pt) == fn(pt, domain) );
73 
74  // Checking forward range
75  {
76  auto pt_it = domain.begin();
77  auto im_it = anImage.constRange().begin();
78  for ( ; pt_it != domain.end(); ++pt_it, ++im_it )
79  REQUIRE( *im_it == fn(*pt_it, domain) );
80 
81  REQUIRE( im_it == anImage.constRange().end() );
82  }
83 
84  // Checking reverse range
85  {
86  auto pt_it = domain.rbegin();
87  auto im_it = anImage.constRange().rbegin();
88  for ( ; pt_it != domain.rend(); ++pt_it, ++im_it )
89  REQUIRE( *im_it == fn(*pt_it, domain) );
90 
91  REQUIRE( im_it == anImage.constRange().rend() );
92  }
93 }
94 
95 // Unary functor
96 struct UnaryFunctor
97 {
98  double cst;
99  explicit UnaryFunctor(double c) : cst(c) {}
100 
101  template <typename Point>
102  double operator() (Point const& pt) const
103  {
104  return unary_kernel(pt, 0, cst);
105  }
106 };
107 
108 // Binary functor
109 struct BinaryFunctor
110 {
111  double cst;
112  explicit BinaryFunctor(double c) : cst(c) {}
113 
114  template <typename Point, typename Domain>
115  double operator() (Point const& pt, Domain const &d) const
116  {
117  return binary_kernel(pt, d, cst);
118  }
119 };
120 
121 TEST_CASE( "2D Image from unary functor by rvalue", "[2D][functor][unary][rvalue]" )
122 {
123  using namespace DGtal;
124  using Space = SpaceND<2, int>;
126  using Point = typename Domain::Point;
127 
128  const Domain domain(Point{-10, -15}, Point{20, 25});
129  const double cst = 3.5;
130  auto image = functors::holdConstImageFunctor<double>( domain, UnaryFunctor(cst) ); // Specifying explicitly the returned value type.
131  checkImage(image, [&cst] (Point pt, Domain d) { return unary_kernel(pt, d, cst); });
132 }
133 
134 TEST_CASE( "2D Image from binary functor by rvalue", "[2D][functor][binary][rvalue]" )
135 {
136  using namespace DGtal;
137  using Space = SpaceND<2, int>;
139  using Point = typename Domain::Point;
140 
141  const Domain domain(Point{-10, -15}, Point{20, 25});
142  const double cst = 3.5;
143  auto image = functors::holdConstImageFunctor( domain, BinaryFunctor(cst) );
144  checkImage(image, [&cst] (Point pt, Domain d) { return binary_kernel(pt, d, cst); });
145 }
146 
147 TEST_CASE( "2D Image from binary functor by lvalue", "[2D][functor][binary][lvalue]" )
148 {
149  using namespace DGtal;
150  using Space = SpaceND<2, int>;
152  using Point = typename Domain::Point;
153 
154  const Domain domain(Point{-10, -15}, Point{20, 25});
155  const double cst = 3.5;
156  const auto fn = BinaryFunctor(cst);
157  auto image = functors::holdConstImageFunctor( domain, fn );
158  checkImage(image, [&cst] (Point pt, Domain d) { return binary_kernel(pt, d, cst); });
159 }
160 
161 TEST_CASE( "2D Image from binary lambda by rvalue", "[2D][lambda][binary][rvalue]" )
162 {
163  using namespace DGtal;
164  using Space = SpaceND<2, int>;
166  using Point = typename Domain::Point;
167 
168  const Domain domain(Point{-10, -15}, Point{20, 25});
169  const double cst = 3.5;
170  auto image = functors::holdConstImageFunctor( domain, [cst] (Point const& pt, Domain const& d) { return binary_kernel(pt, d, cst); } );
171  checkImage(image, [&cst] (Point pt, Domain d) { return binary_kernel(pt, d, cst); });
172 }
173 
174 TEST_CASE( "2D Image from binary std::function by lvalue", "[2D][function][binary][lvalue]" )
175 {
176  using namespace DGtal;
177  using Space = SpaceND<2, int>;
179  using Point = typename Domain::Point;
180 
181  const Domain domain(Point{-10, -15}, Point{20, 25});
182  const double cst = 3.5;
183  std::function<double(Point, Domain)> fn = [cst] (Point const& pt, Domain const& d) { return binary_kernel(pt, d, cst); };
184  auto image = functors::holdConstImageFunctor( domain, fn );
185  checkImage(image, [&cst] (Point pt, Domain d) { return binary_kernel(pt, d, cst); });
186 }
auto holdConstImageFunctor(TDomain const &aDomain, TFunctor &&aFunctor) -> ConstImageFunctorHolder< TDomain, TValue, decltype(holdFunctor(std::forward< TFunctor >(aFunctor)))>
ConstImageFunctorHolder construction helper with specification of the return type.
DGtal is the top-level namespace which contains all DGtal functions and types.
Aim: Defines the concept describing a read-only image, which is a refinement of CPointFunctor.
Definition: CConstImage.h:95
MyPointD Point
Definition: testClone2.cpp:383
bool checkImage(const Image &a, const Image &b)
TEST_CASE("int container traits", "[int][traits]")
Domain domain
ImageContainerBySTLVector< Domain, Value > Image
HyperRectDomain< Space > Domain
REQUIRE(domain.isInside(aPoint))