DGtal  0.9.3beta
ArrayImageAdapter.h
1 
17 #pragma once
18 
29 #if defined(ArrayImageAdapter_RECURSES)
30 #error Recursive header files inclusion detected in ArrayImageAdapter.h
31 #else // defined(ArrayImageAdapter_RECURSES)
32 
33 #define ArrayImageAdapter_RECURSES
34 
35 #if !defined ArrayImageAdapter_h
36 
37 #define ArrayImageAdapter_h
38 
40 // Inclusions
41 #include <boost/concept/assert.hpp>
42 #include <boost/iterator/iterator_concepts.hpp>
43 #include <iterator>
44 #include <type_traits>
45 
46 #include <DGtal/base/Common.h>
47 #include <DGtal/images/CConstImage.h>
48 #include <DGtal/images/ArrayImageIterator.h>
49 #include <DGtal/base/IteratorCompletion.h>
50 #include <DGtal/kernel/domains/Linearizer.h>
52 
53 namespace DGtal
54 {
55 
58 
67  template <
68  typename TArrayIterator,
69  typename TDomain
70  >
71  class ArrayImageAdapter;
73 
75 
112  template <
113  typename TArrayIterator,
114  typename TSpace
115  >
116  class ArrayImageAdapter< TArrayIterator, HyperRectDomain<TSpace> >
117  : public IteratorCompletion< ArrayImageAdapter< TArrayIterator, HyperRectDomain<TSpace> > >
118  {
119 
120  // Checks Random-access iterator concept on TArrayIterator
122 
123  public:
124  // Aliases
125  using Self = ArrayImageAdapter<TArrayIterator, HyperRectDomain<TSpace> >;
126  using ArrayIterator = TArrayIterator;
127  using Value = typename std::iterator_traits<ArrayIterator>::value_type;
128  using Reference = typename std::iterator_traits<ArrayIterator>::reference;
129  using ConstReference = const Reference;
130 
131  // DGtal aliases and constant
133  using Point = typename Domain::Point;
134  using Dimension = typename Domain::Dimension;
135  using Size = typename Domain::Size;
136  using Vector = typename Domain::Vector;
137  using Vertex = Point;
138  using Integer = typename Domain::Integer;
139  BOOST_STATIC_CONSTANT( Dimension, dimension = Domain::dimension );
140 
142 
143  // Iterators & Ranges
144  template <class> friend class ArrayImageIterator;
147 
153  : myArrayIterator{nullptr}
154  , myFullDomain{}
155  , myViewDomain{}
156  {}
157 
164  ArrayImageAdapter( ArrayIterator anArrayIterator, Domain const& aFullDomain, Domain const& aViewDomain )
165  : myArrayIterator(anArrayIterator)
166  , myFullDomain{ aFullDomain }
167  , myViewDomain{ aViewDomain }
168  {
169  ASSERT_MSG(
170  aFullDomain.lowerBound().isLower( aViewDomain.lowerBound() )
171  && aFullDomain.upperBound().isUpper( aViewDomain.upperBound() ),
172  "The viewable domain must be included into the full domain."
173  );
174  }
175 
183  ArrayImageAdapter( ArrayIterator anArrayIterator, Domain const& aFullDomain )
184  : ArrayImageAdapter( anArrayIterator, aFullDomain, aFullDomain )
185  {
186  }
187 
197  ArrayImageAdapter( Self const& other, Domain const& aViewDomain )
198  : ArrayImageAdapter( other.myArrayIterator, other.myFullDomain, aViewDomain )
199  {}
200 
204  inline
205  Domain domain() const
206  {
207  return myViewDomain;
208  }
209 
213  inline
215  {
216  return myFullDomain;
217  }
218 
224  inline
225  Value getValue( Point const& aPoint ) const
226  {
227  ASSERT_MSG(
228  myFullDomain.isInside(aPoint),
229  "The point is outside the full domain."
230  );
231 
232  return myArrayIterator[ Linearizer::getIndex(aPoint, myFullDomain) ];
233  }
234 
240  inline
241  void setValue( Point const& aPoint, Value aValue )
242  {
243  ASSERT_MSG(
244  myFullDomain.isInside(aPoint),
245  "The point is outside the full domain."
246  );
247 
248  myArrayIterator[ Linearizer::getIndex(aPoint, myFullDomain) ] = aValue;
249  }
250 
256  inline
257  Value operator() ( Point const& aPoint ) const
258  {
259  return getValue(aPoint);
260  }
261 
265  inline
267  {
268  return Iterator{ this, myFullDomain, myViewDomain };
269  }
270 
274  inline
276  {
277  return ConstIterator{ this, myFullDomain, myViewDomain };
278  }
279 
283  inline
285  {
286  return ConstIterator{ this, myFullDomain, myViewDomain };
287  }
288 
292  inline
294  {
295  return Iterator{ this, myFullDomain, myViewDomain, true };
296  }
297 
301  inline
303  {
304  return ConstIterator{ this, myFullDomain, myViewDomain, true };
305  }
306 
310  inline
312  {
313  return ConstIterator{ this, myFullDomain, myViewDomain, true };
314  }
315 
316 
317  public: // Should be private since ArrayImageIterator is a friend but g++ 4.9.1 don't care ... (no prob with clang++ 3.5.0)
318 
324  inline
325  Reference dereference( Point const& /* aPoint */, typename Point::Coordinate aFullIndex )
326  {
327  ASSERT_MSG(
328  aFullIndex >= 0 && static_cast<typename Domain::Size>(aFullIndex) < myFullDomain.size(),
329  "linearized index out of bounds !"
330  );
331  return myArrayIterator[aFullIndex];
332  }
333 
339  inline
340  ConstReference dereference( Point const& /* aPoint */, typename Point::Coordinate aFullIndex ) const
341  {
342  ASSERT_MSG(
343  aFullIndex >= 0 && static_cast<typename Domain::Size>(aFullIndex) < myFullDomain.size(),
344  "linearized index out of bounds !"
345  );
346  return myArrayIterator[aFullIndex];
347  }
348 
349  // ----------------------- Interface --------------------------------------
350  public:
355  void selfDisplay ( std::ostream & out ) const
356  {
357  out << "[ArrayImageAdapter] with full domain " << myFullDomain << " and viewable domain " << myViewDomain;
358  }
359 
364  bool isValid() const
365  {
366  return true;
367  }
368 
369  // ------------------------- Private Datas --------------------------------
370  private:
374 
375  }; // end of class ArrayImageAdapter
376 
378 
383  template <
384  typename TArrayIterator,
385  typename TDomain
386  >
387  class IteratorCompletionTraits< ArrayImageAdapter<TArrayIterator, TDomain> >
388  {
389  public:
390  using Self = ArrayImageAdapter<TArrayIterator, TDomain>;
393 
398  class DistanceFunctor
399  {
400  public:
401  using Domain = typename Self::Domain;
402  using Point = typename Self::Point;
403  using Difference = typename Self::Difference;
404 
408  DistanceFunctor( Self const* anImage )
409  : myDomain( anImage->domain() )
410  {}
411 
416  Difference operator() ( Point const& aPoint ) const
417  {
418  ASSERT_MSG(
419  myDomain.isInside(aPoint),
420  "The point is outside the domain !"
421  );
422  return Linearizer<Domain, ColMajorStorage>::getIndex( aPoint, myDomain );
423  }
424 
425  private:
427  };
428 
429  }; // end of specialized class IteratorCompletionTraits
430 
432 
439  template <
440  typename TArrayIterator,
441  typename TDomain
442  >
443  std::ostream&
444  operator<< ( std::ostream & out, const ArrayImageAdapter<TArrayIterator, TDomain> & object )
445  {
446  object.selfDisplay( out );
447  return out;
448  }
449 
450 
451  // ------------------ ArrayImageAdapter construction helpers ----------------
452 
460  template <
461  typename TArrayIterator,
462  typename TDomain
463  >
464  ArrayImageAdapter< TArrayIterator, TDomain >
465  makeArrayImageAdapterFromIterator( TArrayIterator anArrayIterator, TDomain const& aFullDomain, TDomain const& aViewDomain )
466  {
467  return { anArrayIterator, aFullDomain, aViewDomain };
468  }
469 
478  template <
479  typename TArrayIterator,
480  typename TDomain
481  >
482  ArrayImageAdapter< TArrayIterator, TDomain >
483  makeArrayImageAdapterFromIterator( TArrayIterator anArrayIterator, TDomain const& aFullDomain )
484  {
485  return { anArrayIterator, aFullDomain, aFullDomain };
486  }
487 
493  template <
494  typename TImage,
495  typename TDomain = typename TImage::Domain
496  >
497  // We use decltype on begin() iterator because it returns the constant iterator
498  // if the image is constant while ::Iterator typedef returns the mutable iterator.
499  ArrayImageAdapter< decltype( ((TImage*)nullptr)->begin() ), TDomain >
500  makeArrayImageAdapterFromImage( TImage & anImage, TDomain const& aViewDomain )
501  {
502  // Remove constness because CConstImage requires assignability.
503  BOOST_CONCEPT_ASSERT( (DGtal::concepts::CConstImage< typename std::remove_const<TImage>::type >) );
504 
505  return { anImage.begin(), anImage.domain(), aViewDomain };
506  }
507 
514  template <
515  typename TImage,
516  typename TDomain = typename TImage::Domain
517  >
518  // We use decltype on begin() iterator because it returns the constant iterator
519  // if the image is constant while ::Iterator typedef returns the mutable iterator.
520  ArrayImageAdapter< decltype( ((TImage*)nullptr)->begin() ), TDomain >
521  makeArrayImageAdapterFromImage( TImage & anImage )
522  {
523  // Remove constness because CConstImage requires assignability.
524  BOOST_CONCEPT_ASSERT( (DGtal::concepts::CConstImage< typename std::remove_const<TImage>::type >) );
525 
526  return { anImage.begin(), anImage.domain(), anImage.domain() };
527  }
528 
529 } // namespace DGtal
530 
532 // //
534 
535 #endif // !defined ArrayImageAdapter_h
536 
537 #undef ArrayImageAdapter_RECURSES
538 #endif // else defined(ArrayImageAdapter_RECURSES)
539 
ArrayImageAdapter(Self const &other, Domain const &aViewDomain)
typename IteratorCompletionTraits< Self >::Iterator Iterator
Mutable iterator based on ArrayImageIterator.
Aim: Class that uses CRTP to add reverse iterators and ranges to a derived class. ...
Go to http://www.boost.org/doc/libs/1_52_0/libs/iterator/doc/RandomAccessTraversal.html.
TArrayIterator ArrayIterator
The given random-access iterator's type.
Aim: Traits that must be specialized for each IteratorCompletion derived class.
typename Self::Difference Difference
Type of the difference between two iterators.
Aim: Random access iterator over an image given his definition domain and viewable domain...
ArrayImageAdapter< TArrayIterator, TDomain > Self
Self type.
typename std::iterator_traits< ArrayIterator >::value_type Value
The value type stored in the image.
Aim: Parallelepidec region of a digital space, model of a 'CDomain'.
ArrayImageAdapter< TArrayIterator, TDomain > makeArrayImageAdapterFromIterator(TArrayIterator anArrayIterator, TDomain const &aFullDomain, TDomain const &aViewDomain)
Space::Dimension Dimension
Reference dereference(Point const &, typename Point::Coordinate aFullIndex)
Domain myDomain
Stored domain to avoid iterator corruption if domain changed.
typename std::iterator_traits< ArrayIterator >::reference Reference
Mutable reference type.
ArrayImageAdapter< decltype(((TImage *) nullptr) ->begin()), TDomain > makeArrayImageAdapterFromImage(TImage &anImage, TDomain const &aViewDomain)
Aim: Image adapter for generic arrays with sub-domain view capability.
Aim: Linearization and de-linearization interface for domains.
Definition: Linearizer.h:78
ArrayIterator myArrayIterator
Pointer to the allocated memory.
DGtal is the top-level namespace which contains all DGtal functions and types.
ConstReference dereference(Point const &, typename Point::Coordinate aFullIndex) const
Aim: Defines the concept describing a read-only image, which is a refinement of CPointFunctor.
Definition: CConstImage.h:94
ArrayImageAdapter(ArrayIterator anArrayIterator, Domain const &aFullDomain)
ArrayImageAdapter(ArrayIterator anArrayIterator, Domain const &aFullDomain, Domain const &aViewDomain)
typename IteratorCompletionTraits< Self >::ConstIterator ConstIterator
Constant iterator base on ArrayImageIterator.