$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
util/array.hh
1 // Copyright (C) 2008, 2009, 2011, 2012, 2013 EPITA Research and
2 // Development Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_UTIL_ARRAY_HH
28 # define MLN_UTIL_ARRAY_HH
29 
36 
37 # include <vector>
38 # include <iostream>
39 # include <algorithm>
40 
41 # include <mln/core/alias/box1d.hh>
42 # include <mln/core/concept/function.hh>
43 # include <mln/core/concept/proxy.hh>
44 # include <mln/core/concept/iterator.hh>
45 
46 # include <mln/fun/internal/selector.hh>
47 
48 
49 namespace mln
50 {
51 
52  // Forward declarations.
53  namespace fun {
54  namespace i2v {
55  template <typename T> class array;
56  }
57  }
58  template <typename V> struct image1d;
59  // End of forward declarations
60 
61 
62  namespace util
63  {
64 
65  // Forward declarations.
66  template <typename T> class array_fwd_iter;
67  template <typename T> class array_bkd_iter;
68 
69 
78  //
79  template <typename T>
80  class array
82 
83  // public Function_v2v< mln::util::array<T> >
84  {
85  public:
86 
88  typedef T element;
89 
94 
95  typedef T result;
96  typedef typename std::vector<T>::const_reference ro_result;
97  typedef typename std::vector<T>::reference mutable_result;
98 
100 
101 
104 
107 
110 
112  typedef fwd_eiter eiter;
113 
115 
116 
119 
121  array();
122 
124  array(unsigned n);
125 
128  array(unsigned n, const T& value);
129 
131 
133  void reserve(unsigned n);
134 
136  void resize(unsigned n);
137 
139  void resize(unsigned n, const T& value);
140 
141 
143  array<T>& append(const T& elt);
144 
146  template <typename U>
147  array<T>& append(const array<U>& other);
148 
149 
151  unsigned nelements() const;
152 
156  unsigned size() const;
157 
159  bool is_empty() const;
160 
161 
164  ro_result operator()(unsigned i) const;
165 
168  mutable_result operator()(unsigned i);
169 
172  ro_result operator[](unsigned i) const;
173 
176  mutable_result operator[](unsigned i);
177 
179  ro_result last() const;
180 
183 
186  void clear();
187 
189  void fill(const T& value);
190 
192  const std::vector<T>& std_vector() const;
193 
195  std::vector<T>& hook_std_vector_();
196 
198  std::size_t memory_size() const;
199 
200  private:
201  std::vector<T> v_;
202  };
203 
204 
207  template <typename T>
208  std::ostream& operator<<(std::ostream& ostr,
209  const array<T>& a);
210 
213  template <typename T>
214  bool operator==(const array<T>& lhs,
215  const array<T>& rhs);
216 
217 
220  template <typename T1, typename T2>
221  void
222  from_to_(const array<T1>& from, array<T2>& to);
223 
225  template <typename T>
226  inline
227  void
228  from_to_(const array<T>& from, fun::i2v::array<T>& to);
229 
231  template <typename T, typename U>
232  inline
233  void
234  from_to_(const array<T>& from, fun::i2v::array<U>& to);
235 
237  template <typename V, typename T>
238  void from_to_(const util::array<V>& from, image1d<T>& to);
240 
241  // array_fwd_iter<T>
242 
243  template <typename T>
244  class array_fwd_iter : public Proxy< array_fwd_iter<T> >,
245  public mln::internal::proxy_impl< const T&,
246  array_fwd_iter<T> >
247  {
248  public:
249  typedef typename array<T>::ro_result subj_t;
250 
253 
255  array_fwd_iter();
256 
258  array_fwd_iter(const array<T>& a);
259 
261 
263  void change_target(const array<T>& a);
264 
266  void start();
267 
269  void next();
270 
272  bool is_valid() const;
273 
275  void invalidate();
276 
278  T element() const;
279 
280  // As a Proxy.
281  subj_t subj_();
282 
284  unsigned index_() const;
285 
286  protected:
287  unsigned i_;
288  const array<T>* a_;
289  };
290 
291 
292 
293 
294  // array_bkd_iter<T>
295 
296  template <typename T>
297  class array_bkd_iter : public Proxy< array_bkd_iter<T> >,
298  public mln::internal::proxy_impl< const T&,
299  array_bkd_iter<T> >
300  {
301  public:
302  typedef typename array<T>::ro_result subj_t;
303 
306 
308  array_bkd_iter();
309 
311  array_bkd_iter(const array<T>& a);
312 
314 
316  void change_target(const array<T>& a);
317 
319  void start();
320 
322  void next();
323 
325  bool is_valid() const;
326 
328  void invalidate();
329 
331  T element() const;
332 
333  // As a Proxy.
334  subj_t subj_();
335 
337  unsigned index_() const;
338 
339  protected:
340  unsigned i_;
341  const array<T>* a_;
342  };
343 
344  } // end of namespace mln::util
345 
346 
347  namespace internal
348  {
349 
350  template <typename T, typename E>
351  struct subject_impl<const util::array<T>&, E>
352  {
353  typedef typename util::array<T>::ro_result ro_result;
354 
355  unsigned nelements() const;
356  unsigned size() const;
357  bool is_empty() const;
358  ro_result operator()(unsigned i) const;
359  ro_result operator[](unsigned i) const;
360  const std::vector<T>& std_vector() const;
361 
362  private:
363  const E& exact_() const;
364  };
365 
366 
367  template <typename T, typename E>
368  struct subject_impl<util::array<T>&, E>
369  : subject_impl<const util::array<T>&, E>
370  {
371  typedef typename util::array<T>::mutable_result mutable_result;
372 
373  void reserve(unsigned n);
374  void resize(unsigned n);
375  void resize(unsigned n, const T& value);
376 
377  util::array<T>& append(const T& elt);
378 
379  template <typename U>
380  util::array<T>& append(const util::array<U>& other);
381 
382  mutable_result operator()(unsigned i);
383  mutable_result operator[](unsigned i);
384 
385  void clear();
386 
387  void fill(const T& value);
388 
389  std::vector<T>& hook_std_vector_();
390 
391  private:
392  E& exact_();
393  };
394 
395 
396  } // end of namespace mln::internal
397 
398 
399 # ifndef MLN_INCLUDE_ONLY
400 
401 
402  namespace util
403  {
404 
405  // util::array<T>
406 
407 
408  template <typename T>
409  inline
411  {
412  }
413 
414  template <typename T>
415  inline
416  array<T>::array(unsigned n)
417  : v_(n)
418  {
419  }
420 
421  template <typename T>
422  inline
423  array<T>::array(unsigned n, const T& value)
424  : v_(n, value)
425  {
426  }
427 
428  template <typename T>
429  inline
430  void
431  array<T>::reserve(unsigned n)
432  {
433  v_.reserve(n);
434  }
435 
436  template <typename T>
437  inline
438  void
439  array<T>::resize(unsigned n)
440  {
441  v_.resize(n);
442  }
443 
444  template <typename T>
445  inline
446  void
447  array<T>::resize(unsigned n, const T& value)
448  {
449  v_.resize(n, value);
450  }
451 
452  template <typename T>
453  inline
454  array<T>&
455  array<T>::append(const T& elt)
456  {
457  v_.push_back(elt);
458  return *this;
459  }
460 
461  template <typename T>
462  template <typename U>
463  inline
464  array<T>&
465  array<T>::append(const array<U>& other)
466  {
467  if (other.is_empty())
468  // No-op.
469  return *this;
470  v_.insert(v_.end(),
471  other.std_vector().begin(), other.std_vector().end());
472  return *this;
473  }
474 
475  template <typename T>
476  inline
477  void
479  {
480  v_.clear();
481  mln_postcondition(is_empty());
482  }
483 
484  template <typename T>
485  inline
486  void
487  array<T>::fill(const T& value)
488  {
489  std::fill(v_.begin(), v_.end(), value);
490  }
491 
492  template <typename T>
493  inline
494  unsigned
495  array<T>::size() const
496  {
497  return nelements();
498  }
499 
500  template <typename T>
501  inline
502  unsigned
503  array<T>::nelements() const
504  {
505  return v_.size();
506  }
507 
508  template <typename T>
509  inline
510  typename array<T>::ro_result
511  array<T>::operator()(unsigned i) const
512  {
513  return (*this)[i];
514  }
515 
516  template <typename T>
517  inline
518  typename array<T>::mutable_result
519  array<T>::operator()(unsigned i)
520  {
521  return (*this)[i];
522  }
523 
524  template <typename T>
525  inline
526  typename array<T>::ro_result
527  array<T>::operator[](unsigned i) const
528  {
529  mln_precondition(i < nelements());
530  return v_[i];
531  }
532 
533  template <typename T>
534  inline
535  typename array<T>::mutable_result
536  array<T>::operator[](unsigned i)
537  {
538  mln_precondition(i < nelements());
539  return v_[i];
540  }
541 
542  template <typename T>
543  inline
544  typename array<T>::ro_result
545  array<T>::last() const
546  {
547  return v_[nelements() - 1];
548  }
549 
550  template <typename T>
551  inline
552  typename array<T>::mutable_result
554  {
555  return v_[nelements() - 1];
556  }
557 
558  template <typename T>
559  inline
560  bool
561  array<T>::is_empty() const
562  {
563  return nelements() == 0;
564  }
565 
566  template <typename T>
567  inline
568  const std::vector<T>&
569  array<T>::std_vector() const
570  {
571  return v_;
572  }
573 
574  template <typename T>
575  inline
576  std::vector<T>&
578  {
579  return v_;
580  }
581 
582  template <typename T>
583  inline
584  std::size_t
585  array<T>::memory_size() const
586  {
587  return sizeof(*this) + nelements() * sizeof(T);
588  }
589 
590 
591  // Conversions
592 
593  template <typename T1, typename T2>
594  void
595  from_to_(const array<T1>& from, array<T2>& to)
596  {
597  to.resize(from.nelements());
598 
599  for (unsigned i = 0; i < from.nelements(); ++i)
600  to[i] = convert::to<T2>(from[i]);
601  }
602 
603  template <typename T>
604  void
605  from_to_(const array<T>& from, fun::i2v::array<T>& to)
606  {
607  to = fun::i2v::array<T>(from);
608  }
609 
610  template <typename T, typename U>
611  void
612  from_to_(const array<T>& from, fun::i2v::array<U>& to)
613  {
614  to.resize(from.nelements());
615  for (unsigned i = 0; i < from.nelements(); ++i)
616  to(i) = convert::to<U>(from[i]);
617  }
618 
619  template <typename V, typename T>
620  void
621  from_to_(const array<V>& from, image1d<T>& to)
622  {
623  to.init_(make::box1d(from.nelements()));
624  for (unsigned i = 0; i < from.nelements(); ++i)
625  from_to(from[i], to(point1d(i)));
626  }
627 
628 
629 
630  // util::array_fwd_iter<T>
631 
632 
633  template <typename T>
634  inline
636  {
637  a_ = 0;
638  }
639 
640  template <typename T>
641  inline
642  array_fwd_iter<T>::array_fwd_iter(const array<T>& a)
643  {
644  change_target(a);
645  }
646 
647  template <typename T>
648  inline
649  void
650  array_fwd_iter<T>::change_target(const array<T>& a)
651  {
652  a_ = &a;
653  invalidate();
654  }
655 
656  template <typename T>
657  inline
658  void
660  {
661  mln_precondition(a_ != 0);
662  i_ = 0;
663  }
664 
665  template <typename T>
666  inline
667  void
669  {
670  mln_precondition(is_valid());
671  ++i_;
672  }
673 
674  template <typename T>
675  inline
676  bool
678  {
679  return a_ != 0 && i_ != a_->nelements();
680  }
681 
682  template <typename T>
683  inline
684  void
686  {
687  if (a_ != 0)
688  i_ = a_->nelements();
689  mln_postcondition(! is_valid());
690  }
691 
692  template <typename T>
693  inline
694  T
696  {
697  mln_precondition(is_valid());
698  return a_->operator[](i_);
699  }
700 
701  template <typename T>
702  inline
703  typename array_fwd_iter<T>::subj_t
705  {
706  mln_precondition(is_valid());
707  return a_->operator[](i_);
708  }
709 
710  template <typename T>
711  inline
712  unsigned
714  {
715  return i_;
716  }
717 
718 
719 
720  // util::array_bkd_iter<T>
721 
722 
723  template <typename T>
724  inline
726  {
727  a_ = 0;
728  }
729 
730  template <typename T>
731  inline
732  array_bkd_iter<T>::array_bkd_iter(const array<T>& a)
733  {
734  change_target(a);
735  }
736 
737  template <typename T>
738  inline
739  void
740  array_bkd_iter<T>::change_target(const array<T>& a)
741  {
742  a_ = &a;
743  invalidate();
744  }
745 
746  template <typename T>
747  inline
748  void
750  {
751  mln_precondition(a_ != 0);
752  if (! a_->is_empty())
753  i_ = a_->nelements() - 1;
754  }
755 
756  template <typename T>
757  inline
758  void
760  {
761  mln_precondition(is_valid());
762  if (i_ == 0)
763  invalidate();
764  else
765  --i_;
766  }
767 
768  template <typename T>
769  inline
770  bool
772  {
773  return a_ != 0 && i_ != a_->nelements();
774  }
775 
776  template <typename T>
777  inline
778  void
780  {
781  if (a_ != 0)
782  i_ = a_->nelements();
783  mln_postcondition(! is_valid());
784  }
785 
786  template <typename T>
787  inline
788  T
790  {
791  mln_precondition(is_valid());
792  return a_->operator[](i_);
793  }
794 
795  template <typename T>
796  inline
797  typename array_bkd_iter<T>::subj_t
799  {
800  mln_precondition(is_valid());
801  return a_->operator[](i_);
802  }
803 
804  template <typename T>
805  inline
806  unsigned
808  {
809  return i_;
810  }
811 
812 
813 
814  // Operator <<.
815 
816  template <typename T>
817  std::ostream& operator<<(std::ostream& ostr,
818  const array<T>& a)
819  {
820  ostr << '[';
821  const unsigned n = a.nelements();
822  for (unsigned i = 0; i < n; ++i)
823  {
824  ostr << a[i];
825  if (i != n - 1)
826  ostr << ", ";
827  }
828  ostr << ']';
829  return ostr;
830  }
831 
832 
833  // Operator <<.
834 
835  template <typename T>
836  bool operator==(const array<T>& lhs,
837  const array<T>& rhs)
838  {
839  return lhs.std_vector() == rhs.std_vector();
840  }
841 
842  } // end of namespace mln::util
843 
844 
845  namespace internal
846  {
847 
848  template <typename T, typename E>
849  inline
850  void
851  subject_impl<util::array<T>&, E>::reserve(unsigned n)
852  {
853  exact_().get_subject().reserve(n);
854  }
855 
856  template <typename T, typename E>
857  inline
858  void
859  subject_impl<util::array<T>&, E>::resize(unsigned n)
860  {
861  exact_().get_subject().resize(n);
862  }
863 
864  template <typename T, typename E>
865  inline
866  void
867  subject_impl<util::array<T>&, E>::resize(unsigned n, const T& value)
868  {
869  exact_().get_subject().resize(n, value);
870  }
871 
872  template <typename T, typename E>
873  inline
874  util::array<T>&
875  subject_impl<util::array<T>&, E>::append(const T& elt)
876  {
877  return exact_().get_subject().append(elt);
878  }
879 
880  template <typename T, typename E>
881  template <typename U>
882  inline
883  util::array<T>&
884  subject_impl<util::array<T>&, E>::append(const util::array<U>& other)
885  {
886  return exact_().get_subject().append(other);
887  }
888 
889  template <typename T, typename E>
890  inline
891  typename subject_impl<util::array<T>&, E>::mutable_result
892  subject_impl<util::array<T>&, E>::operator()(unsigned i)
893  {
894  return exact_().get_subject()(i);
895  }
896 
897  template <typename T, typename E>
898  inline
899  typename subject_impl<util::array<T>&, E>::mutable_result
900  subject_impl<util::array<T>&, E>::operator[](unsigned i)
901  {
902  return exact_().get_subject()[i];
903  }
904 
905  template <typename T, typename E>
906  inline
907  void
908  subject_impl<util::array<T>&, E>::clear()
909  {
910  exact_().get_subject().clear();
911  }
912 
913  template <typename T, typename E>
914  inline
915  void
916  subject_impl<util::array<T>&, E>::fill(const T& value)
917  {
918  exact_().get_subject().fill(value);
919  }
920 
921  template <typename T, typename E>
922  inline
923  std::vector<T>&
924  subject_impl<util::array<T>&, E>::hook_std_vector_()
925  {
926  return exact_().get_subject().hook_std_vector_();
927  }
928 
929  template <typename T, typename E>
930  inline
931  E&
932  subject_impl<util::array<T>&, E >::exact_()
933  {
934  return internal::force_exact<E>(*this);
935  }
936 
937 
938  template <typename T, typename E>
939  inline
940  unsigned
941  subject_impl<const util::array<T>&, E>::size() const
942  {
943  return exact_().get_subject().size();
944  }
945 
946  template <typename T, typename E>
947  inline
948  unsigned
949  subject_impl<const util::array<T>&, E>::nelements() const
950  {
951  return exact_().get_subject().nelements();
952  }
953 
954  template <typename T, typename E>
955  inline
956  bool
957  subject_impl<const util::array<T>&, E>::is_empty() const
958  {
959  return exact_().get_subject().is_empty();
960  }
961 
962  template <typename T, typename E>
963  inline
964  typename subject_impl<const util::array<T>&, E>::ro_result
965  subject_impl<const util::array<T>&, E>::operator()(unsigned i) const
966  {
967  return exact_().get_subject()(i);
968  }
969 
970  template <typename T, typename E>
971  inline
972  typename subject_impl<const util::array<T>&, E>::ro_result
973  subject_impl<const util::array<T>&, E>::operator[](unsigned i) const
974  {
975  return exact_().get_subject()[i];
976  }
977 
978  template <typename T, typename E>
979  inline
980  const std::vector<T>&
981  subject_impl<const util::array<T>&, E>::std_vector() const
982  {
983  return exact_().get_subject().std_vector();
984  }
985 
986  template <typename T, typename E>
987  inline
988  const E&
989  subject_impl<const util::array<T>&, E >::exact_() const
990  {
991  return internal::force_exact<const E>(*this);
992  }
993 
994 
995  } // end of namespace mln::internal
996 
997 # endif // ! MLN_INCLUDE_ONLY
998 
999 
1000 } // end of namespace mln
1001 
1002 #endif // ! MLN_UTIL_ARRAY_HH