ivl 679
ivl/details/array/impl/common/readwrite_array_common.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 #ifndef IVL_ARRAY_DETAILS_COMMON_READWRITE_ARRAY_COMMON_HPP
00025 #define IVL_ARRAY_DETAILS_COMMON_READWRITE_ARRAY_COMMON_HPP
00026 
00027 namespace ivl {
00028 
00029 namespace array_details {
00030 
00031 template <
00032 class T, class S,
00033 class BASE,
00034 class IS_WRITEABLE >
00035 class readwrite_array_common
00036 {
00037 };
00038 
00039 //not writeable
00040 template <class T, class S, class BASE>
00041 class readwrite_array_common<T, S, BASE, types::t_false>
00042 : public conversions_array_common<T, S, BASE>
00043 {
00044 private:
00045         typedef readwrite_array_common prv_this_type;
00046         typedef array<T, S> t;
00047         t& to_array() { return static_cast<t&>(*this); }
00048         const t& to_array() const { return static_cast<const t&>(*this); }
00049 public:
00050         // ++
00051         // for not writeable arrays, ++ iterates through all the elements...
00052         t& operator++()
00053         {
00054                 typedef typename t::const_iterator c_it;
00055                 for(c_it i = to_array().begin(); i!= to_array().end(); i++) *i;
00056                 return to_array();
00057         }
00058 };
00059 
00060 //writeable
00061 template <class T, class S, class BASE>
00062 class readwrite_array_common<T, S, BASE, types::t_true>
00063 : public conversions_array_common<T, S, BASE>
00064 {
00065 private:
00066         typedef readwrite_array_common prv_this_type;
00067         typedef array<T, S> t;
00068         t& to_array() { return static_cast<t&>(*this); }
00069         const t& to_array() const { return static_cast<const t&>(*this); }
00070 
00071 public:
00072         typedef typename prv_this_type::derived_type derived_type;
00073         // everything is defined twice
00074         // the unsafe way (function call) and the safe way (operator).
00075 
00076         // the unsafe way -------------------------------------------
00077 
00078         //plus_assign(), for +=
00079         template <class A>
00080         derived_type& plus_assign(const A& a)
00081         {
00082                 loop_on<loops::assign_plus_class>(this->derived(), a);
00083                 return this->derived();
00084         }
00085 
00086         //minus_assign(), for -=
00087         template <class A>
00088         derived_type& minus_assign(const A& a)
00089         {
00090                 loop_on<loops::assign_minus_class>(this->derived(), a);
00091                 return this->derived();
00092         }
00093 
00094         //times_assign(), for *=
00095         template <class A>
00096         derived_type& times_assign(const A& a)
00097         {
00098                 loop_on<loops::assign_times_class>(this->derived(), a);
00099                 return this->derived();
00100         }
00101 
00102         //divide_assign(), for /=
00103         template <class A>
00104         derived_type& divide_assign(const A& a)
00105         {
00106                 loop_on<loops::assign_divide_class>(this->derived(), a);
00107                 return this->derived();
00108         }
00109 
00110         // mod_assign(), for %=
00111         template <class A>
00112         derived_type& mod_assign(const A& a)
00113         {
00114                 loop_on<loops::assign_mod_class>(this->derived(), a);
00115                 return this->derived();
00116         }
00117 
00118         // bitor_assign(), for |=
00119         template <class A>
00120         derived_type& bitor_assign(const A& a)
00121         {
00122                 loop_on<loops::assign_bitor_class>(this->derived(), a);
00123                 return this->derived();
00124         }
00125 
00126         // bitand_assign(), for &=
00127         template <class A>
00128         derived_type& bitand_assign(const A& a)
00129         {
00130                 loop_on<loops::assign_bitand_class>(this->derived(), a);
00131                 return this->derived();
00132         }
00133 
00134         // bitxor_assign(), for ^=
00135         template <class A>
00136         derived_type& bitxor_assign(const A& a)
00137         {
00138                 loop_on<loops::assign_bitxor_class>(this->derived(), a);
00139                 return this->derived();
00140         }
00141 
00142         // bitlshift_assign(), for <<=
00143         template <class A>
00144         derived_type& bitlshift_assign(const A& a)
00145         {
00146                 loop_on<loops::assign_bitlshift_class>(this->derived(), a);
00147                 return this->derived();
00148         }
00149 
00150         // bitrshift_assign(), for >>=
00151         template <class A>
00152         derived_type& bitrshift_assign(const A& a)
00153         {
00154                 loop_on<loops::assign_bitrshift_class>(this->derived(), a);
00155                 return this->derived();
00156         }
00157 
00158 
00159         // decrement(), for --. no safe/unsafe way
00160         derived_type& decrement()
00161         {
00162                 //todo: unary loop
00163                 this->minus_assign(1);
00164                 return this->derived();
00165         }
00166 
00167         // increment(), for ++. no safe/unsafe way
00168         derived_type& increment()
00169         {
00170                 //todo: unary loop
00171                 this->plus_assign(1);
00172                 return this->derived();
00173         }
00174 
00175         // --------------------------------------------------------
00176         // the safe way (operator)
00177 
00178 
00179         //+=
00180         template <class A>
00181         derived_type& operator+=(const A& a)
00182         {
00183                 safe_loop_on<loops::assign_plus_class>(this->derived(), a);
00184                 return this->derived();
00185         }
00186 
00187         //-=
00188         template <class A>
00189         derived_type& operator-=(const A& a)
00190         {
00191                 safe_loop_on<loops::assign_minus_class>(this->derived(), a);
00192                 return this->derived();
00193         }
00194 
00195         //*=
00196         template <class A>
00197         derived_type& operator*=(const A& a)
00198         {
00199                 safe_loop_on<loops::assign_times_class>(this->derived(), a);
00200                 return this->derived();
00201         }
00202 
00203         // /=
00204         template <class A>
00205         derived_type& operator/=(const A& a)
00206         {
00207                 safe_loop_on<loops::assign_divide_class>(this->derived(), a);
00208                 return this->derived();
00209         }
00210 
00211         // %=
00212         template <class A>
00213         derived_type& operator%=(const A& a)
00214         {
00215                 safe_loop_on<loops::assign_mod_class>(this->derived(), a);
00216                 return this->derived();
00217         }
00218 
00219         // |=
00220         template <class A>
00221         derived_type& operator|=(const A& a)
00222         {
00223                 safe_loop_on<loops::assign_bitor_class>(this->derived(), a);
00224                 return this->derived();
00225         }
00226 
00227         // &=
00228         template <class A>
00229         derived_type& operator&=(const A& a)
00230         {
00231                 safe_loop_on<loops::assign_bitand_class>(this->derived(), a);
00232                 return this->derived();
00233         }
00234 
00235         // ^=
00236         template <class A>
00237         derived_type& operator^=(const A& a)
00238         {
00239                 safe_loop_on<loops::assign_bitxor_class>(this->derived(), a);
00240                 return this->derived();
00241         }
00242 
00243         // <<=
00244         template <class A>
00245         derived_type& operator<<=(const A& a)
00246         {
00247                 safe_loop_on<loops::assign_bitlshift_class>(this->derived(), a);
00248                 return this->derived();
00249         }
00250 
00251         // >>=
00252         template <class A>
00253         derived_type& operator>>=(const A& a)
00254         {
00255                 safe_loop_on<loops::assign_bitrshift_class>(this->derived(), a);
00256                 return this->derived();
00257         }
00258 
00259         // --
00260         derived_type& operator--()
00261         {
00262                 //todo: unary loop
00263                 this->decrement();
00264                 return this->derived();
00265         }
00266 
00267         elem_func_unary<T, plus1_class,
00268                 typename readwrite_array_common::derived_type> operator--(int)
00269         {
00270                 //todo: unary loop
00271                 typedef elem_func_unary<T, plus1_class,
00272                         typename readwrite_array_common::derived_type> ret_t;
00273                 this->decrement();
00274                 return ret_t(this->derived());
00275         }
00276 
00277         // ++
00278         derived_type& operator++()
00279         {
00280                 //todo: unary loop
00281                 this->increment();
00282                 return this->derived();
00283         }
00284 
00285         elem_func_unary<T, minus1_class,
00286                 typename readwrite_array_common::derived_type> operator++(int)
00287         {
00288                 //todo: unary loop
00289                 typedef elem_func_unary<T, minus1_class,
00290                         typename readwrite_array_common::derived_type> ret_t;
00291                 this->increment();
00292                 return ret_t(this->derived());
00293         }
00294 
00295 
00296         template <class D>
00297         void swap(array<T, D>& a)
00298         {
00299                 // This algorithm is really bad.
00300                 // Needs some improvement. However this is not a priority.
00301                 // Also: I need to check that arrays are of the same level.
00302                 size_t tl = to_array().length();
00303                 size_t al = a.length();
00304                 size_t mxs = std::max(tl, al);
00305                 bool ok;
00306                 /*
00307                 int mns = std::min(length(), a.length());
00308                 loops::loop_ww<write_write_swap_class, T, T>(*this, a);*/
00309                 ok = types::r_resize(to_array(), mxs);
00310                 CHECK(ok, ecomp);
00311                 ok = types::r_resize(a, mxs);
00312                 CHECK(ok, ecomp);
00313 
00314                 // not fast enough. need loop with count or something.
00315                 loops::loop_ww<loops::write_write_swap_class, T, T>(to_array(), a);
00316 
00317                 ok = types::r_resize(to_array(), al);
00318                 CHECK(ok, ecomp);
00319                 ok = types::r_resize(a, tl);
00320                 CHECK(ok, ecomp);
00321         }
00322 
00323 };
00324 
00325 
00326 } /* namespace array_details */
00327 
00328 } /* namespace ivl */
00329 
00330 #endif // IVL_ARRAY_DETAILS_COMMON_READWRITE_ARRAY_COMMON_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations