DGtal 1.4.0
Loading...
Searching...
No Matches
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)
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
49#include "DGtal/kernel/domains/CDomain.h"
50#include "DGtal/base/FunctorHolder.h"
52
53namespace DGtal
54{
55namespace functors
56{
57
98template <
99 typename TDomain,
100 typename TValue,
101 typename TFunctor
102>
104{
106
107 // ----------------------- Interface --------------------------------------
108public:
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.
131private:
134
135 // ----------------------- Standard services ------------------------------
136public:
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 --------------------------------------
150public:
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
220public:
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
252template <typename TDomain, typename TValue, typename TFunctor>
253std::ostream&
254operator<< ( std::ostream & out, const ConstImageFunctorHolder<TDomain, TValue, TFunctor> & object )
255{
256 object.selfDisplay(out);
257 return out;
258}
259
271template <
272 typename TValue,
273 typename TDomain,
274 typename TFunctor
275>
276inline auto
277holdConstImageFunctor( 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.
300template <
301 typename TDomain,
302 typename TFunctor
303>
304inline auto
305holdConstImageFunctor( 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.
320template <
321 typename TDomain,
322 typename TFunctor
323>
324inline auto
325holdConstImageFunctor( 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)
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)
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
std::reverse_iterator< ConstIterator > ConstReverseIterator
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.
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