Loading [MathJax]/extensions/TeX/AMSsymbols.js
DGtal 2.0.0
ConstImageFunctorHolder.h
1
16
17#pragma once
18
28
29#if defined(ConstImageFunctorHolder_RECURSES)
30#error Recursive header files inclusion detected in ConstImageFunctorHolder.h
31#else // defined(ConstImageFunctorHolder_RECURSES)
33#define ConstImageFunctorHolder_RECURSES
34
35#if !defined ConstImageFunctorHolder_h
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#include <boost/iterator/reverse_iterator.hpp>
49
50#include "DGtal/kernel/domains/CDomain.h"
51#include "DGtal/base/FunctorHolder.h"
53
54namespace DGtal
55{
56namespace functors
57{
58
99template <
100 typename TDomain,
101 typename TValue,
102 typename TFunctor
103>
105{
107
108 // ----------------------- Interface --------------------------------------
109public:
110
111 // DGtal types
113 using Domain = TDomain;
114 using Point = typename Domain::Point;
115 using Vector = typename Domain::Vector;
116 using Integer = typename Domain::Integer;
117 using Size = typename Domain::Size;
118 using Dimension = typename Domain::Dimension;
119 using Vertex = Point;
120 using Value = TValue;
121 using Functor = TFunctor;
122
123 using ConstIterator = boost::transform_iterator< std::reference_wrapper<const Self>, typename Domain::ConstIterator >;
124 using ConstReverseIterator = boost::reverse_iterator< ConstIterator >;
125 class ConstRange;
126
127 BOOST_STATIC_CONSTANT( Dimension, dimension = Domain::Space::dimension );
128
129 // ------------------------- Private Datas --------------------------------
130 // Private members moved to the beginning of the class because of
131 // the SFINAE trick in the operator() methods.
132private:
135
136 // ----------------------- Standard services ------------------------------
137public:
138
143 template < class TGivenFunctor >
144 explicit ConstImageFunctorHolder( Domain const& aDomain, TGivenFunctor && aFunctor )
145 : myDomain( aDomain )
146 , myFunctor( std::forward<TGivenFunctor>(aFunctor) )
147 {
148 }
149
150 // ----------------------- Interface --------------------------------------
151public:
152
154 inline
155 Domain const& domain() const
156 {
157 return myDomain;
158 }
159
161
169 template <typename TPoint> // Needed template parameter to enable SFINAE trick
170 inline
171 auto operator() ( TPoint const& aPoint ) const
172 -> decltype( myFunctor( aPoint ) ) // Using SFINAE to enable this overload for unary functor
173 {
174 ASSERT_MSG(
175 myDomain.isInside(aPoint),
176 "The point is outside the domain."
177 );
178 return myFunctor( aPoint );
179 }
180
181 template <typename TPoint> // Needed template parameter to enable SFINAE trick
182 inline
183 auto operator() ( TPoint const& aPoint ) const
184 -> decltype( myFunctor( aPoint, myDomain ) ) // Using SFINAE to enable this overload for binary functor
185 {
186 ASSERT_MSG(
187 myDomain.isInside(aPoint),
188 "The point is outside the domain."
189 );
190 return myFunctor( aPoint, myDomain );
191 }
192
194
197 inline
199 {
200 return ConstRange( *this );
201 }
202
206 inline
207 void selfDisplay ( std::ostream & out ) const
208 {
209 out << "[ConstImageFunctorHolder] holding a " << myFunctor << " on domain " << myDomain;
210 }
211
215 inline constexpr
216 bool isValid() const
217 {
218 return true;
219 }
220
221public:
224 {
225 public:
226 ConstRange( Self const& aConstImageFunctorHolder )
227 : myConstImageFunctorHolder( aConstImageFunctorHolder )
228 {}
229
232 using Point = typename Self::Point;
233
234 inline ConstIterator begin() const { return { myConstImageFunctorHolder.myDomain.begin(), myConstImageFunctorHolder }; }
235 inline ConstIterator begin( Point const& aPoint ) const { return { myConstImageFunctorHolder.myDomain.begin(aPoint), myConstImageFunctorHolder }; }
236 inline ConstIterator end() const { return { myConstImageFunctorHolder.myDomain.end(), myConstImageFunctorHolder }; }
237
238 inline ConstReverseIterator rbegin() const { return ConstReverseIterator( end() ); }
239 inline ConstReverseIterator rbegin( Point const& aPoint ) const { return ConstReverseIterator( ++begin(aPoint) ); }
240 inline ConstReverseIterator rend() const { return ConstReverseIterator( begin() ); }
241
242 private:
244 }; // End of class ConstRange
245}; // End of class ConstImageFunctorHolder
246
253template <typename TDomain, typename TValue, typename TFunctor>
254std::ostream&
255operator<< ( std::ostream & out, const ConstImageFunctorHolder<TDomain, TValue, TFunctor> & object )
256{
257 object.selfDisplay(out);
258 return out;
259}
260
272template <
273 typename TValue,
274 typename TDomain,
275 typename TFunctor
276>
277inline auto
278holdConstImageFunctor( TDomain const& aDomain, TFunctor && aFunctor )
280 {
281 return ConstImageFunctorHolder<TDomain, TValue, decltype(holdFunctor(std::forward<TFunctor>(aFunctor)))>{ aDomain, holdFunctor(std::forward<TFunctor>(aFunctor)) };
282 }
283
285
299
300// Auto-deduction of the return type in case of an unary functor.
301template <
302 typename TDomain,
303 typename TFunctor
304>
305inline auto
306holdConstImageFunctor( TDomain const& aDomain, TFunctor && aFunctor )
308 TDomain,
309 typename std::decay<decltype(aFunctor(std::declval<typename TDomain::Point>()))>::type,
310 decltype(holdFunctor(std::forward<TFunctor>(aFunctor)))
311 >
312 {
314 TDomain,
315 typename std::decay<decltype(aFunctor(std::declval<typename TDomain::Point>()))>::type,
316 decltype(holdFunctor(std::forward<TFunctor>(aFunctor)))
317 >{ aDomain, holdFunctor(std::forward<TFunctor>(aFunctor)) };
318 }
319
320// Auto-deduction of the return type in case of a binary functor.
321template <
322 typename TDomain,
323 typename TFunctor
324>
325inline auto
326holdConstImageFunctor( TDomain const& aDomain, TFunctor && aFunctor )
327 -> ConstImageFunctorHolder<
328 TDomain,
329 typename std::decay<decltype(aFunctor(std::declval<typename TDomain::Point>(), aDomain))>::type,
330 decltype(holdFunctor(std::forward<TFunctor>(aFunctor)))
331 >
332 {
333 return ConstImageFunctorHolder<
334 TDomain,
335 typename std::decay<decltype(aFunctor(std::declval<typename TDomain::Point>(), aDomain))>::type,
336 decltype(holdFunctor(std::forward<TFunctor>(aFunctor)))
337 >{ aDomain, holdFunctor(std::forward<TFunctor>(aFunctor)) };
338 }
339
341
342} // namespace functors
343} // namespace DGtal
344
345#endif // !defined ConstImageFunctorHolder_h
346
347#undef ConstImageFunctorHolder_RECURSES
348#endif // else defined(ConstImageFunctorHolder_RECURSES)
Constant range on a ConstImageFunctorHolder.
ConstReverseIterator rbegin(Point const &aPoint) const
Transform a point-dependent (and possibly domain-dependent) functor into a constant image.
BOOST_STATIC_CONSTANT(Dimension, dimension=Domain::Space::dimension)
boost::reverse_iterator< ConstIterator > ConstReverseIterator
auto operator()(TPoint const &aPoint) const -> decltype(myFunctor(aPoint))
Evaluates the functor at the given point.
ConstImageFunctorHolder(Domain const &aDomain, TGivenFunctor &&aFunctor)
Constructor.
Domain const & domain() const
Returns the associated domain.
void selfDisplay(std::ostream &out) const
Writes/Displays the object on an output stream.
boost::transform_iterator< std::reference_wrapper< const Self >, typename Domain::ConstIterator > ConstIterator
ConstImageFunctorHolder< TDomain, TValue, TFunctor > Self
constexpr bool isValid() const
Checks the validity/consistency of the object.
BOOST_CONCEPT_ASSERT((DGtal::concepts::CDomain< TDomain >))
ConstRange constRange() const
Returns a constant range over this image.
Functor myFunctor
The functor that generates the image.
functors namespace gathers all DGtal functors.
std::ostream & operator<<(std::ostream &out, const FunctorHolder< FunctorStorage, NeedDereference > &object)
Overloads 'operator<<' for displaying objects of class FunctorHolder.
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.
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.
STL namespace.
Aim: This concept represents a digital domain, i.e. a non mutable subset of points of the given digit...
Definition CDomain.h:130
const Point aPoint(3, 4)
Image::ConstRange ConstRange