ivl 679
ivl/details/array/impl/specialization/array_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 
00025 // data::normal is defined in data_base.hpp
00026 
00032 template <class T, class OPTS = data::mem<> >
00033 class array:
00034 
00035         public array_common_base<array<T, OPTS> >,
00036 
00037         public std::vector<T>
00038 {
00039 private:
00040         typedef array_common_base<array<T, OPTS> > common_base_class;
00041 
00042 public:
00043         typedef typename types::t_not<types::is_bool<T> >::type has_c_ptr;
00044 
00045         typedef typename common_base_class::data_type data_type;
00046 
00047         typedef array <T, OPTS> this_type;
00048 
00049         typedef this_type this_array_type;
00050 
00051         typedef this_type array_type;
00052 
00053         typedef T elem_type;
00054 
00055         typedef typename this_type::derived_type derived_type;
00056 
00057         typedef typename common_base_class::base_class base_class;
00058 
00060         typedef size_t size_type;
00061 
00063         typedef ptrdiff_t diff_type;
00064 
00065         using base_class::derived;
00066 
00067         typedef typename std::vector<T>::iterator iterator;
00068         typedef typename std::vector<T>::const_iterator const_iterator;
00069         typedef typename std::vector<T>::reverse_iterator reverse_iterator;
00070         typedef typename std::vector<T>::
00071                 const_reverse_iterator const_reverse_iterator;
00072         using std::vector<T>::begin;
00073         using std::vector<T>::end;
00074         using std::vector<T>::rbegin;
00075         using std::vector<T>::rend;
00076 
00077         typedef iterator best_iterator;
00078         typedef typename const_iterator::reference const_reference;
00079         typedef typename iterator::reference reference;
00080         typedef reference best_reference;
00081 
00082         using common_base_class::assign; // vector assign is not used
00083         // left here along with array.assign() for now, however might be removed.
00084         using std::vector<T>::assign;
00085 
00086         void clear()
00087         {
00088                 std::vector<T>().swap(static_cast<std::vector<T>&>(*this));
00089         }
00090 
00091         void swap(std::vector<T>& v)
00092         {
00093                 std::vector<T>::swap(v);
00094         }
00095 
00096         //TODO: fix
00097         template<class J, class D>
00098         void swap(array<J, D>& a)
00099         {
00100                 this->derived() = a.derived();
00101         }
00102         /*template <class J, class D, class P>
00103         void swap(array_nd<J, D, P>& a)
00104         {
00105                 // error: can't swap array with array_nd.
00106                 throw(ecomp);
00107         }*/
00108 
00109         //TODO: what happens with resize? with base members. do resolve.
00110         //in need, create resize function here that does the right thing.
00111         using std::vector<T>::resize;
00112 
00114         void reshape(size_t len) { resize(len); }
00115         void reshape(size_t len, const T& s) { resize(len, s); }
00116 
00117 
00120 
00121         void init() { this->clear(); }
00122 
00124         void init(size_t count) { this->resize(count); /* does not need to keep data */ }
00125 
00127         void init(int count) { this->init(size_t(count)); }
00128 
00130         void init(long int count) { this->init(size_t(count)); }
00131 
00133         void init(size_t count, const T& s) { std::vector<T>::assign(count, s); }
00134 
00136         void init(size_t count, const T *ptr) { std::vector<T>::assign(ptr, ptr + count); }
00137 
00139         template <class J>
00140         void init(const internal::tuple_rvalue<J>& r)
00141                 { this->clear(); r.tuple_output(internal::reftpl(*this)); }
00142 
00144         void init(const array& a) { std::vector<T>::assign(a.begin(), a.end()); }
00145 
00147         template <class J, class S>
00148         void init(const array<J, S>& a, size_t n) 
00149         {
00150                 std::vector<T>::resize(n > 0 ? n : a.length());
00151                 ivl::copy_out(*this, a);
00152         }
00153 
00155         template <class J, class S>
00156         void init(const array<J, S>& a)
00157         {
00158                 // This implementation needs us to be careful.
00159                 // while  : std::vector<T>(a.begin(), a.end()) { } is always valid,
00160                 // it consumes double time of iteration for non-random-access arrays.
00161                 // so we will have to specialize it.
00162                 std::vector<T>::resize(0);
00163                 array_details::
00164                         vector_initializer<array<T, S>::has_random_access::value>
00165                         ::operate(static_cast<std::vector<T>&>(*this), a);
00166         }
00167 
00169         template <class J, class S>
00170         void init(size_t count, const array<J, S>& a)
00171         {
00172                 std::vector<T>::resize(count);
00173                 this->init_size_with(a);
00174         }
00175                 
00178         /*
00179         void resize(size_t sz)
00180         {
00181                 if(sz == 0)
00182                         std::vector<T>().swap(static_cast<std::vector<T>&>(*this));
00183                 else
00184                         std::vector<T>::resize(sz);
00185         }
00186 
00187         void resize(size_t sz, const T& s)
00188         {
00189                 if(sz == 0)
00190                         std::vector<T>().swap(static_cast<std::vector<T>&>(*this));
00191                 else
00192                         std::vector<T>::resize(sz, s);
00193         }
00194         */
00195         /*
00196         void reset(size_t sz, const T s = T())
00197         {
00198                 if(sz == 0 || sz > std::vector<T>::capacity()
00199                         || sz < std::vector<T>::capacity() / 2)
00200                         std::vector<T>().swap(static_cast<std::vector<T>&>(*this));
00201                 else
00202                         std::vector<T>::resize(0);
00203 
00204                 std::vector<T>::resize(sz, s);
00205         }
00206         */
00207 
00208         typedef ptrdiff_t iter_border_walker;
00209 
00210         // TODO:
00211         // warning: since bit vector does not return an actual pointer
00212         // this function is deceiving cause it doesn't return an actual c_ptr!
00213         // the solution to remove c_ptr from vector is not an option.
00214         // to remove it from bool vector is an option, or another option
00215         // is to get the bitmap data some way.
00216         // also would we need to have the pseudo pointer in some occasions?
00217         // by let's say another function, ptr(). ?
00218         typename std::vector<T>::pointer c_ptr()
00219                 { return &(std::vector<T>::operator[](0)); }
00220         typename std::vector<T>::const_pointer c_ptr() const
00221                 { return &(std::vector<T>::operator[](0)); }
00222 
00225         //TODO: explain this better.
00227         size_t length() const { return std::vector<T>::size(); }
00229         size_type size() const { return length(); }
00231         size_t numel() const { return length(); }
00234         iter_border_walker first_to_last() const { return this->length() - 1; }
00235         iter_border_walker begin_to_end() const { return this->length(); }
00236 
00242 
00243         typename std::vector<T>::const_reference operator[](size_t offset) const
00244         {
00245                 CHECK(offset >= 0 && offset < length(), erange);
00246                 return std::vector<T>::operator[](offset);
00247         }
00249         typename std::vector<T>::reference operator[](size_t offset)
00250         {
00251                 CHECK(offset >= 0 && offset < length(), erange);
00252                 return std::vector<T>::operator[](offset);
00253         }
00254 
00255         using common_base_class::operator[];
00256 
00262 
00263         array() { }
00264 
00266         explicit array(size_t count) : std::vector<T>(count) { }
00267 
00269         explicit array(int count) : std::vector<T>(size_t(count)) { }
00270 
00272         explicit array(long int count) : std::vector<T>(size_t(count)) { }
00273 
00280         array(size_t count, const T& s) : std::vector<T>(count, s) { }
00281 
00288         array(size_t count, const T *ptr) : std::vector<T>(ptr, ptr + count) { }
00289 
00290 
00296         template<class S, int J>
00297         array(S (&arr)[J]) : std::vector<T>(arr, arr + J) { }
00298 
00299 
00301         template <class J>
00302         array(const internal::tuple_rvalue<J>& r)
00303                 { r.tuple_output(internal::reftpl(*this)); }
00304 
00306         array(const array& a) : std::vector<T>(a.begin(), a.end()) { }
00307 
00316         template <class J, class S>
00317         inline
00318         array(const array<J, S>& a, size_t n) :
00319                 std::vector<T>(n > 0 ? n : a.length())
00320         {
00321                 ivl::copy_out(*this, a);
00322         }
00323 
00324 
00327         template <class J, class S>
00328         array(const array<J, S>& a)
00329         {
00330                 // This implementation needs us to be careful.
00331                 // while  : std::vector<T>(a.begin(), a.end()) { } is always valid,
00332                 // it consumes double time of iteration for non-random-access arrays.
00333                 // so we will have to specialize it.
00334                 array_details::
00335                         vector_initializer<array<T, S>::has_random_access::value>
00336                         ::operate(static_cast<std::vector<T>&>(*this), a);
00337         }
00338 
00350         template <class J, class S>
00351         array(size_t count, const array<J, S>& a) : std::vector<T>(count)
00352         {
00353                 this->init_size_with(a);
00354         }
00355 
00356 
00357 
00358 
00361 
00362         ~array() { }
00363 
00364 
00376         template<class K>
00377         derived_type& operator=(const K& k)
00378         {
00379                 common_base_class::operator=(k);
00380                 return derived();
00381         }
00382         //using common_base_class::operator=;
00383         this_type& operator=(const this_type& a) // LEFT IN THE CONST MODE FOR A COPY CONSTRUCTOR!
00384         {
00385                 // if(this != &a) TODO: make this a rule: make clear that ...
00386                 // Note: the data class handles the check: if(this != &a),
00387                 // and only IF needed, so there is no case of cpu waste
00388                 common_base_class::operator=(a);
00389                 return *this;
00390         }
00391 
00392 
00393         /*
00394         template<class S, class K>
00395         derived_type& operator=(const ivl::array<T, S, K>& a)
00396         {
00397                 common_base_class::operator=(a);
00398                 return derived();
00399         }
00400 
00401         derived_type& operator=(const T& s)
00402         */
00403 
00404 
00405 
00406 };
00407 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations