DGtal  1.0.0
ConstImageFunctorHolder.h
1 
17 #pragma once
18 
29 #if defined(ConstImageFunctorHolder_RECURSES)
30 #error Recursive header files inclusion detected in ConstImageFunctorHolder.h
31 #else // defined(ConstImageFunctorHolder_RECURSES)
32 
33 #define ConstImageFunctorHolder_RECURSES
34 
35 #if !defined ConstImageFunctorHolder_h
36 
37 #define ConstImageFunctorHolder_h
38 
40 // Inclusions
41 #include <iostream>
42 #include <type_traits>
43 #include <utility>
44 #include <iterator>
45 
46 #include <boost/iterator/transform_iterator.hpp>
47 #include <boost/concept/assert.hpp>
48 
49 #include "DGtal/kernel/domains/CDomain.h"
50 #include "DGtal/base/FunctorHolder.h"
52 
53 namespace DGtal
54 {
55 namespace functors
56 {
57 
98 template <
99  typename TDomain,
100  typename TValue,
101  typename TFunctor
102 >
104 {
106 
107  // ----------------------- Interface --------------------------------------
108 public:
109 
110  // DGtal types
112  using Domain = TDomain;
113  using Point = typename Domain::Point;
114  using Vector = typename Domain::Vector;
115  using Integer = typename Domain::Integer;
116  using Size = typename Domain::Size;
117  using Dimension = typename Domain::Dimension;
118  using Vertex = Point;
119  using Value = TValue;
120  using Functor = TFunctor;
121 
122  using ConstIterator = boost::transform_iterator< std::reference_wrapper<const Self>, typename Domain::ConstIterator >;
123  using ConstReverseIterator = std::reverse_iterator< ConstIterator >;
124  class ConstRange;
125 
126  BOOST_STATIC_CONSTANT( Dimension, dimension = Domain::Space::dimension );
127 
128  // ------------------------- Private Datas --------------------------------
129  // Private members moved to the beginning of the class because of
130  // the SFINAE trick in the operator() methods.
131 private:
134 
135  // ----------------------- Standard services ------------------------------
136 public:
137 
142  template < class TGivenFunctor >
143  explicit ConstImageFunctorHolder( Domain const& aDomain, TGivenFunctor && aFunctor )
144  : myDomain( aDomain )
145  , myFunctor( std::forward<TGivenFunctor>(aFunctor) )
146  {
147  }
148 
149  // ----------------------- Interface --------------------------------------
150 public:
151 
153  inline
154  Domain const& domain() const
155  {
156  return myDomain;
157  }
158 
160 
168  template <typename TPoint> // Needed template parameter to enable SFINAE trick
169  inline
170  auto operator() ( TPoint const& aPoint ) const
171  -> decltype( myFunctor( aPoint ) ) // Using SFINAE to enable this overload for unary functor
172  {
173  ASSERT_MSG(
174  myDomain.isInside(aPoint),
175  "The point is outside the domain."
176  );
177  return myFunctor( aPoint );
178  }
179 
180  template <typename TPoint> // Needed template parameter to enable SFINAE trick
181  inline
182  auto operator() ( TPoint const& aPoint ) const
183  -> decltype( myFunctor( aPoint, myDomain ) ) // Using SFINAE to enable this overload for binary functor
184  {
185  ASSERT_MSG(
186  myDomain.isInside(aPoint),
187  "The point is outside the domain."
188  );
189  return myFunctor( aPoint, myDomain );
190  }
191 
193 
196  inline
198  {
199  return ConstRange( *this );
200  }
201 
205  inline
206  void selfDisplay ( std::ostream & out ) const
207  {
208  out << "[ConstImageFunctorHolder] holding a " << myFunctor << " on domain " << myDomain;
209  }
210 
214  inline constexpr
215  bool isValid() const
216  {
217  return true;
218  }
219 
220 public:
223  {
224  public:
225  ConstRange( Self const& aConstImageFunctorHolder )
226  : myConstImageFunctorHolder( aConstImageFunctorHolder )
227  {}
228 
231  using Point = typename Self::Point;
232 
236 
237  inline ConstReverseIterator rbegin() const { return ConstReverseIterator( end() ); }
238  inline ConstReverseIterator rbegin( Point const& aPoint ) const { return ConstReverseIterator( ++begin(aPoint) ); }
239  inline ConstReverseIterator rend() const { return ConstReverseIterator( begin() ); }
240 
241  private:
243  }; // End of class ConstRange
244 }; // End of class ConstImageFunctorHolder
245 
252 template <typename TDomain, typename TValue, typename TFunctor>
253 std::ostream&
255 {
256  object.selfDisplay(out);
257  return out;
258 }
259 
271 template <
272  typename TValue,
273  typename TDomain,
274  typename TFunctor
275 >
276 inline auto
277 holdConstImageFunctor( TDomain const& aDomain, TFunctor && aFunctor )
279  {
280  return ConstImageFunctorHolder<TDomain, TValue, decltype(holdFunctor(std::forward<TFunctor>(aFunctor)))>{ aDomain, holdFunctor(std::forward<TFunctor>(aFunctor)) };
281  }
282 
284 
299 // Auto-deduction of the return type in case of an unary functor.
300 template <
301  typename TDomain,
302  typename TFunctor
303 >
304 inline auto
305 holdConstImageFunctor( TDomain const& aDomain, TFunctor && aFunctor )
307  TDomain,
308  typename std::decay<decltype(aFunctor(std::declval<typename TDomain::Point>()))>::type,
309  decltype(holdFunctor(std::forward<TFunctor>(aFunctor)))
310  >
311  {
313  TDomain,
314  typename std::decay<decltype(aFunctor(std::declval<typename TDomain::Point>()))>::type,
315  decltype(holdFunctor(std::forward<TFunctor>(aFunctor)))
316  >{ aDomain, holdFunctor(std::forward<TFunctor>(aFunctor)) };
317  }
318 
319 // Auto-deduction of the return type in case of a binary functor.
320 template <
321  typename TDomain,
322  typename TFunctor
323 >
324 inline auto
325 holdConstImageFunctor( TDomain const& aDomain, TFunctor && aFunctor )
326  -> ConstImageFunctorHolder<
327  TDomain,
328  typename std::decay<decltype(aFunctor(std::declval<typename TDomain::Point>(), aDomain))>::type,
329  decltype(holdFunctor(std::forward<TFunctor>(aFunctor)))
330  >
331  {
332  return ConstImageFunctorHolder<
333  TDomain,
334  typename std::decay<decltype(aFunctor(std::declval<typename TDomain::Point>(), aDomain))>::type,
335  decltype(holdFunctor(std::forward<TFunctor>(aFunctor)))
336  >{ aDomain, holdFunctor(std::forward<TFunctor>(aFunctor)) };
337  }
338 
340 
341 } // namespace functors
342 } // namespace DGtal
343 
344 #endif // !defined ConstImageFunctorHolder_h
345 
346 #undef ConstImageFunctorHolder_RECURSES
347 #endif // else defined(ConstImageFunctorHolder_RECURSES)
const Point aPoint(3, 4)
BOOST_CONCEPT_ASSERT((DGtal::concepts::CDomain< TDomain >))
auto operator()(TPoint const &aPoint) const -> decltype(myFunctor(aPoint))
Evaluates the functor at the given point.
ConstImageFunctorHolder(Domain const &aDomain, TGivenFunctor &&aFunctor)
Constructor.
Functor myFunctor
The functor that generates the image.
Image::ConstRange ConstRange
boost::transform_iterator< std::reference_wrapper< const Self >, typename Domain::ConstIterator > ConstIterator
Domain const & domain() const
Returns the associated domain.
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.
Aim: This concept represents a digital domain, i.e. a non mutable subset of points of the given digit...
Definition: CDomain.h:129
std::reverse_iterator< ConstIterator > ConstReverseIterator
void selfDisplay(std::ostream &out) const
Writes/Displays the object on an output stream.
Transform a point-dependent (and possibly domain-dependent) functor into a constant image.
DGtal is the top-level namespace which contains all DGtal functions and types.
MyPointD Point
Definition: testClone2.cpp:383
ConstRange constRange() const
Returns a constant range over this image.
FreemanChain< int >::Vector Vector
ConstReverseIterator rbegin(Point const &aPoint) const
BOOST_STATIC_CONSTANT(Dimension, dimension=Domain::Space::dimension)
std::ostream & operator<<(std::ostream &out, const FunctorHolder< FunctorStorage, NeedDereference > &object)
Overloads 'operator<<' for displaying objects of class FunctorHolder.
constexpr bool isValid() const
Checks the validity/consistency of the object.
Constant range on a ConstImageFunctorHolder.
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.