ivl 679
ivl/details/array/impl/specialization/unary_elem_func_class.hpp
00001 /* This file is part of the ivl C++ library <http://image.ntua.gr/ivl>.
00002    A C++ template library extending syntax towards mathematical notation.
00003 
00004    Copyright (C) 2012 Yannis Avrithis <iavr@image.ntua.gr>
00005    Copyright (C) 2012 Kimon Kontosis <kimonas@image.ntua.gr>
00006 
00007    ivl is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU Lesser General Public License 
00009    version 3 as published by the Free Software Foundation.
00010 
00011    Alternatively, you can redistribute it and/or modify it under the terms 
00012    of the GNU General Public License version 2 as published by the Free 
00013    Software Foundation.
00014 
00015    ivl is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00018    See the GNU General Public License for more details.
00019 
00020    You should have received a copy of the GNU General Public License 
00021    and a copy of the GNU Lesser General Public License along 
00022    with ivl. If not, see <http://www.gnu.org/licenses/>. */
00023 
00024 template <class T, class J> struct force_class;
00025 
00026 namespace array_details {
00027 
00028 template <template <typename, typename> class F>
00029 struct is_not_force_elem_class : public types::t_true { };
00030 
00031 template <>
00032 struct is_not_force_elem_class <force_class> : public types::t_false { };
00033 
00034 } /* namespace array_details */
00035 
00036 
00042 template <class T,
00043                  template <typename, typename> class F, class A,
00044                  class DERIVED_INFO
00045              >
00046 class array<T, data::unary_elem_func<F, A, DERIVED_INFO> > :
00047 
00048 public array_common_base<array<T,
00049         data::unary_elem_func<F, A, DERIVED_INFO> > >
00050 {
00051 
00052 private:
00053         typedef array_common_base<array<T,
00054                 data::unary_elem_func<F, A, DERIVED_INFO> > > common_base_class;
00055 
00056 protected:
00057         typedef typename array::has_random_access prv_has_random_access;
00058 
00059         typedef array_details::elem_func_tools<typename A::elem_type,
00060                 prv_has_random_access::value> tool;
00061 
00062         friend class tool::not_a_type; // allow disabled types only in our class
00063 
00064         typedef typename types::t_or_3<
00065                 types::t_eq<typename A::data_type, val_repeat>,
00066                 types::t_eq<typename A::data_type, ref_val_repeat>,
00067                 types::is_base<data::ice_wrap_array_attr_base_identifier, 
00068                         typename A::data_type>
00069                 //types::is_base<data::member_identifier, typename A1::data_type>
00070                 >::type
00071                         in_is_scalar;
00072 
00073         typedef typename types::t_if<in_is_scalar,
00074                 internal::pointer_face<A>, const A*>::type in_t;
00075 
00076 
00077         in_t in1;
00078 
00079 public:
00080 
00081         // grant special treatment for the force_class as about the
00082         // is_referencing_array tag.
00083         // TODO: force wont be elem func any more. Act accordingly.
00084         typedef typename array_details::is_not_force_elem_class<F>::type
00085                 is_referencing_array;
00086 
00087         typedef array this_type;
00088 
00089         typedef this_type this_array_type;
00090 
00091         typedef this_type array_type;
00092 
00093         typedef T elem_type;
00094 
00095         typedef typename this_type::derived_type derived_type;
00096 
00097         typedef typename common_base_class::base_class base_class;
00098 
00100         typedef size_t size_type;
00101 
00103         typedef ptrdiff_t diff_type;
00104 
00105         using base_class::derived;
00106 
00107         typedef typename array::has_random_access has_random_access;
00108 
00109         class const_iterator
00110         {
00111         private:
00112                 typedef typename A::const_iterator iter_1;
00113 
00114                 iter_1 i1;
00115 
00116                 typedef typename tool::template rnd_it<const_iterator>::type rnd_iter;
00117 
00118         public:
00119 
00120                 // iterator_traits
00121                 typedef typename types::t_if<has_random_access,
00122                         std::random_access_iterator_tag,
00123                         std::bidirectional_iterator_tag>::type iterator_category;
00124 
00125                 typedef T value_type;
00126                 typedef ptrdiff_t difference_type;
00127                 //typedef const T* pointer;
00128                 //typedef const T reference;
00129                 typedef internal::pointer_face<const T> pointer;
00130                 // using this to comply with std:: iterators. if it is not optimized-out
00131                 // by the compiler, consider using
00132                 // `const internal::reference_face<const T, types::skip>'
00133                 typedef const internal::reference_face<const T, const_iterator>
00134                         reference;
00135 
00136                 // TODO: A::iter_border_walker, and correct place for this
00137                 typedef ptrdiff_t iter_border_walker;
00138 
00139                 // constructors
00140                 const_iterator() { }
00141 
00142                 const_iterator(const iter_1& i1) : i1(i1) { }
00143 
00144                 const_iterator(const const_iterator& it) : i1(it.i1) { }
00145 
00146                 pointer operator ->() const
00147                 {
00148                         return pointer(array_details::elem_func_unary_op<
00149                         T, F<T, typename std::iterator_traits<iter_1>::value_type> >::
00150                         from(*i1));
00151                 }
00152 
00153                 // members
00154                 reference operator *() const
00155                 {
00156                         return reference(array_details::elem_func_unary_op<
00157                                 T, F<T, typename std::iterator_traits<iter_1>::value_type> >::
00158                                 from(*i1), *this);
00159                 }
00160 
00161                 // optional random access in iterator
00162                 reference operator[]
00163                         (typename tool::brackets_arg j) const
00164                 {
00165                         return reference(array_details::elem_func_unary_op<
00166                                 T, F<T, typename std::iterator_traits<iter_1>::value_type> >::
00167                                 from(tool::brackets(i1, j)),
00168                         // hope that the below line will be optimized-out when using T.
00169                         // or disregard the `tight' std:: standard that &(*iter) == &(*iter)
00170                                 rnd_iter(tool::add_op(i1, j)));
00171                 }
00172 
00173                 // increment-decrement
00174                 const_iterator& operator++()
00175                 {
00176                         ++i1;
00177                         return *this;
00178                 }
00179                 const_iterator& operator--()
00180                 {
00181                         --i1;
00182                         return *this;
00183                 }
00184 
00185                 const_iterator operator++(int)
00186                         { const_iterator tmp(*this); ++(*this); return tmp; }
00187 
00188                 const_iterator operator--(int)
00189                         { const_iterator tmp(*this); --(*this); return tmp; }
00190 
00191                 // random access. enabled only if 'has_random_access'
00192                 const_iterator& operator +=(typename tool::brackets_arg j)
00193                 {
00194                         tool::add_asgn(i1, j);
00195                         return *this;
00196                 }
00197                 const_iterator& operator -=(typename tool::brackets_arg j)
00198                 {
00199                         tool::sub_asgn(i1, j);
00200                         return *this;
00201                 }
00202                 inline rnd_iter operator +(typename tool::brackets_arg j) const
00203                 {
00204                         return rnd_iter(tool::add_op(i1, j));
00205                 }
00206                 inline rnd_iter operator -(typename tool::brackets_arg j) const
00207                 {
00208                         return rnd_iter(tool::sub_op(i1, j));
00209                 }
00210 
00211                 // difference
00212                 difference_type operator -(const rnd_iter& a) const
00213                 {
00214                         return tool::dif_op(i1, a.i1);
00215                 }
00216 
00217                 //copy same type iterator
00218                 const_iterator& operator=(const const_iterator& o)
00219                 {
00220                         i1 = o.i1;
00221                         return *this;
00222                 }
00223 
00224                 bool operator==(const const_iterator& o) const { return (i1 == o.i1); }
00225                 bool operator!=(const const_iterator& o) const { return (i1 != o.i1); }
00226                 bool operator<(const const_iterator& o) const { return (i1 < o.i1); }
00227                 bool operator<=(const const_iterator& o) const { return (i1 <= o.i1); }
00228                 bool operator>(const const_iterator& o) const { return (i1 > o.i1); }
00229                 bool operator>=(const const_iterator& o) const { return (i1 >= o.i1); }
00230         };
00231 
00232         typedef typename const_iterator::reference const_reference;
00233         typedef const_reference best_reference;
00234         typedef const_iterator best_iterator;
00235 
00236         typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00237 
00238         typedef typename const_iterator::iter_border_walker iter_border_walker;
00239         // TODO: correct place, same for binary elem_func, A::iter_border_walker, etc.
00240         iter_border_walker first_to_last() const { return this->length() - 1; }
00241         iter_border_walker begin_to_end() const { return this->length(); }
00242 
00243 
00244         const_iterator begin() const { return const_iterator(in1->begin()); }
00245         const_iterator end() const { return const_iterator(in1->end()); }
00246 
00247         const_reverse_iterator rbegin() const
00248                 { return const_reverse_iterator(in1->end()); }
00249         const_reverse_iterator rend() const
00250                 { return const_reverse_iterator(in1->begin()); }
00251 
00252 
00255 
00256 
00257         size_t length() const
00258         {
00259                 return in1->derived().length();
00260         }
00261 
00263         size_type size() const { return length(); }
00265         size_t numel() const { return length(); }
00274 
00275 
00276         /*
00277         T operator[](
00278                 typename tool::brackets_arg i) const
00279         {
00280                 CHECK(i >= 0 && i < length(), erange);
00281 
00282                 return array_details::elem_func_unary_op<
00283                         T, F<T, typename A::elem_type> >::
00284                         from(tool::brackets(in1->derived(), i));
00285         }*/
00286 
00287         const_reference operator[](
00288                 typename tool::brackets_arg i) const
00289         {
00290                 CHECK(i >= 0 && i < length(), erange);
00291 
00292                 return (begin()[i]);
00293         }
00302 
00303 
00304 
00305         void setref(const A& a)
00306         {
00307                 in1 = &a;
00308         }
00309 
00310         template <class D>
00311         inline bool self_overlap(const D& a) const
00312         {
00313                 // Do we need to specialize this so that in1->overlap(a) call is
00314                 // avoided? or is the inline mechanism adequate to cleverly
00315                 // optimize it out. For now let's rely on the compiler,
00316                 // since we've been doing this from the beginning.
00317                 return types::r_if<is_referencing_array>(a.overlap(*in1), false);
00318         }
00319 
00320         // TODO: place
00321         void init(const A& a) { setref(a); }
00322 
00323         void init(const array& o) { setref(*o.in1); }
00324 
00329 
00330         array() { }
00331 
00333         array(const A& a) { setref(a); }
00334 
00336         array(const array& o) { setref(*o.in1); }
00337 
00342 
00343         array(size_t) {}
00344 
00346         array(size_t, const T&) {}
00347 
00349         template <class J, class D>
00350         array(size_t, const array<J, D>&) {}
00351 
00353         array(size_t, const T*) {}
00354 
00356         template<class J, class S>
00357         array(const array<J, S>& a) {}
00358 
00360         array& operator=(const array& o)
00361         {
00362                 setref(*o.in1);
00363                 return *this;
00364                 //TODO: check
00365         }
00366 
00368         ~array() { }
00369 
00370 
00371 };
00372 
00373 template <class T, class J>
00374 struct force_class
00375 {
00376         typedef types::number<1> cost;
00377         static inline T elem_op(const J& elem1)
00378         {
00379                 return elem1;
00380         }
00381 };
 All Classes Namespaces Files Functions Variables Typedefs Enumerations